38 #ifndef FCL_BROADPHASE_BROADPAHSESPATIALHASH_INL_H 39 #define FCL_BROADPHASE_BROADPAHSESPATIALHASH_INL_H 41 #include "fcl/broadphase/broadphase_spatialhash.h" 48 class SpatialHashingCollisionManager<
50 detail::SimpleHashTable<
51 AABB<double>, CollisionObject<double>*, detail::SpatialHash<double>>>;
54 template<
typename S,
typename HashTable>
55 SpatialHashingCollisionManager<S, HashTable>::SpatialHashingCollisionManager(
57 const Vector3<S>& scene_min,
58 const Vector3<S>& scene_max,
59 unsigned int default_table_size)
60 : scene_limit(AABB<S>(scene_min, scene_max)),
61 hash_table(new HashTable(detail::SpatialHash<S>(scene_limit, cell_size)))
63 hash_table->init(default_table_size);
67 template<
typename S,
typename HashTable>
68 SpatialHashingCollisionManager<S, HashTable>::~SpatialHashingCollisionManager()
74 template<
typename S,
typename HashTable>
83 if(scene_limit.overlap(obj_aabb, overlap_aabb))
85 if(!scene_limit.contain(obj_aabb))
86 objs_partially_penetrating_scene_limit.push_back(obj);
88 hash_table->insert(overlap_aabb, obj);
92 objs_outside_scene_limit.push_back(obj);
95 obj_aabb_map[obj] = obj_aabb;
99 template<
typename S,
typename HashTable>
107 if(scene_limit.overlap(obj_aabb, overlap_aabb))
109 if(!scene_limit.contain(obj_aabb))
110 objs_partially_penetrating_scene_limit.remove(obj);
112 hash_table->remove(overlap_aabb, obj);
116 objs_outside_scene_limit.remove(obj);
119 obj_aabb_map.erase(obj);
123 template<
typename S,
typename HashTable>
130 template<
typename S,
typename HashTable>
134 objs_partially_penetrating_scene_limit.clear();
135 objs_outside_scene_limit.clear();
137 for(
auto it = objs.cbegin(), end = objs.cend(); it != end; ++it)
143 if(scene_limit.overlap(obj_aabb, overlap_aabb))
145 if(!scene_limit.contain(obj_aabb))
146 objs_partially_penetrating_scene_limit.push_back(obj);
148 hash_table->insert(overlap_aabb, obj);
152 objs_outside_scene_limit.push_back(obj);
155 obj_aabb_map[obj] = obj_aabb;
160 template<
typename S,
typename HashTable>
164 const AABB<S>& old_aabb = obj_aabb_map[updated_obj];
167 const auto is_old_aabb_overlapping
168 = scene_limit.
overlap(old_aabb, old_overlap_aabb);
169 if(is_old_aabb_overlapping)
170 hash_table->remove(old_overlap_aabb, updated_obj);
173 const auto is_new_aabb_overlapping
174 = scene_limit.
overlap(new_aabb, new_overlap_aabb);
175 if(is_new_aabb_overlapping)
176 hash_table->insert(new_overlap_aabb, updated_obj);
178 ObjectStatus old_status;
179 if(is_old_aabb_overlapping)
181 if(scene_limit.contain(old_aabb))
184 old_status = PartiallyPenetrating;
188 old_status = Outside;
191 if(is_new_aabb_overlapping)
193 if(scene_limit.contain(new_aabb))
195 if (old_status == PartiallyPenetrating)
201 auto find_it = std::find(objs_partially_penetrating_scene_limit.begin(),
202 objs_partially_penetrating_scene_limit.end(),
204 objs_partially_penetrating_scene_limit.erase(find_it);
206 else if (old_status == Outside)
212 auto find_it = std::find(objs_outside_scene_limit.begin(),
213 objs_outside_scene_limit.end(),
215 objs_outside_scene_limit.erase(find_it);
220 if (old_status == Inside)
226 objs_partially_penetrating_scene_limit.push_back(updated_obj);
228 else if (old_status == Outside)
235 auto find_it = std::find(objs_outside_scene_limit.begin(),
236 objs_outside_scene_limit.end(),
238 objs_outside_scene_limit.erase(find_it);
240 objs_partially_penetrating_scene_limit.push_back(updated_obj);
246 if (old_status == Inside)
252 objs_outside_scene_limit.push_back(updated_obj);
254 else if (old_status == PartiallyPenetrating)
261 auto find_it = std::find(objs_partially_penetrating_scene_limit.begin(),
262 objs_partially_penetrating_scene_limit.end(),
264 objs_partially_penetrating_scene_limit.erase(find_it);
266 objs_outside_scene_limit.push_back(updated_obj);
270 obj_aabb_map[updated_obj] = new_aabb;
274 template<
typename S,
typename HashTable>
277 for(
size_t i = 0; i < updated_objs.size(); ++i)
282 template<
typename S,
typename HashTable>
287 objs_outside_scene_limit.clear();
288 obj_aabb_map.clear();
292 template<
typename S,
typename HashTable>
295 objs_.resize(objs.size());
296 std::copy(objs.begin(), objs.end(), objs_.begin());
300 template<
typename S,
typename HashTable>
303 if(
size() == 0)
return;
304 collide_(obj, cdata, callback);
308 template<
typename S,
typename HashTable>
311 if(
size() == 0)
return;
312 S min_dist = std::numeric_limits<S>::max();
313 distance_(obj, cdata, callback, min_dist);
317 template<
typename S,
typename HashTable>
321 const auto& obj_aabb = obj->
getAABB();
324 if(scene_limit.overlap(obj_aabb, overlap_aabb))
326 const auto query_result = hash_table->query(overlap_aabb);
327 for(
const auto& obj2 : query_result)
332 if(callback(obj, obj2, cdata))
336 if(!scene_limit.contain(obj_aabb))
338 for(
const auto& obj2 : objs_outside_scene_limit)
343 if(callback(obj, obj2, cdata))
350 for(
const auto& obj2 : objs_partially_penetrating_scene_limit)
355 if(callback(obj, obj2, cdata))
359 for(
const auto& obj2 : objs_outside_scene_limit)
364 if(callback(obj, obj2, cdata))
373 template<
typename S,
typename HashTable>
379 if(min_dist < std::numeric_limits<S>::max())
381 Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
382 aabb.expand(min_dist_delta);
392 old_min_distance = min_dist;
394 if(scene_limit.overlap(aabb, overlap_aabb))
396 if (distanceObjectToObjects(
397 obj, hash_table->query(overlap_aabb), cdata, callback, min_dist))
402 if(!scene_limit.contain(aabb))
404 if (distanceObjectToObjects(
405 obj, objs_outside_scene_limit, cdata, callback, min_dist))
413 if (distanceObjectToObjects(
414 obj, objs_partially_penetrating_scene_limit, cdata, callback, min_dist))
419 if (distanceObjectToObjects(
420 obj, objs_outside_scene_limit, cdata, callback, min_dist))
428 if(old_min_distance < std::numeric_limits<S>::max())
434 if(min_dist < old_min_distance)
436 Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
459 template<
typename S,
typename HashTable>
466 for(
const auto& obj1 : objs)
468 const auto& obj_aabb = obj1->getAABB();
471 if(scene_limit.overlap(obj_aabb, overlap_aabb))
473 auto query_result = hash_table->query(overlap_aabb);
474 for(
const auto& obj2 : query_result)
478 if(callback(obj1, obj2, cdata))
483 if(!scene_limit.contain(obj_aabb))
485 for(
const auto& obj2 : objs_outside_scene_limit)
489 if(callback(obj1, obj2, cdata))
497 for(
const auto& obj2 : objs_partially_penetrating_scene_limit)
501 if(callback(obj1, obj2, cdata))
506 for(
const auto& obj2 : objs_outside_scene_limit)
510 if(callback(obj1, obj2, cdata))
519 template<
typename S,
typename HashTable>
526 this->enable_tested_set_ =
true;
529 S min_dist = std::numeric_limits<S>::max();
531 for(
const auto& obj : objs)
533 if(distance_(obj, cdata, callback, min_dist))
537 this->enable_tested_set_ =
false;
542 template<
typename S,
typename HashTable>
547 if((
size() == 0) || (other_manager->size() == 0))
550 if(
this == other_manager)
556 if(this->
size() < other_manager->size())
558 for(
const auto& obj : objs)
560 if(other_manager->collide_(obj, cdata, callback))
566 for(
const auto& obj : other_manager->objs)
568 if(collide_(obj, cdata, callback))
575 template<
typename S,
typename HashTable>
580 if((
size() == 0) || (other_manager->size() == 0))
583 if(
this == other_manager)
589 S min_dist = std::numeric_limits<S>::max();
591 if(this->
size() < other_manager->size())
593 for(
const auto& obj : objs)
594 if(other_manager->distance_(obj, cdata, callback, min_dist))
return;
598 for(
const auto& obj : other_manager->objs)
599 if(distance_(obj, cdata, callback, min_dist))
return;
604 template<
typename S,
typename HashTable>
611 template<
typename S,
typename HashTable>
618 template<
typename S,
typename HashTable>
623 for(
unsigned int i = 0; i < objs.size(); ++i)
624 bound += objs[i]->getAABB();
631 template<
typename S,
typename HashTable>
632 template<
typename Container>
635 const Container& objs,
640 for(
auto& obj2 : objs)
645 if(!this->enable_tested_set_)
649 if(callback(obj, obj2, cdata, min_dist))
655 if(!this->inTestedSet(obj, obj2))
659 if(callback(obj, obj2, cdata, min_dist))
663 this->insertTestedSet(obj, obj2);
void getObjects(std::vector< CollisionObject< S > * > &objs) const
return the objects managed by the manager
Definition: broadphase_spatialhash-inl.h:293
void clear()
clear the manager
Definition: broadphase_spatialhash-inl.h:283
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
void distance(CollisionObject< S > *obj, void *cdata, DistanceCallBack< S > callback) const
perform distance computation between one object and all the objects belonging to the manager ...
Definition: broadphase_SaP-inl.h:759
bool empty() const
whether the manager is empty
Definition: broadphase_spatialhash-inl.h:605
void collide(CollisionObject< S > *obj, void *cdata, CollisionCallBack< S > callback) const
perform collision test between one object and all the objects belonging to the manager ...
Definition: broadphase_spatialhash-inl.h:301
size_t size() const
the number of objects managed by the manager
Definition: broadphase_SaP-inl.h:880
static void computeBound(std::vector< CollisionObject< S > * > &objs, Vector3< S > &l, Vector3< S > &u)
compute the bound for the environent
Definition: broadphase_spatialhash-inl.h:619
void distance(CollisionObject< S > *obj, void *cdata, DistanceCallBack< S > callback) const
perform distance computation between one object and all the objects belonging ot the manager ...
Definition: broadphase_spatialhash-inl.h:309
spatial hashing collision mananger
Definition: broadphase_spatialhash.h:56
bool overlap(const AABB< S > &other) const
Check whether two AABB are overlap.
Definition: AABB-inl.h:98
Vector3< S > max_
The max point in the AABB.
Definition: AABB.h:59
std::set< std::pair< CollisionObject< S > *, CollisionObject< S > * > > tested_set
tools help to avoid repeating collision or distance callback for the pairs of objects tested before...
Definition: broadphase_collision_manager.h:127
bool(*)(CollisionObject< S > *o1, CollisionObject< S > *o2, void *cdata) CollisionCallBack
Callback for collision between two objects. Return value is whether can stop now. ...
Definition: broadphase_collision_manager.h:53
void update()
update the condition of manager
Definition: broadphase_SaP-inl.h:507
bool(*)(CollisionObject< S > *o1, CollisionObject< S > *o2, void *cdata, S &dist) DistanceCallBack
Callback for distance between two objects, Return value is whether can stop now, also return the mini...
Definition: broadphase_collision_manager.h:60
void registerObject(CollisionObject< S > *obj)
add one object to the manager
Definition: broadphase_spatialhash-inl.h:75
Vector3< S > min_
The min point in the AABB.
Definition: AABB.h:56
bool collide_(CollisionObject< S > *obj, void *cdata, CollisionCallBack< S > callback) const
perform collision test between one object and all the objects belonging to the manager ...
Definition: broadphase_spatialhash-inl.h:318
void setup()
initialize the manager, related with the specific type of manager
Definition: broadphase_spatialhash-inl.h:124
const AABB< S > & getAABB() const
get the AABB in world space
Definition: collision_object-inl.h:111
void collide(CollisionObject< S > *obj, void *cdata, CollisionCallBack< S > callback) const
perform collision test between one object and all the objects belonging to the manager ...
Definition: broadphase_SaP-inl.h:642
the object for collision or distance computation, contains the geometry and the transform information...
Definition: collision_object.h:51
Base class for broad phase collision. It helps to accelerate the collision/distance between N objects...
Definition: broadphase_collision_manager.h:66
bool distance_(CollisionObject< S > *obj, void *cdata, DistanceCallBack< S > callback, S &min_dist) const
perform distance computation between one object and all the objects belonging ot the manager ...
Definition: broadphase_spatialhash-inl.h:374
AABB< S > & expand(const Vector3< S > &delta)
expand the half size of the AABB by delta, and keep the center unchanged.
Definition: AABB-inl.h:327
S distance(const AABB< S > &other, Vector3< S > *P, Vector3< S > *Q) const
Distance between two AABBs; P and Q, should not be nullptr, return the nearest points.
Definition: AABB-inl.h:237
size_t size() const
the number of objects managed by the manager
Definition: broadphase_spatialhash-inl.h:612
void unregisterObject(CollisionObject< S > *obj)
remove one object from the manager
Definition: broadphase_spatialhash-inl.h:100
void update()
update the condition of manager
Definition: broadphase_spatialhash-inl.h:131