2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
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:
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.
16 #include "btCylinderShape.h"
18 btCylinderShape::btCylinderShape(const btVector3& halfExtents)
19 : btConvexInternalShape(),
22 btVector3 margin(getMargin(), getMargin(), getMargin());
23 m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin;
25 setSafeMargin(halfExtents);
27 m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
30 btCylinderShapeX::btCylinderShapeX(const btVector3& halfExtents)
31 : btCylinderShape(halfExtents)
36 btCylinderShapeZ::btCylinderShapeZ(const btVector3& halfExtents)
37 : btCylinderShape(halfExtents)
42 void btCylinderShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
44 btTransformAabb(getHalfExtentsWithoutMargin(), getMargin(), t, aabbMin, aabbMax);
47 void btCylinderShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const
49 //Until Bullet 2.77 a box approximation was used, so uncomment this if you need backwards compatibility
50 //#define USE_BOX_INERTIA_APPROXIMATION 1
51 #ifndef USE_BOX_INERTIA_APPROXIMATION
54 cylinder is defined as following:
56 * - principle axis aligned along y by default, radius in x, z-value not used
57 * - for btCylinderShapeX: principle axis aligned along x, radius in y direction, z-value not used
58 * - for btCylinderShapeZ: principle axis aligned along z, radius in x direction, y-value not used
62 btScalar radius2; // square of cylinder radius
63 btScalar height2; // square of cylinder height
64 btVector3 halfExtents = getHalfExtentsWithMargin(); // get cylinder dimension
65 btScalar div12 = mass / 12.f;
66 btScalar div4 = mass / 4.f;
67 btScalar div2 = mass / 2.f;
68 int idxRadius, idxHeight;
70 switch (m_upAxis) // get indices of radius and height of cylinder
72 case 0: // cylinder is aligned along x
76 case 2: // cylinder is aligned along z
80 default: // cylinder is aligned along y
86 radius2 = halfExtents[idxRadius] * halfExtents[idxRadius];
87 height2 = btScalar(4.) * halfExtents[idxHeight] * halfExtents[idxHeight];
89 // calculate tensor terms
90 btScalar t1 = div12 * height2 + div4 * radius2;
91 btScalar t2 = div2 * radius2;
93 switch (m_upAxis) // set diagonal elements of inertia tensor
95 case 0: // cylinder is aligned along x
96 inertia.setValue(t2, t1, t1);
98 case 2: // cylinder is aligned along z
99 inertia.setValue(t1, t1, t2);
101 default: // cylinder is aligned along y
102 inertia.setValue(t1, t2, t1);
104 #else //USE_BOX_INERTIA_APPROXIMATION
105 //approximation of box shape
106 btVector3 halfExtents = getHalfExtentsWithMargin();
108 btScalar lx = btScalar(2.) * (halfExtents.x());
109 btScalar ly = btScalar(2.) * (halfExtents.y());
110 btScalar lz = btScalar(2.) * (halfExtents.z());
112 inertia.setValue(mass / (btScalar(12.0)) * (ly * ly + lz * lz),
113 mass / (btScalar(12.0)) * (lx * lx + lz * lz),
114 mass / (btScalar(12.0)) * (lx * lx + ly * ly));
115 #endif //USE_BOX_INERTIA_APPROXIMATION
118 SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents, const btVector3& v)
120 const int cylinderUpAxis = 0;
125 //mapping depends on how cylinder local orientation is
126 // extents of the cylinder is: X,Y is for radius, and Z for height
128 btScalar radius = halfExtents[XX];
129 btScalar halfHeight = halfExtents[cylinderUpAxis];
134 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
135 if (s != btScalar(0.0))
139 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
146 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
147 tmp[ZZ] = btScalar(0.0);
152 inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents, const btVector3& v)
154 const int cylinderUpAxis = 1;
159 btScalar radius = halfExtents[XX];
160 btScalar halfHeight = halfExtents[cylinderUpAxis];
165 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
166 if (s != btScalar(0.0))
170 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
177 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
178 tmp[ZZ] = btScalar(0.0);
183 inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents, const btVector3& v)
185 const int cylinderUpAxis = 2;
190 //mapping depends on how cylinder local orientation is
191 // extents of the cylinder is: X,Y is for radius, and Z for height
193 btScalar radius = halfExtents[XX];
194 btScalar halfHeight = halfExtents[cylinderUpAxis];
199 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
200 if (s != btScalar(0.0))
204 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
211 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
212 tmp[ZZ] = btScalar(0.0);
217 btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec) const
219 return CylinderLocalSupportX(getHalfExtentsWithoutMargin(), vec);
222 btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec) const
224 return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(), vec);
226 btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const
228 return CylinderLocalSupportY(getHalfExtentsWithoutMargin(), vec);
231 void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const
233 for (int i = 0; i < numVectors; i++)
235 supportVerticesOut[i] = CylinderLocalSupportY(getHalfExtentsWithoutMargin(), vectors[i]);
239 void btCylinderShapeZ::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const
241 for (int i = 0; i < numVectors; i++)
243 supportVerticesOut[i] = CylinderLocalSupportZ(getHalfExtentsWithoutMargin(), vectors[i]);
247 void btCylinderShapeX::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const
249 for (int i = 0; i < numVectors; i++)
251 supportVerticesOut[i] = CylinderLocalSupportX(getHalfExtentsWithoutMargin(), vectors[i]);