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