Bullet Collision Detection & Physics Library
btConvexTriangleMeshShape.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
18
21
22
24: btPolyhedralConvexAabbCachingShape(), m_stridingMesh(meshInterface)
25{
27 if ( calcAabb )
29}
30
31
32
33
37{
38
40public:
41
44
45 LocalSupportVertexCallback(const btVector3& supportVecLocal)
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 {
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
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
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;
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
@ CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
Definition: btQuaternion.h:878
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
#define BT_LARGE_FLOAT
Definition: btScalar.h:294
btScalar btSqrt(btScalar y)
Definition: btScalar.h:444
btScalar btFabs(btScalar x)
Definition: btScalar.h:475
#define SIMD_EPSILON
Definition: btScalar.h:521
#define btAssert(x)
Definition: btScalar.h:131
static T sum(const btAlignedObjectArray< T > &items)
It's not nice to have all this virtual function overhead, so perhaps we can also gather the points on...
LocalSupportVertexCallback(const btVector3 &supportVecLocal)
virtual void internalProcessTriangleIndex(btVector3 *triangle, int partId, int triangleIndex)
virtual btScalar getMargin() const
class btStridingMeshInterface * m_stridingMesh
virtual const btVector3 & getLocalScaling() const
btConvexTriangleMeshShape(btStridingMeshInterface *meshInterface, bool calcAabb=true)
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const
virtual btVector3 localGetSupportingVertex(const btVector3 &vec) const
virtual void setLocalScaling(const btVector3 &scaling)
virtual bool isInside(const btVector3 &pt, btScalar tolerance) const
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 void getVertex(int i, btVector3 &vtx) const
virtual void getEdge(int i, btVector3 &pa, btVector3 &pb) const
virtual void getPlane(btVector3 &planeNormal, btVector3 &planeSupport, int i) const
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3 &vec) const
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:48
void diagonalize(btMatrix3x3 &rot, btScalar tolerance=1.0e-9, int maxIter=100)
diagonalizes this matrix
Definition: btMatrix3x3.h:682
The btPolyhedralConvexAabbCachingShape adds aabb caching to the btPolyhedralConvexShape.
The btStridingMeshInterface is the interface class for high performance generic access to triangle me...
const btVector3 & getScaling() const
void setScaling(const btVector3 &scaling)
virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback *callback, const btVector3 &aabbMin, const btVector3 &aabbMax) const
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:84
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:652
btScalar triple(const btVector3 &v1, const btVector3 &v2) const
Definition: btVector3.h:428
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309