1 #ifndef CPP_COLLISION_INCLUDE_COLLISION_GRID_BOX2D_H_ 2 #define CPP_COLLISION_INCLUDE_COLLISION_GRID_BOX2D_H_ 9 #include <box2d/b2_dynamic_tree.h> 10 #include <boost/align/aligned_allocator.hpp> 21 std::vector<T, boost::alignment::aligned_allocator<T, 16>>;
25 namespace accelerators {
40 typedef Eigen::Matrix<uint64_t, Eigen::Dynamic, 1>
VectorXi64;
44 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
50 for (
auto obj : objects_in) {
53 double min_x = std::numeric_limits<double>::max();
54 double max_x = std::numeric_limits<double>::min();
55 double min_y = std::numeric_limits<double>::max();
56 double max_y = std::numeric_limits<double>::min();
57 for (
auto obj : objects_in) {
60 min_x = std::min(min_x, aabb.
x_min);
61 min_y = std::min(min_y, aabb.
y_min);
62 max_x = std::max(max_x, aabb.
x_max);
63 max_y = std::max(max_y, aabb.
y_max);
66 broadphase_manager_ =
new b2DynamicTree();
73 for (
auto obj : sg_ptr->
unpack()) {
77 auto sg_aabb = sg_ptr->
getAABB();
78 double min_x = sg_aabb->min()(0);
79 double min_y = sg_aabb->min()(1);
80 double max_x = sg_aabb->max()(0);
81 double max_y = sg_aabb->max()(1);
83 broadphase_manager_ =
new b2DynamicTree();
89 if (broadphase_manager_)
delete broadphase_manager_;
96 registerObjectId(obj);
97 aabbs_.push_back(aabb);
98 ObjectProxy proxy = CreateProxy(obj, aabbs_.back());
99 objects_.push_back(proxy);
118 numchecks_ += objects_.size();
119 getCandidates(proxy, collision_candidates);
124 for (
int i = 0; i < objects_optimized_id_.size(); i++) {
128 collision_candidates2.push_back(objects_optimized_id_[i]);
133 std::sort(collision_candidates2.begin(), collision_candidates2.end());
134 std::set<int> collision_candidates_set;
135 for (
auto el : collision_candidates) {
136 collision_candidates_set.insert(el);
138 std::sort(collision_candidates.begin(), collision_candidates.end());
139 int found_count = std::unique(collision_candidates.begin(),
140 collision_candidates.end()) -
141 collision_candidates.begin();
142 int real_count = std::unique(collision_candidates2.begin(),
143 collision_candidates2.end()) -
144 collision_candidates2.begin();
146 volatile int missed = real_count - found_count;
148 bool bMissed =
false;
150 for (
auto el : collision_candidates2) {
151 if (collision_candidates_set.find(el) ==
152 collision_candidates_set.end()) {
158 if (missed > 0 || bMissed) {
159 std::cout <<
"broadphase verification: miss\n";
160 throw std::exception();
166 collision_checked_id_.fill(0);
167 int numcands_local = 0;
170 std::vector<OBB_SAT2D, Eigen::aligned_allocator<OBB_SAT2D>>
172 obb1_fast_container.emplace_back(obb1->
center(), obb1->
r_x() * 2,
176 for (
auto el : collision_candidates) {
177 if ((el < 0) || (el >= fast_obbs_.size())) {
178 std::cout <<
"internal error";
179 throw std::exception();
181 if (!collision_checked_id_(el)) {
182 collision_checked_id_(el) = 1;
184 if (fast_obbs_[el].
overlaps(*(obb1_fast_container.begin())))
187 numcands_ += numcands_local;
193 for (
auto el : collision_candidates) {
194 if (!collision_checked_id_(el)) {
196 collision_checked_id_(el) = 1;
198 if (object_by_id_[el]->collide(*obj)) {
199 numcands_ += numcands_local;
205 numcands_ += numcands_local;
215 b2DynamicTree* broadphase_manager_;
217 std::vector<AABB> aabbs_;
218 std::vector<b2AABB> box2d_objects_;
220 std::vector<ObjectProxy> objects_;
222 VectorXi64 masks_optimized_;
223 Eigen::VectorXi res_mask_optimized_;
226 std::vector<OBB_SAT2D, Eigen::aligned_allocator<OBB_SAT2D>> fast_obbs_;
227 Eigen::VectorXi collision_checked_id_;
229 std::map<const CollisionObject*, int> object_ids_;
236 void constructHelper(
void) {
239 broadphase_manager_ = 0;
242 inline int finalizeCreation(
void) {
243 int total_objects = 0;
244 total_objects += objects_.size();
246 objects_optimized_id_.clear();
247 object_by_id_.clear();
248 object_by_id_.resize(object_ids_.size());
249 collision_checked_id_ = Eigen::VectorXi::Zero(object_ids_.size());
251 masks_optimized_ = VectorXi64::Zero(total_objects);
252 res_mask_optimized_ = Eigen::VectorXi::Zero(total_objects);
255 for (
auto el : objects_) {
261 objects_optimized_id_.push_back(getObjectId(el.obj_ptr));
262 object_by_id_[objects_optimized_id_.back()] = el.obj_ptr;
263 masks_optimized_[objects_optimized_id_.size() - 1] = el.mask;
264 auto curAABB = &aabbs_[objects_optimized_id_.back()];
266 (curAABB->x_max - curAABB->x_min) / 2,
267 (curAABB->y_max - curAABB->y_min) / 2,
268 Eigen::Vector2d((curAABB->x_max + curAABB->x_min) / 2,
269 (curAABB->y_max + curAABB->y_min) / 2)));
270 box2d_objects_.emplace_back();
272 box2d_objects_.back().lowerBound =
273 b2Vec2(curAABB->x_min - eps, curAABB->y_min - eps);
274 box2d_objects_.back().upperBound =
275 b2Vec2(curAABB->x_max + eps, curAABB->y_max + eps);
277 for (
auto id : objects_optimized_id_) {
278 broadphase_manager_->CreateProxy(box2d_objects_[
id],
279 &objects_optimized_id_[
id]);
290 b2Obj.lowerBound = b2Vec2(curAABB.
x_min - eps, curAABB.
y_min - eps);
291 b2Obj.upperBound = b2Vec2(curAABB.
x_max + eps, curAABB.
y_max + eps);
294 broadphase_manager_->Query(&reqData, b2Obj);
295 for (
auto el : candidates2) {
296 candidates.push_back(*((
int*)(broadphase_manager_->GetUserData(el))));
302 auto search = object_ids_.find(obj);
303 if (search != object_ids_.end()) {
304 return search->second;
306 throw std::exception();
309 inline uint64_t get_mask(
const AABB& obj) {
return 0; }
313 uint64_t mask = get_mask(aabb);
319 object_ids_.insert(std::make_pair(obj, (
int)object_ids_.size()));
324 fast_obbs_.emplace_back(obb_in->
center(), obb_in->
r_x() * 2,
336 auto aabb_fcl = obj->
getAABB();
337 return AABB(*aabb_fcl);
Eigen::Vector2d local_y_axis() const
std::vector< T, boost::alignment::aligned_allocator< T, 16 > > aligned_vector
#define TIMER_grid_narrowphase
int addObject(const CollisionObject *obj)
aligned_vector< int > * candidates_
virtual CollisionObjectClass getCollisionObjectClass() const
std::vector< ShapeConstPtr > unpack() const
Returns Vector of all shapes contained inside the ShapeGroup.
std::vector< T, boost::alignment::aligned_allocator< T, 16 > > aligned_vector
std::shared_ptr< const RectangleAABB > RectangleAABBConstPtr
Eigen::Matrix< uint64_t, Eigen::Dynamic, 1 > VectorXi64
std::shared_ptr< const collision::RectangleAABB > getAABB() const
EIGEN_MAKE_ALIGNED_OPERATOR_NEW ContainerBox2D(aligned_vector< collision::CollisionObject *> objects_in, const ContainerSettings &sett)
bool collides_eps(const AABB_SAT2D &other, double eps)
ShapeGroup can contain simple shapes.
#define TIMER_grid_hashing
AABB getAABB(const CollisionObject *obj)
ContainerCollisionRequestDataBox2D(aligned_vector< int > &candidates)
bool QueryCallback(int obj_id)
CollisionObject * obj_ptr
ContainerBox2D(const ShapeGroup *sg_ptr, const ContainerSettings &sett)
virtual CollisionObjectType getCollisionObjectType() const
virtual std::shared_ptr< const collision::RectangleAABB > getAABB() const =0
int checkCollision(const CollisionObject *obj, const ContainerCollisionRequest &req)
virtual ~ContainerBox2D()
Base class for CollisionObjects and some of their groups.
Eigen::Vector2d local_x_axis() const
bool overlaps(const Triangle_SAT2D &tri, const OBB_SAT2D &obb)
#define TIMER_grid_candidates
Eigen::Vector2d center() const
Get geometric center of shape.