38 #ifndef HPP_FCL_TRAVERSAL_NODE_MESH_SHAPE_H
39 #define HPP_FCL_TRAVERSAL_NODE_MESH_SHAPE_H
59 template <
typename BV,
typename S>
60 class BVHShapeCollisionTraversalNode :
public CollisionTraversalNodeBase {
62 BVHShapeCollisionTraversalNode(
const CollisionRequest& request)
63 : CollisionTraversalNodeBase(request) {
69 query_time_seconds = 0.0;
73 bool isFirstNodeLeaf(
unsigned int b)
const {
74 return model1->getBV(b).isLeaf();
78 int getFirstLeftChild(
unsigned int b)
const {
79 return model1->getBV(b).leftChild();
83 int getFirstRightChild(
unsigned int b)
const {
84 return model1->getBV(b).rightChild();
87 const BVHModel<BV>* model1;
91 mutable int num_bv_tests;
92 mutable int num_leaf_tests;
97 template <
typename BV,
typename S,
98 int _Options = RelativeTransformationIsIdentity>
99 class MeshShapeCollisionTraversalNode
100 :
public BVHShapeCollisionTraversalNode<BV, S> {
104 RTIsIdentity = _Options & RelativeTransformationIsIdentity
107 MeshShapeCollisionTraversalNode(
const CollisionRequest& request)
108 : BVHShapeCollisionTraversalNode<BV, S>(request) {
120 bool BVDisjoints(
unsigned int b1,
unsigned int ,
121 FCL_REAL& sqrDistLowerBound)
const {
122 if (this->enable_statistics) this->num_bv_tests++;
125 disjoint = !this->model1->getBV(b1).bv.overlap(
126 this->model2_bv, this->request, sqrDistLowerBound);
128 disjoint = !
overlap(this->tf1.getRotation(), this->tf1.getTranslation(),
129 this->model1->getBV(b1).bv, this->model2_bv,
130 this->request, sqrDistLowerBound);
134 assert(!disjoint || sqrDistLowerBound > 0);
139 void leafCollides(
unsigned int b1,
unsigned int ,
140 FCL_REAL& sqrDistLowerBound)
const {
141 if (this->enable_statistics) this->num_leaf_tests++;
142 const BVNode<BV>& node = this->model1->getBV(b1);
144 int primitive_id = node.primitiveId();
146 const Triangle& tri_id = this->tri_indices[primitive_id];
147 const TriangleP tri(this->vertices[tri_id[0]], this->vertices[tri_id[1]],
148 this->vertices[tri_id[2]]);
155 const bool compute_penetration =
156 this->request.enable_contact || (this->request.security_margin < 0);
157 Vec3f c1, c2, normal;
161 static const Transform3f Id;
162 distance = internal::ShapeShapeDistance<TriangleP, S>(
163 &tri, Id, this->model2, this->tf2, this->nsolver, compute_penetration,
166 distance = internal::ShapeShapeDistance<TriangleP, S>(
167 &tri, this->tf1, this->model2, this->tf2, this->nsolver,
168 compute_penetration, c1, c2, normal);
173 distToCollision, c1, c2, normal);
175 if (distToCollision <= this->request.collision_distance_threshold) {
176 sqrDistLowerBound = 0;
177 if (this->result->numContacts() < this->request.num_max_contacts) {
178 this->result->addContact(Contact(this->model1, this->model2,
181 assert(this->result->isCollision());
184 sqrDistLowerBound = distToCollision * distToCollision;
187 assert(this->result->isCollision() || sqrDistLowerBound > 0);
191 Triangle* tri_indices;
193 const GJKSolver* nsolver;
202 template <
typename BV,
typename S>
203 class BVHShapeDistanceTraversalNode :
public DistanceTraversalNodeBase {
205 BVHShapeDistanceTraversalNode() : DistanceTraversalNodeBase() {
211 query_time_seconds = 0.0;
215 bool isFirstNodeLeaf(
unsigned int b)
const {
216 return model1->getBV(b).isLeaf();
220 int getFirstLeftChild(
unsigned int b)
const {
221 return model1->getBV(b).leftChild();
225 int getFirstRightChild(
unsigned int b)
const {
226 return model1->getBV(b).rightChild();
230 FCL_REAL BVDistanceLowerBound(
unsigned int b1,
unsigned int )
const {
231 return model1->getBV(b1).bv.distance(model2_bv);
234 const BVHModel<BV>* model1;
238 mutable int num_bv_tests;
239 mutable int num_leaf_tests;
240 mutable FCL_REAL query_time_seconds;
244 template <
typename S,
typename BV>
245 class ShapeBVHDistanceTraversalNode :
public DistanceTraversalNodeBase {
247 ShapeBVHDistanceTraversalNode() : DistanceTraversalNodeBase() {
253 query_time_seconds = 0.0;
257 bool isSecondNodeLeaf(
unsigned int b)
const {
258 return model2->getBV(b).isLeaf();
262 int getSecondLeftChild(
unsigned int b)
const {
263 return model2->getBV(b).leftChild();
267 int getSecondRightChild(
unsigned int b)
const {
268 return model2->getBV(b).rightChild();
272 FCL_REAL BVDistanceLowerBound(
unsigned int ,
unsigned int b2)
const {
273 return model1_bv.distance(model2->getBV(b2).bv);
277 const BVHModel<BV>* model2;
280 mutable int num_bv_tests;
281 mutable int num_leaf_tests;
282 mutable FCL_REAL query_time_seconds;
286 template <
typename BV,
typename S>
287 class MeshShapeDistanceTraversalNode
288 :
public BVHShapeDistanceTraversalNode<BV, S> {
290 MeshShapeDistanceTraversalNode() : BVHShapeDistanceTraversalNode<BV, S>() {
301 void leafComputeDistance(
unsigned int b1,
unsigned int )
const {
302 if (this->enable_statistics) this->num_leaf_tests++;
304 const BVNode<BV>& node = this->model1->getBV(b1);
306 int primitive_id = node.primitiveId();
308 const Triangle& tri_id = tri_indices[primitive_id];
309 const TriangleP tri(this->vertices[tri_id[0]], this->vertices[tri_id[1]],
310 this->vertices[tri_id[2]]);
312 Vec3f p1, p2, normal;
314 &tri, this->tf1, this->model2, this->tf2, this->nsolver,
315 this->request.enable_signed_distance, p1, p2, normal);
317 this->result->update(
distance, this->model1, this->model2, primitive_id,
323 if ((c >= this->result->min_distance - abs_err) &&
324 (c * (1 + rel_err) >= this->result->min_distance))
330 Triangle* tri_indices;
335 const GJKSolver* nsolver;
341 template <
typename BV,
typename S>
342 void meshShapeDistanceOrientedNodeleafComputeDistance(
343 unsigned int b1,
unsigned int ,
const BVHModel<BV>* model1,
344 const S& model2,
Vec3f* vertices, Triangle* tri_indices,
345 const Transform3f& tf1,
const Transform3f& tf2,
const GJKSolver* nsolver,
346 bool enable_statistics,
int& num_leaf_tests,
const DistanceRequest& request,
347 DistanceResult& result) {
348 if (enable_statistics) num_leaf_tests++;
350 const BVNode<BV>& node = model1->getBV(b1);
351 int primitive_id = node.primitiveId();
353 const Triangle& tri_id = tri_indices[primitive_id];
354 const TriangleP tri(vertices[tri_id[0]], vertices[tri_id[1]],
355 vertices[tri_id[2]]);
357 Vec3f p1, p2, normal;
359 &tri, tf1, &model2, tf2, nsolver, request.enable_signed_distance, p1, p2,
366 template <
typename BV,
typename S>
367 static inline void distancePreprocessOrientedNode(
368 const BVHModel<BV>* model1,
Vec3f* vertices, Triangle* tri_indices,
369 int init_tri_id,
const S& model2,
const Transform3f& tf1,
370 const Transform3f& tf2,
const GJKSolver* nsolver,
371 const DistanceRequest& request, DistanceResult& result) {
372 const Triangle& tri_id = tri_indices[init_tri_id];
373 const TriangleP tri(vertices[tri_id[0]], vertices[tri_id[1]],
374 vertices[tri_id[2]]);
376 Vec3f p1, p2, normal;
378 &tri, tf1, &model2, tf2, nsolver, request.enable_signed_distance, p1, p2,
390 template <
typename S>
392 :
public MeshShapeDistanceTraversalNode<RSS, S> {
395 : MeshShapeDistanceTraversalNode<RSS, S>() {}
398 details::distancePreprocessOrientedNode(
399 this->model1, this->vertices, this->tri_indices, 0, *(this->model2),
400 this->tf1, this->tf2, this->nsolver, this->request, *(this->result));
406 if (this->enable_statistics) this->num_bv_tests++;
407 return distance(this->tf1.getRotation(), this->tf1.getTranslation(),
408 this->model2_bv, this->model1->getBV(b1).bv);
412 details::meshShapeDistanceOrientedNodeleafComputeDistance(
413 b1, b2, this->model1, *(this->model2), this->vertices,
414 this->tri_indices, this->tf1, this->tf2, this->nsolver,
415 this->enable_statistics, this->num_leaf_tests, this->request,
420 template <
typename S>
422 :
public MeshShapeDistanceTraversalNode<kIOS, S> {
425 : MeshShapeDistanceTraversalNode<kIOS, S>() {}
428 details::distancePreprocessOrientedNode(
429 this->model1, this->vertices, this->tri_indices, 0, *(this->model2),
430 this->tf1, this->tf2, this->nsolver, this->request, *(this->result));
436 if (this->enable_statistics) this->num_bv_tests++;
437 return distance(this->tf1.getRotation(), this->tf1.getTranslation(),
438 this->model2_bv, this->model1->getBV(b1).bv);
442 details::meshShapeDistanceOrientedNodeleafComputeDistance(
443 b1, b2, this->model1, *(this->model2), this->vertices,
444 this->tri_indices, this->tf1, this->tf2, this->nsolver,
445 this->enable_statistics, this->num_leaf_tests, this->request,
450 template <
typename S>
452 :
public MeshShapeDistanceTraversalNode<OBBRSS, S> {
455 : MeshShapeDistanceTraversalNode<OBBRSS, S>() {}
458 details::distancePreprocessOrientedNode(
459 this->model1, this->vertices, this->tri_indices, 0, *(this->model2),
460 this->tf1, this->tf2, this->nsolver, this->request, *(this->result));
466 if (this->enable_statistics) this->num_bv_tests++;
467 return distance(this->tf1.getRotation(), this->tf1.getTranslation(),
468 this->model2_bv, this->model1->getBV(b1).bv);
472 details::meshShapeDistanceOrientedNodeleafComputeDistance(
473 b1, b2, this->model1, *(this->model2), this->vertices,
474 this->tri_indices, this->tf1, this->tf2, this->nsolver,
475 this->enable_statistics, this->num_leaf_tests, this->request,
Definition: traversal_node_bvh_shape.h:422
FCL_REAL BVDistanceLowerBound(unsigned int b1, unsigned int) const
Definition: traversal_node_bvh_shape.h:435
void leafComputeDistance(unsigned int b1, unsigned int b2) const
Definition: traversal_node_bvh_shape.h:441
MeshShapeDistanceTraversalNodekIOS()
Definition: traversal_node_bvh_shape.h:424
void preprocess()
Definition: traversal_node_bvh_shape.h:427
void postprocess()
Definition: traversal_node_bvh_shape.h:433
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.
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.
void updateDistanceLowerBoundFromLeaf(const CollisionRequest &, CollisionResult &res, const FCL_REAL &distance, const Vec3f &p0, const Vec3f &p1, const Vec3f &normal)
Definition: collision_data.h:1186
void updateDistanceLowerBoundFromBV(const CollisionRequest &, CollisionResult &res, const FCL_REAL sqrDistLowerBound)
Definition: collision_data.h:1177
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
Definition: data_types.h:67
double FCL_REAL
Definition: data_types.h:66
Main namespace.
Definition: broadphase_bruteforce.h:44
static const int NONE
invalid contact primitive information
Definition: collision_data.h:1088