diff --git a/CMakeLists.txt b/CMakeLists.txt index 33b6335a344d944fd2b64d1853c62c12e36ede37..7af219281a1e2a138dc696ee4234fb1de6db3619 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/BV/AABB.h b/include/hpp/fcl/BV/AABB.h index b875b3c869016b12708968af98169204eecf7a6a..0b93c48a0ab6829d21abf18557526aa2f1d442b5 100644 --- a/include/hpp/fcl/BV/AABB.h +++ b/include/hpp/fcl/BV/AABB.h @@ -262,6 +262,14 @@ static inline AABB rotate(const AABB& aabb, const Matrix3f& t) return res; } +/// @brief Check collision between two aabbs, b1 is in configuration (R0, T0) and b2 is in identity. +bool overlap(const Matrix3f& R0, const Vec3f& T0, const AABB& b1, const AABB& b2); + +/// @brief Check collision between two aabbs, b1 is in configuration (R0, T0) and b2 is in identity. +bool overlap(const Matrix3f& R0, const Vec3f& T0, const AABB& b1, + const AABB& b2, const CollisionRequest& request, + FCL_REAL& sqrDistLowerBound); + } } // namespace hpp diff --git a/include/hpp/fcl/BV/RSS.h b/include/hpp/fcl/BV/RSS.h index 3b33b28023ef9893ad70fae4e01d2ee3b77d3273..6822e97e42abb8ab1186e1e78a0fd3ed74bba667 100644 --- a/include/hpp/fcl/BV/RSS.h +++ b/include/hpp/fcl/BV/RSS.h @@ -155,6 +155,10 @@ FCL_REAL distance(const Matrix3f& R0, const Vec3f& T0, const RSS& b1, const RSS& /// @brief Check collision between two RSSs, b1 is in configuration (R0, T0) and b2 is in identity. bool overlap(const Matrix3f& R0, const Vec3f& T0, const RSS& b1, const RSS& b2); +/// @brief Check collision between two RSSs, b1 is in configuration (R0, T0) and b2 is in identity. +bool overlap(const Matrix3f& R0, const Vec3f& T0, const RSS& b1, const RSS& b2, + const CollisionRequest& request, + FCL_REAL& sqrDistLowerBound); } diff --git a/include/hpp/fcl/BV/kDOP.h b/include/hpp/fcl/BV/kDOP.h index 72be7f89fa9dfaf9d0a0c2652f53ec5cbf553812..da5901624e1f4f8f8e5d380b024daaf36d7c8f26 100644 --- a/include/hpp/fcl/BV/kDOP.h +++ b/include/hpp/fcl/BV/kDOP.h @@ -39,7 +39,7 @@ #define HPP_FCL_KDOP_H #include <stdexcept> -#include <hpp/fcl/math/vec_3f.h> +#include <hpp/fcl/math/matrix_3f.h> namespace hpp { @@ -176,6 +176,20 @@ public: }; +template<size_t N> +bool overlap(const Matrix3f& /*R0*/, const Vec3f& /*T0*/, + const KDOP<N>& /*b1*/, const KDOP<N>& /*b2*/) +{ + throw std::logic_error ("not implemented"); +} + +template<size_t N> +bool overlap(const Matrix3f& /*R0*/, const Vec3f& /*T0*/, + const KDOP<N>& /*b1*/, const KDOP<N>& /*b2*/, + const CollisionRequest& /*request*/, FCL_REAL& /*sqrDistLowerBound*/) +{ + throw std::logic_error ("not implemented"); +} /// @brief translate the KDOP BV template<size_t N> diff --git a/include/hpp/fcl/BV/kIOS.h b/include/hpp/fcl/BV/kIOS.h index 64550f3885322617f8512ff827227e2c1bed2572..a7228168d3d3ffcbf45defdeb6acf6d850037fb7 100644 --- a/include/hpp/fcl/BV/kIOS.h +++ b/include/hpp/fcl/BV/kIOS.h @@ -157,6 +157,12 @@ kIOS translate(const kIOS& bv, const Vec3f& t); /// @todo Not efficient bool overlap(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2); +/// @brief Check collision between two kIOSs, b1 is in configuration (R0, T0) and b2 is in identity. +/// @todo Not efficient +bool overlap(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2, + const CollisionRequest& request, + FCL_REAL& sqrDistLowerBound); + /// @brief Approximate distance between two kIOS bounding volumes /// @todo P and Q is not returned, need implementation FCL_REAL distance(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2, Vec3f* P = NULL, Vec3f* Q = NULL); diff --git a/include/hpp/fcl/narrowphase/narrowphase.h b/include/hpp/fcl/narrowphase/narrowphase.h index 1c0d831e5f1d4da24f9bedf54e6a0521d5eae283..a85f7fae3131b7333d88401a4168af161bdaf42d 100644 --- a/include/hpp/fcl/narrowphase/narrowphase.h +++ b/include/hpp/fcl/narrowphase/narrowphase.h @@ -101,6 +101,7 @@ namespace fcl } //// @brief intersection checking between one shape and a triangle with transformation + /// \return true if the shape are colliding. template<typename S> bool shapeTriangleInteraction (const S& s, const Transform3f& tf1, const Vec3f& P1, const Vec3f& P2, diff --git a/include/hpp/fcl/traversal/details/traversal.h b/include/hpp/fcl/traversal/details/traversal.h new file mode 100644 index 0000000000000000000000000000000000000000..2979a601f169303b8f3e6cf5b0a010c18d0e43fa --- /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_base.h b/include/hpp/fcl/traversal/traversal_node_base.h index 81e1d61c8e6f6419c34787a4c6a92def8b5d4699..918505de5e55d4f0678e8dad64603c96378559ba 100644 --- a/include/hpp/fcl/traversal/traversal_node_base.h +++ b/include/hpp/fcl/traversal/traversal_node_base.h @@ -137,6 +137,8 @@ public: virtual ~DistanceTraversalNodeBase(); /// @brief BV test between b1 and b2 + /// \return a lower bound of the distance between the two BV. + /// \note except for OBB, this method returns the distance. virtual FCL_REAL BVTesting(int b1, int b2) const; /// @brief Leaf test between node b1 and b2, if they are both leafs diff --git a/include/hpp/fcl/traversal/traversal_node_bvh_shape.h b/include/hpp/fcl/traversal/traversal_node_bvh_shape.h index 738d63c58dd1d3e0c31c140443d10c2c5a9670d2..27ec3f9afed15285cdb311fff127bab9028e824e 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; @@ -152,24 +135,6 @@ public: return model2->getBV(b).rightChild(); } - /// BV test between b1 and b2 - /// \param b1, b2 Bounding volumes to test, - bool BVTesting(int b1, int b2) const - { - if(this->enable_statistics) num_bv_tests++; - return !model2->getBV(b2).bv.overlap(model1_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. - bool BVTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - if(this->enable_statistics) num_bv_tests++; - return !model2->getBV(b2).bv.overlap(model1_bv, sqrDistLowerBound); - } - const S* model1; const BVHModel<BV>* model2; BV model1_bv; @@ -181,10 +146,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 +165,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++; + if (RTIsIdentity) + return !this->model1->getBV(b1).bv.overlap(this->model2_bv); + else + return !overlap(this->tf1.getRotation(), this->tf1.getTranslation(), this->model2_bv, this->model1->getBV(b1).bv); + } + + /// 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++; + bool res; + if (RTIsIdentity) + res = !this->model1->getBV(b1).bv.overlap(this->model2_bv, this->request, sqrDistLowerBound); + else + 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; + } + /// @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,27 +210,41 @@ public: FCL_REAL distance; Vec3f normal; - Vec3f c1, c2; + Vec3f c1, c2; // closest point + + bool collision; + if (RTIsIdentity) { + static const Transform3f Id; + collision = + nsolver->shapeTriangleInteraction(*(this->model2), this->tf2, p1, p2, p3, + Id , distance, c2, c1, normal); + } else { + collision = + nsolver->shapeTriangleInteraction(*(this->model2), this->tf2, p1, p2, p3, + this->tf1, distance, c2, c1, 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)); - return; + assert (this->result->isCollision ()); + return; + } } + sqrDistLowerBound = distance * distance; assert (distance > 0); - if (this->request.security_margin > 0) { - if (distance <= this->request.security_margin) { - this->result->addContact(Contact(this->model1, this->model2, - primitive_id, Contact::NONE, - .5 * (c1+c2), (c2-c1).normalized (), - -distance)); - } + if ( this->request.security_margin > 0 + && distance <= this->request.security_margin) + { + this->result->addContact(Contact(this->model1, this->model2, + primitive_id, Contact::NONE, + .5 * (c1+c2), (c2-c1).normalized (), + -distance)); } + assert (!this->result->isCollision () || sqrDistLowerBound > 0); } /// @brief Whether the traversal process can stop early @@ -241,191 +255,68 @@ public: Vec3f* vertices; Triangle* tri_indices; - + const NarrowPhaseSolver* nsolver; }; -/// @cond IGNORE -namespace details -{ -template<typename BV, typename S, typename NarrowPhaseSolver> -static inline void meshShapeCollisionOrientedNodeLeafTesting - (int b1, int /*b2*/, const BVHModel<BV>* model1, const S& model2, - Vec3f* vertices, Triangle* tri_indices, const Transform3f& tf1, - const Transform3f& tf2, const NarrowPhaseSolver* nsolver, - bool enable_statistics, int& num_leaf_tests, - const CollisionRequest& request, CollisionResult& result, - FCL_REAL& sqrDistLowerBound) -{ - if(enable_statistics) num_leaf_tests++; - const BVNode<BV>& node = model1->getBV(b1); - - int primitive_id = node.primitiveId(); - - const Triangle& tri_id = tri_indices[primitive_id]; - - const Vec3f& P1 = vertices[tri_id[0]]; - const Vec3f& P2 = vertices[tri_id[1]]; - const Vec3f& P3 = vertices[tri_id[2]]; - - FCL_REAL distance; - Vec3f normal; - Vec3f p1, p2; // closest points - - if(nsolver->shapeTriangleInteraction(model2, tf2, P1, P2, P3, tf1, - distance, p1, p2, normal)) - { - if(request.num_max_contacts > result.numContacts()) - result.addContact(Contact(model1, &model2, primitive_id, Contact::NONE, - p1, -normal, -distance)); - assert (result.isCollision ()); - return; - } - sqrDistLowerBound = distance * distance; - assert (distance > 0); - if (request.security_margin == 0) return; - if (distance <= request.security_margin) { - result.addContact(Contact(model1, &model2, primitive_id, Contact::NONE, - .5*(p1+p2), (p2-p1).normalized (), -distance)); - } -} - -} - -/// @endcond - - /// @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); } - }; /// @brief Traversal node for collision between shape and mesh -template<typename S, typename BV, typename NarrowPhaseSolver> +template<typename S, typename BV, typename NarrowPhaseSolver, + int _Options = RelativeTransformationIsIdentity> class ShapeMeshCollisionTraversalNode : public ShapeBVHCollisionTraversalNode<S, BV> { public: + enum { + Options = _Options, + RTIsIdentity = _Options & RelativeTransformationIsIdentity + }; + ShapeMeshCollisionTraversalNode() : ShapeBVHCollisionTraversalNode<S, BV>() { vertices = NULL; @@ -434,8 +325,37 @@ public: nsolver = NULL; } + /// BV test between b1 and b2 + /// \param b2 Bounding volumes to test, + bool BVTesting(int /*b1*/, int b2) const + { + if(this->enable_statistics) this->num_bv_tests++; + if (RTIsIdentity) + return !this->model2->getBV(b2).bv.overlap(this->model1_bv); + else + return !overlap(this->tf2.getRotation(), this->tf2.getTranslation(), this->model1_bv, this->model2->getBV(b2).bv); + } + + /// BV test between b1 and b2 + /// \param b2 Bounding volumes to test, + /// \retval sqrDistLowerBound square of a lower bound of the minimal + /// distance between bounding volumes. + bool BVTesting(int /*b1*/, int b2, FCL_REAL& sqrDistLowerBound) const + { + if(this->enable_statistics) this->num_bv_tests++; + bool res; + if (RTIsIdentity) + res = !this->model2->getBV(b2).bv.overlap(this->model1_bv, sqrDistLowerBound); + else + res = !overlap(this->tf2.getRotation(), this->tf2.getTranslation(), + this->model1_bv, this->model2->getBV(b2).bv, + sqrDistLowerBound); + assert (!res || sqrDistLowerBound > 0); + return res; + } + /// @brief Intersection testing between leaves (one shape and one triangle) - 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->model2->getBV(b2); @@ -444,33 +364,47 @@ public: const Triangle& tri_id = tri_indices[primitive_id]; - const Vec3f& P1 = vertices[tri_id[0]]; - const Vec3f& P2 = vertices[tri_id[1]]; - const Vec3f& P3 = vertices[tri_id[2]]; + const Vec3f& p1 = vertices[tri_id[0]]; + const Vec3f& p2 = vertices[tri_id[1]]; + const Vec3f& p3 = vertices[tri_id[2]]; FCL_REAL distance; Vec3f normal; - Vec3f p1, p2; // closest points + Vec3f c1, c2; // closest points + + bool collision; + if (RTIsIdentity) { + static const Transform3f Id; + collision = + nsolver->shapeTriangleInteraction(*(this->model1), this->tf1, p1, p2, p3, + Id , c1, c2, distance, normal); + } else { + collision = + nsolver->shapeTriangleInteraction(*(this->model1), this->tf1, p1, p2, p3, + this->tf2, c1, c2, distance, normal); + } - if(nsolver->shapeTriangleInteraction(*(this->model1), this->tf1, P1, P2, P3, - Transform3f (), p1, p2, distance, - normal)) - { + if (collision) { if(this->request.num_max_contacts > this->result->numContacts()) { - this->result->addContact - (Contact(this->model1, this->model2, primitive_id, - Contact::NONE, p1, -normal, -distance)); + this->result->addContact (Contact(this->model1 , this->model2, + Contact::NONE, primitive_id, + c1, normal, -distance)); + assert (this->result->isCollision ()); + return; } } + sqrDistLowerBound = distance * distance; assert (distance > 0); - if (this->request.security_margin == 0) return; - if (distance <= this->request.security_margin) + if ( this->request.security_margin == 0 + && distance <= this->request.security_margin) { - this->result.addContact - (Contact(this->model1, this->model2, primitive_id, Contact::NONE, - .5 * (p1+p2), (p2-p1).normalized (), -distance)); + this->result.addContact (Contact(this->model1 , this->model2, + Contact::NONE, primitive_id, + .5 * (c1+c2), (c2-c1).normalized (), + -distance)); } + assert (!this->result->isCollision () || sqrDistLowerBound > 0); } /// @brief Whether the traversal process can stop early @@ -487,118 +421,42 @@ public: /// @brief Traversal node for shape and mesh, when mesh BVH is one of the oriented node (OBB, RSS, OBBRSS, kIOS) template<typename S, typename NarrowPhaseSolver> -class ShapeMeshCollisionTraversalNodeOBB : public ShapeMeshCollisionTraversalNode<S, OBB, NarrowPhaseSolver> +class ShapeMeshCollisionTraversalNodeOBB : public ShapeMeshCollisionTraversalNode<S, OBB, NarrowPhaseSolver, 0> { public: ShapeMeshCollisionTraversalNodeOBB() : ShapeMeshCollisionTraversalNode<S, OBB, NarrowPhaseSolver>() { } - - bool BVTesting(int b1, int b2) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf2.getRotation(), this->tf2.getTranslation(), this->model1_bv, this->model2->getBV(b2).bv); - } - - void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - details::meshShapeCollisionOrientedNodeLeafTesting - (b2, b1, *(this->model2), this->model1, this->vertices, this->tri_indices, - this->tf2, this->tf1, this->nsolver, this->enable_statistics, - this->num_leaf_tests, this->request,*(this->request), sqrDistLowerBound); - - // may need to change the order in pairs - } }; template<typename S, typename NarrowPhaseSolver> -class ShapeMeshCollisionTraversalNodeRSS : public ShapeMeshCollisionTraversalNode<S, RSS, NarrowPhaseSolver> +class ShapeMeshCollisionTraversalNodeRSS : public ShapeMeshCollisionTraversalNode<S, RSS, NarrowPhaseSolver, 0> { public: ShapeMeshCollisionTraversalNodeRSS() : ShapeMeshCollisionTraversalNode<S, RSS, NarrowPhaseSolver>() { } - - bool BVTesting(int b1, int b2) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf2.getRotation(), this->tf2.getTranslation(), this->model1_bv, this->model2->getBV(b2).bv); - } - - void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - details::meshShapeCollisionOrientedNodeLeafTesting - (b2, b1, *(this->model2), this->model1, this->vertices, this->tri_indices, - this->tf2, this->tf1, this->nsolver, this->enable_statistics, - this->num_leaf_tests, this->request, *(this->request)); - - // may need to change the order in pairs - } - }; template<typename S, typename NarrowPhaseSolver> -class ShapeMeshCollisionTraversalNodekIOS : public ShapeMeshCollisionTraversalNode<S, kIOS, NarrowPhaseSolver> +class ShapeMeshCollisionTraversalNodekIOS : public ShapeMeshCollisionTraversalNode<S, kIOS, NarrowPhaseSolver, 0> { public: ShapeMeshCollisionTraversalNodekIOS() : ShapeMeshCollisionTraversalNode<S, kIOS, NarrowPhaseSolver>() { } - - bool BVTesting(int b1, int b2) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf2.getRotation(), this->tf2.getTranslation(), this->model1_bv, this->model2->getBV(b2).bv); - } - - void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - details::meshShapeCollisionOrientedNodeLeafTesting - (b2, b1, *(this->model2), this->model1, this->vertices, this->tri_indices, - this->tf2, this->tf1, this->nsolver, this->enable_statistics, - this->num_leaf_tests, this->request,*(this->request), sqrDistLowerBound); - - // may need to change the order in pairs - } - }; template<typename S, typename NarrowPhaseSolver> -class ShapeMeshCollisionTraversalNodeOBBRSS : public ShapeMeshCollisionTraversalNode<S, OBBRSS, NarrowPhaseSolver> +class ShapeMeshCollisionTraversalNodeOBBRSS : public ShapeMeshCollisionTraversalNode<S, OBBRSS, NarrowPhaseSolver, 0> { public: ShapeMeshCollisionTraversalNodeOBBRSS() : ShapeMeshCollisionTraversalNode<S, OBBRSS, NarrowPhaseSolver>() { } - - bool BVTesting(int b1, int b2) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf2.getRotation(), this->tf2.getTranslation(), this->model1_bv, this->model2->getBV(b2).bv); - } - - bool BVTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - if(this->enable_statistics) this->num_bv_tests++; - return !overlap(this->tf2.getRotation(), this->tf2.getTranslation(), - this->model1_bv, this->model2->getBV(b2).bv, - sqrDistLowerBound); - } - - void leafTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - details::meshShapeCollisionOrientedNodeLeafTesting - (b2, b1, *(this->model2), this->model1, this->vertices, - this->tri_indices, this->tf2, this->tf1, this->nsolver, - this->enable_statistics, this->num_leaf_tests, - this->request, *(this->request), sqrDistLowerBound); - - // may need to change the order in pairs - } - }; /// @brief Traversal node for distance computation between BVH and shape diff --git a/include/hpp/fcl/traversal/traversal_node_bvhs.h b/include/hpp/fcl/traversal/traversal_node_bvhs.h index 972955e0f6f74ef0d69ba6509f77c82ccdf24228..985aa90d3f7c9e84fcec17d0d121d4b657f6379b 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> @@ -124,24 +125,6 @@ public: { return model2->getBV(b).rightChild(); } - - /// @brief BV culling test in one BVTT node - bool BVTesting(int b1, int b2) const - { - if(enable_statistics) num_bv_tests++; - return !model1->getBV(b1).overlap(model2->getBV(b2)); - } - - /// 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. - bool BVTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - if(enable_statistics) num_bv_tests++; - return !model1->getBV(b1).overlap(model2->getBV(b2), request, - sqrDistLowerBound); - } /// @brief The first BVH model const BVHModel<BV>* model1; @@ -154,12 +137,16 @@ public: mutable FCL_REAL query_time_seconds; }; - /// @brief Traversal node for collision between two meshes -template<typename BV> +template<typename BV, int _Options = RelativeTransformationIsIdentity> class MeshCollisionTraversalNode : public BVHCollisionTraversalNode<BV> { public: + enum { + Options = _Options, + RTIsIdentity = _Options & RelativeTransformationIsIdentity + }; + MeshCollisionTraversalNode(const CollisionRequest& request) : BVHCollisionTraversalNode<BV> (request) { @@ -169,6 +156,36 @@ public: tri_indices2 = NULL; } + /// @brief BV culling test in one BVTT node + bool BVTesting(int b1, int b2) const + { + if(this->enable_statistics) this->num_bv_tests++; + if (RTIsIdentity) + return !this->model1->getBV(b1).overlap(this->model2->getBV(b2)); + else + return !overlap(RT._R(), RT._T(), + this->model1->getBV(b1).bv, this->model2->getBV(b2).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. + 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).overlap(this->model2->getBV(b2), + this->request, sqrDistLowerBound); + else { + bool res = !overlap(RT._R(), RT._T(), + this->model1->getBV(b1).bv, this->model2->getBV(b2).bv, + this->request, sqrDistLowerBound); + assert (!res || sqrDistLowerBound > 0); + return res; + } + } + /// Intersection testing between leaves (two triangles) /// /// \param b1, b2 id of primitive in bounding volume hierarchy @@ -242,61 +259,41 @@ public: Triangle* tri_indices1; Triangle* tri_indices2; -}; - - -/// @brief Traversal node for collision between two meshes if their underlying BVH node is oriented node (OBB, RSS, OBBRSS, kIOS) -class MeshCollisionTraversalNodeOBB : public MeshCollisionTraversalNode<OBB> -{ -public: - MeshCollisionTraversalNodeOBB (const CollisionRequest& request); - - bool BVTesting(int b1, int b2) const; - - bool BVTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const; - - Matrix3f R; - Vec3f T; -}; -class MeshCollisionTraversalNodeRSS : public MeshCollisionTraversalNode<RSS> -{ -public: - MeshCollisionTraversalNodeRSS (const CollisionRequest& request); - - bool BVTesting(int b1, int b2) const; - - bool BVTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const; - - Matrix3f R; - Vec3f T; + details::RelativeTransformation<!bool(RTIsIdentity)> RT; }; -class MeshCollisionTraversalNodekIOS : public MeshCollisionTraversalNode<kIOS> -{ -public: - MeshCollisionTraversalNodekIOS (const CollisionRequest& request); - - bool BVTesting(int b1, int b2) const; - - bool BVTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const; - - Matrix3f R; - Vec3f T; -}; +/// @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 ; +typedef MeshCollisionTraversalNode<kIOS , 0> MeshCollisionTraversalNodekIOS ; +typedef MeshCollisionTraversalNode<OBBRSS, 0> MeshCollisionTraversalNodeOBBRSS; -class MeshCollisionTraversalNodeOBBRSS : public MeshCollisionTraversalNode<OBBRSS> +namespace details { -public: - MeshCollisionTraversalNodeOBBRSS (const CollisionRequest& request); - - bool BVTesting(int b1, int b2) const; - - bool BVTesting(int b1, int b2, FCL_REAL& sqrDistLowerBound) const; + template<typename BV> struct DistanceTraversalBVTesting_impl + { + static FCL_REAL run(const BVNode<BV>& b1, const BVNode<BV>& b2) + { + return b1.distance(b2); + } + }; - Matrix3f R; - Vec3f T; -}; + template<> struct DistanceTraversalBVTesting_impl<OBB> + { + static FCL_REAL run(const BVNode<OBB>& b1, const BVNode<OBB>& b2) + { + FCL_REAL sqrDistLowerBound; + CollisionRequest request (DISTANCE_LOWER_BOUND, 0); + // request.break_distance = ? + if (b1.overlap(b2, request, sqrDistLowerBound)) { + // TODO A penetration upper bound should be computed. + return -1; + } + return sqrt (sqrDistLowerBound); + } + }; +} // namespace details /// @brief Traversal node for distance computation between BVH models template<typename BV> @@ -367,7 +364,8 @@ public: FCL_REAL BVTesting(int b1, int b2) const { if(enable_statistics) num_bv_tests++; - return model1->getBV(b1).distance(model2->getBV(b2)); + return details::DistanceTraversalBVTesting_impl<BV> + ::run (model1->getBV(b1), model2->getBV(b2)); } /// @brief The first BVH model diff --git a/src/BV/AABB.cpp b/src/BV/AABB.cpp index e65bee4bb899c521a70ec1b4bce45b6ea1a389af..782e0bc16b778e3a31ad3b92acdd95a1671679a6 100644 --- a/src/BV/AABB.cpp +++ b/src/BV/AABB.cpp @@ -128,6 +128,20 @@ FCL_REAL AABB::distance(const AABB& other) const return std::sqrt(result); } +bool overlap(const Matrix3f& R0, const Vec3f& T0, const AABB& b1, const AABB& b2) +{ + AABB bb1 (translate (rotate (b1, R0), T0)); + return bb1.overlap (b2); +} + +bool overlap(const Matrix3f& R0, const Vec3f& T0, const AABB& b1, + const AABB& b2, const CollisionRequest& request, + FCL_REAL& sqrDistLowerBound) +{ + AABB bb1 (translate (rotate (b1, R0), T0)); + return bb1.overlap (b2, request, sqrDistLowerBound); +} + } } // namespace hpp diff --git a/src/BV/RSS.cpp b/src/BV/RSS.cpp index 7ef7cc7b75e9f979fff6ff1d5c7491fc8b5354ff..0f719bcebdad1f71a2bcbfe2b78005dd164842a9 100644 --- a/src/BV/RSS.cpp +++ b/src/BV/RSS.cpp @@ -862,6 +862,25 @@ bool overlap(const Matrix3f& R0, const Vec3f& T0, const RSS& b1, const RSS& b2) return (dist <= (b1.r + b2.r)); } +bool overlap(const Matrix3f& R0, const Vec3f& T0, const RSS& b1, const RSS& b2, + const CollisionRequest& /*request*/, + FCL_REAL& sqrDistLowerBound) +{ + // ROb2 = R0 . b2 + // where b2 = [ b2.axis [0] | b2.axis [1] | b2.axis [2] ] + + // (1 0 0)^T R0b2^T axis [0] = (1 0 0)^T b2^T R0^T axis [0] + // R = b2^T RO^T b1 + Vec3f Ttemp (R0 * b2.Tr + T0 - b1.Tr); + Vec3f T(b1.axes.transpose() * Ttemp); + Matrix3f R(b1.axes.transpose() * R0 * b2.axes); + + FCL_REAL dist = rectDistance(R, T, b1.l, b2.l) - b1.r - b2.r; + if (dist <= 0) return true; + sqrDistLowerBound = dist * dist; + return false; +} + bool RSS::contain(const Vec3f& p) const { Vec3f local_p = p - Tr; diff --git a/src/BV/kIOS.cpp b/src/BV/kIOS.cpp index e6c267a8b6df9e55e801d807cf0856c3246a022b..010966e3b0580c7fce54e34774d1ebb38fa9c51c 100644 --- a/src/BV/kIOS.cpp +++ b/src/BV/kIOS.cpp @@ -61,17 +61,27 @@ bool kIOS::overlap(const kIOS& other) const } return obb.overlap(other.obb); - - return true; } - bool kIOS::overlap(const kIOS& other, const CollisionRequest&, - FCL_REAL& sqrDistLowerBound) const +bool kIOS::overlap(const kIOS& other, const CollisionRequest& request, + FCL_REAL& sqrDistLowerBound) const +{ + for(unsigned int i = 0; i < num_spheres; ++i) { - sqrDistLowerBound = sqrt (-1); - return overlap (other); + for(unsigned int j = 0; j < other.num_spheres; ++j) + { + FCL_REAL o_dist = (spheres[i].o - other.spheres[j].o).squaredNorm(); + FCL_REAL sum_r = spheres[i].r + other.spheres[j].r; + if(o_dist > sum_r * sum_r) { + o_dist = sqrt(o_dist) - sum_r; + sqrDistLowerBound = o_dist*o_dist; + return false; + } + } } + return obb.overlap(other.obb, request, sqrDistLowerBound); +} bool kIOS::contain(const Vec3f& p) const { @@ -192,6 +202,23 @@ bool overlap(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2 return b1.overlap(b2_temp); } +bool overlap(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2, + const CollisionRequest& request, + FCL_REAL& sqrDistLowerBound) +{ + kIOS b2_temp = b2; + for(unsigned int i = 0; i < b2_temp.num_spheres; ++i) + { + b2_temp.spheres[i].o = R0 * b2_temp.spheres[i].o + T0; + } + + + b2_temp.obb.To = R0 * b2_temp.obb.To + T0; + b2_temp.obb.axes.applyOnTheLeft(R0); + + return b1.overlap(b2_temp, request, sqrDistLowerBound); +} + FCL_REAL distance(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2, Vec3f* P, Vec3f* Q) { kIOS b2_temp = b2; diff --git a/src/distance_func_matrix.cpp b/src/distance_func_matrix.cpp index c83148c07e5bc412692f9eef213e3f9391d78c3b..423d8d62e52306a70bf19559e5a5020479ee8c30 100644 --- a/src/distance_func_matrix.cpp +++ b/src/distance_func_matrix.cpp @@ -379,6 +379,7 @@ DistanceFunctionMatrix<NarrowPhaseSolver>::DistanceFunctionMatrix() distance_matrix[BV_AABB][GEOM_CONVEX] = &BVHShapeDistancer<AABB, Convex, NarrowPhaseSolver>::distance; distance_matrix[BV_AABB][GEOM_PLANE] = &BVHShapeDistancer<AABB, Plane, NarrowPhaseSolver>::distance; distance_matrix[BV_AABB][GEOM_HALFSPACE] = &BVHShapeDistancer<AABB, Halfspace, NarrowPhaseSolver>::distance; + */ distance_matrix[BV_OBB][GEOM_BOX] = &BVHShapeDistancer<OBB, Box, NarrowPhaseSolver>::distance; distance_matrix[BV_OBB][GEOM_SPHERE] = &BVHShapeDistancer<OBB, Sphere, NarrowPhaseSolver>::distance; @@ -388,7 +389,6 @@ DistanceFunctionMatrix<NarrowPhaseSolver>::DistanceFunctionMatrix() distance_matrix[BV_OBB][GEOM_CONVEX] = &BVHShapeDistancer<OBB, Convex, NarrowPhaseSolver>::distance; distance_matrix[BV_OBB][GEOM_PLANE] = &BVHShapeDistancer<OBB, Plane, NarrowPhaseSolver>::distance; distance_matrix[BV_OBB][GEOM_HALFSPACE] = &BVHShapeDistancer<OBB, Halfspace, NarrowPhaseSolver>::distance; - */ distance_matrix[BV_RSS][GEOM_BOX] = &BVHShapeDistancer<RSS, Box, NarrowPhaseSolver>::distance; distance_matrix[BV_RSS][GEOM_SPHERE] = &BVHShapeDistancer<RSS, Sphere, NarrowPhaseSolver>::distance; @@ -448,6 +448,7 @@ DistanceFunctionMatrix<NarrowPhaseSolver>::DistanceFunctionMatrix() distance_matrix[BV_OBBRSS][GEOM_HALFSPACE] = &BVHShapeDistancer<OBBRSS, Halfspace, NarrowPhaseSolver>::distance; distance_matrix[BV_AABB][BV_AABB] = &BVHDistance<AABB, NarrowPhaseSolver>; + distance_matrix[BV_OBB][BV_OBB] = &BVHDistance<OBB, NarrowPhaseSolver>; distance_matrix[BV_RSS][BV_RSS] = &BVHDistance<RSS, NarrowPhaseSolver>; distance_matrix[BV_kIOS][BV_kIOS] = &BVHDistance<kIOS, NarrowPhaseSolver>; distance_matrix[BV_OBBRSS][BV_OBBRSS] = &BVHDistance<OBBRSS, NarrowPhaseSolver>; diff --git a/src/traversal/traversal_node_bvhs.cpp b/src/traversal/traversal_node_bvhs.cpp index d241780e58bd83bf0a4ecc8fe6832dbdb5f8480a..5fe97fa5a0eaf8b892e77971b24ca2854e8b02d2 100644 --- a/src/traversal/traversal_node_bvhs.cpp +++ b/src/traversal/traversal_node_bvhs.cpp @@ -86,92 +86,6 @@ static inline void meshDistanceOrientedNodeLeafTesting(int b1, int b2, } } // namespace details -MeshCollisionTraversalNodeOBB::MeshCollisionTraversalNodeOBB -(const CollisionRequest& request) : - MeshCollisionTraversalNode<OBB> (request) -{ - R.setIdentity(); -} - -bool MeshCollisionTraversalNodeOBB::BVTesting(int b1, int b2) const -{ - if(enable_statistics) num_bv_tests++; - return !overlap(R, T, model1->getBV(b1).bv, model2->getBV(b2).bv); -} - -bool MeshCollisionTraversalNodeOBB::BVTesting -(int b1, int b2, FCL_REAL& sqrDistLowerBound) const -{ - if(enable_statistics) num_bv_tests++; - return !overlap(R, T, model1->getBV(b1).bv, model2->getBV(b2).bv, - request, sqrDistLowerBound); -} - -MeshCollisionTraversalNodeRSS::MeshCollisionTraversalNodeRSS -(const CollisionRequest& request) : - MeshCollisionTraversalNode<RSS> (request) -{ - R.setIdentity(); -} - -bool MeshCollisionTraversalNodeRSS::BVTesting(int b1, int b2) const -{ - if(enable_statistics) num_bv_tests++; - return !overlap(R, T, model1->getBV(b1).bv, model2->getBV(b2).bv); -} - -bool MeshCollisionTraversalNodeRSS::BVTesting(int b1, int b2, - FCL_REAL& sqrDistLowerBound) const -{ - if(enable_statistics) num_bv_tests++; - sqrDistLowerBound = 0; - return !overlap(R, T, model1->getBV(b1).bv, model2->getBV(b2).bv); -} - -MeshCollisionTraversalNodekIOS::MeshCollisionTraversalNodekIOS -(const CollisionRequest& request) : - MeshCollisionTraversalNode<kIOS>(request) -{ - R.setIdentity(); -} - -bool MeshCollisionTraversalNodekIOS::BVTesting(int b1, int b2) const -{ - if(enable_statistics) num_bv_tests++; - return !overlap(R, T, model1->getBV(b1).bv, model2->getBV(b2).bv); -} - -bool MeshCollisionTraversalNodekIOS::BVTesting -(int b1, int b2, FCL_REAL& sqrDistLowerBound) const -{ - if(enable_statistics) num_bv_tests++; - sqrDistLowerBound = 0; - return !overlap(R, T, model1->getBV(b1).bv, model2->getBV(b2).bv); -} - -MeshCollisionTraversalNodeOBBRSS::MeshCollisionTraversalNodeOBBRSS -(const CollisionRequest& request) : - MeshCollisionTraversalNode<OBBRSS> (request) -{ - R.setIdentity(); -} - -bool MeshCollisionTraversalNodeOBBRSS::BVTesting(int b1, int b2) const -{ - if(enable_statistics) num_bv_tests++; - return !overlap(R, T, model1->getBV(b1).bv, model2->getBV(b2).bv); -} - - bool MeshCollisionTraversalNodeOBBRSS::BVTesting - (int b1, int b2, FCL_REAL& sqrDistLowerBound) const - { - if(enable_statistics) num_bv_tests++; - bool res (!overlap(R, T, model1->getBV(b1).bv, model2->getBV(b2).bv, - request, sqrDistLowerBound)); - assert (!res || sqrDistLowerBound > 0); - return res; - } - namespace details { diff --git a/src/traversal/traversal_node_setup.cpp b/src/traversal/traversal_node_setup.cpp index 321ca128f8f2b6028b7b14981f5b59c1288b8169..7275286062ab008bbba9dcb3abbb7f5d3053bb87 100644 --- a/src/traversal/traversal_node_setup.cpp +++ b/src/traversal/traversal_node_setup.cpp @@ -68,7 +68,7 @@ static inline bool setupMeshCollisionOrientedNode(OrientedNode& node, node.result = &result; - relativeTransform(tf1.getRotation(), tf1.getTranslation(), tf2.getRotation(), tf2.getTranslation(), node.R, node.T); + relativeTransform(tf1.getRotation(), tf1.getTranslation(), tf2.getRotation(), tf2.getTranslation(), node.RT.R, node.RT.T); return true; } diff --git a/test/benchmark.cpp b/test/benchmark.cpp index 4ecf04e29dfc3c4a64df5690c8eb90ced11efd4f..28b718c5df33032ccd153c1b949ac7583ec518d4 100644 --- a/test/benchmark.cpp +++ b/test/benchmark.cpp @@ -127,6 +127,7 @@ double collide (const std::vector<Transform3f>& tf, for (std::size_t i = 0; i < tf.size(); ++i) { bool success (initialize(node, m1, tf[i], m2, pose2, local_result)); + (void)success; assert (success); CollisionResult result; diff --git a/test/test_fcl_distance.cpp b/test/test_fcl_distance.cpp index 192a9508120dabf0dd6eacd146477c1b484246ed..35eb58408d061fbafbed6f6f8ff60ad9ffebfae8 100644 --- a/test/test_fcl_distance.cpp +++ b/test/test_fcl_distance.cpp @@ -198,7 +198,36 @@ BOOST_AUTO_TEST_CASE(mesh_distance) BOOST_CHECK(fabs(res.distance) < DELTA || (res.distance > 0 && nearlyEqual(res.p1, res_now.p1) && nearlyEqual(res.p2, res_now.p2))); + distance_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, 2, res_now, verbose); + BOOST_CHECK(fabs(res.distance - res_now.distance) < DELTA); + BOOST_CHECK(fabs(res.distance) < DELTA || (res.distance > 0 && nearlyEqual(res.p1, res_now.p1) && nearlyEqual(res.p2, res_now.p2))); + + distance_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, 2, res_now, verbose); + + BOOST_CHECK(fabs(res.distance - res_now.distance) < DELTA); + BOOST_CHECK(fabs(res.distance) < DELTA || (res.distance > 0 && nearlyEqual(res.p1, res_now.p1) && nearlyEqual(res.p2, res_now.p2))); + + distance_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, 2, res_now, verbose); + + BOOST_CHECK(fabs(res.distance - res_now.distance) < DELTA); + BOOST_CHECK(fabs(res.distance) < DELTA || (res.distance > 0 && nearlyEqual(res.p1, res_now.p1) && nearlyEqual(res.p2, res_now.p2))); + + distance_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, 20, res_now, verbose); + + BOOST_CHECK(fabs(res.distance - res_now.distance) < DELTA); + BOOST_CHECK(fabs(res.distance) < DELTA || (res.distance > 0 && nearlyEqual(res.p1, res_now.p1) && nearlyEqual(res.p2, res_now.p2))); + + distance_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, 20, res_now, verbose); + + BOOST_CHECK(fabs(res.distance - res_now.distance) < DELTA); + BOOST_CHECK(fabs(res.distance) < DELTA || (res.distance > 0 && nearlyEqual(res.p1, res_now.p1) && nearlyEqual(res.p2, res_now.p2))); + + distance_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, 20, res_now, verbose); + + BOOST_CHECK(fabs(res.distance - res_now.distance) < DELTA); + BOOST_CHECK(fabs(res.distance) < DELTA || (res.distance > 0 && nearlyEqual(res.p1, res_now.p1) && nearlyEqual(res.p2, res_now.p2))); + distance_Test<RSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, 2, res_now, verbose); BOOST_CHECK(fabs(res.distance - res_now.distance) < DELTA); diff --git a/test/test_fcl_utility.cpp b/test/test_fcl_utility.cpp index b60b015d9d4a07c12d606490dff2ac3760290135..9a22a9dffeac0c854e64a551ed151c1529a71e98 100644 --- a/test/test_fcl_utility.cpp +++ b/test/test_fcl_utility.cpp @@ -68,8 +68,8 @@ double Timer::getElapsedTimeInMicroSec() if(!stopped) gettimeofday(&endCount, NULL); - startTimeInMicroSec = (startCount.tv_sec * 1000000.0) + startCount.tv_usec; - endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec; + startTimeInMicroSec = ((double)startCount.tv_sec * 1000000.0) + (double)startCount.tv_usec; + endTimeInMicroSec = ((double)endCount.tv_sec * 1000000.0) + (double)endCount.tv_usec; #endif return endTimeInMicroSec - startTimeInMicroSec; @@ -333,8 +333,8 @@ void generateRandomTransforms(FCL_REAL extents[6], FCL_REAL delta_trans[3], FCL_ } void generateRandomTransform_ccd(FCL_REAL extents[6], std::vector<Transform3f>& transforms, std::vector<Transform3f>& transforms2, FCL_REAL delta_trans[3], FCL_REAL delta_rot, std::size_t n, - const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1, - const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2) + const std::vector<Vec3f>& /*vertices1*/, const std::vector<Triangle>& /*riangles1*/, + const std::vector<Vec3f>& /*vertices2*/, const std::vector<Triangle>& /*riangles2*/) { transforms.resize(n); transforms2.resize(n);