Bullet Collision Detection & Physics Library
btConvexTriangleMeshShape.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 
18 
21 
22 
24 : btPolyhedralConvexAabbCachingShape(), m_stridingMesh(meshInterface)
25 {
27  if ( calcAabb )
29 }
30 
31 
32 
33 
37 {
38 
40 public:
41 
44 
45  LocalSupportVertexCallback(const btVector3& supportVecLocal)
46  : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)),
47  m_maxDot(btScalar(-BT_LARGE_FLOAT)),
48  m_supportVecLocal(supportVecLocal)
49  {
50  }
51 
52  virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
53  {
54  (void)triangleIndex;
55  (void)partId;
56 
57  for (int i=0;i<3;i++)
58  {
59  btScalar dot = m_supportVecLocal.dot(triangle[i]);
60  if (dot > m_maxDot)
61  {
62  m_maxDot = dot;
63  m_supportVertexLocal = triangle[i];
64  }
65  }
66  }
67 
69  {
70  return m_supportVertexLocal;
71  }
72 
73 };
74 
75 
76 
77 
78 
80 {
81  btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
82 
83  btVector3 vec = vec0;
84  btScalar lenSqr = vec.length2();
85  if (lenSqr < btScalar(0.0001))
86  {
87  vec.setValue(1,0,0);
88  } else
89  {
90  btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
91  vec *= rlen;
92  }
93 
94  LocalSupportVertexCallback supportCallback(vec);
96  m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
97  supVec = supportCallback.GetSupportVertexLocal();
98 
99  return supVec;
100 }
101 
102 void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
103 {
104  //use 'w' component of supportVerticesOut?
105  {
106  for (int i=0;i<numVectors;i++)
107  {
108  supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
109  }
110  }
111 
113 
114 
115  for (int j=0;j<numVectors;j++)
116  {
117  const btVector3& vec = vectors[j];
118  LocalSupportVertexCallback supportCallback(vec);
120  m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
121  supportVerticesOut[j] = supportCallback.GetSupportVertexLocal();
122  }
123 
124 }
125 
126 
127 
129 {
131 
132  if ( getMargin()!=btScalar(0.) )
133  {
134  btVector3 vecnorm = vec;
135  if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
136  {
137  vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
138  }
139  vecnorm.normalize();
140  supVertex+= getMargin() * vecnorm;
141  }
142  return supVertex;
143 }
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 //currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
154 //Please note that you can debug-draw btConvexTriangleMeshShape with the Raytracer Demo
156 {
157  //cache this?
158  return 0;
159 
160 }
161 
163 {
164  return 0;
165 }
166 
168 {
169  btAssert(0);
170 }
171 
173 {
174  btAssert(0);
175 }
176 
178 {
179  return 0;
180 }
181 
183 {
184  btAssert(0);
185 }
186 
187 //not yet
189 {
190  btAssert(0);
191  return false;
192 }
193 
194 
195 
197 {
198  m_stridingMesh->setScaling(scaling);
199 
200  recalcLocalAabb();
201 
202 }
203 
204 
206 {
207  return m_stridingMesh->getScaling();
208 }
209 
211 {
212  class CenterCallback: public btInternalTriangleIndexCallback
213  {
214  bool first;
215  btVector3 ref;
216  btVector3 sum;
217  btScalar volume;
218 
219  public:
220 
221  CenterCallback() : first(true), ref(0, 0, 0), sum(0, 0, 0), volume(0)
222  {
223  }
224 
225  virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
226  {
227  (void) triangleIndex;
228  (void) partId;
229  if (first)
230  {
231  ref = triangle[0];
232  first = false;
233  }
234  else
235  {
236  btScalar vol = btFabs((triangle[0] - ref).triple(triangle[1] - ref, triangle[2] - ref));
237  sum += (btScalar(0.25) * vol) * ((triangle[0] + triangle[1] + triangle[2] + ref));
238  volume += vol;
239  }
240  }
241 
242  btVector3 getCenter()
243  {
244  return (volume > 0) ? sum / volume : ref;
245  }
246 
247  btScalar getVolume()
248  {
249  return volume * btScalar(1. / 6);
250  }
251 
252  };
253 
254  class InertiaCallback: public btInternalTriangleIndexCallback
255  {
257  btVector3 center;
258 
259  public:
260 
261  InertiaCallback(btVector3& center) : sum(0, 0, 0, 0, 0, 0, 0, 0, 0), center(center)
262  {
263  }
264 
265  virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
266  {
267  (void) triangleIndex;
268  (void) partId;
269  btMatrix3x3 i;
270  btVector3 a = triangle[0] - center;
271  btVector3 b = triangle[1] - center;
272  btVector3 c = triangle[2] - center;
273  btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6);
274  for (int j = 0; j < 3; j++)
275  {
276  for (int k = 0; k <= j; k++)
277  {
278  i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
279  + btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j]));
280  }
281  }
282  btScalar i00 = -i[0][0];
283  btScalar i11 = -i[1][1];
284  btScalar i22 = -i[2][2];
285  i[0][0] = i11 + i22;
286  i[1][1] = i22 + i00;
287  i[2][2] = i00 + i11;
288  sum[0] += i[0];
289  sum[1] += i[1];
290  sum[2] += i[2];
291  }
292 
293  btMatrix3x3& getInertia()
294  {
295  return sum;
296  }
297 
298  };
299 
300  CenterCallback centerCallback;
302  m_stridingMesh->InternalProcessAllTriangles(&centerCallback, -aabbMax, aabbMax);
303  btVector3 center = centerCallback.getCenter();
304  principal.setOrigin(center);
305  volume = centerCallback.getVolume();
306 
307  InertiaCallback inertiaCallback(center);
308  m_stridingMesh->InternalProcessAllTriangles(&inertiaCallback, -aabbMax, aabbMax);
309 
310  btMatrix3x3& i = inertiaCallback.getInertia();
311  i.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
312  inertia.setValue(i[0][0], i[1][1], i[2][2]);
313  inertia /= volume;
314 }
315 
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
static T sum(const btAlignedObjectArray< T > &items)
#define SIMD_EPSILON
Definition: btScalar.h:521
virtual void getEdge(int i, btVector3 &pa, btVector3 &pb) const
virtual btVector3 localGetSupportingVertex(const btVector3 &vec) const
#define BT_LARGE_FLOAT
Definition: btScalar.h:294
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
virtual bool isInside(const btVector3 &pt, btScalar tolerance) const
It&#39;s not nice to have all this virtual function overhead, so perhaps we can also gather the points on...
btScalar btSqrt(btScalar y)
Definition: btScalar.h:444
#define btAssert(x)
Definition: btScalar.h:131
LocalSupportVertexCallback(const btVector3 &supportVecLocal)
void calculatePrincipalAxisTransform(btTransform &principal, btVector3 &inertia, btScalar &volume) const
computes the exact moment of inertia and the transform from the coordinate system defined by the prin...
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
const btVector3 & getScaling() const
virtual void getVertex(int i, btVector3 &vtx) const
void setScaling(const btVector3 &scaling)
virtual const btVector3 & getLocalScaling() const
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
virtual btScalar getMargin() const
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
virtual void setLocalScaling(const btVector3 &scaling)
btScalar triple(const btVector3 &v1, const btVector3 &v2) const
Definition: btVector3.h:428
void diagonalize(btMatrix3x3 &rot, btScalar threshold, int maxSteps)
diagonalizes this matrix by the Jacobi method.
Definition: btMatrix3x3.h:690
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
class btStridingMeshInterface * m_stridingMesh
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
virtual void internalProcessTriangleIndex(btVector3 *triangle, int partId, int triangleIndex)
virtual void getPlane(btVector3 &planeNormal, btVector3 &planeSupport, int i) const
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
The btPolyhedralConvexAabbCachingShape adds aabb caching to the btPolyhedralConvexShape.
The btStridingMeshInterface is the interface class for high performance generic access to triangle me...
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:48
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
Definition: btQuaternion.h:898
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
btConvexTriangleMeshShape(btStridingMeshInterface *meshInterface, bool calcAabb=true)
btScalar btFabs(btScalar x)
Definition: btScalar.h:475