38 #ifndef COAL_TRAVERSAL_NODE_MESH_SHAPE_H 
   39 #define COAL_TRAVERSAL_NODE_MESH_SHAPE_H 
   58 template <
typename BV, 
typename S>
 
   59 class BVHShapeCollisionTraversalNode : 
public CollisionTraversalNodeBase {
 
   61   BVHShapeCollisionTraversalNode(
const CollisionRequest& request)
 
   62       : CollisionTraversalNodeBase(request) {
 
   68     query_time_seconds = 0.0;
 
   72   bool isFirstNodeLeaf(
unsigned int b)
 const {
 
   73     return model1->getBV(
b).isLeaf();
 
   77   int getFirstLeftChild(
unsigned int b)
 const {
 
   78     return model1->getBV(
b).leftChild();
 
   82   int getFirstRightChild(
unsigned int b)
 const {
 
   83     return model1->getBV(
b).rightChild();
 
   86   const BVHModel<BV>* model1;
 
   90   mutable int num_bv_tests;
 
   91   mutable int num_leaf_tests;
 
   96 template <
typename BV, 
typename S,
 
   97           int _Options = RelativeTransformationIsIdentity>
 
   98 class MeshShapeCollisionTraversalNode
 
   99     : 
public BVHShapeCollisionTraversalNode<BV, S> {
 
  103     RTIsIdentity = _Options & RelativeTransformationIsIdentity
 
  106   MeshShapeCollisionTraversalNode(
const CollisionRequest& request)
 
  107       : BVHShapeCollisionTraversalNode<BV, S>(request) {
 
  119   bool BVDisjoints(
unsigned int b1, 
unsigned int ,
 
  121     if (this->enable_statistics) this->num_bv_tests++;
 
  124       disjoint = !this->model1->getBV(b1).bv.overlap(
 
  125           this->model2_bv, this->request, sqrDistLowerBound);
 
  127       disjoint = !
overlap(this->
tf1.getRotation(), this->tf1.getTranslation(),
 
  128                           this->model1->getBV(b1).bv, this->model2_bv,
 
  129                           this->request, sqrDistLowerBound);
 
  133     assert(!disjoint || sqrDistLowerBound > 0);
 
  138   void leafCollides(
unsigned int b1, 
unsigned int ,
 
  140     if (this->enable_statistics) this->num_leaf_tests++;
 
  141     const BVNode<BV>& node = this->model1->getBV(b1);
 
  143     int primitive_id = node.primitiveId();
 
  145     const Triangle& tri_id = this->tri_indices[primitive_id];
 
  146     const TriangleP tri(this->vertices[tri_id[0]], this->vertices[tri_id[1]],
 
  147                         this->vertices[tri_id[2]]);
 
  154     const bool compute_penetration =
 
  155         this->request.enable_contact || (this->request.security_margin < 0);
 
  160       static const Transform3s Id;
 
  161       distance = internal::ShapeShapeDistance<TriangleP, S>(
 
  162           &tri, Id, this->model2, this->
tf2, this->nsolver, compute_penetration,
 
  165       distance = internal::ShapeShapeDistance<TriangleP, S>(
 
  166           &tri, this->
tf1, this->model2, this->
tf2, this->nsolver,
 
  167           compute_penetration, c1, c2, normal);
 
  172                                                distToCollision, c1, c2, normal);
 
  174     if (distToCollision <= this->request.collision_distance_threshold) {
 
  175       sqrDistLowerBound = 0;
 
  176       if (this->result->numContacts() < this->request.num_max_contacts) {
 
  177         this->result->addContact(Contact(this->model1, this->model2,
 
  180         assert(this->result->isCollision());
 
  183       sqrDistLowerBound = distToCollision * distToCollision;
 
  186     assert(this->result->isCollision() || sqrDistLowerBound > 0);
 
  190   Triangle* tri_indices;
 
  192   const GJKSolver* nsolver;
 
  201 template <
typename BV, 
typename S>
 
  202 class BVHShapeDistanceTraversalNode : 
public DistanceTraversalNodeBase {
 
  204   BVHShapeDistanceTraversalNode() : DistanceTraversalNodeBase() {
 
  210     query_time_seconds = 0.0;
 
  214   bool isFirstNodeLeaf(
unsigned int b)
 const {
 
  215     return model1->getBV(
b).isLeaf();
 
  219   int getFirstLeftChild(
unsigned int b)
 const {
 
  220     return model1->getBV(
b).leftChild();
 
  224   int getFirstRightChild(
unsigned int b)
 const {
 
  225     return model1->getBV(
b).rightChild();
 
  229   CoalScalar BVDistanceLowerBound(
unsigned int b1, 
unsigned int )
 const {
 
  230     return model1->getBV(b1).bv.distance(model2_bv);
 
  233   const BVHModel<BV>* model1;
 
  237   mutable int num_bv_tests;
 
  238   mutable int num_leaf_tests;
 
  243 template <
typename S, 
typename BV>
 
  244 class ShapeBVHDistanceTraversalNode : 
public DistanceTraversalNodeBase {
 
  246   ShapeBVHDistanceTraversalNode() : DistanceTraversalNodeBase() {
 
  252     query_time_seconds = 0.0;
 
  256   bool isSecondNodeLeaf(
unsigned int b)
 const {
 
  257     return model2->getBV(
b).isLeaf();
 
  261   int getSecondLeftChild(
unsigned int b)
 const {
 
  262     return model2->getBV(
b).leftChild();
 
  266   int getSecondRightChild(
unsigned int b)
 const {
 
  267     return model2->getBV(
b).rightChild();
 
  271   CoalScalar BVDistanceLowerBound(
unsigned int , 
unsigned int b2)
 const {
 
  272     return model1_bv.distance(model2->getBV(b2).bv);
 
  276   const BVHModel<BV>* model2;
 
  279   mutable int num_bv_tests;
 
  280   mutable int num_leaf_tests;
 
  285 template <
typename BV, 
typename S>
 
  286 class MeshShapeDistanceTraversalNode
 
  287     : 
public BVHShapeDistanceTraversalNode<BV, S> {
 
  289   MeshShapeDistanceTraversalNode() : BVHShapeDistanceTraversalNode<BV, S>() {
 
  300   void leafComputeDistance(
unsigned int b1, 
unsigned int )
 const {
 
  301     if (this->enable_statistics) this->num_leaf_tests++;
 
  303     const BVNode<BV>& node = this->model1->getBV(b1);
 
  305     int primitive_id = node.primitiveId();
 
  307     const Triangle& tri_id = tri_indices[primitive_id];
 
  308     const TriangleP tri(this->vertices[tri_id[0]], this->vertices[tri_id[1]],
 
  309                         this->vertices[tri_id[2]]);
 
  313         &tri, this->
tf1, this->model2, this->
tf2, this->nsolver,
 
  314         this->request.enable_signed_distance, 
p1, p2, normal);
 
  316     this->result->update(
distance, this->model1, this->model2, primitive_id,
 
  322     if ((c >= this->result->min_distance - abs_err) &&
 
  323         (c * (1 + rel_err) >= this->result->min_distance))
 
  329   Triangle* tri_indices;
 
  334   const GJKSolver* nsolver;
 
  340 template <
typename BV, 
typename S>
 
  341 void meshShapeDistanceOrientedNodeleafComputeDistance(
 
  342     unsigned int b1, 
unsigned int , 
const BVHModel<BV>* model1,
 
  343     const S& model2, 
Vec3s* vertices, Triangle* tri_indices,
 
  344     const Transform3s& 
tf1, 
const Transform3s& 
tf2, 
const GJKSolver* nsolver,
 
  345     bool enable_statistics, 
int& num_leaf_tests, 
const DistanceRequest& request,
 
  346     DistanceResult& result) {
 
  347   if (enable_statistics) num_leaf_tests++;
 
  349   const BVNode<BV>& node = model1->getBV(b1);
 
  350   int primitive_id = node.primitiveId();
 
  352   const Triangle& tri_id = tri_indices[primitive_id];
 
  353   const TriangleP tri(vertices[tri_id[0]], vertices[tri_id[1]],
 
  354                       vertices[tri_id[2]]);
 
  358       &tri, 
tf1, &model2, 
tf2, nsolver, request.enable_signed_distance, 
p1, p2,
 
  365 template <
typename BV, 
typename S>
 
  366 static inline void distancePreprocessOrientedNode(
 
  367     const BVHModel<BV>* model1, 
Vec3s* vertices, Triangle* tri_indices,
 
  368     int init_tri_id, 
const S& model2, 
const Transform3s& 
tf1,
 
  369     const Transform3s& 
tf2, 
const GJKSolver* nsolver,
 
  370     const DistanceRequest& request, DistanceResult& result) {
 
  371   const Triangle& tri_id = tri_indices[init_tri_id];
 
  372   const TriangleP tri(vertices[tri_id[0]], vertices[tri_id[1]],
 
  373                       vertices[tri_id[2]]);
 
  377       &tri, 
tf1, &model2, 
tf2, nsolver, request.enable_signed_distance, 
p1, p2,
 
  389 template <
typename S>
 
  391     : 
public MeshShapeDistanceTraversalNode<RSS, S> {
 
  394       : MeshShapeDistanceTraversalNode<RSS, S>() {}
 
  397     details::distancePreprocessOrientedNode(
 
  398         this->model1, this->vertices, this->tri_indices, 0, *(this->model2),
 
  399         this->tf1, this->tf2, this->nsolver, this->request, *(this->result));
 
  405     if (this->enable_statistics) this->num_bv_tests++;
 
  406     return distance(this->tf1.getRotation(), this->tf1.getTranslation(),
 
  407                     this->model2_bv, this->model1->getBV(b1).bv);
 
  411     details::meshShapeDistanceOrientedNodeleafComputeDistance(
 
  412         b1, b2, this->model1, *(this->model2), this->vertices,
 
  413         this->tri_indices, this->tf1, this->tf2, this->nsolver,
 
  414         this->enable_statistics, this->num_leaf_tests, this->request,
 
  419 template <
typename S>
 
  421     : 
public MeshShapeDistanceTraversalNode<kIOS, S> {
 
  424       : MeshShapeDistanceTraversalNode<kIOS, S>() {}
 
  427     details::distancePreprocessOrientedNode(
 
  428         this->model1, this->vertices, this->tri_indices, 0, *(this->model2),
 
  429         this->tf1, this->tf2, this->nsolver, this->request, *(this->result));
 
  435     if (this->enable_statistics) this->num_bv_tests++;
 
  436     return distance(this->tf1.getRotation(), this->tf1.getTranslation(),
 
  437                     this->model2_bv, this->model1->getBV(b1).bv);
 
  441     details::meshShapeDistanceOrientedNodeleafComputeDistance(
 
  442         b1, b2, this->model1, *(this->model2), this->vertices,
 
  443         this->tri_indices, this->tf1, this->tf2, this->nsolver,
 
  444         this->enable_statistics, this->num_leaf_tests, this->request,
 
  449 template <
typename S>
 
  451     : 
public MeshShapeDistanceTraversalNode<OBBRSS, S> {
 
  454       : MeshShapeDistanceTraversalNode<OBBRSS, S>() {}
 
  457     details::distancePreprocessOrientedNode(
 
  458         this->model1, this->vertices, this->tri_indices, 0, *(this->model2),
 
  459         this->tf1, this->tf2, this->nsolver, this->request, *(this->result));
 
  465     if (this->enable_statistics) this->num_bv_tests++;
 
  466     return distance(this->tf1.getRotation(), this->tf1.getTranslation(),
 
  467                     this->model2_bv, this->model1->getBV(b1).bv);
 
  471     details::meshShapeDistanceOrientedNodeleafComputeDistance(
 
  472         b1, b2, this->model1, *(this->model2), this->vertices,
 
  473         this->tri_indices, this->tf1, this->tf2, this->nsolver,
 
  474         this->enable_statistics, this->num_leaf_tests, this->request,