- Added compressed/quantized AABB tree, 16 bytes per node, while supporting 32-bit (triangle) indices. Should be faster and smaller then original version (quantized aabb check is done in integer space)
Original aabb nodes are 44 bytes (with full floating point precision and additional part index) - added meter-unit scaling support in ColladaConverter.cpp
This commit is contained in:
@@ -18,17 +18,16 @@ subject to the following restrictions:
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
|
||||
|
||||
btOptimizedBvh::btOptimizedBvh() :m_rootNode1(0), m_numNodes(0)
|
||||
btOptimizedBvh::btOptimizedBvh() : m_contiguousNodes(0), m_quantizedContiguousNodes(0), m_useQuantization(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::build(btStridingMeshInterface* triangles)
|
||||
void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression)
|
||||
{
|
||||
//int countTriangles = 0;
|
||||
m_useQuantization = useQuantizedAabbCompression;
|
||||
|
||||
|
||||
|
||||
// NodeArray triangleNodes;
|
||||
|
||||
@@ -39,61 +38,148 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles)
|
||||
NodeTriangleCallback(NodeArray& triangleNodes)
|
||||
:m_triangleNodes(triangleNodes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
|
||||
{
|
||||
|
||||
btOptimizedBvhNode node;
|
||||
node.m_aabbMin = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
node.m_aabbMax = btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
node.m_aabbMin.setMin(triangle[0]);
|
||||
node.m_aabbMax.setMax(triangle[0]);
|
||||
node.m_aabbMin.setMin(triangle[1]);
|
||||
node.m_aabbMax.setMax(triangle[1]);
|
||||
node.m_aabbMin.setMin(triangle[2]);
|
||||
node.m_aabbMax.setMax(triangle[2]);
|
||||
btVector3 aabbMin,aabbMax;
|
||||
aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
aabbMin.setMin(triangle[0]);
|
||||
aabbMax.setMax(triangle[0]);
|
||||
aabbMin.setMin(triangle[1]);
|
||||
aabbMax.setMax(triangle[1]);
|
||||
aabbMin.setMin(triangle[2]);
|
||||
aabbMax.setMax(triangle[2]);
|
||||
|
||||
//with quantization?
|
||||
node.m_aabbMinOrg = aabbMin;
|
||||
node.m_aabbMaxOrg = aabbMax;
|
||||
|
||||
node.m_escapeIndex = -1;
|
||||
node.m_leftChild = 0;
|
||||
node.m_rightChild = 0;
|
||||
|
||||
|
||||
|
||||
//for child nodes
|
||||
node.m_subPart = partId;
|
||||
node.m_triangleIndex = triangleIndex;
|
||||
|
||||
|
||||
m_triangleNodes.push_back(node);
|
||||
}
|
||||
};
|
||||
struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback
|
||||
{
|
||||
QuantizedNodeArray& m_triangleNodes;
|
||||
const btOptimizedBvh* m_optimizedTree; // for quantization
|
||||
|
||||
QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const btOptimizedBvh* tree)
|
||||
:m_triangleNodes(triangleNodes),m_optimizedTree(tree)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
|
||||
{
|
||||
btAssert(partId==0);
|
||||
//negative indices are reserved for escapeIndex
|
||||
btAssert(triangleIndex>=0);
|
||||
|
||||
btQuantizedBvhNode node;
|
||||
btVector3 aabbMin,aabbMax;
|
||||
aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
aabbMin.setMin(triangle[0]);
|
||||
aabbMax.setMax(triangle[0]);
|
||||
aabbMin.setMin(triangle[1]);
|
||||
aabbMax.setMax(triangle[1]);
|
||||
aabbMin.setMin(triangle[2]);
|
||||
aabbMax.setMax(triangle[2]);
|
||||
|
||||
m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMin[0],aabbMin);
|
||||
m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMax[0],aabbMax);
|
||||
|
||||
node.m_escapeIndexOrTriangleIndex = triangleIndex;
|
||||
|
||||
m_triangleNodes.push_back(node);
|
||||
}
|
||||
};
|
||||
struct AabbCalculationCallback : public btInternalTriangleIndexCallback
|
||||
{
|
||||
btVector3 m_aabbMin;
|
||||
btVector3 m_aabbMax;
|
||||
|
||||
AabbCalculationCallback()
|
||||
{
|
||||
m_aabbMin.setValue(1e30,1e30,1e30);
|
||||
m_aabbMax.setValue(-1e30,-1e30,-1e30);
|
||||
}
|
||||
|
||||
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
|
||||
{
|
||||
m_aabbMin.setMin(triangle[0]);
|
||||
m_aabbMax.setMax(triangle[0]);
|
||||
m_aabbMin.setMin(triangle[1]);
|
||||
m_aabbMax.setMax(triangle[1]);
|
||||
m_aabbMin.setMin(triangle[2]);
|
||||
m_aabbMax.setMax(triangle[2]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int numLeafNodes = 0;
|
||||
|
||||
|
||||
if (m_useQuantization)
|
||||
{
|
||||
//first calculate the total aabb for all triangles
|
||||
AabbCalculationCallback aabbCallback;
|
||||
btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
triangles->InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
|
||||
|
||||
NodeTriangleCallback callback(m_leafNodes);
|
||||
//initialize quantization values
|
||||
m_bvhAabbMin = aabbCallback.m_aabbMin;
|
||||
m_bvhAabbMax = aabbCallback.m_aabbMax;
|
||||
btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
|
||||
m_bvhQuantization = btVector3(btScalar(65535.0),btScalar(65535.0),btScalar(65535.0)) / aabbSize;
|
||||
|
||||
btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this);
|
||||
|
||||
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_quantizedLeafNodes.size();
|
||||
|
||||
|
||||
m_quantizedContiguousNodes = new btQuantizedBvhNode[2*numLeafNodes];
|
||||
|
||||
|
||||
} else
|
||||
{
|
||||
NodeTriangleCallback callback(m_leafNodes);
|
||||
|
||||
btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
|
||||
triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax);
|
||||
|
||||
//now we have an array of leafnodes in m_leafNodes
|
||||
numLeafNodes = m_leafNodes.size();
|
||||
|
||||
m_contiguousNodes = new btOptimizedBvhNode[2*numLeafNodes];
|
||||
}
|
||||
|
||||
m_contiguousNodes = new btOptimizedBvhNode[2*m_leafNodes.size()];
|
||||
m_curNodeIndex = 0;
|
||||
|
||||
m_rootNode1 = buildTree(m_leafNodes,0,m_leafNodes.size());
|
||||
buildTree(0,numLeafNodes);
|
||||
|
||||
|
||||
///create the leafnodes first
|
||||
// btOptimizedBvhNode* leafNodes = new btOptimizedBvhNode;
|
||||
}
|
||||
|
||||
btOptimizedBvh::~btOptimizedBvh()
|
||||
{
|
||||
if (m_contiguousNodes)
|
||||
delete []m_contiguousNodes;
|
||||
|
||||
if (m_quantizedContiguousNodes)
|
||||
delete []m_quantizedContiguousNodes;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TREE_BUILDING
|
||||
@@ -101,7 +187,7 @@ int gStackDepth = 0;
|
||||
int gMaxStackDepth = 0;
|
||||
#endif //DEBUG_TREE_BUILDING
|
||||
|
||||
btOptimizedBvhNode* btOptimizedBvh::buildTree (NodeArray& leafNodes,int startIndex,int endIndex)
|
||||
void btOptimizedBvh::buildTree (int startIndex,int endIndex)
|
||||
{
|
||||
#ifdef DEBUG_TREE_BUILDING
|
||||
gStackDepth++;
|
||||
@@ -109,7 +195,6 @@ btOptimizedBvhNode* btOptimizedBvh::buildTree (NodeArray& leafNodes,int startInd
|
||||
gMaxStackDepth = gStackDepth;
|
||||
#endif //DEBUG_TREE_BUILDING
|
||||
|
||||
btOptimizedBvhNode* internalNode;
|
||||
|
||||
int splitAxis, splitIndex, i;
|
||||
int numIndices =endIndex-startIndex;
|
||||
@@ -122,38 +207,48 @@ btOptimizedBvhNode* btOptimizedBvh::buildTree (NodeArray& leafNodes,int startInd
|
||||
#ifdef DEBUG_TREE_BUILDING
|
||||
gStackDepth--;
|
||||
#endif //DEBUG_TREE_BUILDING
|
||||
return new (&m_contiguousNodes[m_curNodeIndex++]) btOptimizedBvhNode(leafNodes[startIndex]);
|
||||
|
||||
assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex);
|
||||
|
||||
m_curNodeIndex++;
|
||||
return;
|
||||
}
|
||||
//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
|
||||
|
||||
splitAxis = calcSplittingAxis(leafNodes,startIndex,endIndex);
|
||||
splitAxis = calcSplittingAxis(startIndex,endIndex);
|
||||
|
||||
splitIndex = sortAndCalcSplittingIndex(leafNodes,startIndex,endIndex,splitAxis);
|
||||
splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis);
|
||||
|
||||
internalNode = &m_contiguousNodes[m_curNodeIndex++];
|
||||
int internalNodeIndex = m_curNodeIndex;
|
||||
|
||||
internalNode->m_aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
internalNode->m_aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
setInternalNodeAabbMax(m_curNodeIndex,btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)));
|
||||
setInternalNodeAabbMin(m_curNodeIndex,btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30)));
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
{
|
||||
internalNode->m_aabbMax.setMax(leafNodes[i].m_aabbMax);
|
||||
internalNode->m_aabbMin.setMin(leafNodes[i].m_aabbMin);
|
||||
mergeInternalNodeAabb(m_curNodeIndex,getAabbMin(i),getAabbMax(i));
|
||||
}
|
||||
|
||||
m_curNodeIndex++;
|
||||
|
||||
|
||||
//internalNode->m_escapeIndex;
|
||||
internalNode->m_leftChild = buildTree(leafNodes,startIndex,splitIndex);
|
||||
internalNode->m_rightChild = buildTree(leafNodes,splitIndex,endIndex);
|
||||
|
||||
//build left child tree
|
||||
buildTree(startIndex,splitIndex);
|
||||
|
||||
//build right child tree
|
||||
buildTree(splitIndex,endIndex);
|
||||
|
||||
#ifdef DEBUG_TREE_BUILDING
|
||||
gStackDepth--;
|
||||
#endif //DEBUG_TREE_BUILDING
|
||||
internalNode->m_escapeIndex = m_curNodeIndex - curIndex;
|
||||
return internalNode;
|
||||
|
||||
setInternalNodeEscapeIndex(internalNodeIndex,m_curNodeIndex - curIndex);
|
||||
|
||||
}
|
||||
|
||||
int btOptimizedBvh::sortAndCalcSplittingIndex(NodeArray& leafNodes,int startIndex,int endIndex,int splitAxis)
|
||||
int btOptimizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis)
|
||||
{
|
||||
int i;
|
||||
int splitIndex =startIndex;
|
||||
@@ -163,7 +258,7 @@ int btOptimizedBvh::sortAndCalcSplittingIndex(NodeArray& leafNodes,int startInde
|
||||
btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
|
||||
btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
|
||||
means+=center;
|
||||
}
|
||||
means *= (btScalar(1.)/(btScalar)numIndices);
|
||||
@@ -173,13 +268,11 @@ int btOptimizedBvh::sortAndCalcSplittingIndex(NodeArray& leafNodes,int startInde
|
||||
//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
|
||||
btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
|
||||
if (center[splitAxis] > splitValue)
|
||||
{
|
||||
//swap
|
||||
btOptimizedBvhNode tmp = leafNodes[i];
|
||||
leafNodes[i] = leafNodes[splitIndex];
|
||||
leafNodes[splitIndex] = tmp;
|
||||
swapLeafNodes(i,splitIndex);
|
||||
splitIndex++;
|
||||
}
|
||||
}
|
||||
@@ -208,7 +301,7 @@ int btOptimizedBvh::sortAndCalcSplittingIndex(NodeArray& leafNodes,int startInde
|
||||
}
|
||||
|
||||
|
||||
int btOptimizedBvh::calcSplittingAxis(NodeArray& leafNodes,int startIndex,int endIndex)
|
||||
int btOptimizedBvh::calcSplittingAxis(int startIndex,int endIndex)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -218,15 +311,14 @@ int btOptimizedBvh::calcSplittingAxis(NodeArray& leafNodes,int startIndex,int en
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
{
|
||||
btOptimizedBvhNode& node = leafNodes[i];
|
||||
btVector3 center = btScalar(0.5)*(node.m_aabbMax+node.m_aabbMin);
|
||||
btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
|
||||
means+=center;
|
||||
}
|
||||
means *= (btScalar(1.)/(btScalar)numIndices);
|
||||
|
||||
for (i=startIndex;i<endIndex;i++)
|
||||
{
|
||||
btVector3 center = btScalar(0.5)*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
|
||||
btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
|
||||
btVector3 diff2 = center-means;
|
||||
diff2 = diff2 * diff2;
|
||||
variance += diff2;
|
||||
@@ -242,11 +334,104 @@ void btOptimizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallb
|
||||
{
|
||||
//either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
|
||||
|
||||
//walkTree(m_rootNode1,nodeCallback,aabbMin,aabbMax);
|
||||
|
||||
walkStacklessTree(m_rootNode1,nodeCallback,aabbMin,aabbMax);
|
||||
if (m_useQuantization)
|
||||
{
|
||||
walkStacklessQuantizedTree(nodeCallback,aabbMin,aabbMax);
|
||||
} else
|
||||
{
|
||||
walkStacklessTree(nodeCallback,aabbMin,aabbMax);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int maxIterations = 0;
|
||||
|
||||
void btOptimizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
{
|
||||
btAssert(!m_useQuantization);
|
||||
|
||||
btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
|
||||
int escapeIndex, curIndex = 0;
|
||||
int walkIterations = 0;
|
||||
bool aabbOverlap, isLeafNode;
|
||||
|
||||
while (curIndex < m_curNodeIndex)
|
||||
{
|
||||
//catch bugs in tree data
|
||||
assert (walkIterations < m_curNodeIndex);
|
||||
|
||||
walkIterations++;
|
||||
aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
|
||||
isLeafNode = rootNode->m_escapeIndex == -1;
|
||||
|
||||
if (isLeafNode && aabbOverlap)
|
||||
{
|
||||
nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
|
||||
}
|
||||
|
||||
if (aabbOverlap || isLeafNode)
|
||||
{
|
||||
rootNode++;
|
||||
curIndex++;
|
||||
} else
|
||||
{
|
||||
escapeIndex = rootNode->m_escapeIndex;
|
||||
rootNode += escapeIndex;
|
||||
curIndex += escapeIndex;
|
||||
}
|
||||
}
|
||||
if (maxIterations < walkIterations)
|
||||
maxIterations = walkIterations;
|
||||
|
||||
}
|
||||
|
||||
void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
{
|
||||
btAssert(m_useQuantization);
|
||||
|
||||
unsigned short int quantizedQueryAabbMin[3];
|
||||
unsigned short int quantizedQueryAabbMax[3];
|
||||
quantizeWithClamp(quantizedQueryAabbMin,aabbMin);
|
||||
quantizeWithClamp(quantizedQueryAabbMax,aabbMax);
|
||||
|
||||
btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[0];
|
||||
int escapeIndex, curIndex = 0;
|
||||
int walkIterations = 0;
|
||||
bool aabbOverlap, isLeafNode;
|
||||
|
||||
while (curIndex < m_curNodeIndex)
|
||||
{
|
||||
//catch bugs in tree data
|
||||
assert (walkIterations < m_curNodeIndex);
|
||||
|
||||
walkIterations++;
|
||||
aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
|
||||
isLeafNode = rootNode->isLeafNode();
|
||||
|
||||
if (isLeafNode && aabbOverlap)
|
||||
{
|
||||
nodeCallback->processNode(0,rootNode->getTriangleIndex());
|
||||
}
|
||||
|
||||
if (aabbOverlap || isLeafNode)
|
||||
{
|
||||
rootNode++;
|
||||
curIndex++;
|
||||
} else
|
||||
{
|
||||
escapeIndex = rootNode->getEscapeIndex();
|
||||
rootNode += escapeIndex;
|
||||
curIndex += escapeIndex;
|
||||
}
|
||||
}
|
||||
if (maxIterations < walkIterations)
|
||||
maxIterations = walkIterations;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
///this was the original recursive traversal, before we optimized towards stackless traversal
|
||||
void btOptimizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
{
|
||||
bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
|
||||
@@ -264,46 +449,8 @@ void btOptimizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
int maxIterations = 0;
|
||||
|
||||
void btOptimizedBvh::walkStacklessTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
{
|
||||
int escapeIndex, curIndex = 0;
|
||||
int walkIterations = 0;
|
||||
bool aabbOverlap, isLeafNode;
|
||||
|
||||
while (curIndex < m_curNodeIndex)
|
||||
{
|
||||
//catch bugs in tree data
|
||||
assert (walkIterations < m_curNodeIndex);
|
||||
|
||||
walkIterations++;
|
||||
aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
|
||||
isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild);
|
||||
|
||||
if (isLeafNode && aabbOverlap)
|
||||
{
|
||||
nodeCallback->processNode(rootNode);
|
||||
}
|
||||
|
||||
if (aabbOverlap || isLeafNode)
|
||||
{
|
||||
rootNode++;
|
||||
curIndex++;
|
||||
} else
|
||||
{
|
||||
escapeIndex = rootNode->m_escapeIndex;
|
||||
rootNode += escapeIndex;
|
||||
curIndex += escapeIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (maxIterations < walkIterations)
|
||||
maxIterations = walkIterations;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
|
||||
@@ -311,3 +458,56 @@ void btOptimizedBvh::reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCal
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::quantizeWithClamp(unsigned short* out, const btVector3& point) const
|
||||
{
|
||||
|
||||
btAssert(m_useQuantization);
|
||||
|
||||
btVector3 clampedPoint(point);
|
||||
clampedPoint.setMax(m_bvhAabbMin);
|
||||
clampedPoint.setMin(m_bvhAabbMax);
|
||||
|
||||
btVector3 v = (clampedPoint - m_bvhAabbMin) * m_bvhQuantization;
|
||||
out[0] = (unsigned short)(v.getX()+0.5f);
|
||||
out[1] = (unsigned short)(v.getY()+0.5f);
|
||||
out[2] = (unsigned short)(v.getZ()+0.5f);
|
||||
}
|
||||
|
||||
btVector3 btOptimizedBvh::unQuantize(const unsigned short* vecIn) const
|
||||
{
|
||||
btVector3 vecOut;
|
||||
vecOut.setValue(
|
||||
(btScalar)(vecIn[0]) / (m_bvhQuantization.getX()),
|
||||
(btScalar)(vecIn[1]) / (m_bvhQuantization.getY()),
|
||||
(btScalar)(vecIn[2]) / (m_bvhQuantization.getZ()));
|
||||
vecOut += m_bvhAabbMin;
|
||||
return vecOut;
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::swapLeafNodes(int i,int splitIndex)
|
||||
{
|
||||
if (m_useQuantization)
|
||||
{
|
||||
btQuantizedBvhNode tmp = m_quantizedLeafNodes[i];
|
||||
m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex];
|
||||
m_quantizedLeafNodes[splitIndex] = tmp;
|
||||
} else
|
||||
{
|
||||
btOptimizedBvhNode tmp = m_leafNodes[i];
|
||||
m_leafNodes[i] = m_leafNodes[splitIndex];
|
||||
m_leafNodes[splitIndex] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void btOptimizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex)
|
||||
{
|
||||
if (m_useQuantization)
|
||||
{
|
||||
m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex];
|
||||
} else
|
||||
{
|
||||
m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user