-
Florent Lamiraux authored
- classes CollisionObject and ContinuousCollisionObject, - declare former accessors as deprecated.
Florent Lamiraux authored- classes CollisionObject and ContinuousCollisionObject, - declare former accessors as deprecated.
collision_object.h 12.12 KiB
/*
* Software License Agreement (BSD License)
*
* Copyright (c) 2011, Willow Garage, Inc.
* 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 Willow Garage, Inc. 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 Jia Pan */
#ifndef FCL_COLLISION_OBJECT_BASE_H
#define FCL_COLLISION_OBJECT_BASE_H
#include <fcl/deprecated.h>
#include "fcl/BV/AABB.h"
#include "fcl/math/transform.h"
#include "fcl/ccd/motion_base.h"
#include <boost/shared_ptr.hpp>
namespace fcl
{
/// @brief object type: BVH (mesh, points), basic geometry, octree
enum OBJECT_TYPE {OT_UNKNOWN, OT_BVH, OT_GEOM, OT_OCTREE, OT_COUNT};
/// @brief traversal node type: bounding volume (AABB, OBB, RSS, kIOS, OBBRSS, KDOP16, KDOP18, kDOP24), basic shape (box, sphere, capsule, cone, cylinder, convex, plane, triangle), and octree
enum NODE_TYPE {BV_UNKNOWN, BV_AABB, BV_OBB, BV_RSS, BV_kIOS, BV_OBBRSS, BV_KDOP16, BV_KDOP18, BV_KDOP24,
GEOM_BOX, GEOM_SPHERE, GEOM_CAPSULE, GEOM_CONE, GEOM_CYLINDER, GEOM_CONVEX, GEOM_PLANE, GEOM_HALFSPACE, GEOM_TRIANGLE, GEOM_OCTREE, NODE_COUNT};
/// @brief The geometry for the object for collision or distance computation
class CollisionGeometry
{
public:
CollisionGeometry() : cost_density(1),
threshold_occupied(1),
threshold_free(0)
{
}
virtual ~CollisionGeometry() {}
/// @brief get the type of the object
virtual OBJECT_TYPE getObjectType() const { return OT_UNKNOWN; }
/// @brief get the node type
virtual NODE_TYPE getNodeType() const { return BV_UNKNOWN; }
/// @brief compute the AABB for object in local coordinate
virtual void computeLocalAABB() = 0;
/// @brief get user data in geometry
void* getUserData() const
{
return user_data;
}
/// @brief set user data in geometry
void setUserData(void *data)
{
user_data = data;
}
/// @brief whether the object is completely occupied
inline bool isOccupied() const { return cost_density >= threshold_occupied; }
/// @brief whether the object is completely free
inline bool isFree() const { return cost_density <= threshold_free; }
/// @brief whether the object has some uncertainty
inline bool isUncertain() const { return !isOccupied() && !isFree(); }
/// @brief AABB center in local coordinate
Vec3f aabb_center;
/// @brief AABB radius
FCL_REAL aabb_radius;
/// @brief AABB in local coordinate, used for tight AABB when only translation transform
AABB aabb_local;
/// @brief pointer to user defined data specific to this object
void *user_data;
/// @brief collision cost for unit volume
FCL_REAL cost_density;
/// @brief threshold for occupied ( >= is occupied)
FCL_REAL threshold_occupied;
/// @brief threshold for free (<= is free)
FCL_REAL threshold_free;
/// @brief compute center of mass
virtual Vec3f computeCOM() const { return Vec3f(); }
/// @brief compute the inertia matrix, related to the origin
virtual Matrix3f computeMomentofInertia() const { return Matrix3f(); }
/// @brief compute the volume
virtual FCL_REAL computeVolume() const { return 0; }
/// @brief compute the inertia matrix, related to the com
virtual Matrix3f computeMomentofInertiaRelatedToCOM() const
{
Matrix3f C = computeMomentofInertia();
Vec3f com = computeCOM();
FCL_REAL V = computeVolume();
return Matrix3f(C(0, 0) - V * (com[1] * com[1] + com[2] * com[2]),
C(0, 1) + V * com[0] * com[1],
C(0, 2) + V * com[0] * com[2],
C(1, 0) + V * com[1] * com[0],
C(1, 1) - V * (com[0] * com[0] + com[2] * com[2]),
C(1, 2) + V * com[1] * com[2],
C(2, 0) + V * com[2] * com[0],
C(2, 1) + V * com[2] * com[1],
C(2, 2) - V * (com[0] * com[0] + com[1] * com[1]));
}
};
/// @brief the object for collision or distance computation, contains the geometry and the transform information
class CollisionObject
{
public:
CollisionObject(const boost::shared_ptr<CollisionGeometry> &cgeom_) : cgeom(cgeom_)
{
cgeom->computeLocalAABB();
computeAABB();
}
CollisionObject(const boost::shared_ptr<CollisionGeometry> &cgeom_, const Transform3f& tf) : cgeom(cgeom_), t(tf)
{
cgeom->computeLocalAABB();
computeAABB();
}
CollisionObject(const boost::shared_ptr<CollisionGeometry> &cgeom_, const Matrix3f& R, const Vec3f& T):
cgeom(cgeom_), t(Transform3f(R, T))
{
cgeom->computeLocalAABB();
computeAABB();
}
CollisionObject()
{
}
~CollisionObject()
{
}
/// @brief get the type of the object
OBJECT_TYPE getObjectType() const
{
return cgeom->getObjectType();
}
/// @brief get the node type
NODE_TYPE getNodeType() const
{
return cgeom->getNodeType();
}
/// @brief get the AABB in world space
inline const AABB& getAABB() const
{
return aabb;
}
/// @brief compute the AABB in world space
inline void computeAABB()
{
if(t.getQuatRotation().isIdentity())
{
aabb = translate(cgeom->aabb_local, t.getTranslation());
}
else
{
Vec3f center = t.transform(cgeom->aabb_center);
Vec3f delta(cgeom->aabb_radius);
aabb.min_ = center - delta;
aabb.max_ = center + delta;
}
}
/// @brief get user data in object
void* getUserData() const
{
return user_data;
}
/// @brief set user data in object
void setUserData(void *data)
{
user_data = data;
}
/// @brief get translation of the object
inline const Vec3f& getTranslation() const
{
return t.getTranslation();
}
/// @brief get matrix rotation of the object
inline const Matrix3f& getRotation() const
{
return t.getRotation();
}
/// @brief get quaternion rotation of the object
inline const Quaternion3f& getQuatRotation() const
{
return t.getQuatRotation();
}
/// @brief get object's transform
inline const Transform3f& getTransform() const
{
return t;
}
/// @brief set object's rotation matrix
void setRotation(const Matrix3f& R)
{
t.setRotation(R);
}
/// @brief set object's translation
void setTranslation(const Vec3f& T)
{
t.setTranslation(T);
}
/// @brief set object's quatenrion rotation
void setQuatRotation(const Quaternion3f& q)
{
t.setQuatRotation(q);
}
/// @brief set object's transform
void setTransform(const Matrix3f& R, const Vec3f& T)
{
t.setTransform(R, T);
}
/// @brief set object's transform
void setTransform(const Quaternion3f& q, const Vec3f& T)
{
t.setTransform(q, T);
}
/// @brief set object's transform
void setTransform(const Transform3f& tf)
{
t = tf;
}
/// @brief whether the object is in local coordinate
bool isIdentityTransform() const
{
return t.isIdentity();
}
/// @brief set the object in local coordinate
void setIdentityTransform()
{
t.setIdentity();
}
/// @brief get geometry from the object instance
const CollisionGeometry* getCollisionGeometry() const FCL_DEPRECATED
{
return cgeom.get();
}
/// @brief get geometry from the object instance
boost::shared_ptr<const CollisionGeometry> collisionGeometry() const
{
return cgeom;
}
/// @brief get object's cost density
FCL_REAL getCostDensity() const
{
return cgeom->cost_density;
}
/// @brief set object's cost density
void setCostDensity(FCL_REAL c)
{
cgeom->cost_density = c;
}
/// @brief whether the object is completely occupied
inline bool isOccupied() const
{
return cgeom->isOccupied();
}
/// @brief whether the object is completely free
inline bool isFree() const
{
return cgeom->isFree();
}
/// @brief whether the object is uncertain
inline bool isUncertain() const
{
return cgeom->isUncertain();
}
protected:
boost::shared_ptr<CollisionGeometry> cgeom;
Transform3f t;
/// @brief AABB in global coordinate
mutable AABB aabb;
/// @brief pointer to user defined data specific to this object
void *user_data;
};
/// @brief the object for continuous collision or distance computation, contains the geometry and the motion information
class ContinuousCollisionObject
{
public:
ContinuousCollisionObject(const boost::shared_ptr<CollisionGeometry>& cgeom_) : cgeom(cgeom_)
{
}
ContinuousCollisionObject(const boost::shared_ptr<CollisionGeometry>& cgeom_, const boost::shared_ptr<MotionBase>& motion_) : cgeom(cgeom_), motion(motion_)
{
}
ContinuousCollisionObject() {}
~ContinuousCollisionObject() {}
/// @brief get the type of the object
OBJECT_TYPE getObjectType() const
{
return cgeom->getObjectType();
}
/// @brief get the node type
NODE_TYPE getNodeType() const
{
return cgeom->getNodeType();
}
/// @brief get the AABB in the world space for the motion
inline const AABB& getAABB() const
{
return aabb;
}
/// @brief compute the AABB in the world space for the motion
inline void computeAABB()
{
IVector3 box;
TMatrix3 R;
TVector3 T;
motion->getTaylorModel(R, T);
Vec3f p = cgeom->aabb_local.min_;
box = (R * p + T).getTightBound();
p[2] = cgeom->aabb_local.max_[2];
box = bound(box, (R * p + T).getTightBound());
p[1] = cgeom->aabb_local.max_[1];
p[2] = cgeom->aabb_local.min_[2];
box = bound(box, (R * p + T).getTightBound());
p[2] = cgeom->aabb_local.max_[2];
box = bound(box, (R * p + T).getTightBound());
p[0] = cgeom->aabb_local.max_[0];
p[1] = cgeom->aabb_local.min_[1];
p[2] = cgeom->aabb_local.min_[2];
box = bound(box, (R * p + T).getTightBound());
p[2] = cgeom->aabb_local.max_[2];
box = bound(box, (R * p + T).getTightBound());
p[1] = cgeom->aabb_local.max_[1];
p[2] = cgeom->aabb_local.min_[2];
box = bound(box, (R * p + T).getTightBound());
p[2] = cgeom->aabb_local.max_[2];
box = bound(box, (R * p + T).getTightBound());
aabb.min_ = box.getLow();
aabb.max_ = box.getHigh();
}
/// @brief get user data in object
void* getUserData() const
{
return user_data;
}
/// @brief set user data in object
void setUserData(void* data)
{
user_data = data;
}
/// @brief get motion from the object instance
inline MotionBase* getMotion() const
{
return motion.get();
}
/// @brief get geometry from the object instance
inline const CollisionGeometry* getCollisionGeometry() const FCL_DEPRECATED
{
return cgeom.get();
}
/// @brief get geometry from the object instance
inline boost::shared_ptr<const CollisionGeometry> collisionGeometry() const
{
return cgeom;
}
protected:
boost::shared_ptr<CollisionGeometry> cgeom;
boost::shared_ptr<MotionBase> motion;
/// @brief AABB in the global coordinate for the motion
mutable AABB aabb;
/// @brief pointer to user defined data specific to this object
void* user_data;
};
}
#endif