Bullet Collision Detection & Physics Library: btCylinderShape.cpp Source File

Bullet Collision Detection & Physics Library

btCylinderShape.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#include "btCylinderShape.h"
17
18btCylinderShape::btCylinderShape(const btVector3& halfExtents)
19 : btConvexInternalShape(),
20 m_upAxis(1)
21{
22 btVector3 margin(getMargin(), getMargin(), getMargin());
23 m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin;
24
25 setSafeMargin(halfExtents);
26
27 m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
28}
29
30btCylinderShapeX::btCylinderShapeX(const btVector3& halfExtents)
31 : btCylinderShape(halfExtents)
32{
33 m_upAxis = 0;
34}
35
36btCylinderShapeZ::btCylinderShapeZ(const btVector3& halfExtents)
37 : btCylinderShape(halfExtents)
38{
39 m_upAxis = 2;
40}
41
42 void btCylinderShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
43{
44 btTransformAabb(getHalfExtentsWithoutMargin(), getMargin(), t, aabbMin, aabbMax);
45}
46
47 void btCylinderShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const
48{
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
52
53 /*
54 cylinder is defined as following:
55 *
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
59 *
60 */
61
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;
69
70 switch (m_upAxis) // get indices of radius and height of cylinder
71 {
72 case 0: // cylinder is aligned along x
73 idxRadius = 1;
74 idxHeight = 0;
75 break;
76 case 2: // cylinder is aligned along z
77 idxRadius = 0;
78 idxHeight = 2;
79 break;
80 default: // cylinder is aligned along y
81 idxRadius = 0;
82 idxHeight = 1;
83 }
84
85 // calculate squares
86 radius2 = halfExtents[idxRadius] * halfExtents[idxRadius];
87 height2 = btScalar(4.) * halfExtents[idxHeight] * halfExtents[idxHeight];
88
89 // calculate tensor terms
90 btScalar t1 = div12 * height2 + div4 * radius2;
91 btScalar t2 = div2 * radius2;
92
93 switch (m_upAxis) // set diagonal elements of inertia tensor
94 {
95 case 0: // cylinder is aligned along x
96 inertia.setValue(t2, t1, t1);
97 break;
98 case 2: // cylinder is aligned along z
99 inertia.setValue(t1, t1, t2);
100 break;
101 default: // cylinder is aligned along y
102 inertia.setValue(t1, t2, t1);
103 }
104#else //USE_BOX_INERTIA_APPROXIMATION
105 //approximation of box shape
106 btVector3 halfExtents = getHalfExtentsWithMargin();
107
108 btScalar lx = btScalar(2.) * (halfExtents.x());
109 btScalar ly = btScalar(2.) * (halfExtents.y());
110 btScalar lz = btScalar(2.) * (halfExtents.z());
111
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
116}
117
118 SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents, const btVector3& v)
119{
120 const int cylinderUpAxis = 0;
121 const int XX = 1;
122 const int YY = 0;
123 const int ZZ = 2;
124
125 //mapping depends on how cylinder local orientation is
126 // extents of the cylinder is: X,Y is for radius, and Z for height
127
128 btScalar radius = halfExtents[XX];
129 btScalar halfHeight = halfExtents[cylinderUpAxis];
130
131 btVector3 tmp;
132 btScalar d;
133
134 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
135 if (s != btScalar(0.0))
136 {
137 d = radius / s;
138 tmp[XX] = v[XX] * d;
139 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
140 tmp[ZZ] = v[ZZ] * d;
141 return tmp;
142 }
143 else
144 {
145 tmp[XX] = radius;
146 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
147 tmp[ZZ] = btScalar(0.0);
148 return tmp;
149 }
150}
151
152 inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents, const btVector3& v)
153{
154 const int cylinderUpAxis = 1;
155 const int XX = 0;
156 const int YY = 1;
157 const int ZZ = 2;
158
159 btScalar radius = halfExtents[XX];
160 btScalar halfHeight = halfExtents[cylinderUpAxis];
161
162 btVector3 tmp;
163 btScalar d;
164
165 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
166 if (s != btScalar(0.0))
167 {
168 d = radius / s;
169 tmp[XX] = v[XX] * d;
170 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
171 tmp[ZZ] = v[ZZ] * d;
172 return tmp;
173 }
174 else
175 {
176 tmp[XX] = radius;
177 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
178 tmp[ZZ] = btScalar(0.0);
179 return tmp;
180 }
181}
182
183 inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents, const btVector3& v)
184{
185 const int cylinderUpAxis = 2;
186 const int XX = 0;
187 const int YY = 2;
188 const int ZZ = 1;
189
190 //mapping depends on how cylinder local orientation is
191 // extents of the cylinder is: X,Y is for radius, and Z for height
192
193 btScalar radius = halfExtents[XX];
194 btScalar halfHeight = halfExtents[cylinderUpAxis];
195
196 btVector3 tmp;
197 btScalar d;
198
199 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
200 if (s != btScalar(0.0))
201 {
202 d = radius / s;
203 tmp[XX] = v[XX] * d;
204 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
205 tmp[ZZ] = v[ZZ] * d;
206 return tmp;
207 }
208 else
209 {
210 tmp[XX] = radius;
211 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
212 tmp[ZZ] = btScalar(0.0);
213 return tmp;
214 }
215}
216
217 btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec) const
218{
219 return CylinderLocalSupportX(getHalfExtentsWithoutMargin(), vec);
220}
221
222 btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec) const
223{
224 return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(), vec);
225}
226 btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const
227{
228 return CylinderLocalSupportY(getHalfExtentsWithoutMargin(), vec);
229}
230
231 void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const
232{
233 for (int i = 0; i < numVectors; i++)
234 {
235 supportVerticesOut[i] = CylinderLocalSupportY(getHalfExtentsWithoutMargin(), vectors[i]);
236 }
237}
238
239 void btCylinderShapeZ::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const
240{
241 for (int i = 0; i < numVectors; i++)
242 {
243 supportVerticesOut[i] = CylinderLocalSupportZ(getHalfExtentsWithoutMargin(), vectors[i]);
244 }
245}
246
247 void btCylinderShapeX::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const
248{
249 for (int i = 0; i < numVectors; i++)
250 {
251 supportVerticesOut[i] = CylinderLocalSupportX(getHalfExtentsWithoutMargin(), vectors[i]);
252 }
253}
btTransformAabb
void btTransformAabb(const btVector3 &halfExtents, btScalar margin, const btTransform &t, btVector3 &aabbMinOut, btVector3 &aabbMaxOut)
Definition btAabbUtil2.h:172
CYLINDER_SHAPE_PROXYTYPE
@ CYLINDER_SHAPE_PROXYTYPE
Definition btBroadphaseProxy.h:44
CylinderLocalSupportX
btVector3 CylinderLocalSupportX(const btVector3 &halfExtents, const btVector3 &v)
Definition btCylinderShape.cpp:118
CylinderLocalSupportZ
btVector3 CylinderLocalSupportZ(const btVector3 &halfExtents, const btVector3 &v)
Definition btCylinderShape.cpp:183
CylinderLocalSupportY
btVector3 CylinderLocalSupportY(const btVector3 &halfExtents, const btVector3 &v)
Definition btCylinderShape.cpp:152
btCylinderShape.h
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
btSqrt
btScalar btSqrt(btScalar y)
Definition btScalar.h:466
SIMD_FORCE_INLINE
#define SIMD_FORCE_INLINE
Definition btScalar.h:98
btCollisionShape::m_shapeType
int m_shapeType
Definition btCollisionShape.h:30
btConvexInternalShape::m_localScaling
btVector3 m_localScaling
Definition btConvexInternalShape.h:33
btConvexInternalShape::m_implicitShapeDimensions
btVector3 m_implicitShapeDimensions
Definition btConvexInternalShape.h:35
btConvexInternalShape::setSafeMargin
void setSafeMargin(btScalar minDimension, btScalar defaultMarginMultiplier=0.1f)
Definition btConvexInternalShape.h:66
btConvexInternalShape::btConvexInternalShape
btConvexInternalShape()
Definition btConvexInternalShape.cpp:18
btConvexInternalShape::getMargin
virtual btScalar getMargin() const
Definition btConvexInternalShape.h:106
btCylinderShapeX::btCylinderShapeX
btCylinderShapeX(const btVector3 &halfExtents)
Definition btCylinderShape.cpp:30
btCylinderShapeX::localGetSupportingVertexWithoutMargin
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
Definition btCylinderShape.cpp:217
btCylinderShapeX::batchedUnitVectorGetSupportingVertexWithoutMargin
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
Definition btCylinderShape.cpp:247
btCylinderShapeZ::batchedUnitVectorGetSupportingVertexWithoutMargin
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
Definition btCylinderShape.cpp:239
btCylinderShapeZ::localGetSupportingVertexWithoutMargin
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
Definition btCylinderShape.cpp:222
btCylinderShapeZ::btCylinderShapeZ
btCylinderShapeZ(const btVector3 &halfExtents)
Definition btCylinderShape.cpp:36
btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
Definition btCylinderShape.cpp:231
btCylinderShape::btCylinderShape
btCylinderShape(const btVector3 &halfExtents)
Definition btCylinderShape.cpp:18
btCylinderShape::calculateLocalInertia
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
Definition btCylinderShape.cpp:47
btCylinderShape::getAabb
void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const
getAabb's default implementation is brute force, expected derived classes to implement a fast dedicat...
Definition btCylinderShape.cpp:42
btCylinderShape::m_upAxis
int m_upAxis
Definition btCylinderShape.h:29
btCylinderShape::getHalfExtentsWithoutMargin
const btVector3 & getHalfExtentsWithoutMargin() const
Definition btCylinderShape.h:42
btCylinderShape::getHalfExtentsWithMargin
btVector3 getHalfExtentsWithMargin() const
Definition btCylinderShape.h:34
btCylinderShape::localGetSupportingVertexWithoutMargin
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
Definition btCylinderShape.cpp:226
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:30
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
btVector3::z
const btScalar & z() const
Return the z value.
Definition btVector3.h:579
btVector3::setValue
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition btVector3.h:640
btVector3::x
const btScalar & x() const
Return the x value.
Definition btVector3.h:575
btVector3::y
const btScalar & y() const
Return the y value.
Definition btVector3.h:577