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
20m_upAxis(1)
21{
23 m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin;
24
25 setSafeMargin(halfExtents);
26
28}
29
30
32:btCylinderShape(halfExtents)
33{
34 m_upAxis = 0;
35
36}
37
38
40:btCylinderShape(halfExtents)
41{
42 m_upAxis = 2;
43
44}
45
46void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
47{
49}
50
52{
53
54//Until Bullet 2.77 a box approximation was used, so uncomment this if you need backwards compatibility
55//#define USE_BOX_INERTIA_APPROXIMATION 1
56#ifndef USE_BOX_INERTIA_APPROXIMATION
57
58 /*
59 cylinder is defined as following:
60 *
61 * - principle axis aligned along y by default, radius in x, z-value not used
62 * - for btCylinderShapeX: principle axis aligned along x, radius in y direction, z-value not used
63 * - for btCylinderShapeZ: principle axis aligned along z, radius in x direction, y-value not used
64 *
65 */
66
67 btScalar radius2; // square of cylinder radius
68 btScalar height2; // square of cylinder height
69 btVector3 halfExtents = getHalfExtentsWithMargin(); // get cylinder dimension
70 btScalar div12 = mass / 12.f;
71 btScalar div4 = mass / 4.f;
72 btScalar div2 = mass / 2.f;
73 int idxRadius, idxHeight;
74
75 switch (m_upAxis) // get indices of radius and height of cylinder
76 {
77 case 0: // cylinder is aligned along x
78 idxRadius = 1;
79 idxHeight = 0;
80 break;
81 case 2: // cylinder is aligned along z
82 idxRadius = 0;
83 idxHeight = 2;
84 break;
85 default: // cylinder is aligned along y
86 idxRadius = 0;
87 idxHeight = 1;
88 }
89
90 // calculate squares
91 radius2 = halfExtents[idxRadius] * halfExtents[idxRadius];
92 height2 = btScalar(4.) * halfExtents[idxHeight] * halfExtents[idxHeight];
93
94 // calculate tensor terms
95 btScalar t1 = div12 * height2 + div4 * radius2;
96 btScalar t2 = div2 * radius2;
97
98 switch (m_upAxis) // set diagonal elements of inertia tensor
99 {
100 case 0: // cylinder is aligned along x
101 inertia.setValue(t2,t1,t1);
102 break;
103 case 2: // cylinder is aligned along z
104 inertia.setValue(t1,t1,t2);
105 break;
106 default: // cylinder is aligned along y
107 inertia.setValue(t1,t2,t1);
108 }
109#else //USE_BOX_INERTIA_APPROXIMATION
110 //approximation of box shape
111 btVector3 halfExtents = getHalfExtentsWithMargin();
112
113 btScalar lx=btScalar(2.)*(halfExtents.x());
114 btScalar ly=btScalar(2.)*(halfExtents.y());
115 btScalar lz=btScalar(2.)*(halfExtents.z());
116
117 inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
118 mass/(btScalar(12.0)) * (lx*lx + lz*lz),
119 mass/(btScalar(12.0)) * (lx*lx + ly*ly));
120#endif //USE_BOX_INERTIA_APPROXIMATION
121}
122
123
125{
126const int cylinderUpAxis = 0;
127const int XX = 1;
128const int YY = 0;
129const int ZZ = 2;
130
131 //mapping depends on how cylinder local orientation is
132 // extents of the cylinder is: X,Y is for radius, and Z for height
133
134
135 btScalar radius = halfExtents[XX];
136 btScalar halfHeight = halfExtents[cylinderUpAxis];
137
138
139 btVector3 tmp;
140 btScalar d ;
141
142 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
143 if (s != btScalar(0.0))
144 {
145 d = radius / s;
146 tmp[XX] = v[XX] * d;
147 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
148 tmp[ZZ] = v[ZZ] * d;
149 return tmp;
150 }
151 else
152 {
153 tmp[XX] = radius;
154 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
155 tmp[ZZ] = btScalar(0.0);
156 return tmp;
157 }
158
159
160}
161
162
163
164
165
166
167inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v)
168{
169
170const int cylinderUpAxis = 1;
171const int XX = 0;
172const int YY = 1;
173const int ZZ = 2;
174
175
176 btScalar radius = halfExtents[XX];
177 btScalar halfHeight = halfExtents[cylinderUpAxis];
178
179
180 btVector3 tmp;
181 btScalar d ;
182
183 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
184 if (s != btScalar(0.0))
185 {
186 d = radius / s;
187 tmp[XX] = v[XX] * d;
188 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
189 tmp[ZZ] = v[ZZ] * d;
190 return tmp;
191 }
192 else
193 {
194 tmp[XX] = radius;
195 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
196 tmp[ZZ] = btScalar(0.0);
197 return tmp;
198 }
199
200}
201
202inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v)
203{
204const int cylinderUpAxis = 2;
205const int XX = 0;
206const int YY = 2;
207const int ZZ = 1;
208
209 //mapping depends on how cylinder local orientation is
210 // extents of the cylinder is: X,Y is for radius, and Z for height
211
212
213 btScalar radius = halfExtents[XX];
214 btScalar halfHeight = halfExtents[cylinderUpAxis];
215
216
217 btVector3 tmp;
218 btScalar d ;
219
220 btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
221 if (s != btScalar(0.0))
222 {
223 d = radius / s;
224 tmp[XX] = v[XX] * d;
225 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
226 tmp[ZZ] = v[ZZ] * d;
227 return tmp;
228 }
229 else
230 {
231 tmp[XX] = radius;
232 tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
233 tmp[ZZ] = btScalar(0.0);
234 return tmp;
235 }
236
237
238}
239
241{
243}
244
245
247{
249}
251{
253}
254
255void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
256{
257 for (int i=0;i<numVectors;i++)
258 {
259 supportVerticesOut[i] = CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vectors[i]);
260 }
261}
262
263void btCylinderShapeZ::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
264{
265 for (int i=0;i<numVectors;i++)
266 {
267 supportVerticesOut[i] = CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vectors[i]);
268 }
269}
270
271
272
273
274void btCylinderShapeX::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
275{
276 for (int i=0;i<numVectors;i++)
277 {
278 supportVerticesOut[i] = CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vectors[i]);
279 }
280}
281
282
void btTransformAabb(const btVector3 &halfExtents, btScalar margin, const btTransform &t, btVector3 &aabbMinOut, btVector3 &aabbMaxOut)
Definition: btAabbUtil2.h:182
@ CYLINDER_SHAPE_PROXYTYPE
btVector3 CylinderLocalSupportX(const btVector3 &halfExtents, const btVector3 &v)
btVector3 CylinderLocalSupportZ(const btVector3 &halfExtents, const btVector3 &v)
btVector3 CylinderLocalSupportY(const btVector3 &halfExtents, const btVector3 &v)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
btScalar btSqrt(btScalar y)
Definition: btScalar.h:444
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
The btConvexInternalShape is an internal base class, shared by most convex shape implementations.
void setSafeMargin(btScalar minDimension, btScalar defaultMarginMultiplier=0.1f)
virtual btScalar getMargin() const
btCylinderShapeX(const btVector3 &halfExtents)
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
btCylinderShapeZ(const btVector3 &halfExtents)
The btCylinderShape class implements a cylinder shape primitive, centered around the origin....
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
btCylinderShape(const btVector3 &halfExtents)
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
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...
const btVector3 & getHalfExtentsWithoutMargin() const
btVector3 getHalfExtentsWithMargin() const
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:84
const btScalar & z() const
Return the z value.
Definition: btVector3.h:591
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
const btScalar & x() const
Return the x value.
Definition: btVector3.h:587
const btScalar & y() const
Return the y value.
Definition: btVector3.h:589