btBvhTriangleMeshShape.cpp

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 //#define DISABLE_BVH
00017 
00018 #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
00019 #include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
00020 
00023 btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh)
00024 :btTriangleMeshShape(meshInterface),
00025 m_bvh(0),
00026 m_useQuantizedAabbCompression(useQuantizedAabbCompression),
00027 m_ownsBvh(false)
00028 {
00029         m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
00030         //construct bvh from meshInterface
00031 #ifndef DISABLE_BVH
00032 
00033         if (buildBvh)
00034         {
00035                 buildOptimizedBvh();
00036         }
00037 
00038 #endif //DISABLE_BVH
00039 
00040 }
00041 
00042 btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh)
00043 :btTriangleMeshShape(meshInterface),
00044 m_bvh(0),
00045 m_useQuantizedAabbCompression(useQuantizedAabbCompression),
00046 m_ownsBvh(false)
00047 {
00048         m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
00049         //construct bvh from meshInterface
00050 #ifndef DISABLE_BVH
00051 
00052         if (buildBvh)
00053         {
00054                 void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
00055                 m_bvh = new (mem) btOptimizedBvh();
00056                 
00057                 m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
00058                 m_ownsBvh = true;
00059         }
00060 
00061 #endif //DISABLE_BVH
00062 
00063 }
00064 
00065 void    btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax)
00066 {
00067         m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax );
00068         
00069         m_localAabbMin.setMin(aabbMin);
00070         m_localAabbMax.setMax(aabbMax);
00071 }
00072 
00073 
00074 void    btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin,const btVector3& aabbMax)
00075 {
00076         m_bvh->refit( m_meshInterface, aabbMin,aabbMax );
00077         
00078         recalcLocalAabb();
00079 }
00080 
00081 btBvhTriangleMeshShape::~btBvhTriangleMeshShape()
00082 {
00083         if (m_ownsBvh)
00084         {
00085                 m_bvh->~btOptimizedBvh();
00086                 btAlignedFree(m_bvh);
00087         }
00088 }
00089 
00090 void    btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget)
00091 {
00092         struct  MyNodeOverlapCallback : public btNodeOverlapCallback
00093         {
00094                 btStridingMeshInterface*        m_meshInterface;
00095                 btTriangleCallback* m_callback;
00096 
00097                 MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
00098                         :m_meshInterface(meshInterface),
00099                         m_callback(callback)
00100                 {
00101                 }
00102                                 
00103                 virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
00104                 {
00105                         btVector3 m_triangle[3];
00106                         const unsigned char *vertexbase;
00107                         int numverts;
00108                         PHY_ScalarType type;
00109                         int stride;
00110                         const unsigned char *indexbase;
00111                         int indexstride;
00112                         int numfaces;
00113                         PHY_ScalarType indicestype;
00114 
00115                         m_meshInterface->getLockedReadOnlyVertexIndexBase(
00116                                 &vertexbase,
00117                                 numverts,
00118                                 type,
00119                                 stride,
00120                                 &indexbase,
00121                                 indexstride,
00122                                 numfaces,
00123                                 indicestype,
00124                                 nodeSubPart);
00125 
00126                         unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
00127                         btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
00128         
00129                         const btVector3& meshScaling = m_meshInterface->getScaling();
00130                         for (int j=2;j>=0;j--)
00131                         {
00132                                 int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
00133                                 
00134                                 if (type == PHY_FLOAT)
00135                                 {
00136                                         float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
00137                                         
00138                                         m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());            
00139                                 }
00140                                 else
00141                                 {
00142                                         double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
00143                                         
00144                                         m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());              
00145                                 }
00146                         }
00147 
00148                         /* Perform ray vs. triangle collision here */
00149                         m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
00150                         m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
00151                 }
00152         };
00153 
00154         MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface);
00155 
00156         m_bvh->reportRayOverlappingNodex(&myNodeCallback,raySource,rayTarget);
00157 }
00158 
00159 void    btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax)
00160 {
00161         struct  MyNodeOverlapCallback : public btNodeOverlapCallback
00162         {
00163                 btStridingMeshInterface*        m_meshInterface;
00164                 btTriangleCallback* m_callback;
00165 
00166                 MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
00167                         :m_meshInterface(meshInterface),
00168                         m_callback(callback)
00169                 {
00170                 }
00171                                 
00172                 virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
00173                 {
00174                         btVector3 m_triangle[3];
00175                         const unsigned char *vertexbase;
00176                         int numverts;
00177                         PHY_ScalarType type;
00178                         int stride;
00179                         const unsigned char *indexbase;
00180                         int indexstride;
00181                         int numfaces;
00182                         PHY_ScalarType indicestype;
00183 
00184                         m_meshInterface->getLockedReadOnlyVertexIndexBase(
00185                                 &vertexbase,
00186                                 numverts,
00187                                 type,
00188                                 stride,
00189                                 &indexbase,
00190                                 indexstride,
00191                                 numfaces,
00192                                 indicestype,
00193                                 nodeSubPart);
00194 
00195                         unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
00196                         btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
00197         
00198                         const btVector3& meshScaling = m_meshInterface->getScaling();
00199                         for (int j=2;j>=0;j--)
00200                         {
00201                                 int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
00202 
00203                                 if (type == PHY_FLOAT)
00204                                 {
00205                                         float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
00206 
00207                                         m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());            
00208                                 }
00209                                 else
00210                                 {
00211                                         double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
00212                                         
00213                                         m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());              
00214                                 }
00215                         }
00216 
00217                         /* Perform ray vs. triangle collision here */
00218                         m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
00219                         m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
00220                 }
00221         };
00222 
00223         MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface);
00224 
00225         m_bvh->reportBoxCastOverlappingNodex (&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax);
00226 }
00227 
00228 //perform bvh tree traversal and report overlapping triangles to 'callback'
00229 void    btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
00230 {
00231 
00232 #ifdef DISABLE_BVH
00233         //brute force traverse all triangles
00234         btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax);
00235 #else
00236 
00237         //first get all the nodes
00238 
00239         
00240         struct  MyNodeOverlapCallback : public btNodeOverlapCallback
00241         {
00242                 btStridingMeshInterface*        m_meshInterface;
00243                 btTriangleCallback*             m_callback;
00244                 btVector3                               m_triangle[3];
00245 
00246 
00247                 MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
00248                         :m_meshInterface(meshInterface),
00249                         m_callback(callback)
00250                 {
00251                 }
00252                                 
00253                 virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
00254                 {
00255                         const unsigned char *vertexbase;
00256                         int numverts;
00257                         PHY_ScalarType type;
00258                         int stride;
00259                         const unsigned char *indexbase;
00260                         int indexstride;
00261                         int numfaces;
00262                         PHY_ScalarType indicestype;
00263                         
00264 
00265                         m_meshInterface->getLockedReadOnlyVertexIndexBase(
00266                                 &vertexbase,
00267                                 numverts,
00268                                 type,
00269                                 stride,
00270                                 &indexbase,
00271                                 indexstride,
00272                                 numfaces,
00273                                 indicestype,
00274                                 nodeSubPart);
00275 
00276                         unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
00277                         btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
00278         
00279                         const btVector3& meshScaling = m_meshInterface->getScaling();
00280                         for (int j=2;j>=0;j--)
00281                         {
00282                                 
00283                                 int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
00284 
00285 
00286 #ifdef DEBUG_TRIANGLE_MESH
00287                                 printf("%d ,",graphicsindex);
00288 #endif //DEBUG_TRIANGLE_MESH
00289                                 if (type == PHY_FLOAT)
00290                                 {
00291                                         float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
00292                                         
00293                                         m_triangle[j] = btVector3(
00294                                                                                                                                                 graphicsbase[0]*meshScaling.getX(),
00295                                                                                                                                                 graphicsbase[1]*meshScaling.getY(),
00296                                                                                                                                                 graphicsbase[2]*meshScaling.getZ());
00297                                 }
00298                                 else
00299                                 {
00300                                         double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
00301 
00302                                         m_triangle[j] = btVector3(
00303                                                 btScalar(graphicsbase[0])*meshScaling.getX(),
00304                                                 btScalar(graphicsbase[1])*meshScaling.getY(),
00305                                                 btScalar(graphicsbase[2])*meshScaling.getZ());
00306                                 }
00307 #ifdef DEBUG_TRIANGLE_MESH
00308                                 printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
00309 #endif //DEBUG_TRIANGLE_MESH
00310                         }
00311 
00312                         m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
00313                         m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
00314                 }
00315 
00316         };
00317 
00318         MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface);
00319 
00320         m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
00321 
00322 
00323 #endif//DISABLE_BVH
00324 
00325 
00326 }
00327 
00328 void   btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
00329 {
00330    if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
00331    {
00332       btTriangleMeshShape::setLocalScaling(scaling);
00333           buildOptimizedBvh();
00334    }
00335 }
00336 
00337 void   btBvhTriangleMeshShape::buildOptimizedBvh()
00338 {
00339         if (m_ownsBvh)
00340         {
00341                 m_bvh->~btOptimizedBvh();
00342                 btAlignedFree(m_bvh);
00343         }
00345         void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
00346         m_bvh = new(mem) btOptimizedBvh();
00347         //rebuild the bvh...
00348         m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
00349         m_ownsBvh = true;
00350 }
00351 
00352 void   btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling)
00353 {
00354    btAssert(!m_bvh);
00355    btAssert(!m_ownsBvh);
00356 
00357    m_bvh = bvh;
00358    m_ownsBvh = false;
00359    // update the scaling without rebuilding the bvh
00360    if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
00361    {
00362       btTriangleMeshShape::setLocalScaling(scaling);
00363    }
00364 }
00365 
00366 

Generated on Mon Feb 15 22:17:02 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1