|
|
|
|
@@ -19,32 +19,11 @@ subject to the following restrictions:
|
|
|
|
|
#include "LinearMath/btIDebugDraw.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline bool testQuantizedAabbAgainstQuantizedAabb2(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
|
|
|
|
|
{
|
|
|
|
|
bool overlap = true;
|
|
|
|
|
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
|
|
|
|
|
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
|
|
|
|
|
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
|
|
|
|
|
return overlap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///Branch-free version of quantized aabb versus quantized aabb
|
|
|
|
|
inline unsigned testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
|
|
|
|
|
{
|
|
|
|
|
return btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
|
|
|
|
|
& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
|
|
|
|
|
& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
|
|
|
|
|
1, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
btOptimizedBvh::btOptimizedBvh() : m_useQuantization(false),
|
|
|
|
|
m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
|
|
|
|
|
// m_traversalMode(TRAVERSAL_STACKLESS)
|
|
|
|
|
//m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
|
|
|
|
|
m_traversalMode(TRAVERSAL_STACKLESS)
|
|
|
|
|
//m_traversalMode(TRAVERSAL_RECURSIVE)
|
|
|
|
|
,m_subtreeHeaderCount(0) //PCK: add this line
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
@@ -132,6 +111,25 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized
|
|
|
|
|
aabbMin.setMin(triangle[2]);
|
|
|
|
|
aabbMax.setMax(triangle[2]);
|
|
|
|
|
|
|
|
|
|
//PCK: add these checks for zero dimensions of aabb
|
|
|
|
|
const btScalar MIN_AABB_DIMENSION = btScalar(0.002);
|
|
|
|
|
const btScalar MIN_AABB_HALF_DIMENSION = btScalar(0.001);
|
|
|
|
|
if (aabbMax.x() - aabbMin.x() < MIN_AABB_DIMENSION)
|
|
|
|
|
{
|
|
|
|
|
aabbMax.setX(aabbMax.x() + MIN_AABB_HALF_DIMENSION);
|
|
|
|
|
aabbMin.setX(aabbMin.x() - MIN_AABB_HALF_DIMENSION);
|
|
|
|
|
}
|
|
|
|
|
if (aabbMax.y() - aabbMin.y() < MIN_AABB_DIMENSION)
|
|
|
|
|
{
|
|
|
|
|
aabbMax.setY(aabbMax.y() + MIN_AABB_HALF_DIMENSION);
|
|
|
|
|
aabbMin.setY(aabbMin.y() - MIN_AABB_HALF_DIMENSION);
|
|
|
|
|
}
|
|
|
|
|
if (aabbMax.z() - aabbMin.z() < MIN_AABB_DIMENSION)
|
|
|
|
|
{
|
|
|
|
|
aabbMax.setZ(aabbMax.z() + MIN_AABB_HALF_DIMENSION);
|
|
|
|
|
aabbMin.setZ(aabbMin.z() - MIN_AABB_HALF_DIMENSION);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMin[0],aabbMin);
|
|
|
|
|
m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMax[0],aabbMax);
|
|
|
|
|
|
|
|
|
|
@@ -192,8 +190,12 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized
|
|
|
|
|
subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_leafNodes.clear();
|
|
|
|
|
//PCK: update the copy of the size
|
|
|
|
|
m_subtreeHeaderCount = m_SubtreeHeaders.size();
|
|
|
|
|
|
|
|
|
|
//PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary
|
|
|
|
|
m_quantizedLeafNodes.clear();
|
|
|
|
|
m_leafNodes.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -225,8 +227,9 @@ void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const b
|
|
|
|
|
{
|
|
|
|
|
btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
|
|
|
|
|
|
|
|
|
|
unsigned int overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
|
|
|
|
|
if (overlap)
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
|
|
|
|
|
if (overlap != 0)
|
|
|
|
|
{
|
|
|
|
|
updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i);
|
|
|
|
|
|
|
|
|
|
@@ -503,6 +506,9 @@ void btOptimizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChild
|
|
|
|
|
subtree.m_rootNodeIndex = rightChildNodexIndex;
|
|
|
|
|
subtree.m_subtreeSize = rightSubTreeSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//PCK: update the copy of the size
|
|
|
|
|
m_subtreeHeaderCount = m_SubtreeHeaders.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -635,7 +641,9 @@ void btOptimizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const
|
|
|
|
|
const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
|
|
|
|
|
int escapeIndex, curIndex = 0;
|
|
|
|
|
int walkIterations = 0;
|
|
|
|
|
bool aabbOverlap, isLeafNode;
|
|
|
|
|
bool isLeafNode;
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
unsigned aabbOverlap;
|
|
|
|
|
|
|
|
|
|
while (curIndex < m_curNodeIndex)
|
|
|
|
|
{
|
|
|
|
|
@@ -646,12 +654,14 @@ void btOptimizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const
|
|
|
|
|
aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
|
|
|
|
|
isLeafNode = rootNode->m_escapeIndex == -1;
|
|
|
|
|
|
|
|
|
|
if (isLeafNode && aabbOverlap)
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
if (isLeafNode && (aabbOverlap != 0))
|
|
|
|
|
{
|
|
|
|
|
nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aabbOverlap || isLeafNode)
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
if ((aabbOverlap != 0) || isLeafNode)
|
|
|
|
|
{
|
|
|
|
|
rootNode++;
|
|
|
|
|
curIndex++;
|
|
|
|
|
@@ -692,12 +702,16 @@ void btOptimizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantize
|
|
|
|
|
{
|
|
|
|
|
btAssert(m_useQuantization);
|
|
|
|
|
|
|
|
|
|
unsigned int aabbOverlap, isLeafNode;
|
|
|
|
|
bool isLeafNode;
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
unsigned aabbOverlap;
|
|
|
|
|
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax);
|
|
|
|
|
isLeafNode = currentNode->isLeafNode();
|
|
|
|
|
|
|
|
|
|
if (aabbOverlap)
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
if (aabbOverlap != 0)
|
|
|
|
|
{
|
|
|
|
|
if (isLeafNode)
|
|
|
|
|
{
|
|
|
|
|
@@ -731,7 +745,9 @@ void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb
|
|
|
|
|
const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
|
|
|
|
|
int escapeIndex;
|
|
|
|
|
|
|
|
|
|
unsigned int aabbOverlap, isLeafNode;
|
|
|
|
|
bool isLeafNode;
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
unsigned aabbOverlap;
|
|
|
|
|
|
|
|
|
|
while (curIndex < endNodeIndex)
|
|
|
|
|
{
|
|
|
|
|
@@ -756,6 +772,7 @@ void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb
|
|
|
|
|
assert (walkIterations < subTreeSize);
|
|
|
|
|
|
|
|
|
|
walkIterations++;
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
|
|
|
|
|
isLeafNode = rootNode->isLeafNode();
|
|
|
|
|
|
|
|
|
|
@@ -764,7 +781,8 @@ void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb
|
|
|
|
|
nodeCallback->processNode(0,rootNode->getTriangleIndex());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aabbOverlap || isLeafNode)
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
if ((aabbOverlap != 0) || isLeafNode)
|
|
|
|
|
{
|
|
|
|
|
rootNode++;
|
|
|
|
|
curIndex++;
|
|
|
|
|
@@ -792,8 +810,9 @@ void btOptimizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallba
|
|
|
|
|
{
|
|
|
|
|
const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
|
|
|
|
|
|
|
|
|
|
unsigned int overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
|
|
|
|
|
if (overlap)
|
|
|
|
|
//PCK: unsigned instead of bool
|
|
|
|
|
unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
|
|
|
|
|
if (overlap != 0)
|
|
|
|
|
{
|
|
|
|
|
walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
|
|
|
|
|
subtree.m_rootNodeIndex,
|
|
|
|
|
@@ -867,3 +886,305 @@ void btOptimizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNod
|
|
|
|
|
m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//PCK: include
|
|
|
|
|
#include <new>
|
|
|
|
|
|
|
|
|
|
//PCK: consts
|
|
|
|
|
static const unsigned BVH_ALIGNMENT = 16;
|
|
|
|
|
static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1;
|
|
|
|
|
|
|
|
|
|
static const unsigned BVH_ALIGNMENT_BLOCKS = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned btOptimizedBvh::calculateSerializeBufferSize()
|
|
|
|
|
{
|
|
|
|
|
unsigned baseSize = sizeof(btOptimizedBvh) + BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
|
|
|
|
|
baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
|
|
|
|
|
if (m_useQuantization)
|
|
|
|
|
{
|
|
|
|
|
return baseSize + m_curNodeIndex * sizeof(btQuantizedBvhNode);
|
|
|
|
|
}
|
|
|
|
|
return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool btOptimizedBvh::serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
assert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
|
|
|
|
|
m_subtreeHeaderCount = m_SubtreeHeaders.size();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK != 0)
|
|
|
|
|
{
|
|
|
|
|
///check alignedment for buffer?
|
|
|
|
|
btAssert(0);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btOptimizedBvh *targetBvh = (btOptimizedBvh *)o_alignedDataBuffer;
|
|
|
|
|
|
|
|
|
|
// construct the class so the virtual function table, etc will be set up
|
|
|
|
|
// Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
|
|
|
|
|
new (targetBvh) btOptimizedBvh;
|
|
|
|
|
|
|
|
|
|
if (i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
targetBvh->m_curNodeIndex = btSwapEndian(m_curNodeIndex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin);
|
|
|
|
|
btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax);
|
|
|
|
|
btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization);
|
|
|
|
|
|
|
|
|
|
targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode);
|
|
|
|
|
targetBvh->m_subtreeHeaderCount = btSwapEndian(m_subtreeHeaderCount);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
targetBvh->m_curNodeIndex = m_curNodeIndex;
|
|
|
|
|
targetBvh->m_bvhAabbMin = m_bvhAabbMin;
|
|
|
|
|
targetBvh->m_bvhAabbMax = m_bvhAabbMax;
|
|
|
|
|
targetBvh->m_bvhQuantization = m_bvhQuantization;
|
|
|
|
|
targetBvh->m_traversalMode = m_traversalMode;
|
|
|
|
|
targetBvh->m_subtreeHeaderCount = m_subtreeHeaderCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
targetBvh->m_useQuantization = m_useQuantization;
|
|
|
|
|
|
|
|
|
|
unsigned char *nodeData = (unsigned char *)targetBvh;
|
|
|
|
|
nodeData += sizeof(btOptimizedBvh);
|
|
|
|
|
|
|
|
|
|
unsigned sizeToAdd = (unsigned)nodeData & BVH_ALIGNMENT_MASK;
|
|
|
|
|
nodeData += sizeToAdd;
|
|
|
|
|
|
|
|
|
|
int nodeCount = m_curNodeIndex;
|
|
|
|
|
|
|
|
|
|
if (m_useQuantization)
|
|
|
|
|
{
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
|
|
|
|
|
|
|
|
|
|
if (i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
|
|
|
|
|
{
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
|
|
|
|
|
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
|
|
|
|
|
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0];
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1];
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2];
|
|
|
|
|
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0];
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1];
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2];
|
|
|
|
|
|
|
|
|
|
targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
targetBvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
|
|
|
|
|
|
|
|
|
|
if (i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
|
|
|
|
|
{
|
|
|
|
|
btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMinOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
|
|
|
|
|
btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMaxOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
|
|
|
|
|
|
|
|
|
|
targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = btSwapEndian(m_contiguousNodes[nodeIndex].m_escapeIndex);
|
|
|
|
|
targetBvh->m_contiguousNodes[nodeIndex].m_subPart = btSwapEndian(m_contiguousNodes[nodeIndex].m_subPart);
|
|
|
|
|
targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = btSwapEndian(m_contiguousNodes[nodeIndex].m_triangleIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
|
|
|
|
|
{
|
|
|
|
|
targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg = m_contiguousNodes[nodeIndex].m_aabbMinOrg;
|
|
|
|
|
targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg = m_contiguousNodes[nodeIndex].m_aabbMaxOrg;
|
|
|
|
|
|
|
|
|
|
targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = m_contiguousNodes[nodeIndex].m_escapeIndex;
|
|
|
|
|
targetBvh->m_contiguousNodes[nodeIndex].m_subPart = m_contiguousNodes[nodeIndex].m_subPart;
|
|
|
|
|
targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = m_contiguousNodes[nodeIndex].m_triangleIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sizeToAdd = (unsigned)nodeData & BVH_ALIGNMENT_MASK;
|
|
|
|
|
nodeData += sizeToAdd;
|
|
|
|
|
|
|
|
|
|
// Now serialize the subtree headers
|
|
|
|
|
targetBvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, m_subtreeHeaderCount, m_subtreeHeaderCount);
|
|
|
|
|
if (i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < m_subtreeHeaderCount; i++)
|
|
|
|
|
{
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
|
|
|
|
|
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
|
|
|
|
|
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = btSwapEndian(m_SubtreeHeaders[i].m_rootNodeIndex);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_subtreeSize = btSwapEndian(m_SubtreeHeaders[i].m_subtreeSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < m_subtreeHeaderCount; i++)
|
|
|
|
|
{
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = (m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = (m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = (m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
|
|
|
|
|
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = (m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = (m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = (m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
|
|
|
|
|
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize);
|
|
|
|
|
targetBvh->m_SubtreeHeaders[i] = m_SubtreeHeaders[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
btOptimizedBvh *btOptimizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
if (i_alignedDataBuffer == NULL || (unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK != 0)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
btOptimizedBvh *bvh = (btOptimizedBvh *)i_alignedDataBuffer;
|
|
|
|
|
|
|
|
|
|
if (i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
bvh->m_curNodeIndex = btSwapEndian(bvh->m_curNodeIndex);
|
|
|
|
|
|
|
|
|
|
btUnSwapVector3Endian(bvh->m_bvhAabbMin);
|
|
|
|
|
btUnSwapVector3Endian(bvh->m_bvhAabbMax);
|
|
|
|
|
btUnSwapVector3Endian(bvh->m_bvhQuantization);
|
|
|
|
|
|
|
|
|
|
bvh->m_traversalMode = (btTraversalMode)btSwapEndian(bvh->m_traversalMode);
|
|
|
|
|
bvh->m_subtreeHeaderCount = btSwapEndian(bvh->m_subtreeHeaderCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int calculatedBufSize = bvh->calculateSerializeBufferSize();
|
|
|
|
|
btAssert(calculatedBufSize <= i_dataBufferSize);
|
|
|
|
|
|
|
|
|
|
if (calculatedBufSize > i_dataBufferSize)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char *nodeData = (unsigned char *)bvh;
|
|
|
|
|
nodeData += sizeof(btOptimizedBvh);
|
|
|
|
|
|
|
|
|
|
unsigned sizeToAdd = (unsigned)nodeData & BVH_ALIGNMENT_MASK;
|
|
|
|
|
nodeData += sizeToAdd;
|
|
|
|
|
|
|
|
|
|
int nodeCount = bvh->m_curNodeIndex;
|
|
|
|
|
|
|
|
|
|
// Must call placement new to fill in virtual function table, etc, but we don't want to overwrite most data, so call a special version of the constructor
|
|
|
|
|
// Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
|
|
|
|
|
new (bvh) btOptimizedBvh(*bvh, false);
|
|
|
|
|
|
|
|
|
|
if (bvh->m_useQuantization)
|
|
|
|
|
{
|
|
|
|
|
bvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
|
|
|
|
|
|
|
|
|
|
if (i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
|
|
|
|
|
{
|
|
|
|
|
bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
|
|
|
|
|
bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
|
|
|
|
|
bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
|
|
|
|
|
|
|
|
|
|
bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
|
|
|
|
|
bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
|
|
|
|
|
bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
|
|
|
|
|
|
|
|
|
|
bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
|
|
|
|
|
|
|
|
|
|
if (i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
|
|
|
|
|
{
|
|
|
|
|
btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
|
|
|
|
|
btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
|
|
|
|
|
|
|
|
|
|
bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex);
|
|
|
|
|
bvh->m_contiguousNodes[nodeIndex].m_subPart = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart);
|
|
|
|
|
bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sizeToAdd = (unsigned)nodeData & BVH_ALIGNMENT_MASK;
|
|
|
|
|
nodeData += sizeToAdd;
|
|
|
|
|
|
|
|
|
|
// Now serialize the subtree headers
|
|
|
|
|
bvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, bvh->m_subtreeHeaderCount, bvh->m_subtreeHeaderCount);
|
|
|
|
|
if (i_swapEndian)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < bvh->m_subtreeHeaderCount; i++)
|
|
|
|
|
{
|
|
|
|
|
bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
|
|
|
|
|
bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
|
|
|
|
|
bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
|
|
|
|
|
|
|
|
|
|
bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
|
|
|
|
|
bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
|
|
|
|
|
bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
|
|
|
|
|
|
|
|
|
|
bvh->m_SubtreeHeaders[i].m_rootNodeIndex = btSwapEndian(bvh->m_SubtreeHeaders[i].m_rootNodeIndex);
|
|
|
|
|
bvh->m_SubtreeHeaders[i].m_subtreeSize = btSwapEndian(bvh->m_SubtreeHeaders[i].m_subtreeSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bvh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Constructor that prevents btVector3's default constructor from being called
|
|
|
|
|
btOptimizedBvh::btOptimizedBvh(btOptimizedBvh &self, bool ownsMemory) :
|
|
|
|
|
m_bvhAabbMin(self.m_bvhAabbMin),
|
|
|
|
|
m_bvhAabbMax(self.m_bvhAabbMax),
|
|
|
|
|
m_bvhQuantization(self.m_bvhQuantization)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|