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  btVector3 margin(getMargin(),getMargin(),getMargin());
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 
46 void 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 {
126 const int cylinderUpAxis = 0;
127 const int XX = 1;
128 const int YY = 0;
129 const 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 
167 inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v)
168 {
169 
170 const int cylinderUpAxis = 1;
171 const int XX = 0;
172 const int YY = 1;
173 const 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 
202 inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v)
203 {
204 const int cylinderUpAxis = 2;
205 const int XX = 0;
206 const int YY = 2;
207 const 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 
255 void 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 
263 void 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 
274 void 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 
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:652
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:444
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
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:587
btVector3 CylinderLocalSupportZ(const btVector3 &halfExtents, const btVector3 &v)
const btScalar & y() const
Return the y value.
Definition: btVector3.h:589
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&#39;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:292
const btScalar & z() const
Return the z value.
Definition: btVector3.h:591