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
20 m_upAxis(1)
21{
22 btVector3 margin(getMargin(), getMargin(), getMargin());
23 m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin;
24
25 setSafeMargin(halfExtents);
26
28}
29
31 : btCylinderShape(halfExtents)
32{
33 m_upAxis = 0;
34}
35
37 : btCylinderShape(halfExtents)
38{
39 m_upAxis = 2;
40}
41
42void btCylinderShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
43{
44 btTransformAabb(getHalfExtentsWithoutMargin(), getMargin(), t, aabbMin, aabbMax);
45}
46
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
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
152inline 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
183inline 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
218{
220}
221
223{
225}
227{
229}
230
231void 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
239void 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
247void 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}
void btTransformAabb(const btVector3 &halfExtents, btScalar margin, const btTransform &t, btVector3 &aabbMinOut, btVector3 &aabbMaxOut)
Definition: btAabbUtil2.h:172
@ 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:314
btScalar btSqrt(btScalar y)
Definition: btScalar.h:466
#define SIMD_FORCE_INLINE
Definition: btScalar.h:98
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:30
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
const btScalar & z() const
Return the z value.
Definition: btVector3.h:579
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
const btScalar & x() const
Return the x value.
Definition: btVector3.h:575
const btScalar & y() const
Return the y value.
Definition: btVector3.h:577