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_CYLINDER_MINKOWSKI_H
17 #define BT_CYLINDER_MINKOWSKI_H
18 
19 #include "btBoxShape.h"
20 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
21 #include "LinearMath/btVector3.h"
22 
23 /// The btCylinderShape class implements a cylinder shape primitive, centered around the origin. Its central axis aligned with the Y axis. btCylinderShapeX is aligned with the X axis and btCylinderShapeZ around the Z axis.
ATTRIBUTE_ALIGNED16(class)24 ATTRIBUTE_ALIGNED16(class) btCylinderShape : public btConvexInternalShape
25 
26 {
27 
28 protected:
29 
30 	int	m_upAxis;
31 
32 public:
33 
34 BT_DECLARE_ALIGNED_ALLOCATOR();
35 
36 	btVector3 getHalfExtentsWithMargin() const
37 	{
38 		btVector3 halfExtents = getHalfExtentsWithoutMargin();
39 		btVector3 margin(getMargin(),getMargin(),getMargin());
40 		halfExtents += margin;
41 		return halfExtents;
42 	}
43 
44 	const btVector3& getHalfExtentsWithoutMargin() const
45 	{
46 		return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
47 	}
48 
49 	btCylinderShape (const btVector3& halfExtents);
50 
51 	void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
52 
53 	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
54 
55 	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
56 
57 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
58 
59 	virtual void setMargin(btScalar collisionMargin)
60 	{
61 		//correct the m_implicitShapeDimensions for the margin
62 		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
63 		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
64 
65 		btConvexInternalShape::setMargin(collisionMargin);
66 		btVector3 newMargin(getMargin(),getMargin(),getMargin());
67 		m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
68 
69 	}
70 
71 	virtual btVector3	localGetSupportingVertex(const btVector3& vec) const
72 	{
73 
74 		btVector3 supVertex;
75 		supVertex = localGetSupportingVertexWithoutMargin(vec);
76 
77 		if ( getMargin()!=btScalar(0.) )
78 		{
79 			btVector3 vecnorm = vec;
80 			if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
81 			{
82 				vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
83 			}
84 			vecnorm.normalize();
85 			supVertex+= getMargin() * vecnorm;
86 		}
87 		return supVertex;
88 	}
89 
90 
91 	//use box inertia
92 	//	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
93 
94 
95 	int	getUpAxis() const
96 	{
97 		return m_upAxis;
98 	}
99 
100 	virtual btVector3	getAnisotropicRollingFrictionDirection() const
101 	{
102 		btVector3 aniDir(0,0,0);
103 		aniDir[getUpAxis()]=1;
104 		return aniDir;
105 	}
106 
107 	virtual btScalar getRadius() const
108 	{
109 		return getHalfExtentsWithMargin().getX();
110 	}
111 
112 	virtual void	setLocalScaling(const btVector3& scaling)
113 	{
114 		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
115 		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
116 		btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
117 
118 		btConvexInternalShape::setLocalScaling(scaling);
119 
120 		m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
121 
122 	}
123 
124 	//debugging
125 	virtual const char*	getName()const
126 	{
127 		return "CylinderY";
128 	}
129 
130 	virtual	int	calculateSerializeBufferSize() const;
131 
132 	///fills the dataBuffer and returns the struct name (and 0 on failure)
133 	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;
134 
135 };
136 
137 class btCylinderShapeX : public btCylinderShape
138 {
139 public:
140 	BT_DECLARE_ALIGNED_ALLOCATOR();
141 
142 	btCylinderShapeX (const btVector3& halfExtents);
143 
144 	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
145 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
146 
147 		//debugging
getName()148 	virtual const char*	getName()const
149 	{
150 		return "CylinderX";
151 	}
152 
getRadius()153 	virtual btScalar getRadius() const
154 	{
155 		return getHalfExtentsWithMargin().getY();
156 	}
157 
158 };
159 
160 class btCylinderShapeZ : public btCylinderShape
161 {
162 public:
163 	BT_DECLARE_ALIGNED_ALLOCATOR();
164 
165 	btCylinderShapeZ (const btVector3& halfExtents);
166 
167 	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
168 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
169 
170 		//debugging
getName()171 	virtual const char*	getName()const
172 	{
173 		return "CylinderZ";
174 	}
175 
getRadius()176 	virtual btScalar getRadius() const
177 	{
178 		return getHalfExtentsWithMargin().getX();
179 	}
180 
181 };
182 
183 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
184 struct	btCylinderShapeData
185 {
186 	btConvexInternalShapeData	m_convexInternalShapeData;
187 
188 	int	m_upAxis;
189 
190 	char	m_padding[4];
191 };
192 
calculateSerializeBufferSize()193 SIMD_FORCE_INLINE	int	btCylinderShape::calculateSerializeBufferSize() const
194 {
195 	return sizeof(btCylinderShapeData);
196 }
197 
198 	///fills the dataBuffer and returns the struct name (and 0 on failure)
serialize(void * dataBuffer,btSerializer * serializer)199 SIMD_FORCE_INLINE	const char*	btCylinderShape::serialize(void* dataBuffer, btSerializer* serializer) const
200 {
201 	btCylinderShapeData* shapeData = (btCylinderShapeData*) dataBuffer;
202 
203 	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer);
204 
205 	shapeData->m_upAxis = m_upAxis;
206 
207 	return "btCylinderShapeData";
208 }
209 
210 
211 
212 #endif //BT_CYLINDER_MINKOWSKI_H
213 
214