From 358e5fca05def769192b17f0341af69de64d80ba Mon Sep 17 00:00:00 2001 From: Joseph Mirabel <jmirabel@laas.fr> Date: Thu, 13 Jun 2019 17:43:20 +0200 Subject: [PATCH] Remove duplication of MeshShapeCollisionTraversalNode --- CMakeLists.txt | 1 + include/hpp/fcl/traversal/details/traversal.h | 76 ++++++++ .../fcl/traversal/traversal_node_bvh_shape.h | 179 +++++++----------- .../hpp/fcl/traversal/traversal_node_bvhs.h | 28 +-- 4 files changed, 143 insertions(+), 141 deletions(-) create mode 100644 include/hpp/fcl/traversal/details/traversal.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 33b6335a..7af21928 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ SET(${PROJECT_NAME}_HEADERS include/hpp/fcl/math/vec_3f.h include/hpp/fcl/math/tools.h include/hpp/fcl/math/transform.h + include/hpp/fcl/traversal/details/traversal.h include/hpp/fcl/traversal/traversal_node_shapes.h include/hpp/fcl/traversal/traversal_node_setup.h include/hpp/fcl/traversal/traversal_recurse.h diff --git a/include/hpp/fcl/traversal/details/traversal.h b/include/hpp/fcl/traversal/details/traversal.h new file mode 100644 index 00000000..2979a601 --- /dev/null +++ b/include/hpp/fcl/traversal/details/traversal.h @@ -0,0 +1,76 @@ +/* + * Software License Agreement (BSD License) + * + * Copyright (c) 2019, LAAS CNRS + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Open Source Robotics Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** \author Joseph Mirabel */ + + +#ifndef HPP_FCL_TRAVERSAL_DETAILS_TRAVERSAL_H +#define HPP_FCL_TRAVERSAL_DETAILS_TRAVERSAL_H + +namespace hpp +{ +namespace fcl +{ + +enum { + RelativeTransformationIsIdentity = 1 +}; + +namespace details +{ + template <bool enabled> + struct RelativeTransformation + { + RelativeTransformation () : R (Matrix3f::Identity()) {} + + const Matrix3f& _R () const { return R; } + const Vec3f & _T () const { return T; } + + Matrix3f R; + Vec3f T; + }; + + template <> + struct RelativeTransformation <false> + { + static const Matrix3f& _R () { throw std::logic_error ("should never reach this point"); } + static const Vec3f & _T () { throw std::logic_error ("should never reach this point"); } + }; +} // namespace details + +} + +} // namespace hpp + +#endif diff --git a/include/hpp/fcl/traversal/traversal_node_bvh_shape.h b/include/hpp/fcl/traversal/traversal_node_bvh_shape.h index 738d63c5..b919ac08 100644 --- a/include/hpp/fcl/traversal/traversal_node_bvh_shape.h +++ b/include/hpp/fcl/traversal/traversal_node_bvh_shape.h @@ -43,6 +43,7 @@ #include <hpp/fcl/shape/geometric_shapes.h> #include <hpp/fcl/shape/geometric_shapes_utility.h> #include <hpp/fcl/traversal/traversal_node_base.h> +#include <hpp/fcl/traversal/details/traversal.h> #include <hpp/fcl/BVH/BVH_model.h> @@ -85,24 +86,6 @@ public: return model1->getBV(b).rightChild(); } - /// @brief BV culling test in one BVTT node - bool BVTesting(int b1, int /*b2*/) const - { - if(this->enable_statistics) num_bv_tests++; - return !model1->getBV(b1).bv.overlap(model2_bv); - } - - /// BV test between b1 and b2 - /// \param b1, b2 Bounding volumes to test, - /// \retval sqrDistLowerBound square of a lower bound of the minimal - /// distance between bounding volumes. - /// @brief BV culling test in one BVTT node - bool BVTesting(int b1, int /*b2*/, FCL_REAL& sqrDistLowerBound) const - { - if(this->enable_statistics) num_bv_tests++; - return !model1->getBV(b1).bv.overlap(model2_bv, request, sqrDistLowerBound); - } - const BVHModel<BV>* model1; const S* model2; BV model2_bv; @@ -181,10 +164,16 @@ public: /// @brief Traversal node for collision between mesh and shape -template<typename BV, typename S, typename NarrowPhaseSolver> +template<typename BV, typename S, typename NarrowPhaseSolver, + int _Options = RelativeTransformationIsIdentity> class MeshShapeCollisionTraversalNode : public BVHShapeCollisionTraversalNode<BV, S> { public: + enum { + Options = _Options, + RTIsIdentity = _Options & RelativeTransformationIsIdentity + }; + MeshShapeCollisionTraversalNode(const CollisionRequest& request) : BVHShapeCollisionTraversalNode<BV, S> (request) { @@ -194,8 +183,37 @@ public: nsolver = NULL; } + /// @brief BV culling test in one BVTT node + bool BVTesting(int b1, int /*b2*/) const + { + if(this->enable_statistics) this->num_bv_tests++; + bool res; + if (RTIsIdentity) + res = !this->model1->getBV(b1).bv.overlap(this->model2_bv); + else + res = !overlap(this->tf1.getRotation(), this->tf1.getTranslation(), this->model2_bv, this->model1->getBV(b1).bv); + assert (!res || sqrDistLowerBound > 0); + return res; + } + + /// test between BV b1 and shape + /// \param b1 BV to test, + /// \retval sqrDistLowerBound square of a lower bound of the minimal + /// distance between bounding volumes. + /// @brief BV culling test in one BVTT node + bool BVTesting(int b1, int /*b2*/, FCL_REAL& sqrDistLowerBound) const + { + if(this->enable_statistics) this->num_bv_tests++; + if (RTIsIdentity) + return !this->model1->getBV(b1).bv.overlap(this->model2_bv, this->request, sqrDistLowerBound); + else + return !overlap(this->tf1.getRotation(), this->tf1.getTranslation(), + this->model2_bv, this->model1->getBV(b1).bv, + this->request, sqrDistLowerBound); + } + /// @brief Intersection testing between leaves (one triangle and one shape) - void leafTesting(int b1, int b2) const + void leafTesting(int b1, int /*b2*/, FCL_REAL& sqrDistLowerBound) const { if(this->enable_statistics) this->num_leaf_tests++; const BVNode<BV>& node = this->model1->getBV(b1); @@ -210,18 +228,29 @@ public: FCL_REAL distance; Vec3f normal; - Vec3f c1, c2; + Vec3f c1, c2; // closest point + + bool collision; + if (RTIsIdentity) { + collision = + nsolver->shapeTriangleInteraction(*(this->model2), this->tf2, p1, p2, p3, + Transform3f (), distance, c1, c2, + normal); + } else { + collision = + nsolver->shapeTriangleInteraction(*(this->model2), this->tf2, p1, p2, p3, + this->tf1 , distance, c1, c2, normal); + } - if(nsolver->shapeTriangleInteraction(*(this->model2), this->tf2, p1, p2, p3, - Transform3f (), distance, c1, c2, - normal)) - { + if(collision) { if(this->request.num_max_contacts > this->result->numContacts()) this->result->addContact(Contact(this->model1, this->model2, primitive_id, Contact::NONE, c1, -normal, -distance)); + assert (this->result->isCollision ()); return; } + sqrDistLowerBound = distance * distance; assert (distance > 0); if (this->request.security_margin > 0) { if (distance <= this->request.security_margin) { @@ -231,6 +260,7 @@ public: -distance)); } } + assert (!this->result->isCollision () || sqrDistLowerBound > 0); } /// @brief Whether the traversal process can stop early @@ -297,127 +327,48 @@ static inline void meshShapeCollisionOrientedNodeLeafTesting /// @brief Traversal node for mesh and shape, when mesh BVH is one of the oriented node (OBB, RSS, OBBRSS, kIOS) template<typename S, typename NarrowPhaseSolver> -class MeshShapeCollisionTraversalNodeOBB : public MeshShapeCollisionTraversalNode<OBB, S, NarrowPhaseSolver> +class MeshShapeCollisionTraversalNodeOBB : public MeshShapeCollisionTraversalNode<OBB, S, NarrowPhaseSolver, 0> { public: MeshShapeCollisionTraversalNodeOBB(const CollisionRequest& request) : - MeshShapeCollisionTraversalNode<OBB, S, NarrowPhaseSolver> + MeshShapeCollisionTraversalNode<OBB, S, NarrowPhaseSolver, 0> (request) { } - bool BVTesting(int b1, int /*b2*/) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf1.getRotation(), this->tf1.getTranslation(), this->model2_bv, this->model1->getBV(b1).bv); - } - - bool BVTesting(int b1, int /*b2*/, FCL_REAL& sqrDistLowerBound) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf1.getRotation(), this->tf1.getTranslation(), - this->model2_bv, this->model1->getBV(b1).bv, - this->request, sqrDistLowerBound); - } - - void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - details::meshShapeCollisionOrientedNodeLeafTesting - (b1, b2, this->model1, *(this->model2), this->vertices, this->tri_indices, - this->tf1, this->tf2, this->nsolver, this->enable_statistics, - this->num_leaf_tests, this->request, *(this->result), sqrDistLowerBound); - } - }; template<typename S, typename NarrowPhaseSolver> -class MeshShapeCollisionTraversalNodeRSS : public MeshShapeCollisionTraversalNode<RSS, S, NarrowPhaseSolver> +class MeshShapeCollisionTraversalNodeRSS : public MeshShapeCollisionTraversalNode<RSS, S, NarrowPhaseSolver, 0> { public: MeshShapeCollisionTraversalNodeRSS (const CollisionRequest& request): - MeshShapeCollisionTraversalNode<RSS, S, NarrowPhaseSolver> + MeshShapeCollisionTraversalNode<RSS, S, NarrowPhaseSolver, 0> (request) { } - - bool BVTesting(int b1, int /*b2*/) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf1.getRotation(), this->tf1.getTranslation(), this->model2_bv, this->model1->getBV(b1).bv); - } - - void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - details::meshShapeCollisionOrientedNodeLeafTesting - (b1, b2, this->model1, *(this->model2), this->vertices, this->tri_indices, - this->tf1, this->tf2, this->nsolver, this->enable_statistics, - this->num_leaf_tests, this->request, *(this->result), sqrDistLowerBound); - } - }; template<typename S, typename NarrowPhaseSolver> -class MeshShapeCollisionTraversalNodekIOS : public MeshShapeCollisionTraversalNode<kIOS, S, NarrowPhaseSolver> +class MeshShapeCollisionTraversalNodekIOS : public MeshShapeCollisionTraversalNode<kIOS, S, NarrowPhaseSolver, 0> { public: MeshShapeCollisionTraversalNodekIOS(const CollisionRequest& request): - MeshShapeCollisionTraversalNode<kIOS, S, NarrowPhaseSolver> + MeshShapeCollisionTraversalNode<kIOS, S, NarrowPhaseSolver, 0> (request) { } - - bool BVTesting(int b1, int /*b2*/) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf1.getRotation(), this->tf1.getTranslation(), this->model2_bv, this->model1->getBV(b1).bv); - } - - void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - details::meshShapeCollisionOrientedNodeLeafTesting - (b1, b2, this->model1, *(this->model2), this->vertices, this->tri_indices, - this->tf1, this->tf2, this->nsolver, this->enable_statistics, - this->num_leaf_tests, this->request, *(this->result), sqrDistLowerBound); - } - }; template<typename S, typename NarrowPhaseSolver> -class MeshShapeCollisionTraversalNodeOBBRSS : public MeshShapeCollisionTraversalNode<OBBRSS, S, NarrowPhaseSolver> +class MeshShapeCollisionTraversalNodeOBBRSS : public MeshShapeCollisionTraversalNode<OBBRSS, S, NarrowPhaseSolver, 0> { public: - MeshShapeCollisionTraversalNodeOBBRSS - (const CollisionRequest& request) : - MeshShapeCollisionTraversalNode - <OBBRSS, S, NarrowPhaseSolver>(request) - { - } - - bool BVTesting(int b1, int /*b2*/) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf1.getRotation(), this->tf1.getTranslation(), this->model2_bv, this->model1->getBV(b1).bv); - } - - bool BVTesting(int b1, int /*b2*/, FCL_REAL& sqrDistLowerBound) const - { - if(this->enable_statistics) this->num_bv_tests++; - bool res (!overlap(this->tf1.getRotation(), this->tf1.getTranslation(), - this->model2_bv, this->model1->getBV(b1).bv, - this->request, sqrDistLowerBound)); - assert (!res || sqrDistLowerBound > 0); - return res; - } - - void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const + MeshShapeCollisionTraversalNodeOBBRSS (const CollisionRequest& request) : + MeshShapeCollisionTraversalNode <OBBRSS, S, NarrowPhaseSolver, 0> + (request) { - details::meshShapeCollisionOrientedNodeLeafTesting - (b1, b2, this->model1, *(this->model2), this->vertices, this->tri_indices, - this->tf1, this->tf2, this->nsolver, this->enable_statistics, - this->num_leaf_tests, this->request, *(this->result), sqrDistLowerBound); - assert (this->result->isCollision () || sqrDistLowerBound > 0); } - }; diff --git a/include/hpp/fcl/traversal/traversal_node_bvhs.h b/include/hpp/fcl/traversal/traversal_node_bvhs.h index 71dafc1f..985aa90d 100644 --- a/include/hpp/fcl/traversal/traversal_node_bvhs.h +++ b/include/hpp/fcl/traversal/traversal_node_bvhs.h @@ -47,6 +47,7 @@ #include <hpp/fcl/intersect.h> #include <hpp/fcl/shape/geometric_shapes.h> #include <hpp/fcl/narrowphase/narrowphase.h> +#include <hpp/fcl/traversal/details/traversal.h> #include <boost/shared_array.hpp> #include <boost/shared_ptr.hpp> @@ -59,10 +60,6 @@ namespace hpp { namespace fcl { -enum { - RelativeTransformationIsIdentity = 1 -}; - /// @brief Traversal node for collision between BVH models template<typename BV> class BVHCollisionTraversalNode : public CollisionTraversalNodeBase @@ -140,28 +137,6 @@ public: mutable FCL_REAL query_time_seconds; }; -namespace details -{ - template <bool enabled> - struct RelativeTransformation - { - RelativeTransformation () : R (Matrix3f::Identity()) {} - - const Matrix3f& _R () const { return R; } - const Vec3f & _T () const { return T; } - - Matrix3f R; - Vec3f T; - }; - - template <> - struct RelativeTransformation <false> - { - static const Matrix3f& _R () { throw std::logic_error ("should never reach this point"); } - static const Vec3f & _T () { throw std::logic_error ("should never reach this point"); } - }; -} // namespace details - /// @brief Traversal node for collision between two meshes template<typename BV, int _Options = RelativeTransformationIsIdentity> class MeshCollisionTraversalNode : public BVHCollisionTraversalNode<BV> @@ -288,7 +263,6 @@ public: details::RelativeTransformation<!bool(RTIsIdentity)> RT; }; - /// @brief Traversal node for collision between two meshes if their underlying BVH node is oriented node (OBB, RSS, OBBRSS, kIOS) typedef MeshCollisionTraversalNode<OBB , 0> MeshCollisionTraversalNodeOBB ; typedef MeshCollisionTraversalNode<RSS , 0> MeshCollisionTraversalNodeRSS ; -- GitLab