| [1963] | 1 | /* | 
|---|
|  | 2 | Bullet Continuous Collision Detection and Physics Library | 
|---|
| [8351] | 3 | Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org | 
|---|
| [1963] | 4 |  | 
|---|
|  | 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: | 
|---|
|  | 10 |  | 
|---|
|  | 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. | 
|---|
|  | 14 | */ | 
|---|
|  | 15 |  | 
|---|
|  | 16 | //#define DISABLE_BVH | 
|---|
|  | 17 |  | 
|---|
|  | 18 | #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" | 
|---|
|  | 19 | #include "BulletCollision/CollisionShapes/btOptimizedBvh.h" | 
|---|
| [8351] | 20 | #include "LinearMath/btSerializer.h" | 
|---|
| [1963] | 21 |  | 
|---|
|  | 22 | ///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. | 
|---|
|  | 23 | ///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. | 
|---|
|  | 24 | btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh) | 
|---|
|  | 25 | :btTriangleMeshShape(meshInterface), | 
|---|
|  | 26 | m_bvh(0), | 
|---|
| [8351] | 27 | m_triangleInfoMap(0), | 
|---|
| [1963] | 28 | m_useQuantizedAabbCompression(useQuantizedAabbCompression), | 
|---|
|  | 29 | m_ownsBvh(false) | 
|---|
|  | 30 | { | 
|---|
|  | 31 | m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; | 
|---|
|  | 32 | //construct bvh from meshInterface | 
|---|
|  | 33 | #ifndef DISABLE_BVH | 
|---|
|  | 34 |  | 
|---|
|  | 35 | if (buildBvh) | 
|---|
|  | 36 | { | 
|---|
| [8351] | 37 | buildOptimizedBvh(); | 
|---|
| [1963] | 38 | } | 
|---|
|  | 39 |  | 
|---|
|  | 40 | #endif //DISABLE_BVH | 
|---|
|  | 41 |  | 
|---|
|  | 42 | } | 
|---|
|  | 43 |  | 
|---|
|  | 44 | btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh) | 
|---|
|  | 45 | :btTriangleMeshShape(meshInterface), | 
|---|
|  | 46 | m_bvh(0), | 
|---|
| [8351] | 47 | m_triangleInfoMap(0), | 
|---|
| [1963] | 48 | m_useQuantizedAabbCompression(useQuantizedAabbCompression), | 
|---|
|  | 49 | m_ownsBvh(false) | 
|---|
|  | 50 | { | 
|---|
|  | 51 | m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; | 
|---|
|  | 52 | //construct bvh from meshInterface | 
|---|
|  | 53 | #ifndef DISABLE_BVH | 
|---|
|  | 54 |  | 
|---|
|  | 55 | if (buildBvh) | 
|---|
|  | 56 | { | 
|---|
|  | 57 | void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); | 
|---|
|  | 58 | m_bvh = new (mem) btOptimizedBvh(); | 
|---|
|  | 59 |  | 
|---|
|  | 60 | m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); | 
|---|
|  | 61 | m_ownsBvh = true; | 
|---|
|  | 62 | } | 
|---|
|  | 63 |  | 
|---|
|  | 64 | #endif //DISABLE_BVH | 
|---|
|  | 65 |  | 
|---|
|  | 66 | } | 
|---|
|  | 67 |  | 
|---|
|  | 68 | void    btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax) | 
|---|
|  | 69 | { | 
|---|
|  | 70 | m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax ); | 
|---|
|  | 71 |  | 
|---|
|  | 72 | m_localAabbMin.setMin(aabbMin); | 
|---|
|  | 73 | m_localAabbMax.setMax(aabbMax); | 
|---|
|  | 74 | } | 
|---|
|  | 75 |  | 
|---|
|  | 76 |  | 
|---|
|  | 77 | void    btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin,const btVector3& aabbMax) | 
|---|
|  | 78 | { | 
|---|
|  | 79 | m_bvh->refit( m_meshInterface, aabbMin,aabbMax ); | 
|---|
|  | 80 |  | 
|---|
|  | 81 | recalcLocalAabb(); | 
|---|
|  | 82 | } | 
|---|
|  | 83 |  | 
|---|
|  | 84 | btBvhTriangleMeshShape::~btBvhTriangleMeshShape() | 
|---|
|  | 85 | { | 
|---|
|  | 86 | if (m_ownsBvh) | 
|---|
|  | 87 | { | 
|---|
|  | 88 | m_bvh->~btOptimizedBvh(); | 
|---|
|  | 89 | btAlignedFree(m_bvh); | 
|---|
|  | 90 | } | 
|---|
|  | 91 | } | 
|---|
|  | 92 |  | 
|---|
|  | 93 | void    btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget) | 
|---|
|  | 94 | { | 
|---|
|  | 95 | struct  MyNodeOverlapCallback : public btNodeOverlapCallback | 
|---|
|  | 96 | { | 
|---|
|  | 97 | btStridingMeshInterface*        m_meshInterface; | 
|---|
|  | 98 | btTriangleCallback* m_callback; | 
|---|
|  | 99 |  | 
|---|
|  | 100 | MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) | 
|---|
|  | 101 | :m_meshInterface(meshInterface), | 
|---|
|  | 102 | m_callback(callback) | 
|---|
|  | 103 | { | 
|---|
|  | 104 | } | 
|---|
|  | 105 |  | 
|---|
|  | 106 | virtual void processNode(int nodeSubPart, int nodeTriangleIndex) | 
|---|
|  | 107 | { | 
|---|
|  | 108 | btVector3 m_triangle[3]; | 
|---|
|  | 109 | const unsigned char *vertexbase; | 
|---|
|  | 110 | int numverts; | 
|---|
|  | 111 | PHY_ScalarType type; | 
|---|
|  | 112 | int stride; | 
|---|
|  | 113 | const unsigned char *indexbase; | 
|---|
|  | 114 | int indexstride; | 
|---|
|  | 115 | int numfaces; | 
|---|
|  | 116 | PHY_ScalarType indicestype; | 
|---|
|  | 117 |  | 
|---|
|  | 118 | m_meshInterface->getLockedReadOnlyVertexIndexBase( | 
|---|
|  | 119 | &vertexbase, | 
|---|
|  | 120 | numverts, | 
|---|
|  | 121 | type, | 
|---|
|  | 122 | stride, | 
|---|
|  | 123 | &indexbase, | 
|---|
|  | 124 | indexstride, | 
|---|
|  | 125 | numfaces, | 
|---|
|  | 126 | indicestype, | 
|---|
|  | 127 | nodeSubPart); | 
|---|
|  | 128 |  | 
|---|
|  | 129 | unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); | 
|---|
|  | 130 | btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); | 
|---|
|  | 131 |  | 
|---|
|  | 132 | const btVector3& meshScaling = m_meshInterface->getScaling(); | 
|---|
|  | 133 | for (int j=2;j>=0;j--) | 
|---|
|  | 134 | { | 
|---|
|  | 135 | int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; | 
|---|
| [2430] | 136 |  | 
|---|
|  | 137 | if (type == PHY_FLOAT) | 
|---|
|  | 138 | { | 
|---|
|  | 139 | float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); | 
|---|
|  | 140 |  | 
|---|
|  | 141 | m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); | 
|---|
|  | 142 | } | 
|---|
|  | 143 | else | 
|---|
|  | 144 | { | 
|---|
|  | 145 | double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); | 
|---|
|  | 146 |  | 
|---|
|  | 147 | m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ()); | 
|---|
|  | 148 | } | 
|---|
| [1963] | 149 | } | 
|---|
|  | 150 |  | 
|---|
|  | 151 | /* Perform ray vs. triangle collision here */ | 
|---|
|  | 152 | m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); | 
|---|
|  | 153 | m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); | 
|---|
|  | 154 | } | 
|---|
|  | 155 | }; | 
|---|
|  | 156 |  | 
|---|
|  | 157 | MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface); | 
|---|
|  | 158 |  | 
|---|
|  | 159 | m_bvh->reportRayOverlappingNodex(&myNodeCallback,raySource,rayTarget); | 
|---|
|  | 160 | } | 
|---|
|  | 161 |  | 
|---|
|  | 162 | void    btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax) | 
|---|
|  | 163 | { | 
|---|
|  | 164 | struct  MyNodeOverlapCallback : public btNodeOverlapCallback | 
|---|
|  | 165 | { | 
|---|
|  | 166 | btStridingMeshInterface*        m_meshInterface; | 
|---|
|  | 167 | btTriangleCallback* m_callback; | 
|---|
|  | 168 |  | 
|---|
|  | 169 | MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) | 
|---|
|  | 170 | :m_meshInterface(meshInterface), | 
|---|
|  | 171 | m_callback(callback) | 
|---|
|  | 172 | { | 
|---|
|  | 173 | } | 
|---|
|  | 174 |  | 
|---|
|  | 175 | virtual void processNode(int nodeSubPart, int nodeTriangleIndex) | 
|---|
|  | 176 | { | 
|---|
|  | 177 | btVector3 m_triangle[3]; | 
|---|
|  | 178 | const unsigned char *vertexbase; | 
|---|
|  | 179 | int numverts; | 
|---|
|  | 180 | PHY_ScalarType type; | 
|---|
|  | 181 | int stride; | 
|---|
|  | 182 | const unsigned char *indexbase; | 
|---|
|  | 183 | int indexstride; | 
|---|
|  | 184 | int numfaces; | 
|---|
|  | 185 | PHY_ScalarType indicestype; | 
|---|
|  | 186 |  | 
|---|
|  | 187 | m_meshInterface->getLockedReadOnlyVertexIndexBase( | 
|---|
|  | 188 | &vertexbase, | 
|---|
|  | 189 | numverts, | 
|---|
|  | 190 | type, | 
|---|
|  | 191 | stride, | 
|---|
|  | 192 | &indexbase, | 
|---|
|  | 193 | indexstride, | 
|---|
|  | 194 | numfaces, | 
|---|
|  | 195 | indicestype, | 
|---|
|  | 196 | nodeSubPart); | 
|---|
|  | 197 |  | 
|---|
|  | 198 | unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); | 
|---|
|  | 199 | btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); | 
|---|
|  | 200 |  | 
|---|
|  | 201 | const btVector3& meshScaling = m_meshInterface->getScaling(); | 
|---|
|  | 202 | for (int j=2;j>=0;j--) | 
|---|
|  | 203 | { | 
|---|
|  | 204 | int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; | 
|---|
|  | 205 |  | 
|---|
| [2430] | 206 | if (type == PHY_FLOAT) | 
|---|
|  | 207 | { | 
|---|
|  | 208 | float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); | 
|---|
| [1963] | 209 |  | 
|---|
| [2430] | 210 | m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); | 
|---|
|  | 211 | } | 
|---|
|  | 212 | else | 
|---|
|  | 213 | { | 
|---|
|  | 214 | double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); | 
|---|
|  | 215 |  | 
|---|
|  | 216 | m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ()); | 
|---|
|  | 217 | } | 
|---|
| [1963] | 218 | } | 
|---|
|  | 219 |  | 
|---|
|  | 220 | /* Perform ray vs. triangle collision here */ | 
|---|
|  | 221 | m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); | 
|---|
|  | 222 | m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); | 
|---|
|  | 223 | } | 
|---|
|  | 224 | }; | 
|---|
|  | 225 |  | 
|---|
|  | 226 | MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface); | 
|---|
|  | 227 |  | 
|---|
|  | 228 | m_bvh->reportBoxCastOverlappingNodex (&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax); | 
|---|
|  | 229 | } | 
|---|
|  | 230 |  | 
|---|
|  | 231 | //perform bvh tree traversal and report overlapping triangles to 'callback' | 
|---|
|  | 232 | void    btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const | 
|---|
|  | 233 | { | 
|---|
|  | 234 |  | 
|---|
|  | 235 | #ifdef DISABLE_BVH | 
|---|
|  | 236 | //brute force traverse all triangles | 
|---|
|  | 237 | btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax); | 
|---|
|  | 238 | #else | 
|---|
|  | 239 |  | 
|---|
|  | 240 | //first get all the nodes | 
|---|
|  | 241 |  | 
|---|
|  | 242 |  | 
|---|
|  | 243 | struct  MyNodeOverlapCallback : public btNodeOverlapCallback | 
|---|
|  | 244 | { | 
|---|
|  | 245 | btStridingMeshInterface*        m_meshInterface; | 
|---|
|  | 246 | btTriangleCallback*             m_callback; | 
|---|
|  | 247 | btVector3                               m_triangle[3]; | 
|---|
|  | 248 |  | 
|---|
|  | 249 |  | 
|---|
|  | 250 | MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) | 
|---|
|  | 251 | :m_meshInterface(meshInterface), | 
|---|
|  | 252 | m_callback(callback) | 
|---|
|  | 253 | { | 
|---|
|  | 254 | } | 
|---|
|  | 255 |  | 
|---|
|  | 256 | virtual void processNode(int nodeSubPart, int nodeTriangleIndex) | 
|---|
|  | 257 | { | 
|---|
|  | 258 | const unsigned char *vertexbase; | 
|---|
|  | 259 | int numverts; | 
|---|
|  | 260 | PHY_ScalarType type; | 
|---|
|  | 261 | int stride; | 
|---|
|  | 262 | const unsigned char *indexbase; | 
|---|
|  | 263 | int indexstride; | 
|---|
|  | 264 | int numfaces; | 
|---|
|  | 265 | PHY_ScalarType indicestype; | 
|---|
|  | 266 |  | 
|---|
|  | 267 |  | 
|---|
|  | 268 | m_meshInterface->getLockedReadOnlyVertexIndexBase( | 
|---|
|  | 269 | &vertexbase, | 
|---|
|  | 270 | numverts, | 
|---|
|  | 271 | type, | 
|---|
|  | 272 | stride, | 
|---|
|  | 273 | &indexbase, | 
|---|
|  | 274 | indexstride, | 
|---|
|  | 275 | numfaces, | 
|---|
|  | 276 | indicestype, | 
|---|
|  | 277 | nodeSubPart); | 
|---|
|  | 278 |  | 
|---|
|  | 279 | unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); | 
|---|
|  | 280 | btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); | 
|---|
|  | 281 |  | 
|---|
|  | 282 | const btVector3& meshScaling = m_meshInterface->getScaling(); | 
|---|
|  | 283 | for (int j=2;j>=0;j--) | 
|---|
|  | 284 | { | 
|---|
|  | 285 |  | 
|---|
|  | 286 | int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; | 
|---|
|  | 287 |  | 
|---|
|  | 288 |  | 
|---|
|  | 289 | #ifdef DEBUG_TRIANGLE_MESH | 
|---|
|  | 290 | printf("%d ,",graphicsindex); | 
|---|
|  | 291 | #endif //DEBUG_TRIANGLE_MESH | 
|---|
| [2430] | 292 | if (type == PHY_FLOAT) | 
|---|
|  | 293 | { | 
|---|
|  | 294 | float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); | 
|---|
|  | 295 |  | 
|---|
|  | 296 | m_triangle[j] = btVector3( | 
|---|
|  | 297 | graphicsbase[0]*meshScaling.getX(), | 
|---|
|  | 298 | graphicsbase[1]*meshScaling.getY(), | 
|---|
|  | 299 | graphicsbase[2]*meshScaling.getZ()); | 
|---|
|  | 300 | } | 
|---|
|  | 301 | else | 
|---|
|  | 302 | { | 
|---|
|  | 303 | double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); | 
|---|
| [1963] | 304 |  | 
|---|
| [2430] | 305 | m_triangle[j] = btVector3( | 
|---|
|  | 306 | btScalar(graphicsbase[0])*meshScaling.getX(), | 
|---|
|  | 307 | btScalar(graphicsbase[1])*meshScaling.getY(), | 
|---|
|  | 308 | btScalar(graphicsbase[2])*meshScaling.getZ()); | 
|---|
|  | 309 | } | 
|---|
| [1963] | 310 | #ifdef DEBUG_TRIANGLE_MESH | 
|---|
|  | 311 | printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z()); | 
|---|
|  | 312 | #endif //DEBUG_TRIANGLE_MESH | 
|---|
|  | 313 | } | 
|---|
|  | 314 |  | 
|---|
|  | 315 | m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); | 
|---|
|  | 316 | m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); | 
|---|
|  | 317 | } | 
|---|
|  | 318 |  | 
|---|
|  | 319 | }; | 
|---|
|  | 320 |  | 
|---|
|  | 321 | MyNodeOverlapCallback   myNodeCallback(callback,m_meshInterface); | 
|---|
|  | 322 |  | 
|---|
|  | 323 | m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); | 
|---|
|  | 324 |  | 
|---|
|  | 325 |  | 
|---|
|  | 326 | #endif//DISABLE_BVH | 
|---|
|  | 327 |  | 
|---|
|  | 328 |  | 
|---|
|  | 329 | } | 
|---|
|  | 330 |  | 
|---|
|  | 331 | void   btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) | 
|---|
|  | 332 | { | 
|---|
|  | 333 | if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) | 
|---|
|  | 334 | { | 
|---|
|  | 335 | btTriangleMeshShape::setLocalScaling(scaling); | 
|---|
| [8351] | 336 | buildOptimizedBvh(); | 
|---|
| [1963] | 337 | } | 
|---|
|  | 338 | } | 
|---|
|  | 339 |  | 
|---|
| [8351] | 340 | void   btBvhTriangleMeshShape::buildOptimizedBvh() | 
|---|
|  | 341 | { | 
|---|
|  | 342 | if (m_ownsBvh) | 
|---|
|  | 343 | { | 
|---|
|  | 344 | m_bvh->~btOptimizedBvh(); | 
|---|
|  | 345 | btAlignedFree(m_bvh); | 
|---|
|  | 346 | } | 
|---|
|  | 347 | ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work | 
|---|
|  | 348 | void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); | 
|---|
|  | 349 | m_bvh = new(mem) btOptimizedBvh(); | 
|---|
|  | 350 | //rebuild the bvh... | 
|---|
|  | 351 | m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax); | 
|---|
|  | 352 | m_ownsBvh = true; | 
|---|
|  | 353 | } | 
|---|
|  | 354 |  | 
|---|
| [1963] | 355 | void   btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling) | 
|---|
|  | 356 | { | 
|---|
|  | 357 | btAssert(!m_bvh); | 
|---|
|  | 358 | btAssert(!m_ownsBvh); | 
|---|
|  | 359 |  | 
|---|
|  | 360 | m_bvh = bvh; | 
|---|
|  | 361 | m_ownsBvh = false; | 
|---|
|  | 362 | // update the scaling without rebuilding the bvh | 
|---|
|  | 363 | if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) | 
|---|
|  | 364 | { | 
|---|
|  | 365 | btTriangleMeshShape::setLocalScaling(scaling); | 
|---|
|  | 366 | } | 
|---|
|  | 367 | } | 
|---|
|  | 368 |  | 
|---|
|  | 369 |  | 
|---|
| [8351] | 370 |  | 
|---|
|  | 371 | ///fills the dataBuffer and returns the struct name (and 0 on failure) | 
|---|
|  | 372 | const char*     btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const | 
|---|
|  | 373 | { | 
|---|
|  | 374 | btTriangleMeshShapeData* trimeshData = (btTriangleMeshShapeData*) dataBuffer; | 
|---|
|  | 375 |  | 
|---|
|  | 376 | btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer); | 
|---|
|  | 377 |  | 
|---|
|  | 378 | m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer); | 
|---|
|  | 379 |  | 
|---|
|  | 380 | trimeshData->m_collisionMargin = float(m_collisionMargin); | 
|---|
|  | 381 |  | 
|---|
|  | 382 |  | 
|---|
|  | 383 |  | 
|---|
|  | 384 | if (m_bvh && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_BVH)) | 
|---|
|  | 385 | { | 
|---|
|  | 386 | void* chunk = serializer->findPointer(m_bvh); | 
|---|
|  | 387 | if (chunk) | 
|---|
|  | 388 | { | 
|---|
|  | 389 | #ifdef BT_USE_DOUBLE_PRECISION | 
|---|
|  | 390 | trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)chunk; | 
|---|
|  | 391 | trimeshData->m_quantizedFloatBvh = 0; | 
|---|
|  | 392 | #else | 
|---|
|  | 393 | trimeshData->m_quantizedFloatBvh  = (btQuantizedBvhData*)chunk; | 
|---|
|  | 394 | trimeshData->m_quantizedDoubleBvh= 0; | 
|---|
|  | 395 | #endif //BT_USE_DOUBLE_PRECISION | 
|---|
|  | 396 | } else | 
|---|
|  | 397 | { | 
|---|
|  | 398 |  | 
|---|
|  | 399 | #ifdef BT_USE_DOUBLE_PRECISION | 
|---|
|  | 400 | trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh); | 
|---|
|  | 401 | trimeshData->m_quantizedFloatBvh = 0; | 
|---|
|  | 402 | #else | 
|---|
|  | 403 | trimeshData->m_quantizedFloatBvh  = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh); | 
|---|
|  | 404 | trimeshData->m_quantizedDoubleBvh= 0; | 
|---|
|  | 405 | #endif //BT_USE_DOUBLE_PRECISION | 
|---|
|  | 406 |  | 
|---|
|  | 407 | int sz = m_bvh->calculateSerializeBufferSizeNew(); | 
|---|
|  | 408 | btChunk* chunk = serializer->allocate(sz,1); | 
|---|
|  | 409 | const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer); | 
|---|
|  | 410 | serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,m_bvh); | 
|---|
|  | 411 | } | 
|---|
|  | 412 | } else | 
|---|
|  | 413 | { | 
|---|
|  | 414 | trimeshData->m_quantizedFloatBvh = 0; | 
|---|
|  | 415 | trimeshData->m_quantizedDoubleBvh = 0; | 
|---|
|  | 416 | } | 
|---|
|  | 417 |  | 
|---|
|  | 418 |  | 
|---|
|  | 419 |  | 
|---|
|  | 420 | if (m_triangleInfoMap && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_TRIANGLEINFOMAP)) | 
|---|
|  | 421 | { | 
|---|
|  | 422 | void* chunk = serializer->findPointer(m_triangleInfoMap); | 
|---|
|  | 423 | if (chunk) | 
|---|
|  | 424 | { | 
|---|
|  | 425 | trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)chunk; | 
|---|
|  | 426 | } else | 
|---|
|  | 427 | { | 
|---|
|  | 428 | trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)serializer->getUniquePointer(m_triangleInfoMap); | 
|---|
|  | 429 | int sz = m_triangleInfoMap->calculateSerializeBufferSize(); | 
|---|
|  | 430 | btChunk* chunk = serializer->allocate(sz,1); | 
|---|
|  | 431 | const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer); | 
|---|
|  | 432 | serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,m_triangleInfoMap); | 
|---|
|  | 433 | } | 
|---|
|  | 434 | } else | 
|---|
|  | 435 | { | 
|---|
|  | 436 | trimeshData->m_triangleInfoMap = 0; | 
|---|
|  | 437 | } | 
|---|
|  | 438 |  | 
|---|
|  | 439 | return "btTriangleMeshShapeData"; | 
|---|
|  | 440 | } | 
|---|
|  | 441 |  | 
|---|
|  | 442 | void    btBvhTriangleMeshShape::serializeSingleBvh(btSerializer* serializer) const | 
|---|
|  | 443 | { | 
|---|
|  | 444 | if (m_bvh) | 
|---|
|  | 445 | { | 
|---|
|  | 446 | int len = m_bvh->calculateSerializeBufferSizeNew(); //make sure not to use calculateSerializeBufferSize because it is used for in-place | 
|---|
|  | 447 | btChunk* chunk = serializer->allocate(len,1); | 
|---|
|  | 448 | const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer); | 
|---|
|  | 449 | serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,(void*)m_bvh); | 
|---|
|  | 450 | } | 
|---|
|  | 451 | } | 
|---|
|  | 452 |  | 
|---|
|  | 453 | void    btBvhTriangleMeshShape::serializeSingleTriangleInfoMap(btSerializer* serializer) const | 
|---|
|  | 454 | { | 
|---|
|  | 455 | if (m_triangleInfoMap) | 
|---|
|  | 456 | { | 
|---|
|  | 457 | int len = m_triangleInfoMap->calculateSerializeBufferSize(); | 
|---|
|  | 458 | btChunk* chunk = serializer->allocate(len,1); | 
|---|
|  | 459 | const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer); | 
|---|
|  | 460 | serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,(void*)m_triangleInfoMap); | 
|---|
|  | 461 | } | 
|---|
|  | 462 | } | 
|---|
|  | 463 |  | 
|---|
|  | 464 |  | 
|---|
|  | 465 |  | 
|---|
|  | 466 |  | 
|---|