diff --git a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp index eea263fe5..a390cc73b 100644 --- a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp @@ -141,12 +141,13 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co nodeSubPart); int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride); + btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); const btVector3& meshScaling = m_meshInterface->getScaling(); for (int j=2;j>=0;j--) { - int graphicsindex = gfxbase[j]; + int graphicsindex = indicestype==PHY_SHORT?((short*)gfxbase)[j]:gfxbase[j]; #ifdef DEBUG_TRIANGLE_MESH diff --git a/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp b/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp index e80469f45..bd264f76f 100644 --- a/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp +++ b/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp @@ -95,7 +95,9 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) { - btAssert(partId==0); + // The partId and triangle index must fit in the same (positive) integer + btAssert(partId < (1<=0); @@ -132,7 +134,7 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMin[0],aabbMin); m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMax[0],aabbMax); - node.m_escapeIndexOrTriangleIndex = triangleIndex; + node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; m_triangleNodes.push_back(node); } @@ -256,7 +258,7 @@ void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int f btAssert(m_useQuantization); - int nodeSubPart=0; + int curNodeSubPart=-1; //get access info to trianglemesh data const unsigned char *vertexbase; @@ -267,7 +269,6 @@ void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int f int indexstride; int numfaces; PHY_ScalarType indicestype; - meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart); btVector3 triangleVerts[3]; btVector3 aabbMin,aabbMax; @@ -282,7 +283,15 @@ void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int f if (curNode.isLeafNode()) { //recalc aabb from triangle data + int nodeSubPart = curNode.getPartId(); int nodeTriangleIndex = curNode.getTriangleIndex(); + if (nodeSubPart != curNodeSubPart) + { + if (curNodeSubPart >= 0) + meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); + meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart); + btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); + } //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride); @@ -291,7 +300,7 @@ void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int f for (int j=2;j>=0;j--) { - int graphicsindex = gfxbase[j]; + int graphicsindex = indicestype==PHY_SHORT?((short*)gfxbase)[j]:gfxbase[j]; btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); #ifdef DEBUG_PATCH_COLORS btVector3 mycolor = color[index&3]; @@ -347,7 +356,8 @@ void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int f } - meshInterface->unLockReadOnlyVertexBase(nodeSubPart); + if (curNodeSubPart >= 0) + meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); } @@ -713,7 +723,7 @@ void btOptimizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantize { if (isLeafNode) { - nodeCallback->processNode(0,currentNode->getTriangleIndex()); + nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex()); } else { //process left and right children @@ -776,7 +786,7 @@ void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb if (isLeafNode && aabbOverlap) { - nodeCallback->processNode(0,rootNode->getTriangleIndex()); + nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex()); } //PCK: unsigned instead of bool diff --git a/src/BulletCollision/CollisionShapes/btOptimizedBvh.h b/src/BulletCollision/CollisionShapes/btOptimizedBvh.h index bcacdbe58..6f9ec2d83 100644 --- a/src/BulletCollision/CollisionShapes/btOptimizedBvh.h +++ b/src/BulletCollision/CollisionShapes/btOptimizedBvh.h @@ -31,6 +31,9 @@ class btStridingMeshInterface; //Note: currently we have 16 bytes per quantized node #define MAX_SUBTREE_SIZE_IN_BYTES 2048 +// 10 gives the potential for 1024 parts, with at most 2^21 (2097152) (minus one +// actually) triangles each (since the sign bit is reserved +#define MAX_NUM_PARTS_IN_BITS 10 ///btQuantizedBvhNode is a compressed aabb node, 16 bytes. ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). @@ -57,7 +60,14 @@ ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode int getTriangleIndex() const { btAssert(isLeafNode()); - return m_escapeIndexOrTriangleIndex; + // Get only the lower bits where the triangle index is stored + return (m_escapeIndexOrTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS))); + } + int getPartId() const + { + btAssert(isLeafNode()); + // Get only the highest bits where the part index is stored + return (m_escapeIndexOrTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS)); } } ; diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp index 554915a70..f4f938161 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp @@ -54,7 +54,7 @@ void btTriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char **vertex (*indexbase) = (unsigned char *)mesh.m_triangleIndexBase; indexstride = mesh.m_triangleIndexStride; - indicestype = PHY_INTEGER; + indicestype = mesh.m_indexType; } void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const @@ -73,6 +73,6 @@ void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned numfaces = mesh.m_numTriangles; (*indexbase) = (const unsigned char *)mesh.m_triangleIndexBase; indexstride = mesh.m_triangleIndexStride; - indicestype = PHY_INTEGER; + indicestype = mesh.m_indexType; } diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h index 3441a8325..0d09a23cc 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h @@ -34,7 +34,10 @@ ATTRIBUTE_ALIGNED16( struct) btIndexedMesh int m_numVertices; const unsigned char * m_vertexBase; int m_vertexStride; - int pad[2]; + // The index type is set when adding an indexed mesh to the + // btTriangleIndexVertexArray, do not set it manually + PHY_ScalarType m_indexType; + int pad; } ; @@ -64,9 +67,10 @@ public: //just to be backwards compatible btTriangleIndexVertexArray(int numTriangleIndices,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride); - void addIndexedMesh(const btIndexedMesh& mesh) + void addIndexedMesh(const btIndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER) { m_indexedMeshes.push_back(mesh); + m_indexedMeshes[m_indexedMeshes.size()-1].m_indexType = indexType; }