diff --git a/trunk/fcl/include/fcl/geometric_shapes.h b/trunk/fcl/include/fcl/geometric_shapes.h index 2757df853645123b7cf358e2c93fd208367825e3..4681fc8957aee7f1ec46e0a0e7c157a235f075b8 100644 --- a/trunk/fcl/include/fcl/geometric_shapes.h +++ b/trunk/fcl/include/fcl/geometric_shapes.h @@ -60,7 +60,10 @@ public: class Triangle2 : public ShapeBase { public: - Triangle2(const Vec3f& a_, const Vec3f& b_, const Vec3f& c_) : a(a_), b(b_), c(c_) {} + Triangle2(const Vec3f& a_, const Vec3f& b_, const Vec3f& c_) : ShapeBase(), a(a_), b(b_), c(c_) + { + computeLocalAABB(); + } void computeLocalAABB(); @@ -73,7 +76,10 @@ public: class Box : public ShapeBase { public: - Box(FCL_REAL x, FCL_REAL y, FCL_REAL z) : ShapeBase(), side(x, y, z) {} + Box(FCL_REAL x, FCL_REAL y, FCL_REAL z) : ShapeBase(), side(x, y, z) + { + computeLocalAABB(); + } /** box side length */ Vec3f side; @@ -89,7 +95,10 @@ public: class Sphere : public ShapeBase { public: - Sphere(FCL_REAL radius_) : ShapeBase(), radius(radius_) {} + Sphere(FCL_REAL radius_) : ShapeBase(), radius(radius_) + { + computeLocalAABB(); + } /** \brief Radius of the sphere */ FCL_REAL radius; @@ -105,7 +114,10 @@ public: class Capsule : public ShapeBase { public: - Capsule(FCL_REAL radius_, FCL_REAL lz_) : ShapeBase(), radius(radius_), lz(lz_) {} + Capsule(FCL_REAL radius_, FCL_REAL lz_) : ShapeBase(), radius(radius_), lz(lz_) + { + computeLocalAABB(); + } /** \brief Radius of capsule */ FCL_REAL radius; @@ -124,7 +136,11 @@ public: class Cone : public ShapeBase { public: - Cone(FCL_REAL radius_, FCL_REAL lz_) : ShapeBase(), radius(radius_), lz(lz_) {} + Cone(FCL_REAL radius_, FCL_REAL lz_) : ShapeBase(), radius(radius_), lz(lz_) + { + computeLocalAABB(); + } + /** \brief Radius of the cone */ FCL_REAL radius; @@ -143,7 +159,11 @@ public: class Cylinder : public ShapeBase { public: - Cylinder(FCL_REAL radius_, FCL_REAL lz_) : ShapeBase(), radius(radius_), lz(lz_) {} + Cylinder(FCL_REAL radius_, FCL_REAL lz_) : ShapeBase(), radius(radius_), lz(lz_) + { + computeLocalAABB(); + } + /** \brief Radius of the cylinder */ FCL_REAL radius; @@ -186,6 +206,8 @@ public: center = sum * (FCL_REAL)(1.0 / num_points); fillEdges(); + + computeLocalAABB(); } /** Copy constructor */ @@ -198,6 +220,8 @@ public: polygons = other.polygons; edges = new Edge[other.num_edges]; memcpy(edges, other.edges, sizeof(Edge) * num_edges); + + computeLocalAABB(); } ~Convex() @@ -245,12 +269,19 @@ class Plane : public ShapeBase { public: /** \brief Construct a plane with normal direction and offset */ - Plane(const Vec3f& n_, FCL_REAL d_) : ShapeBase(), n(n_), d(d_) { unitNormalTest(); } + Plane(const Vec3f& n_, FCL_REAL d_) : ShapeBase(), n(n_), d(d_) + { + unitNormalTest(); + + computeLocalAABB(); + } /** \brief Construct a plane with normal direction and offset */ Plane(FCL_REAL a, FCL_REAL b, FCL_REAL c, FCL_REAL d_) : n(a, b, c), d(d_) { unitNormalTest(); + + computeLocalAABB(); } /** \brief Compute AABB */ diff --git a/trunk/fcl/include/fcl/octomap_extension.h b/trunk/fcl/include/fcl/octomap_extension.h index 6b45b42bd4adb6adeef03edb815c97d214aec6dd..fa52446a1f1ddcea237be2f6b15bff28198482c1 100644 --- a/trunk/fcl/include/fcl/octomap_extension.h +++ b/trunk/fcl/include/fcl/octomap_extension.h @@ -38,6 +38,7 @@ #ifndef FCL_OCTOMAP_EXTENSION_H #define FCL_OCTOMAP_EXTENSION_H +#include <vector> #include <set> #include <octomap/octomap.h> #include "fcl/broad_phase_collision.h" @@ -45,22 +46,34 @@ namespace fcl { +struct OcTreeNode_AABB_pair +{ + octomap::OcTreeNode* node; + AABB aabb; + + OcTreeNode_AABB_pair(octomap::OcTreeNode* node_, const AABB& aabb_) : node(node_), aabb(aabb_) {} + + bool operator < (const OcTreeNode_AABB_pair& other) const + { + return node < other.node; + } +}; -bool defaultCollisionCostFunction(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost); +bool defaultCollisionCostOctomapFunction(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost); -bool defaultCollisionCostExtFunction(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost, std::set<octomap::OcTreeNode*>& nodes); +bool defaultCollisionCostOctomapExtFunction(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost, std::set<OcTreeNode_AABB_pair>& nodes); -typedef bool (*CollisionCostCallBack)(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost); +typedef bool (*CollisionCostOctomapCallBack)(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost); -typedef bool (*CollisionCostCallBackExt)(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost, std::set<octomap::OcTreeNode*>& nodes); +typedef bool (*CollisionCostOctomapCallBackExt)(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost, std::set<OcTreeNode_AABB_pair>& nodes); void collide(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCallBack callback); -FCL_REAL collideCost(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCostCallBack callback); +FCL_REAL collideCost(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCostOctomapCallBack callback); -FCL_REAL collideCost(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCostCallBackExt callback, std::set<octomap::OcTreeNode*>& nodes); +FCL_REAL collideCost(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCostOctomapCallBackExt callback, std::vector<AABB>& nodes); } diff --git a/trunk/fcl/include/fcl/transform.h b/trunk/fcl/include/fcl/transform.h index a5e9f7c9e29a92bf4aca083a1d3a3d127bf6e0b6..cdaff8d4f5889bb08d4c2019d622d9e4721b8625 100644 --- a/trunk/fcl/include/fcl/transform.h +++ b/trunk/fcl/include/fcl/transform.h @@ -65,6 +65,11 @@ public: data[3] = d; // z } + bool isIdentity() const + { + return (data[0] == 1) && (data[1] == 0) && (data[2] == 0) && (data[3] == 0); + } + /** \brief Matrix to quaternion */ void fromRotation(const Matrix3f& R); diff --git a/trunk/fcl/src/octomap_extension.cpp b/trunk/fcl/src/octomap_extension.cpp index 69ec965c138094606f93e61c3a0d3cf390cac423..81b9cfc3e49aee8b311733f1f5328899ea82b346 100644 --- a/trunk/fcl/src/octomap_extension.cpp +++ b/trunk/fcl/src/octomap_extension.cpp @@ -63,13 +63,15 @@ bool collisionRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* root1, { if(root1->bv.overlap(root2_bv)) { - CollisionGeometry* box = new ExtendedBox(root2_bv.max_[0] - root2_bv.min_[0], - root2_bv.max_[1] - root2_bv.min_[1], - root2_bv.max_[2] - root2_bv.min_[2]); + Box* box = new Box(root2_bv.max_[0] - root2_bv.min_[0], + root2_bv.max_[1] - root2_bv.min_[1], + root2_bv.max_[2] - root2_bv.min_[2]); CollisionObject obj(boost::shared_ptr<CollisionGeometry>(box), SimpleTransform(root2_bv.center())); return callback(static_cast<CollisionObject*>(root1->data), &obj, cdata); } + else return false; } + else return false; } if(!tree2->isNodeOccupied(root2) || !root1->bv.overlap(root2_bv)) return false; @@ -83,43 +85,43 @@ bool collisionRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* root1, } else { - for(int i = 0; i < 8; ++i) + for(unsigned int i = 0; i < 8; ++i) { if(root2->childExists(i)) { octomap::OcTreeNode* child = root2->getChild(i); AABB child_bv; - if(i&1 == 0) - { - child_bv.min_[0] = root2_bv.min_[0]; - child_bv.max_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; - } - else + if(i&1) { child_bv.min_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; child_bv.max_[0] = root2_bv.max_[0]; } - - if(i&2 == 0) + else { - child_bv.min_[1] = root2_bv.min_[1]; - child_bv.max_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; + child_bv.min_[0] = root2_bv.min_[0]; + child_bv.max_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; } - else + + if(i&2) { child_bv.min_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; child_bv.max_[1] = root2_bv.max_[1]; } - - if(i&4 == 0) + else { - child_bv.min_[2] = root2_bv.min_[2]; - child_bv.max_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; + child_bv.min_[1] = root2_bv.min_[1]; + child_bv.max_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; } - else + + if(i&4) { child_bv.min_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; child_bv.max_[2] = root2_bv.max_[2]; + } + else + { + child_bv.min_[2] = root2_bv.min_[2]; + child_bv.max_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; } if(collisionRecurse(root1, tree2, child, child_bv, cdata, callback)) @@ -127,21 +129,25 @@ bool collisionRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* root1, } } } + + return false; } void collide(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCallBack callback) { DynamicAABBTreeCollisionManager::DynamicAABBNode* root1 = manager->getTree().getRoot(); octomap::OcTreeNode* root2 = octree->getRoot(); - const octomap::point3d& bv_min = octree->getBBXMin(); - const octomap::point3d& bv_max = octree->getBBXMax(); - collisionRecurse(root1, octree, root2, AABB(Vec3f(bv_min.x(), bv_min.y(), bv_min.z()), Vec3f(bv_max.x(), bv_max.y(), bv_max.z())), cdata, callback); + + FCL_REAL delta = (1 << octree->getTreeDepth()) * octree->getResolution() / 2; + + collisionRecurse(root1, octree, root2, AABB(Vec3f(-delta, -delta, -delta), Vec3f(delta, delta, delta)), + cdata, callback); } bool collisionCostRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* root1, octomap::OcTree* tree2, octomap::OcTreeNode* root2, const AABB& root2_bv, - void* cdata, CollisionCostCallBack callback, FCL_REAL& cost) + void* cdata, CollisionCostOctomapCallBack callback, FCL_REAL& cost) { if(root1->isLeaf() && !root2->hasChildren()) { @@ -178,37 +184,37 @@ bool collisionCostRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* root { octomap::OcTreeNode* child = root2->getChild(i); AABB child_bv; - if(i&1 == 0) - { - child_bv.min_[0] = root2_bv.min_[0]; - child_bv.max_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; - } - else + if(i&1) { child_bv.min_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; child_bv.max_[0] = root2_bv.max_[0]; } - - if(i&2 == 0) + else { - child_bv.min_[1] = root2_bv.min_[1]; - child_bv.max_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; + child_bv.min_[0] = root2_bv.min_[0]; + child_bv.max_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; } - else + + if(i&2) { child_bv.min_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; child_bv.max_[1] = root2_bv.max_[1]; } - - if(i&4 == 0) + else { - child_bv.min_[2] = root2_bv.min_[2]; - child_bv.max_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; + child_bv.min_[1] = root2_bv.min_[1]; + child_bv.max_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; } - else + + if(i&4) { child_bv.min_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; child_bv.max_[2] = root2_bv.max_[2]; + } + else + { + child_bv.min_[2] = root2_bv.min_[2]; + child_bv.max_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; } if(collisionCostRecurse(root1, tree2, child, child_bv, cdata, callback, cost)) @@ -216,12 +222,14 @@ bool collisionCostRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* root } } } + + return false; } bool collisionCostExtRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* root1, octomap::OcTree* tree2, octomap::OcTreeNode* root2, const AABB& root2_bv, - void* cdata, CollisionCostCallBackExt callback, FCL_REAL& cost, std::set<octomap::OcTreeNode*>& nodes) + void* cdata, CollisionCostOctomapCallBackExt callback, FCL_REAL& cost, std::set<OcTreeNode_AABB_pair>& nodes) { if(root1->isLeaf() && !root2->hasChildren()) { @@ -234,8 +242,6 @@ bool collisionCostExtRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* r root2_bv.max_[2] - root2_bv.min_[2]); box->prob = root2->getOccupancy(); - box->node = root2; - CollisionObject obj(boost::shared_ptr<CollisionGeometry>(box), SimpleTransform(root2_bv.center())); return callback(static_cast<CollisionObject*>(root1->data), &obj, cdata, cost, nodes); } @@ -259,37 +265,37 @@ bool collisionCostExtRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* r { octomap::OcTreeNode* child = root2->getChild(i); AABB child_bv; - if(i&1 == 0) - { - child_bv.min_[0] = root2_bv.min_[0]; - child_bv.max_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; - } - else + if(i&1) { child_bv.min_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; child_bv.max_[0] = root2_bv.max_[0]; } - - if(i&2 == 0) + else { - child_bv.min_[1] = root2_bv.min_[1]; - child_bv.max_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; + child_bv.min_[0] = root2_bv.min_[0]; + child_bv.max_[0] = (root2_bv.min_[0] + root2_bv.max_[0]) * 0.5; } - else + + if(i&2) { child_bv.min_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; child_bv.max_[1] = root2_bv.max_[1]; } - - if(i&4 == 0) + else { - child_bv.min_[2] = root2_bv.min_[2]; - child_bv.max_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; + child_bv.min_[1] = root2_bv.min_[1]; + child_bv.max_[1] = (root2_bv.min_[1] + root2_bv.max_[1]) * 0.5; } - else + + if(i&4) { child_bv.min_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; child_bv.max_[2] = root2_bv.max_[2]; + } + else + { + child_bv.min_[2] = root2_bv.min_[2]; + child_bv.max_[2] = (root2_bv.min_[2] + root2_bv.max_[2]) * 0.5; } if(collisionCostExtRecurse(root1, tree2, child, child_bv, cdata, callback, cost, nodes)) @@ -297,11 +303,13 @@ bool collisionCostExtRecurse(DynamicAABBTreeCollisionManager::DynamicAABBNode* r } } } + + return false; } -bool defaultCollisionCostFunction(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost) +bool defaultCollisionCostOctomapFunction(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost) { const AABB& aabb1 = o1->getAABB(); const AABB& aabb2 = o2->getAABB(); @@ -311,36 +319,44 @@ bool defaultCollisionCostFunction(CollisionObject* o1, CollisionObject* o2, void return false; } -bool defaultCollisionCostExtFunction(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost, std::set<octomap::OcTreeNode*>& nodes) + +bool defaultCollisionCostOctomapExtFunction(CollisionObject* o1, CollisionObject* o2, void* cdata, FCL_REAL& cost, std::set<OcTreeNode_AABB_pair>& nodes) { const AABB& aabb1 = o1->getAABB(); const AABB& aabb2 = o2->getAABB(); Vec3f delta = min(aabb1.max_, aabb2.max_) - max(aabb1.min_, aabb2.min_); const ExtendedBox* box = static_cast<const ExtendedBox*>(o2->getCollisionGeometry()); cost += delta[0] * delta[1] * delta[2] * box->prob; - nodes.insert(box->node); + + const Vec3f& c = box->aabb_center; + const Vec3f& side = box->side; + AABB aabb(Vec3f(c[0] - side[0] / 2, c[1] - side[1] / 2, c[2] - side[2] / 2), Vec3f(c[0] + side[0] / 2, c[1] + side[1] / 2, c[2] + side[2] / 2)); + nodes.insert(OcTreeNode_AABB_pair(box->node, aabb)); return false; } -FCL_REAL collideCost(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCostCallBack callback) +FCL_REAL collideCost(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCostOctomapCallBack callback) { DynamicAABBTreeCollisionManager::DynamicAABBNode* root1 = manager->getTree().getRoot(); octomap::OcTreeNode* root2 = octree->getRoot(); - const octomap::point3d& bv_min = octree->getBBXMin(); - const octomap::point3d& bv_max = octree->getBBXMax(); + + FCL_REAL delta = (1 << octree->getTreeDepth()) * octree->getResolution() / 2; FCL_REAL cost = 0; - collisionCostRecurse(root1, octree, root2, AABB(Vec3f(bv_min.x(), bv_min.y(), bv_min.z()), Vec3f(bv_max.x(), bv_max.y(), bv_max.z())), cdata, callback, cost); + collisionCostRecurse(root1, octree, root2, AABB(Vec3f(-delta, -delta, -delta), Vec3f(delta, delta, delta)), cdata, callback, cost); return cost; } -FCL_REAL collideCost(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCostCallBackExt callback, std::set<octomap::OcTreeNode*>& nodes) +FCL_REAL collideCost(DynamicAABBTreeCollisionManager* manager, octomap::OcTree* octree, void* cdata, CollisionCostOctomapCallBackExt callback, std::vector<AABB>& nodes) { DynamicAABBTreeCollisionManager::DynamicAABBNode* root1 = manager->getTree().getRoot(); octomap::OcTreeNode* root2 = octree->getRoot(); - const octomap::point3d& bv_min = octree->getBBXMin(); - const octomap::point3d& bv_max = octree->getBBXMax(); + + FCL_REAL delta = (1 << octree->getTreeDepth()) * octree->getResolution() / 2; FCL_REAL cost = 0; - collisionCostExtRecurse(root1, octree, root2, AABB(Vec3f(bv_min.x(), bv_min.y(), bv_min.z()), Vec3f(bv_max.x(), bv_max.y(), bv_max.z())), cdata, callback, cost, nodes); + std::set<OcTreeNode_AABB_pair> pairs; + collisionCostExtRecurse(root1, octree, root2, AABB(Vec3f(-delta, -delta, -delta), Vec3f(delta, delta, delta)), cdata, callback, cost, pairs); + for(std::set<OcTreeNode_AABB_pair>::iterator it = pairs.begin(), end = pairs.end(); it != end; ++it) + nodes.push_back(it->aabb); return cost; }