Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp @ 1963

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

Added Bullet physics engine.

  • Property svn:eol-style set to native
File size: 10.2 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
16//#define DISABLE_BVH
17
18#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
19#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
20
21///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
22///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
23btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh)
24:btTriangleMeshShape(meshInterface),
25m_bvh(0),
26m_useQuantizedAabbCompression(useQuantizedAabbCompression),
27m_ownsBvh(false)
28{
29        m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
30        //construct bvh from meshInterface
31#ifndef DISABLE_BVH
32
33        btVector3 bvhAabbMin,bvhAabbMax;
34        if(meshInterface->hasPremadeAabb())
35        {
36                meshInterface->getPremadeAabb(&bvhAabbMin, &bvhAabbMax);
37        }
38        else
39        {
40                meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
41        }
42       
43        if (buildBvh)
44        {
45                void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
46                m_bvh = new (mem) btOptimizedBvh();
47                m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
48                m_ownsBvh = true;
49        }
50
51#endif //DISABLE_BVH
52
53}
54
55btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh)
56:btTriangleMeshShape(meshInterface),
57m_bvh(0),
58m_useQuantizedAabbCompression(useQuantizedAabbCompression),
59m_ownsBvh(false)
60{
61        m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
62        //construct bvh from meshInterface
63#ifndef DISABLE_BVH
64
65        if (buildBvh)
66        {
67                void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
68                m_bvh = new (mem) btOptimizedBvh();
69               
70                m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
71                m_ownsBvh = true;
72        }
73
74#endif //DISABLE_BVH
75
76}
77
78void    btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax)
79{
80        m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax );
81       
82        m_localAabbMin.setMin(aabbMin);
83        m_localAabbMax.setMax(aabbMax);
84}
85
86
87void    btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin,const btVector3& aabbMax)
88{
89        m_bvh->refit( m_meshInterface, aabbMin,aabbMax );
90       
91        recalcLocalAabb();
92}
93
94btBvhTriangleMeshShape::~btBvhTriangleMeshShape()
95{
96        if (m_ownsBvh)
97        {
98                m_bvh->~btOptimizedBvh();
99                btAlignedFree(m_bvh);
100        }
101}
102
103void    btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget)
104{
105        struct  MyNodeOverlapCallback : public btNodeOverlapCallback
106        {
107                btStridingMeshInterface*        m_meshInterface;
108                btTriangleCallback* m_callback;
109
110                MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
111                        :m_meshInterface(meshInterface),
112                        m_callback(callback)
113                {
114                }
115                               
116                virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
117                {
118                        btVector3 m_triangle[3];
119                        const unsigned char *vertexbase;
120                        int numverts;
121                        PHY_ScalarType type;
122                        int stride;
123                        const unsigned char *indexbase;
124                        int indexstride;
125                        int numfaces;
126                        PHY_ScalarType indicestype;
127
128                        m_meshInterface->getLockedReadOnlyVertexIndexBase(
129                                &vertexbase,
130                                numverts,
131                                type,
132                                stride,
133                                &indexbase,
134                                indexstride,
135                                numfaces,
136                                indicestype,
137                                nodeSubPart);
138
139                        unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
140                        btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
141       
142                        const btVector3& meshScaling = m_meshInterface->getScaling();
143                        for (int j=2;j>=0;j--)
144                        {
145                                int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
146
147                                btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
148
149                                m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());           
150                        }
151
152                        /* Perform ray vs. triangle collision here */
153                        m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
154                        m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
155                }
156        };
157
158        MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface);
159
160        m_bvh->reportRayOverlappingNodex(&myNodeCallback,raySource,rayTarget);
161}
162
163void    btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax)
164{
165        struct  MyNodeOverlapCallback : public btNodeOverlapCallback
166        {
167                btStridingMeshInterface*        m_meshInterface;
168                btTriangleCallback* m_callback;
169
170                MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
171                        :m_meshInterface(meshInterface),
172                        m_callback(callback)
173                {
174                }
175                               
176                virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
177                {
178                        btVector3 m_triangle[3];
179                        const unsigned char *vertexbase;
180                        int numverts;
181                        PHY_ScalarType type;
182                        int stride;
183                        const unsigned char *indexbase;
184                        int indexstride;
185                        int numfaces;
186                        PHY_ScalarType indicestype;
187
188                        m_meshInterface->getLockedReadOnlyVertexIndexBase(
189                                &vertexbase,
190                                numverts,
191                                type,
192                                stride,
193                                &indexbase,
194                                indexstride,
195                                numfaces,
196                                indicestype,
197                                nodeSubPart);
198
199                        unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
200                        btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
201       
202                        const btVector3& meshScaling = m_meshInterface->getScaling();
203                        for (int j=2;j>=0;j--)
204                        {
205                                int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
206
207                                btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
208
209                                m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());           
210                        }
211
212                        /* Perform ray vs. triangle collision here */
213                        m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
214                        m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
215                }
216        };
217
218        MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface);
219
220        m_bvh->reportBoxCastOverlappingNodex (&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax);
221}
222
223//perform bvh tree traversal and report overlapping triangles to 'callback'
224void    btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
225{
226
227#ifdef DISABLE_BVH
228        //brute force traverse all triangles
229        btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax);
230#else
231
232        //first get all the nodes
233
234       
235        struct  MyNodeOverlapCallback : public btNodeOverlapCallback
236        {
237                btStridingMeshInterface*        m_meshInterface;
238                btTriangleCallback*             m_callback;
239                btVector3                               m_triangle[3];
240
241
242                MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
243                        :m_meshInterface(meshInterface),
244                        m_callback(callback)
245                {
246                }
247                               
248                virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
249                {
250                        const unsigned char *vertexbase;
251                        int numverts;
252                        PHY_ScalarType type;
253                        int stride;
254                        const unsigned char *indexbase;
255                        int indexstride;
256                        int numfaces;
257                        PHY_ScalarType indicestype;
258                       
259
260                        m_meshInterface->getLockedReadOnlyVertexIndexBase(
261                                &vertexbase,
262                                numverts,
263                                type,
264                                stride,
265                                &indexbase,
266                                indexstride,
267                                numfaces,
268                                indicestype,
269                                nodeSubPart);
270
271                        unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
272                        btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
273       
274                        const btVector3& meshScaling = m_meshInterface->getScaling();
275                        for (int j=2;j>=0;j--)
276                        {
277                               
278                                int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
279
280
281#ifdef DEBUG_TRIANGLE_MESH
282                                printf("%d ,",graphicsindex);
283#endif //DEBUG_TRIANGLE_MESH
284                                btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
285
286                                m_triangle[j] = btVector3(
287                                        graphicsbase[0]*meshScaling.getX(),
288                                        graphicsbase[1]*meshScaling.getY(),
289                                        graphicsbase[2]*meshScaling.getZ());
290#ifdef DEBUG_TRIANGLE_MESH
291                                printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
292#endif //DEBUG_TRIANGLE_MESH
293                        }
294
295                        m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
296                        m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
297                }
298
299        };
300
301        MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface);
302
303        m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
304
305
306#endif//DISABLE_BVH
307
308
309}
310
311void   btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
312{
313   if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
314   {
315      btTriangleMeshShape::setLocalScaling(scaling);
316      if (m_ownsBvh)
317      {
318         m_bvh->~btOptimizedBvh();
319         btAlignedFree(m_bvh);
320      }
321      ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
322      void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
323      m_bvh = new(mem) btOptimizedBvh();
324      //rebuild the bvh...
325      m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
326      m_ownsBvh = true;
327   }
328}
329
330void   btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling)
331{
332   btAssert(!m_bvh);
333   btAssert(!m_ownsBvh);
334
335   m_bvh = bvh;
336   m_ownsBvh = false;
337   // update the scaling without rebuilding the bvh
338   if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
339   {
340      btTriangleMeshShape::setLocalScaling(scaling);
341   }
342}
343
344
Note: See TracBrowser for help on using the repository browser.