Blender  V3.3
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 
27  m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
28 }
29 
31  : btCylinderShape(halfExtents)
32 {
33  m_upAxis = 0;
34 }
35 
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 
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 
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 
218 {
220 }
221 
223 {
225 }
227 {
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 }
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE void btTransformAabb(const btVector3 &halfExtents, btScalar margin, const btTransform &t, btVector3 &aabbMinOut, btVector3 &aabbMaxOut)
Definition: btAabbUtil2.h:172
SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
btConvexShape Interface
Definition: btBox2dShape.h:62
const btVector3 & getHalfExtentsWithoutMargin() const
Definition: btBox2dShape.h:46
btVector3 getHalfExtentsWithMargin() const
Definition: btBox2dShape.h:38
virtual void calculateLocalInertia(btScalar mass, btVector3 &inertia) const
Definition: btConeShape.h:54
virtual 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 void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
Definition: btBox2dShape.h:71
@ CYLINDER_SHAPE_PROXYTYPE
virtual btScalar getMargin() const =0
btVector3 m_localScaling
void setSafeMargin(btScalar minDimension, btScalar defaultMarginMultiplier=0.1f)
btConvexInternalShape()
btVector3 m_implicitShapeDimensions
btVector3 CylinderLocalSupportZ(const btVector3 &halfExtents, const btVector3 &v)
btVector3 CylinderLocalSupportY(const btVector3 &halfExtents, const btVector3 &v)
SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3 &halfExtents, const btVector3 &v)
btCylinderShape(const btVector3 &halfExtents)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
Definition: btScalar.h:466
#define SIMD_FORCE_INLINE
Definition: btScalar.h:280
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. It has an un-used w component to suit 16-by...
Definition: btVector3.h:82
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)