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;
24
m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
28
btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents)
29
:btCylinderShape(halfExtents)
36
btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents)
37
:btCylinderShape(halfExtents)
43
void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
45
btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax);
48
void btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
51
//Until Bullet 2.77 a box approximation was used, so uncomment this if you need backwards compatibility
52
//#define USE_BOX_INERTIA_APPROXIMATION 1
53
#ifndef USE_BOX_INERTIA_APPROXIMATION
56
cylinder is defined as following:
58
* - principle axis aligned along y by default, radius in x, z-value not used
59
* - for btCylinderShapeX: principle axis aligned along x, radius in y direction, z-value not used
60
* - for btCylinderShapeZ: principle axis aligned along z, radius in x direction, y-value not used
64
btScalar radius2; // square of cylinder radius
65
btScalar height2; // square of cylinder height
66
btVector3 halfExtents = getHalfExtentsWithMargin(); // get cylinder dimension
67
btScalar div12 = mass / 12.f;
68
btScalar div4 = mass / 4.f;
69
btScalar div2 = mass / 2.f;
70
int idxRadius, idxHeight;
72
switch (m_upAxis) // get indices of radius and height of cylinder
74
case 0: // cylinder is aligned along x
78
case 2: // cylinder is aligned along z
82
default: // cylinder is aligned along y
88
radius2 = halfExtents[idxRadius] * halfExtents[idxRadius];
89
height2 = btScalar(4.) * halfExtents[idxHeight] * halfExtents[idxHeight];
91
// calculate tensor terms
92
btScalar t1 = div12 * height2 + div4 * radius2;
93
btScalar t2 = div2 * radius2;
95
switch (m_upAxis) // set diagonal elements of inertia tensor
97
case 0: // cylinder is aligned along x
98
inertia.setValue(t2,t1,t1);
100
case 2: // cylinder is aligned along z
101
inertia.setValue(t1,t1,t2);
103
default: // cylinder is aligned along y
104
inertia.setValue(t1,t2,t1);
106
#else //USE_BOX_INERTIA_APPROXIMATION
107
//approximation of box shape
108
btVector3 halfExtents = getHalfExtentsWithMargin();
110
btScalar lx=btScalar(2.)*(halfExtents.x());
111
btScalar ly=btScalar(2.)*(halfExtents.y());
112
btScalar lz=btScalar(2.)*(halfExtents.z());
114
inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
115
mass/(btScalar(12.0)) * (lx*lx + lz*lz),
116
mass/(btScalar(12.0)) * (lx*lx + ly*ly));
117
#endif //USE_BOX_INERTIA_APPROXIMATION
121
SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v)
123
const int cylinderUpAxis = 0;
128
//mapping depends on how cylinder local orientation is
129
// extents of the cylinder is: X,Y is for radius, and Z for height
132
btScalar radius = halfExtents[XX];
133
btScalar halfHeight = halfExtents[cylinderUpAxis];
139
btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
140
if (s != btScalar(0.0))
144
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
151
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
152
tmp[ZZ] = btScalar(0.0);
164
inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v)
167
const int cylinderUpAxis = 1;
173
btScalar radius = halfExtents[XX];
174
btScalar halfHeight = halfExtents[cylinderUpAxis];
180
btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
181
if (s != btScalar(0.0))
185
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
192
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
193
tmp[ZZ] = btScalar(0.0);
199
inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v)
201
const int cylinderUpAxis = 2;
206
//mapping depends on how cylinder local orientation is
207
// extents of the cylinder is: X,Y is for radius, and Z for height
210
btScalar radius = halfExtents[XX];
211
btScalar halfHeight = halfExtents[cylinderUpAxis];
217
btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
218
if (s != btScalar(0.0))
222
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
229
tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
230
tmp[ZZ] = btScalar(0.0);
237
btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
239
return CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vec);
243
btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
245
return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vec);
247
btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
249
return CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vec);
252
void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
254
for (int i=0;i<numVectors;i++)
256
supportVerticesOut[i] = CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vectors[i]);
260
void btCylinderShapeZ::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
262
for (int i=0;i<numVectors;i++)
264
supportVerticesOut[i] = CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vectors[i]);
271
void btCylinderShapeX::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
273
for (int i=0;i<numVectors;i++)
275
supportVerticesOut[i] = CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vectors[i]);