38 #ifndef HPP_FCL_TRAVERSAL_NODE_MESHES_H 39 #define HPP_FCL_TRAVERSAL_NODE_MESHES_H 53 #include <boost/shared_array.hpp> 54 #include <boost/shared_ptr.hpp> 69 class BVHCollisionTraversalNode :
public CollisionTraversalNodeBase
72 BVHCollisionTraversalNode(
const CollisionRequest& request) :
73 CollisionTraversalNodeBase (request)
80 query_time_seconds = 0.0;
84 bool isFirstNodeLeaf(
int b)
const 86 return model1->getBV(b).isLeaf();
90 bool isSecondNodeLeaf(
int b)
const 92 return model2->getBV(b).isLeaf();
96 bool firstOverSecond(
int b1,
int b2)
const 98 FCL_REAL sz1 = model1->getBV(b1).bv.size();
99 FCL_REAL sz2 = model2->getBV(b2).bv.size();
101 bool l1 = model1->getBV(b1).isLeaf();
102 bool l2 = model2->getBV(b2).isLeaf();
104 if(l2 || (!l1 && (sz1 > sz2)))
110 int getFirstLeftChild(
int b)
const 112 return model1->getBV(b).leftChild();
116 int getFirstRightChild(
int b)
const 118 return model1->getBV(b).rightChild();
122 int getSecondLeftChild(
int b)
const 124 return model2->getBV(b).leftChild();
128 int getSecondRightChild(
int b)
const 130 return model2->getBV(b).rightChild();
134 const BVHModel<BV>* model1;
136 const BVHModel<BV>* model2;
139 mutable int num_bv_tests;
140 mutable int num_leaf_tests;
141 mutable FCL_REAL query_time_seconds;
145 template<
typename BV,
int _Options = RelativeTransformationIsIdentity>
146 class MeshCollisionTraversalNode :
public BVHCollisionTraversalNode<BV>
151 RTIsIdentity = _Options & RelativeTransformationIsIdentity
154 MeshCollisionTraversalNode(
const CollisionRequest& request) :
155 BVHCollisionTraversalNode<BV> (request)
164 bool BVDisjoints(
int b1,
int b2)
const 166 if(this->enable_statistics) this->num_bv_tests++;
168 return !this->model1->getBV(b1).overlap(this->model2->getBV(b2));
170 return !
overlap(RT._R(), RT._T(),
171 this->model1->getBV(b1).bv, this->model2->getBV(b2).bv);
178 bool BVDisjoints(
int b1,
int b2,
FCL_REAL& sqrDistLowerBound)
const 180 if(this->enable_statistics) this->num_bv_tests++;
182 return !this->model1->getBV(b1).overlap(this->model2->getBV(b2),
183 this->request, sqrDistLowerBound);
185 bool res = !
overlap(RT._R(), RT._T(),
186 this->model1->getBV(b1).bv, this->model2->getBV(b2).bv,
187 this->request, sqrDistLowerBound);
188 assert (!res || sqrDistLowerBound > 0);
207 void leafCollides(
int b1,
int b2,
FCL_REAL& sqrDistLowerBound)
const 209 if(this->enable_statistics) this->num_leaf_tests++;
211 const BVNode<BV>& node1 = this->model1->getBV(b1);
212 const BVNode<BV>& node2 = this->model2->getBV(b2);
214 int primitive_id1 = node1.primitiveId();
215 int primitive_id2 = node2.primitiveId();
217 const Triangle& tri_id1 = tri_indices1[primitive_id1];
218 const Triangle& tri_id2 = tri_indices2[primitive_id2];
220 const Vec3f& P1 = vertices1[tri_id1[0]];
221 const Vec3f& P2 = vertices1[tri_id1[1]];
222 const Vec3f& P3 = vertices1[tri_id1[2]];
223 const Vec3f& Q1 = vertices2[tri_id2[0]];
224 const Vec3f& Q2 = vertices2[tri_id2[1]];
225 const Vec3f& Q3 = vertices2[tri_id2[2]];
227 TriangleP tri1 (P1, P2, P3);
228 TriangleP tri2 (Q1, Q2, Q3);
233 solver.shapeDistance (tri1, this->tf1, tri2, this->tf2,
234 distance, p1, p2, normal);
235 FCL_REAL distToCollision = distance - this->request.security_margin;
236 sqrDistLowerBound = distance *
distance;
237 if (distToCollision <= 0) {
240 if(this->result->numContacts() < this->request.num_max_contacts) {
245 normal = (p2-p1).normalized ();
248 this->result->addContact(Contact(this->model1, this->model2,
249 primitive_id1, primitive_id2,
250 p, normal, penetrationDepth));
258 Triangle* tri_indices1;
259 Triangle* tri_indices2;
261 details::RelativeTransformation<!bool(RTIsIdentity)> RT;
265 typedef MeshCollisionTraversalNode<OBB , 0> MeshCollisionTraversalNodeOBB ;
266 typedef MeshCollisionTraversalNode<RSS , 0> MeshCollisionTraversalNodeRSS ;
267 typedef MeshCollisionTraversalNode<kIOS , 0> MeshCollisionTraversalNodekIOS ;
268 typedef MeshCollisionTraversalNode<OBBRSS, 0> MeshCollisionTraversalNodeOBBRSS;
274 template<
typename BV>
struct DistanceTraversalBVDistanceLowerBound_impl
276 static FCL_REAL run(
const BVNode<BV>& b1,
const BVNode<BV>& b2)
278 return b1.distance(b2);
282 return distance(R, T, b1.bv, b2.bv);
286 template<>
struct DistanceTraversalBVDistanceLowerBound_impl<OBB>
288 static FCL_REAL run(
const BVNode<OBB>& b1,
const BVNode<OBB>& b2)
293 if (b1.overlap(b2, request, sqrDistLowerBound)) {
297 return sqrt (sqrDistLowerBound);
304 if (
overlap(R, T, b1.bv, b2.bv, request, sqrDistLowerBound)) {
308 return sqrt (sqrDistLowerBound);
312 template<>
struct DistanceTraversalBVDistanceLowerBound_impl<AABB>
314 static FCL_REAL run(
const BVNode<AABB>& b1,
const BVNode<AABB>& b2)
319 if (b1.overlap(b2, request, sqrDistLowerBound)) {
323 return sqrt (sqrDistLowerBound);
325 static FCL_REAL run(
const Matrix3f& R,
const Vec3f& T,
const BVNode<AABB>& b1,
const BVNode<AABB>& b2)
330 if (
overlap(R, T, b1.bv, b2.bv, request, sqrDistLowerBound)) {
334 return sqrt (sqrDistLowerBound);
343 template<
typename BV>
344 class BVHDistanceTraversalNode :
public DistanceTraversalNodeBase
347 BVHDistanceTraversalNode() : DistanceTraversalNodeBase()
354 query_time_seconds = 0.0;
358 bool isFirstNodeLeaf(
int b)
const 360 return model1->getBV(b).isLeaf();
364 bool isSecondNodeLeaf(
int b)
const 366 return model2->getBV(b).isLeaf();
370 bool firstOverSecond(
int b1,
int b2)
const 372 FCL_REAL sz1 = model1->getBV(b1).bv.size();
373 FCL_REAL sz2 = model2->getBV(b2).bv.size();
375 bool l1 = model1->getBV(b1).isLeaf();
376 bool l2 = model2->getBV(b2).isLeaf();
378 if(l2 || (!l1 && (sz1 > sz2)))
384 int getFirstLeftChild(
int b)
const 386 return model1->getBV(b).leftChild();
390 int getFirstRightChild(
int b)
const 392 return model1->getBV(b).rightChild();
396 int getSecondLeftChild(
int b)
const 398 return model2->getBV(b).leftChild();
402 int getSecondRightChild(
int b)
const 404 return model2->getBV(b).rightChild();
408 const BVHModel<BV>* model1;
410 const BVHModel<BV>* model2;
413 mutable int num_bv_tests;
414 mutable int num_leaf_tests;
415 mutable FCL_REAL query_time_seconds;
420 template<
typename BV,
int _Options = RelativeTransformationIsIdentity>
421 class MeshDistanceTraversalNode :
public BVHDistanceTraversalNode<BV>
426 RTIsIdentity = _Options & RelativeTransformationIsIdentity
429 using BVHDistanceTraversalNode<BV>::enable_statistics;
430 using BVHDistanceTraversalNode<BV>::request;
431 using BVHDistanceTraversalNode<BV>::result;
432 using BVHDistanceTraversalNode<BV>::tf1;
433 using BVHDistanceTraversalNode<BV>::model1;
434 using BVHDistanceTraversalNode<BV>::model2;
435 using BVHDistanceTraversalNode<BV>::num_bv_tests;
436 using BVHDistanceTraversalNode<BV>::num_leaf_tests;
438 MeshDistanceTraversalNode() : BVHDistanceTraversalNode<BV>()
445 rel_err = this->request.rel_err;
446 abs_err = this->request.abs_err;
451 if(!RTIsIdentity) preprocessOrientedNode();
456 if(!RTIsIdentity) postprocessOrientedNode();
460 FCL_REAL BVDistanceLowerBound(
int b1,
int b2)
const 462 if(enable_statistics) num_bv_tests++;
464 return details::DistanceTraversalBVDistanceLowerBound_impl<BV>
465 ::run (model1->getBV(b1), model2->getBV(b2));
467 return details::DistanceTraversalBVDistanceLowerBound_impl<BV>
468 ::run (RT._R(), RT._T(), model1->getBV(b1), model2->getBV(b2));
472 void leafComputeDistance(
int b1,
int b2)
const 474 if(this->enable_statistics) this->num_leaf_tests++;
476 const BVNode<BV>& node1 = this->model1->getBV(b1);
477 const BVNode<BV>& node2 = this->model2->getBV(b2);
479 int primitive_id1 = node1.primitiveId();
480 int primitive_id2 = node2.primitiveId();
482 const Triangle& tri_id1 = tri_indices1[primitive_id1];
483 const Triangle& tri_id2 = tri_indices2[primitive_id2];
485 const Vec3f& t11 = vertices1[tri_id1[0]];
486 const Vec3f& t12 = vertices1[tri_id1[1]];
487 const Vec3f& t13 = vertices1[tri_id1[2]];
489 const Vec3f& t21 = vertices2[tri_id2[0]];
490 const Vec3f& t22 = vertices2[tri_id2[1]];
491 const Vec3f& t23 = vertices2[tri_id2[2]];
494 Vec3f P1, P2, normal;
498 d2 = TriangleDistance::sqrTriDistance (t11, t12, t13, t21, t22, t23,
501 d2 = TriangleDistance::sqrTriDistance (t11, t12, t13, t21, t22, t23,
506 this->result->update(d, this->model1, this->model2, primitive_id1,
507 primitive_id2, P1, P2, normal);
513 if((c >= this->result->min_distance - abs_err) && (c * (1 + rel_err) >= this->result->min_distance))
521 Triangle* tri_indices1;
522 Triangle* tri_indices2;
528 details::RelativeTransformation<!bool(RTIsIdentity)> RT;
531 void preprocessOrientedNode()
533 const int init_tri_id1 = 0, init_tri_id2 = 0;
534 const Triangle& init_tri1 = tri_indices1[init_tri_id1];
535 const Triangle& init_tri2 = tri_indices2[init_tri_id2];
537 Vec3f init_tri1_points[3];
538 Vec3f init_tri2_points[3];
540 init_tri1_points[0] = vertices1[init_tri1[0]];
541 init_tri1_points[1] = vertices1[init_tri1[1]];
542 init_tri1_points[2] = vertices1[init_tri1[2]];
544 init_tri2_points[0] = vertices2[init_tri2[0]];
545 init_tri2_points[1] = vertices2[init_tri2[1]];
546 init_tri2_points[2] = vertices2[init_tri2[2]];
548 Vec3f p1, p2, normal;
549 FCL_REAL distance = sqrt (TriangleDistance::sqrTriDistance
550 (init_tri1_points[0], init_tri1_points[1],
551 init_tri1_points[2], init_tri2_points[0],
552 init_tri2_points[1], init_tri2_points[2],
553 RT._R(), RT._T(), p1, p2));
555 result->update(distance, model1, model2, init_tri_id1, init_tri_id2, p1, p2,
558 void postprocessOrientedNode()
561 if(request.enable_nearest_points && (result->o1 == model1) && (result->o2 == model2))
563 result->nearest_points[0] = tf1.transform(result->nearest_points[0]);
564 result->nearest_points[1] = tf1.transform(result->nearest_points[1]);
570 typedef MeshDistanceTraversalNode<RSS , 0> MeshDistanceTraversalNodeRSS;
571 typedef MeshDistanceTraversalNode<kIOS , 0> MeshDistanceTraversalNodekIOS;
572 typedef MeshDistanceTraversalNode<OBBRSS, 0> MeshDistanceTraversalNodeOBBRSS;
580 template<
typename BV>
581 inline const Matrix3f& getBVAxes(
const BV& bv)
587 inline const Matrix3f& getBVAxes<OBBRSS>(
const OBBRSS& bv)
Main namespace.
Definition: AABB.h:43
Eigen::Matrix< FCL_REAL, 3, 3 > Matrix3f
Definition: data_types.h:74
FCL_REAL distance(const Matrix3f &R0, const Vec3f &T0, const kIOS &b1, const kIOS &b2, Vec3f *P=NULL, Vec3f *Q=NULL)
Approximate distance between two kIOS bounding volumes.
double FCL_REAL
Definition: data_types.h:68
Definition: traversal_node_setup.h:775
bool overlap(const Matrix3f &R0, const Vec3f &T0, const AABB &b1, const AABB &b2)
Check collision between two aabbs, b1 is in configuration (R0, T0) and b2 is in identity.
Definition: collision_data.h:145
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
Definition: data_types.h:73