Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp @ 2760

Last change on this file since 2760 was 2662, checked in by rgrieder, 16 years ago

Merged presentation branch back to trunk.

  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
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#include "btConvexTriangleMeshShape.h"
16#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
17
18#include "LinearMath/btQuaternion.h"
19#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
20
21
22btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb)
23: btPolyhedralConvexShape(), m_stridingMesh(meshInterface)
24{
25        m_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE;
26        if ( calcAabb )
27                recalcLocalAabb();
28}
29
30
31
32
33///It's not nice to have all this virtual function overhead, so perhaps we can also gather the points once
34///but then we are duplicating
35class LocalSupportVertexCallback: public btInternalTriangleIndexCallback
36{
37
38        btVector3 m_supportVertexLocal;
39public:
40
41        btScalar m_maxDot;
42        btVector3 m_supportVecLocal;
43
44        LocalSupportVertexCallback(const btVector3& supportVecLocal)
45                : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)),
46                m_maxDot(btScalar(-1e30)),
47                m_supportVecLocal(supportVecLocal)
48        {
49        }
50
51        virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
52        {
53                (void)triangleIndex;
54                (void)partId;
55
56                for (int i=0;i<3;i++)
57                {
58                        btScalar dot = m_supportVecLocal.dot(triangle[i]);
59                        if (dot > m_maxDot)
60                        {
61                                m_maxDot = dot;
62                                m_supportVertexLocal = triangle[i];
63                        }
64                }
65        }
66       
67        btVector3       GetSupportVertexLocal()
68        {
69                return m_supportVertexLocal;
70        }
71
72};
73
74
75
76
77
78btVector3       btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
79{
80        btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
81
82        btVector3 vec = vec0;
83        btScalar lenSqr = vec.length2();
84        if (lenSqr < btScalar(0.0001))
85        {
86                vec.setValue(1,0,0);
87        } else
88        {
89                btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
90                vec *= rlen;
91        }
92
93        LocalSupportVertexCallback      supportCallback(vec);
94        btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
95        m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
96        supVec = supportCallback.GetSupportVertexLocal();
97
98        return supVec;
99}
100
101void    btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
102{
103        //use 'w' component of supportVerticesOut?
104        {
105                for (int i=0;i<numVectors;i++)
106                {
107                        supportVerticesOut[i][3] = btScalar(-1e30);
108                }
109        }
110       
111        ///@todo: could do the batch inside the callback!
112
113
114        for (int j=0;j<numVectors;j++)
115        {
116                const btVector3& vec = vectors[j];
117                LocalSupportVertexCallback      supportCallback(vec);
118                btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
119                m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
120                supportVerticesOut[j] = supportCallback.GetSupportVertexLocal();
121        }
122       
123}
124       
125
126
127btVector3       btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& vec)const
128{
129        btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
130
131        if ( getMargin()!=btScalar(0.) )
132        {
133                btVector3 vecnorm = vec;
134                if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
135                {
136                        vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
137                } 
138                vecnorm.normalize();
139                supVertex+= getMargin() * vecnorm;
140        }
141        return supVertex;
142}
143
144
145
146
147
148
149
150
151
152//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
153//Please note that you can debug-draw btConvexTriangleMeshShape with the Raytracer Demo
154int     btConvexTriangleMeshShape::getNumVertices() const
155{
156        //cache this?
157        return 0;
158       
159}
160
161int btConvexTriangleMeshShape::getNumEdges() const
162{
163        return 0;
164}
165
166void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const
167{
168        btAssert(0);   
169}
170
171void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const
172{
173        btAssert(0);
174}
175
176int     btConvexTriangleMeshShape::getNumPlanes() const
177{
178        return 0;
179}
180
181void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int  ) const
182{
183        btAssert(0);
184}
185
186//not yet
187bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const
188{
189        btAssert(0);
190        return false;
191}
192
193
194
195void    btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling)
196{
197        m_stridingMesh->setScaling(scaling);
198       
199        recalcLocalAabb();
200       
201}
202
203
204const btVector3& btConvexTriangleMeshShape::getLocalScaling() const
205{
206        return m_stridingMesh->getScaling();
207}
208
209void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const
210{
211   class CenterCallback: public btInternalTriangleIndexCallback
212   {
213      bool first;
214      btVector3 ref;
215      btVector3 sum;
216      btScalar volume;
217
218   public:
219
220      CenterCallback() : first(true), ref(0, 0, 0), sum(0, 0, 0), volume(0)
221      {
222      }
223
224      virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
225      {
226         (void) triangleIndex;
227         (void) partId;
228         if (first)
229         {
230            ref = triangle[0];
231            first = false;
232         }
233         else
234         {
235            btScalar vol = btFabs((triangle[0] - ref).triple(triangle[1] - ref, triangle[2] - ref));
236            sum += (btScalar(0.25) * vol) * ((triangle[0] + triangle[1] + triangle[2] + ref));
237            volume += vol;
238         }
239      }
240     
241      btVector3 getCenter()
242      {
243         return (volume > 0) ? sum / volume : ref;
244      }
245
246      btScalar getVolume()
247      {
248         return volume * btScalar(1. / 6);
249      }
250
251   };
252
253   class InertiaCallback: public btInternalTriangleIndexCallback
254   {
255      btMatrix3x3 sum;
256      btVector3 center;
257
258   public:
259
260      InertiaCallback(btVector3& center) : sum(0, 0, 0, 0, 0, 0, 0, 0, 0), center(center)
261      {
262      }
263
264      virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
265      {
266         (void) triangleIndex;
267         (void) partId;
268         btMatrix3x3 i;
269         btVector3 a = triangle[0] - center;
270         btVector3 b = triangle[1] - center;
271         btVector3 c = triangle[2] - center;
272         btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6);
273         for (int j = 0; j < 3; j++)
274         {
275            for (int k = 0; k <= j; k++)
276            {
277               i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
278                  + 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]));
279            }
280         }
281         btScalar i00 = -i[0][0];
282         btScalar i11 = -i[1][1];
283         btScalar i22 = -i[2][2];
284         i[0][0] = i11 + i22; 
285         i[1][1] = i22 + i00; 
286         i[2][2] = i00 + i11;
287         sum[0] += i[0];
288         sum[1] += i[1];
289         sum[2] += i[2];
290      }
291     
292      btMatrix3x3& getInertia()
293      {
294         return sum;
295      }
296
297   };
298
299   CenterCallback centerCallback;
300   btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
301   m_stridingMesh->InternalProcessAllTriangles(&centerCallback, -aabbMax, aabbMax);
302   btVector3 center = centerCallback.getCenter();
303   principal.setOrigin(center);
304   volume = centerCallback.getVolume();
305
306   InertiaCallback inertiaCallback(center);
307   m_stridingMesh->InternalProcessAllTriangles(&inertiaCallback, -aabbMax, aabbMax);
308
309   btMatrix3x3& i = inertiaCallback.getInertia();
310   i.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
311   inertia.setValue(i[0][0], i[1][1], i[2][2]);
312   inertia /= volume;
313}
314
Note: See TracBrowser for help on using the repository browser.