Changeset View
Changeset View
Standalone View
Standalone View
extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
| /* | /* | ||||
| Bullet Continuous Collision Detection and Physics Library | Bullet Continuous Collision Detection and Physics Library | ||||
| Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org | Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org | ||||
| This software is provided 'as-is', without any express or implied warranty. | This software is provided 'as-is', without any express or implied warranty. | ||||
| In no event will the authors be held liable for any damages arising from the use of this software. | In no event will the authors be held liable for any damages arising from the use of this software. | ||||
| Permission is granted to anyone to use this software for any purpose, | Permission is granted to anyone to use this software for any purpose, | ||||
| including commercial applications, and to alter it and redistribute it freely, | including commercial applications, and to alter it and redistribute it freely, | ||||
| subject to the following restrictions: | subject to the following restrictions: | ||||
| 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. | 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. | ||||
| 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | ||||
| 3. This notice may not be removed or altered from any source distribution. | 3. This notice may not be removed or altered from any source distribution. | ||||
| */ | */ | ||||
| #include "btOptimizedBvh.h" | #include "btOptimizedBvh.h" | ||||
| #include "btStridingMeshInterface.h" | #include "btStridingMeshInterface.h" | ||||
| #include "LinearMath/btAabbUtil2.h" | #include "LinearMath/btAabbUtil2.h" | ||||
| #include "LinearMath/btIDebugDraw.h" | #include "LinearMath/btIDebugDraw.h" | ||||
| btOptimizedBvh::btOptimizedBvh() | btOptimizedBvh::btOptimizedBvh() | ||||
| { | { | ||||
| } | } | ||||
| btOptimizedBvh::~btOptimizedBvh() | btOptimizedBvh::~btOptimizedBvh() | ||||
| { | { | ||||
| } | } | ||||
| void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax) | void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax) | ||||
| { | { | ||||
| m_useQuantization = useQuantizedAabbCompression; | m_useQuantization = useQuantizedAabbCompression; | ||||
| // NodeArray triangleNodes; | // NodeArray triangleNodes; | ||||
| struct NodeTriangleCallback : public btInternalTriangleIndexCallback | struct NodeTriangleCallback : public btInternalTriangleIndexCallback | ||||
| { | { | ||||
| NodeArray& m_triangleNodes; | NodeArray& m_triangleNodes; | ||||
| NodeTriangleCallback& operator=(NodeTriangleCallback& other) | NodeTriangleCallback& operator=(NodeTriangleCallback& other) | ||||
| { | { | ||||
| m_triangleNodes.copyFromArray(other.m_triangleNodes); | m_triangleNodes.copyFromArray(other.m_triangleNodes); | ||||
| return *this; | return *this; | ||||
| } | } | ||||
| NodeTriangleCallback(NodeArray& triangleNodes) | NodeTriangleCallback(NodeArray& triangleNodes) | ||||
| :m_triangleNodes(triangleNodes) | : m_triangleNodes(triangleNodes) | ||||
| { | { | ||||
| } | } | ||||
| virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) | virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) | ||||
| { | { | ||||
| btOptimizedBvhNode node; | btOptimizedBvhNode node; | ||||
| btVector3 aabbMin,aabbMax; | btVector3 aabbMin, aabbMax; | ||||
| aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); | aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); | ||||
| aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); | aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); | ||||
| aabbMin.setMin(triangle[0]); | aabbMin.setMin(triangle[0]); | ||||
| aabbMax.setMax(triangle[0]); | aabbMax.setMax(triangle[0]); | ||||
| aabbMin.setMin(triangle[1]); | aabbMin.setMin(triangle[1]); | ||||
| aabbMax.setMax(triangle[1]); | aabbMax.setMax(triangle[1]); | ||||
| aabbMin.setMin(triangle[2]); | aabbMin.setMin(triangle[2]); | ||||
| aabbMax.setMax(triangle[2]); | aabbMax.setMax(triangle[2]); | ||||
| //with quantization? | //with quantization? | ||||
| node.m_aabbMinOrg = aabbMin; | node.m_aabbMinOrg = aabbMin; | ||||
| node.m_aabbMaxOrg = aabbMax; | node.m_aabbMaxOrg = aabbMax; | ||||
| node.m_escapeIndex = -1; | node.m_escapeIndex = -1; | ||||
| //for child nodes | //for child nodes | ||||
| node.m_subPart = partId; | node.m_subPart = partId; | ||||
| node.m_triangleIndex = triangleIndex; | node.m_triangleIndex = triangleIndex; | ||||
| m_triangleNodes.push_back(node); | m_triangleNodes.push_back(node); | ||||
| } | } | ||||
| }; | }; | ||||
| struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback | struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback | ||||
| { | { | ||||
| QuantizedNodeArray& m_triangleNodes; | QuantizedNodeArray& m_triangleNodes; | ||||
| const btQuantizedBvh* m_optimizedTree; // for quantization | const btQuantizedBvh* m_optimizedTree; // for quantization | ||||
| QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other) | QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other) | ||||
| { | { | ||||
| m_triangleNodes.copyFromArray(other.m_triangleNodes); | m_triangleNodes.copyFromArray(other.m_triangleNodes); | ||||
| m_optimizedTree = other.m_optimizedTree; | m_optimizedTree = other.m_optimizedTree; | ||||
| return *this; | return *this; | ||||
| } | } | ||||
| QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const btQuantizedBvh* tree) | QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes, const btQuantizedBvh* tree) | ||||
| :m_triangleNodes(triangleNodes),m_optimizedTree(tree) | : m_triangleNodes(triangleNodes), m_optimizedTree(tree) | ||||
| { | { | ||||
| } | } | ||||
| virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) | virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) | ||||
| { | { | ||||
| // The partId and triangle index must fit in the same (positive) integer | // The partId and triangle index must fit in the same (positive) integer | ||||
| btAssert(partId < (1<<MAX_NUM_PARTS_IN_BITS)); | btAssert(partId < (1 << MAX_NUM_PARTS_IN_BITS)); | ||||
| btAssert(triangleIndex < (1<<(31-MAX_NUM_PARTS_IN_BITS))); | btAssert(triangleIndex < (1 << (31 - MAX_NUM_PARTS_IN_BITS))); | ||||
| //negative indices are reserved for escapeIndex | //negative indices are reserved for escapeIndex | ||||
| btAssert(triangleIndex>=0); | btAssert(triangleIndex >= 0); | ||||
| btQuantizedBvhNode node; | btQuantizedBvhNode node; | ||||
| btVector3 aabbMin,aabbMax; | btVector3 aabbMin, aabbMax; | ||||
| aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); | aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); | ||||
| aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); | aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); | ||||
| aabbMin.setMin(triangle[0]); | aabbMin.setMin(triangle[0]); | ||||
| aabbMax.setMax(triangle[0]); | aabbMax.setMax(triangle[0]); | ||||
| aabbMin.setMin(triangle[1]); | aabbMin.setMin(triangle[1]); | ||||
| aabbMax.setMax(triangle[1]); | aabbMax.setMax(triangle[1]); | ||||
| aabbMin.setMin(triangle[2]); | aabbMin.setMin(triangle[2]); | ||||
| aabbMax.setMax(triangle[2]); | aabbMax.setMax(triangle[2]); | ||||
| //PCK: add these checks for zero dimensions of aabb | //PCK: add these checks for zero dimensions of aabb | ||||
| Show All 10 Lines | virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) | ||||
| aabbMin.setY(aabbMin.y() - MIN_AABB_HALF_DIMENSION); | aabbMin.setY(aabbMin.y() - MIN_AABB_HALF_DIMENSION); | ||||
| } | } | ||||
| if (aabbMax.z() - aabbMin.z() < MIN_AABB_DIMENSION) | if (aabbMax.z() - aabbMin.z() < MIN_AABB_DIMENSION) | ||||
| { | { | ||||
| aabbMax.setZ(aabbMax.z() + MIN_AABB_HALF_DIMENSION); | aabbMax.setZ(aabbMax.z() + MIN_AABB_HALF_DIMENSION); | ||||
| aabbMin.setZ(aabbMin.z() - MIN_AABB_HALF_DIMENSION); | aabbMin.setZ(aabbMin.z() - MIN_AABB_HALF_DIMENSION); | ||||
| } | } | ||||
| m_optimizedTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0); | m_optimizedTree->quantize(&node.m_quantizedAabbMin[0], aabbMin, 0); | ||||
| m_optimizedTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1); | m_optimizedTree->quantize(&node.m_quantizedAabbMax[0], aabbMax, 1); | ||||
| node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; | node.m_escapeIndexOrTriangleIndex = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | triangleIndex; | ||||
| m_triangleNodes.push_back(node); | m_triangleNodes.push_back(node); | ||||
| } | } | ||||
| }; | }; | ||||
| int numLeafNodes = 0; | int numLeafNodes = 0; | ||||
| if (m_useQuantization) | if (m_useQuantization) | ||||
| { | { | ||||
| //initialize quantization values | //initialize quantization values | ||||
| setQuantizationValues(bvhAabbMin,bvhAabbMax); | setQuantizationValues(bvhAabbMin, bvhAabbMax); | ||||
| QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this); | QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes, this); | ||||
| triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax); | triangles->InternalProcessAllTriangles(&callback, m_bvhAabbMin, m_bvhAabbMax); | ||||
| //now we have an array of leafnodes in m_leafNodes | //now we have an array of leafnodes in m_leafNodes | ||||
| numLeafNodes = m_quantizedLeafNodes.size(); | numLeafNodes = m_quantizedLeafNodes.size(); | ||||
| m_quantizedContiguousNodes.resize(2*numLeafNodes); | m_quantizedContiguousNodes.resize(2 * numLeafNodes); | ||||
| } | |||||
| else | |||||
| } else | |||||
| { | { | ||||
| NodeTriangleCallback callback(m_leafNodes); | NodeTriangleCallback callback(m_leafNodes); | ||||
| btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); | btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); | ||||
| btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); | btVector3 aabbMax(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); | ||||
| triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax); | triangles->InternalProcessAllTriangles(&callback, aabbMin, aabbMax); | ||||
| //now we have an array of leafnodes in m_leafNodes | //now we have an array of leafnodes in m_leafNodes | ||||
| numLeafNodes = m_leafNodes.size(); | numLeafNodes = m_leafNodes.size(); | ||||
| m_contiguousNodes.resize(2*numLeafNodes); | m_contiguousNodes.resize(2 * numLeafNodes); | ||||
| } | } | ||||
| m_curNodeIndex = 0; | m_curNodeIndex = 0; | ||||
| buildTree(0,numLeafNodes); | buildTree(0, numLeafNodes); | ||||
| ///if the entire tree is small then subtree size, we need to create a header info for the tree | ///if the entire tree is small then subtree size, we need to create a header info for the tree | ||||
| if(m_useQuantization && !m_SubtreeHeaders.size()) | if (m_useQuantization && !m_SubtreeHeaders.size()) | ||||
| { | { | ||||
| btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); | btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); | ||||
| subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); | subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); | ||||
| subtree.m_rootNodeIndex = 0; | subtree.m_rootNodeIndex = 0; | ||||
| subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex(); | subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex(); | ||||
| } | } | ||||
| //PCK: update the copy of the size | //PCK: update the copy of the size | ||||
| m_subtreeHeaderCount = m_SubtreeHeaders.size(); | m_subtreeHeaderCount = m_SubtreeHeaders.size(); | ||||
| //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary | //PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary | ||||
| m_quantizedLeafNodes.clear(); | m_quantizedLeafNodes.clear(); | ||||
| m_leafNodes.clear(); | m_leafNodes.clear(); | ||||
| } | } | ||||
| void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax) | void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface, const btVector3& aabbMin, const btVector3& aabbMax) | ||||
| { | { | ||||
| if (m_useQuantization) | if (m_useQuantization) | ||||
| { | { | ||||
| setQuantizationValues(aabbMin,aabbMax); | setQuantizationValues(aabbMin, aabbMax); | ||||
| updateBvhNodes(meshInterface,0,m_curNodeIndex,0); | updateBvhNodes(meshInterface, 0, m_curNodeIndex, 0); | ||||
| ///now update all subtree headers | ///now update all subtree headers | ||||
| int i; | int i; | ||||
| for (i=0;i<m_SubtreeHeaders.size();i++) | for (i = 0; i < m_SubtreeHeaders.size(); i++) | ||||
| { | { | ||||
| btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; | btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; | ||||
| subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); | subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); | ||||
| } | } | ||||
| } | |||||
| } else | else | ||||
| { | { | ||||
| } | } | ||||
| } | } | ||||
| void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax) | void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface, const btVector3& aabbMin, const btVector3& aabbMax) | ||||
| { | { | ||||
| //incrementally initialize quantization values | //incrementally initialize quantization values | ||||
| btAssert(m_useQuantization); | btAssert(m_useQuantization); | ||||
| btAssert(aabbMin.getX() > m_bvhAabbMin.getX()); | btAssert(aabbMin.getX() > m_bvhAabbMin.getX()); | ||||
| btAssert(aabbMin.getY() > m_bvhAabbMin.getY()); | btAssert(aabbMin.getY() > m_bvhAabbMin.getY()); | ||||
| btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ()); | btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ()); | ||||
| btAssert(aabbMax.getX() < m_bvhAabbMax.getX()); | btAssert(aabbMax.getX() < m_bvhAabbMax.getX()); | ||||
| btAssert(aabbMax.getY() < m_bvhAabbMax.getY()); | btAssert(aabbMax.getY() < m_bvhAabbMax.getY()); | ||||
| btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ()); | btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ()); | ||||
| ///we should update all quantization values, using updateBvhNodes(meshInterface); | ///we should update all quantization values, using updateBvhNodes(meshInterface); | ||||
| ///but we only update chunks that overlap the given aabb | ///but we only update chunks that overlap the given aabb | ||||
| unsigned short quantizedQueryAabbMin[3]; | unsigned short quantizedQueryAabbMin[3]; | ||||
| unsigned short quantizedQueryAabbMax[3]; | unsigned short quantizedQueryAabbMax[3]; | ||||
| quantize(&quantizedQueryAabbMin[0],aabbMin,0); | quantize(&quantizedQueryAabbMin[0], aabbMin, 0); | ||||
| quantize(&quantizedQueryAabbMax[0],aabbMax,1); | quantize(&quantizedQueryAabbMax[0], aabbMax, 1); | ||||
| int i; | int i; | ||||
| for (i=0;i<this->m_SubtreeHeaders.size();i++) | for (i = 0; i < this->m_SubtreeHeaders.size(); i++) | ||||
| { | { | ||||
| btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; | btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; | ||||
| //PCK: unsigned instead of bool | //PCK: unsigned instead of bool | ||||
| unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); | unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, subtree.m_quantizedAabbMin, subtree.m_quantizedAabbMax); | ||||
| if (overlap != 0) | if (overlap != 0) | ||||
| { | { | ||||
| updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i); | updateBvhNodes(meshInterface, subtree.m_rootNodeIndex, subtree.m_rootNodeIndex + subtree.m_subtreeSize, i); | ||||
| subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); | subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index) | void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface, int firstNode, int endNode, int index) | ||||
| { | { | ||||
| (void)index; | (void)index; | ||||
| btAssert(m_useQuantization); | btAssert(m_useQuantization); | ||||
| int curNodeSubPart=-1; | int curNodeSubPart = -1; | ||||
| //get access info to trianglemesh data | //get access info to trianglemesh data | ||||
| const unsigned char *vertexbase = 0; | const unsigned char* vertexbase = 0; | ||||
| int numverts = 0; | int numverts = 0; | ||||
| PHY_ScalarType type = PHY_INTEGER; | PHY_ScalarType type = PHY_INTEGER; | ||||
| int stride = 0; | int stride = 0; | ||||
| const unsigned char *indexbase = 0; | const unsigned char* indexbase = 0; | ||||
| int indexstride = 0; | int indexstride = 0; | ||||
| int numfaces = 0; | int numfaces = 0; | ||||
| PHY_ScalarType indicestype = PHY_INTEGER; | PHY_ScalarType indicestype = PHY_INTEGER; | ||||
| btVector3 triangleVerts[3]; | btVector3 triangleVerts[3]; | ||||
| btVector3 aabbMin,aabbMax; | btVector3 aabbMin, aabbMax; | ||||
| const btVector3& meshScaling = meshInterface->getScaling(); | const btVector3& meshScaling = meshInterface->getScaling(); | ||||
| int i; | int i; | ||||
| for (i=endNode-1;i>=firstNode;i--) | for (i = endNode - 1; i >= firstNode; i--) | ||||
| { | { | ||||
| btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; | btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; | ||||
| if (curNode.isLeafNode()) | if (curNode.isLeafNode()) | ||||
| { | { | ||||
| //recalc aabb from triangle data | //recalc aabb from triangle data | ||||
| int nodeSubPart = curNode.getPartId(); | int nodeSubPart = curNode.getPartId(); | ||||
| int nodeTriangleIndex = curNode.getTriangleIndex(); | int nodeTriangleIndex = curNode.getTriangleIndex(); | ||||
| if (nodeSubPart != curNodeSubPart) | if (nodeSubPart != curNodeSubPart) | ||||
| { | { | ||||
| if (curNodeSubPart >= 0) | if (curNodeSubPart >= 0) | ||||
| meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); | meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); | ||||
| meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart); | meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numfaces, indicestype, nodeSubPart); | ||||
| curNodeSubPart = nodeSubPart; | curNodeSubPart = nodeSubPart; | ||||
| btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); | |||||
| } | } | ||||
| //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, | //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, | ||||
| unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); | unsigned int* gfxbase = (unsigned int*)(indexbase + nodeTriangleIndex * indexstride); | ||||
| for (int j=2;j>=0;j--) | for (int j = 2; j >= 0; j--) | ||||
| { | { | ||||
| int graphicsindex; | |||||
| int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; | switch (indicestype) { | ||||
| case PHY_INTEGER: graphicsindex = gfxbase[j]; break; | |||||
| case PHY_SHORT: graphicsindex = ((unsigned short*)gfxbase)[j]; break; | |||||
| case PHY_UCHAR: graphicsindex = ((unsigned char*)gfxbase)[j]; break; | |||||
| default: btAssert(0); | |||||
| } | |||||
| if (type == PHY_FLOAT) | if (type == PHY_FLOAT) | ||||
| { | { | ||||
| float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); | float* graphicsbase = (float*)(vertexbase + graphicsindex * stride); | ||||
| triangleVerts[j] = btVector3( | triangleVerts[j] = btVector3( | ||||
| graphicsbase[0]*meshScaling.getX(), | graphicsbase[0] * meshScaling.getX(), | ||||
| graphicsbase[1]*meshScaling.getY(), | graphicsbase[1] * meshScaling.getY(), | ||||
| graphicsbase[2]*meshScaling.getZ()); | graphicsbase[2] * meshScaling.getZ()); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); | double* graphicsbase = (double*)(vertexbase + graphicsindex * stride); | ||||
| triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ())); | triangleVerts[j] = btVector3(btScalar(graphicsbase[0] * meshScaling.getX()), btScalar(graphicsbase[1] * meshScaling.getY()), btScalar(graphicsbase[2] * meshScaling.getZ())); | ||||
| } | } | ||||
| } | } | ||||
| aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); | aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); | ||||
| aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); | aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); | ||||
| aabbMin.setMin(triangleVerts[0]); | aabbMin.setMin(triangleVerts[0]); | ||||
| aabbMax.setMax(triangleVerts[0]); | aabbMax.setMax(triangleVerts[0]); | ||||
| aabbMin.setMin(triangleVerts[1]); | aabbMin.setMin(triangleVerts[1]); | ||||
| aabbMax.setMax(triangleVerts[1]); | aabbMax.setMax(triangleVerts[1]); | ||||
| aabbMin.setMin(triangleVerts[2]); | aabbMin.setMin(triangleVerts[2]); | ||||
| aabbMax.setMax(triangleVerts[2]); | aabbMax.setMax(triangleVerts[2]); | ||||
| quantize(&curNode.m_quantizedAabbMin[0],aabbMin,0); | quantize(&curNode.m_quantizedAabbMin[0], aabbMin, 0); | ||||
| quantize(&curNode.m_quantizedAabbMax[0],aabbMax,1); | quantize(&curNode.m_quantizedAabbMax[0], aabbMax, 1); | ||||
| } | |||||
| } else | else | ||||
| { | { | ||||
| //combine aabb from both children | //combine aabb from both children | ||||
| btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1]; | btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i + 1]; | ||||
| btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] : | btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i + 2] : &m_quantizedContiguousNodes[i + 1 + leftChildNode->getEscapeIndex()]; | ||||
| &m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()]; | |||||
| { | { | ||||
| for (int i=0;i<3;i++) | for (int i = 0; i < 3; i++) | ||||
| { | { | ||||
| curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; | curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; | ||||
| if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i]) | if (curNode.m_quantizedAabbMin[i] > rightChildNode->m_quantizedAabbMin[i]) | ||||
| curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i]; | curNode.m_quantizedAabbMin[i] = rightChildNode->m_quantizedAabbMin[i]; | ||||
| curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; | curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; | ||||
| if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) | if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) | ||||
| curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; | curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (curNodeSubPart >= 0) | if (curNodeSubPart >= 0) | ||||
| meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); | meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); | ||||
| } | } | ||||
| ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' | ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' | ||||
| btOptimizedBvh* btOptimizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) | btOptimizedBvh* btOptimizedBvh::deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) | ||||
| { | { | ||||
| btQuantizedBvh* bvh = btQuantizedBvh::deSerializeInPlace(i_alignedDataBuffer,i_dataBufferSize,i_swapEndian); | btQuantizedBvh* bvh = btQuantizedBvh::deSerializeInPlace(i_alignedDataBuffer, i_dataBufferSize, i_swapEndian); | ||||
| //we don't add additional data so just do a static upcast | //we don't add additional data so just do a static upcast | ||||
| return static_cast<btOptimizedBvh*>(bvh); | return static_cast<btOptimizedBvh*>(bvh); | ||||
| } | } | ||||