2
Bullet Continuous Collision Detection and Physics Library
3
Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
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:
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.
16
#include "btConvexTriangleMeshShape.h"
17
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
19
#include "LinearMath/btQuaternion.h"
20
#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
23
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb)
24
: btPolyhedralConvexAabbCachingShape(), m_stridingMesh(meshInterface)
26
m_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE;
34
///It's not nice to have all this virtual function overhead, so perhaps we can also gather the points once
35
///but then we are duplicating
36
class LocalSupportVertexCallback: public btInternalTriangleIndexCallback
39
btVector3 m_supportVertexLocal;
43
btVector3 m_supportVecLocal;
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)
52
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
59
btScalar dot = m_supportVecLocal.dot(triangle[i]);
63
m_supportVertexLocal = triangle[i];
68
btVector3 GetSupportVertexLocal()
70
return m_supportVertexLocal;
79
btVector3 btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
81
btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
84
btScalar lenSqr = vec.length2();
85
if (lenSqr < btScalar(0.0001))
90
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
94
LocalSupportVertexCallback supportCallback(vec);
95
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
96
m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
97
supVec = supportCallback.GetSupportVertexLocal();
102
void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
104
//use 'w' component of supportVerticesOut?
106
for (int i=0;i<numVectors;i++)
108
supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
112
///@todo: could do the batch inside the callback!
115
for (int j=0;j<numVectors;j++)
117
const btVector3& vec = vectors[j];
118
LocalSupportVertexCallback supportCallback(vec);
119
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
120
m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
121
supportVerticesOut[j] = supportCallback.GetSupportVertexLocal();
128
btVector3 btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& vec)const
130
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
132
if ( getMargin()!=btScalar(0.) )
134
btVector3 vecnorm = vec;
135
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
137
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
140
supVertex+= getMargin() * vecnorm;
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
155
int btConvexTriangleMeshShape::getNumVertices() const
162
int btConvexTriangleMeshShape::getNumEdges() const
167
void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const
172
void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const
177
int btConvexTriangleMeshShape::getNumPlanes() const
182
void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int ) const
188
bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const
196
void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling)
198
m_stridingMesh->setScaling(scaling);
205
const btVector3& btConvexTriangleMeshShape::getLocalScaling() const
207
return m_stridingMesh->getScaling();
210
void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const
212
class CenterCallback: public btInternalTriangleIndexCallback
221
CenterCallback() : first(true), ref(0, 0, 0), sum(0, 0, 0), volume(0)
225
virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
227
(void) triangleIndex;
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));
242
btVector3 getCenter()
244
return (volume > 0) ? sum / volume : ref;
249
return volume * btScalar(1. / 6);
254
class InertiaCallback: public btInternalTriangleIndexCallback
261
InertiaCallback(btVector3& center) : sum(0, 0, 0, 0, 0, 0, 0, 0, 0), center(center)
265
virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
267
(void) triangleIndex;
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++)
276
for (int k = 0; k <= j; k++)
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]));
282
btScalar i00 = -i[0][0];
283
btScalar i11 = -i[1][1];
284
btScalar i22 = -i[2][2];
293
btMatrix3x3& getInertia()
300
CenterCallback centerCallback;
301
btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
302
m_stridingMesh->InternalProcessAllTriangles(¢erCallback, -aabbMax, aabbMax);
303
btVector3 center = centerCallback.getCenter();
304
principal.setOrigin(center);
305
volume = centerCallback.getVolume();
307
InertiaCallback inertiaCallback(center);
308
m_stridingMesh->InternalProcessAllTriangles(&inertiaCallback, -aabbMax, aabbMax);
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]);