Home | History | Annotate | Download | only in CollisionShapes
      1 /*
      2 Bullet Continuous Collision Detection and Physics Library
      3 Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
      4 
      5 This software is provided 'as-is', without any express or implied warranty.
      6 In no event will the authors be held liable for any damages arising from the use of this software.
      7 Permission is granted to anyone to use this software for any purpose,
      8 including commercial applications, and to alter it and redistribute it freely,
      9 subject to the following restrictions:
     10 
     11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
     12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
     13 3. This notice may not be removed or altered from any source distribution.
     14 */
     15 
     16 #ifndef BT_CAPSULE_SHAPE_H
     17 #define BT_CAPSULE_SHAPE_H
     18 
     19 #include "btConvexInternalShape.h"
     20 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
     21 
     22 
     23 ///The btCapsuleShape represents a capsule around the Y axis, there is also the btCapsuleShapeX aligned around the X axis and btCapsuleShapeZ around the Z axis.
     24 ///The total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
     25 ///The btCapsuleShape is a convex hull of two spheres. The btMultiSphereShape is a more general collision shape that takes the convex hull of multiple sphere, so it can also represent a capsule when just using two spheres.
     26 ATTRIBUTE_ALIGNED16(class) btCapsuleShape : public btConvexInternalShape
     27 {
     28 protected:
     29 	int	m_upAxis;
     30 
     31 protected:
     32 	///only used for btCapsuleShapeZ and btCapsuleShapeX subclasses.
     33 	btCapsuleShape() : btConvexInternalShape() {m_shapeType = CAPSULE_SHAPE_PROXYTYPE;};
     34 
     35 public:
     36 
     37 	BT_DECLARE_ALIGNED_ALLOCATOR();
     38 
     39 	btCapsuleShape(btScalar radius,btScalar height);
     40 
     41 	///CollisionShape Interface
     42 	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
     43 
     44 	/// btConvexShape Interface
     45 	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
     46 
     47 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
     48 
     49 	virtual void setMargin(btScalar collisionMargin)
     50 	{
     51 		//correct the m_implicitShapeDimensions for the margin
     52 		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
     53 		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
     54 
     55 		btConvexInternalShape::setMargin(collisionMargin);
     56 		btVector3 newMargin(getMargin(),getMargin(),getMargin());
     57 		m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
     58 
     59 	}
     60 
     61 	virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
     62 	{
     63 			btVector3 halfExtents(getRadius(),getRadius(),getRadius());
     64 			halfExtents[m_upAxis] = getRadius() + getHalfHeight();
     65 			halfExtents += btVector3(getMargin(),getMargin(),getMargin());
     66 			btMatrix3x3 abs_b = t.getBasis().absolute();
     67 			btVector3 center = t.getOrigin();
     68             btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
     69 
     70 			aabbMin = center - extent;
     71 			aabbMax = center + extent;
     72 	}
     73 
     74 	virtual const char*	getName()const
     75 	{
     76 		return "CapsuleShape";
     77 	}
     78 
     79 	int	getUpAxis() const
     80 	{
     81 		return m_upAxis;
     82 	}
     83 
     84 	btScalar	getRadius() const
     85 	{
     86 		int radiusAxis = (m_upAxis+2)%3;
     87 		return m_implicitShapeDimensions[radiusAxis];
     88 	}
     89 
     90 	btScalar	getHalfHeight() const
     91 	{
     92 		return m_implicitShapeDimensions[m_upAxis];
     93 	}
     94 
     95 	virtual void	setLocalScaling(const btVector3& scaling)
     96 	{
     97 		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
     98 		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
     99 		btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
    100 
    101 		btConvexInternalShape::setLocalScaling(scaling);
    102 
    103 		m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
    104 
    105 	}
    106 
    107 	virtual btVector3	getAnisotropicRollingFrictionDirection() const
    108 	{
    109 		btVector3 aniDir(0,0,0);
    110 		aniDir[getUpAxis()]=1;
    111 		return aniDir;
    112 	}
    113 
    114 
    115 	virtual	int	calculateSerializeBufferSize() const;
    116 
    117 	///fills the dataBuffer and returns the struct name (and 0 on failure)
    118 	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;
    119 
    120 	SIMD_FORCE_INLINE	void	deSerializeFloat(struct btCapsuleShapeData* dataBuffer);
    121 
    122 };
    123 
    124 ///btCapsuleShapeX represents a capsule around the Z axis
    125 ///the total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
    126 class btCapsuleShapeX : public btCapsuleShape
    127 {
    128 public:
    129 
    130 	btCapsuleShapeX(btScalar radius,btScalar height);
    131 
    132 	//debugging
    133 	virtual const char*	getName()const
    134 	{
    135 		return "CapsuleX";
    136 	}
    137 
    138 
    139 
    140 };
    141 
    142 ///btCapsuleShapeZ represents a capsule around the Z axis
    143 ///the total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
    144 class btCapsuleShapeZ : public btCapsuleShape
    145 {
    146 public:
    147 	btCapsuleShapeZ(btScalar radius,btScalar height);
    148 
    149 		//debugging
    150 	virtual const char*	getName()const
    151 	{
    152 		return "CapsuleZ";
    153 	}
    154 
    155 
    156 };
    157 
    158 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
    159 struct	btCapsuleShapeData
    160 {
    161 	btConvexInternalShapeData	m_convexInternalShapeData;
    162 
    163 	int	m_upAxis;
    164 
    165 	char	m_padding[4];
    166 };
    167 
    168 SIMD_FORCE_INLINE	int	btCapsuleShape::calculateSerializeBufferSize() const
    169 {
    170 	return sizeof(btCapsuleShapeData);
    171 }
    172 
    173 	///fills the dataBuffer and returns the struct name (and 0 on failure)
    174 SIMD_FORCE_INLINE	const char*	btCapsuleShape::serialize(void* dataBuffer, btSerializer* serializer) const
    175 {
    176 	btCapsuleShapeData* shapeData = (btCapsuleShapeData*) dataBuffer;
    177 
    178 	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer);
    179 
    180 	shapeData->m_upAxis = m_upAxis;
    181 
    182 	return "btCapsuleShapeData";
    183 }
    184 
    185 SIMD_FORCE_INLINE	void	btCapsuleShape::deSerializeFloat(btCapsuleShapeData* dataBuffer)
    186 {
    187 	m_implicitShapeDimensions.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_implicitShapeDimensions);
    188 	m_collisionMargin = dataBuffer->m_convexInternalShapeData.m_collisionMargin;
    189 	m_localScaling.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_localScaling);
    190 	//it is best to already pre-allocate the matching btCapsuleShape*(X/Z) version to match m_upAxis
    191 	m_upAxis = dataBuffer->m_upAxis;
    192 }
    193 
    194 #endif //BT_CAPSULE_SHAPE_H
    195