38 #ifndef FCL_BROAD_PHASE_DYNAMIC_AABB_TREE_ARRAY_INL_H 39 #define FCL_BROAD_PHASE_DYNAMIC_AABB_TREE_ARRAY_INL_H 57 namespace dynamic_AABB_tree_array
65 bool collisionRecurse_(
68 const OcTree<S>* tree2,
69 const typename OcTree<S>::OcTreeNode* root2,
97 return callback(obj1, &obj2, cdata);
103 if(collisionRecurse_<S>(nodes1, root1->
children[0], tree2,
nullptr, root2_bv, tf2, cdata, callback))
105 if(collisionRecurse_<S>(nodes1, root1->
children[1], tree2,
nullptr, root2_bv, tf2, cdata, callback))
111 else if(root1->
isLeaf() && !tree2->nodeHasChildren(root2))
114 if(!tree2->isNodeFree(root2) && !obj1->
isFree())
130 return callback(obj1, &obj2, cdata);
141 if(tree2->isNodeFree(root2) || !obb1.
overlap(obb2))
return false;
143 if(!tree2->nodeHasChildren(root2) || (!root1->
isLeaf() && (root1->
bv.size() > root2_bv.
size())))
145 if(collisionRecurse_(nodes1, root1->
children[0], tree2, root2, root2_bv, tf2, cdata, callback))
147 if(collisionRecurse_(nodes1, root1->
children[1], tree2, root2, root2_bv, tf2, cdata, callback))
152 for(
unsigned int i = 0; i < 8; ++i)
154 if(tree2->nodeChildExists(root2, i))
156 const typename OcTree<S>::OcTreeNode* child = tree2->getNodeChild(root2, i);
158 computeChildBV(root2_bv, i, child_bv);
160 if(collisionRecurse_(nodes1, root1_id, tree2, child, child_bv, tf2, cdata, callback))
166 computeChildBV(root2_bv, i, child_bv);
167 if(collisionRecurse_<S>(nodes1, root1_id, tree2,
nullptr, child_bv, tf2, cdata, callback))
177 template <
typename S,
typename Derived>
179 bool collisionRecurse_(
182 const OcTree<S>* tree2,
183 const typename OcTree<S>::OcTreeNode* root2,
185 const Eigen::MatrixBase<Derived>& translation2,
199 if(root1->
bv.overlap(root_bv_t))
204 tf2.translation() = translation2;
210 return callback(obj1, &obj2, cdata);
216 if(collisionRecurse_<S>(nodes1, root1->
children[0], tree2,
nullptr, root2_bv, translation2, cdata, callback))
218 if(collisionRecurse_<S>(nodes1, root1->
children[1], tree2,
nullptr, root2_bv, translation2, cdata, callback))
224 else if(root1->
isLeaf() && !tree2->nodeHasChildren(root2))
227 if(!tree2->isNodeFree(root2) && !obj1->
isFree())
230 if(root1->
bv.overlap(root_bv_t))
235 tf2.translation() = translation2;
242 return callback(obj1, &obj2, cdata);
250 if(tree2->isNodeFree(root2) || !root1->
bv.overlap(root_bv_t))
return false;
252 if(!tree2->nodeHasChildren(root2) || (!root1->
isLeaf() && (root1->
bv.size() > root2_bv.
size())))
254 if(collisionRecurse_(nodes1, root1->
children[0], tree2, root2, root2_bv, translation2, cdata, callback))
256 if(collisionRecurse_(nodes1, root1->
children[1], tree2, root2, root2_bv, translation2, cdata, callback))
261 for(
unsigned int i = 0; i < 8; ++i)
263 if(tree2->nodeChildExists(root2, i))
265 const typename OcTree<S>::OcTreeNode* child = tree2->getNodeChild(root2, i);
267 computeChildBV(root2_bv, i, child_bv);
269 if(collisionRecurse_(nodes1, root1_id, tree2, child, child_bv, translation2, cdata, callback))
275 computeChildBV(root2_bv, i, child_bv);
276 if(collisionRecurse_<S>(nodes1, root1_id, tree2,
nullptr, child_bv, translation2, cdata, callback))
286 template <
typename S>
291 if(root1->
isLeaf() && !tree2->nodeHasChildren(root2))
293 if(tree2->isNodeOccupied(root2))
304 if(!tree2->isNodeOccupied(root2))
return false;
306 if(!tree2->nodeHasChildren(root2) || (!root1->
isLeaf() && (root1->
bv.size() > root2_bv.
size())))
318 if(distanceRecurse_(nodes1, root1->
children[1], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
324 if(distanceRecurse_(nodes1, root1->
children[0], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
332 if(distanceRecurse_(nodes1, root1->
children[0], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
338 if(distanceRecurse_(nodes1, root1->
children[1], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
345 for(
unsigned int i = 0; i < 8; ++i)
347 if(tree2->nodeChildExists(root2, i))
349 const typename OcTree<S>::OcTreeNode* child = tree2->getNodeChild(root2, i);
351 computeChildBV(root2_bv, i, child_bv);
355 S d = root1->
bv.distance(aabb2);
359 if(distanceRecurse_(nodes1, root1_id, tree2, child, child_bv, tf2, cdata, callback, min_dist))
370 template <
typename S,
typename Derived>
372 bool distanceRecurse_(
375 const OcTree<S>* tree2,
376 const typename OcTree<S>::OcTreeNode* root2,
378 const Eigen::MatrixBase<Derived>& translation2,
384 if(root1->
isLeaf() && !tree2->nodeHasChildren(root2))
386 if(tree2->isNodeOccupied(root2))
391 tf2.translation() = translation2;
399 if(!tree2->isNodeOccupied(root2))
return false;
401 if(!tree2->nodeHasChildren(root2) || (!root1->
isLeaf() && (root1->
bv.size() > root2_bv.
size())))
412 if(distanceRecurse_(nodes1, root1->
children[1], tree2, root2, root2_bv, translation2, cdata, callback, min_dist))
418 if(distanceRecurse_(nodes1, root1->
children[0], tree2, root2, root2_bv, translation2, cdata, callback, min_dist))
426 if(distanceRecurse_(nodes1, root1->
children[0], tree2, root2, root2_bv, translation2, cdata, callback, min_dist))
432 if(distanceRecurse_(nodes1, root1->
children[1], tree2, root2, root2_bv, translation2, cdata, callback, min_dist))
439 for(
unsigned int i = 0; i < 8; ++i)
441 if(tree2->nodeChildExists(root2, i))
443 const typename OcTree<S>::OcTreeNode* child = tree2->getNodeChild(root2, i);
445 computeChildBV(root2_bv, i, child_bv);
448 S d = root1->
bv.distance(aabb2);
452 if(distanceRecurse_(nodes1, root1_id, tree2, child, child_bv, translation2, cdata, callback, min_dist))
466 template <
typename S>
476 if(!root1->
bv.overlap(root2->
bv))
return false;
480 if(!root1->
bv.overlap(root2->
bv))
return false;
482 if(root2->
isLeaf() || (!root1->
isLeaf() && (root1->
bv.size() > root2->
bv.size())))
500 template <
typename S>
507 if(!root->
bv.overlap(query->
getAABB()))
return false;
511 if(!root->
bv.overlap(query->
getAABB()))
return false;
525 template <
typename S>
530 if(root->
isLeaf())
return false;
545 template <
typename S>
557 return callback(root1_obj, root2_obj, cdata, min_dist);
560 if(root2->
isLeaf() || (!root1->
isLeaf() && (root1->
bv.size() > root2->
bv.size())))
562 S d1 = root2->
bv.distance((nodes1 + root1->
children[0])->bv);
563 S d2 = root2->
bv.distance((nodes1 + root1->
children[1])->bv);
596 S d1 = root1->
bv.distance((nodes2 + root2->
children[0])->bv);
597 S d2 = root1->
bv.distance((nodes2 + root2->
children[1])->bv);
633 template <
typename S>
641 return callback(root_obj, query, cdata, min_dist);
680 template <
typename S>
685 if(root->
isLeaf())
return false;
703 template <
typename S>
707 if(tf2.linear().isIdentity())
708 return collisionRecurse_(nodes1, root1_id, tree2, root2, root2_bv, tf2.translation(), cdata, callback);
710 return collisionRecurse_(nodes1, root1_id, tree2, root2, root2_bv, tf2, cdata, callback);
714 template <
typename S>
718 if(tf2.linear().isIdentity())
719 return distanceRecurse_(nodes1, root1_id, tree2, root2, root2_bv, tf2.translation(), cdata, callback, min_dist);
721 return distanceRecurse_(nodes1, root1_id, tree2, root2, root2_bv, tf2, cdata, callback, min_dist);
731 template <
typename S>
734 : tree_topdown_balance_threshold(dtree.bu_threshold),
735 tree_topdown_level(dtree.topdown_level)
750 template <
typename S>
755 if(other_objs.empty())
return;
764 table.rehash(other_objs.size());
765 for(
size_t i = 0,
size = other_objs.size(); i <
size; ++i)
767 leaves[i].
bv = other_objs[i]->getAABB();
770 leaves[i].
data = other_objs[i];
771 table[other_objs[i]] = i;
774 int n_leaves = other_objs.size();
783 template <
typename S>
792 template <
typename S>
802 template <
typename S>
808 int num =
dtree.size();
815 int height =
dtree.getMaxHeight();
821 dtree.balanceTopdown();
828 template <
typename S>
832 for(
auto it =
table.cbegin(), end =
table.cend(); it != end; ++it)
835 size_t node = it->second;
846 template <
typename S>
850 const auto it =
table.find(updated_obj);
851 if(it !=
table.end())
853 size_t node = it->second;
854 if(!
dtree.getNodes()[node].bv.equal(updated_obj->
getAABB()))
861 template <
typename S>
870 template <
typename S>
874 for(
size_t i = 0,
size = updated_objs.size(); i <
size; ++i)
880 template <
typename S>
889 template <
typename S>
893 objs.resize(this->
size());
894 std::transform(
table.begin(),
table.end(), objs.begin(), std::bind(&DynamicAABBTable::value_type::first, std::placeholders::_1));
898 template <
typename S>
902 if(
size() == 0)
return;
910 const OcTree<S>* octree =
static_cast<const OcTree<S>*
>(obj->
collisionGeometry().get());
924 template <
typename S>
928 if(
size() == 0)
return;
937 const OcTree<S>* octree =
static_cast<const OcTree<S>*
>(obj->
collisionGeometry().get());
951 template <
typename S>
955 if(
size() == 0)
return;
960 template <
typename S>
964 if(
size() == 0)
return;
970 template <
typename S>
975 if((
size() == 0) || (other_manager->
size() == 0))
return;
980 template <
typename S>
985 if((
size() == 0) || (other_manager->
size() == 0))
return;
991 template <
typename S>
995 return dtree.empty();
999 template <
typename S>
1003 return dtree.size();
1007 template <
typename S>
template class FCL_EXPORT DynamicAABBTreeCollisionManager_Array< double >
FCL_EXPORT void convertBV(const BV1 &bv1, const Transform3< typename BV1::S > &tf1, BV2 &bv2)
Convert a bounding volume of type BV1 in configuration tf1 to bounding volume of type BV2 in identity...
Class for hierarchy tree structure.
detail::implementation_array::HierarchyTree< AABB< S > > dtree
const Transform3< S > & getTransform() const
get object's transform
FCL_EXPORT bool distanceRecurse(typename DynamicAABBTreeCollisionManager_Array< S >::DynamicAABBNode *nodes, size_t root_id, CollisionObject< S > *query, void *cdata, DistanceCallBack< S > callback, S &min_dist)
const AABB< S > & getAABB() const
get the AABB in world space
template Halfspace< double > transform(const Halfspace< double > &a, const Transform3< double > &tf)
int & tree_topdown_balance_threshold
Eigen::Transform< S, 3, Eigen::Isometry > Transform3
CollisionObject< S > * obj1
AABB< S > translate(const AABB< S > &aabb, const Eigen::MatrixBase< Derived > &t)
translate the center of AABB by t
DynamicAABBTreeCollisionManager_Array()
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 ...
bool isFree() const
whether the object is completely free
void registerObjects(const std::vector< CollisionObject< S > *> &other_objs)
add objects to the manager
void registerObject(CollisionObject< S > *obj)
add one object to the manager
FCL_EXPORT bool selfCollisionRecurse(typename DynamicAABBTreeCollisionManager_Array< S >::DynamicAABBNode *nodes, size_t root_id, void *cdata, CollisionCallBack< S > callback)
virtual void registerObjects(const std::vector< CollisionObject< S > *> &other_objs)
add objects to the manager
std::unordered_map< CollisionObject< S > *, size_t > table
void update()
update the condition of manager
The geometry for the object for collision or distance computation.
bool(*)(CollisionObject< S > *o1, CollisionObject< S > *o2, void *cdata) CollisionCallBack
Callback for collision between two objects. Return value is whether can stop now. ...
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...
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 ...
size_t select(const NodeBase< BV > &query, const NodeBase< BV > &node1, const NodeBase< BV > &node2)
select from node1 and node2 which is close to a given query. 0 for node1 and 1 for node2 ...
FCL_EXPORT bool distanceRecurse(typename DynamicAABBTreeCollisionManager_Array< S >::DynamicAABBNode *nodes1, size_t root1_id, typename DynamicAABBTreeCollisionManager_Array< S >::DynamicAABBNode *nodes2, size_t root2_id, void *cdata, DistanceCallBack< S > callback, S &min_dist)
bool overlap(const OBB< S > &other) const
Check collision between two OBB, return true if collision happens.
Center at zero point, axis aligned box.
void clear()
clear the manager
FCL_EXPORT bool collisionRecurse(typename DynamicAABBTreeCollisionManager_Array< S >::DynamicAABBNode *nodes1, size_t root1_id, typename DynamicAABBTreeCollisionManager_Array< S >::DynamicAABBNode *nodes2, size_t root2_id, void *cdata, CollisionCallBack< S > callback)
S_ threshold_occupied
threshold for occupied ( >= is occupied)
template void constructBox(const OBB< double > &bv, Box< double > &box, Transform3< double > &tf)
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.
bool octree_as_geometry_collide
int tree_incremental_balance_pass
void getObjects(std::vector< CollisionObject< S > *> &objs) const
return the objects managed by the manager
int max_tree_nonbalanced_level
the object for collision or distance computation, contains the geometry and the transform information...
S_ cost_density
collision cost for unit volume
CollisionObject< S > * obj2
void update_(CollisionObject< S > *updated_obj)
bool empty() const
whether the manager is empty
FCL_EXPORT bool collisionRecurse(typename DynamicAABBTreeCollisionManager_Array< S >::DynamicAABBNode *nodes, size_t root_id, CollisionObject< S > *query, void *cdata, CollisionCallBack< S > callback)
void unregisterObject(CollisionObject< S > *obj)
remove one object from the manager
Base class for broad phase collision. It helps to accelerate the collision/distance between N objects...
CollisionObject< S > * obj
object
S size() const
Size of the AABB (used in BV_Splitter to order two AABBs)
size_t size() const
the number of objects managed by the manager
bool octree_as_geometry_distance
void setup()
initialize the manager, related with the specific type of manager
const detail::implementation_array::HierarchyTree< AABB< S > > & getTree() const
const std::shared_ptr< const CollisionGeometry< S > > & collisionGeometry() const
get geometry from the object instance
FCL_EXPORT bool selfDistanceRecurse(typename DynamicAABBTreeCollisionManager_Array< S >::DynamicAABBNode *nodes, size_t root_id, void *cdata, DistanceCallBack< S > callback, S &min_dist)