allow incremental refitting of the quantized aabb tree
This commit is contained in:
@@ -28,12 +28,36 @@ btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInte
|
||||
#ifndef DISABLE_BVH
|
||||
|
||||
m_bvh = new btOptimizedBvh();
|
||||
m_bvh->build(meshInterface,m_useQuantizedAabbCompression);
|
||||
btVector3 bvhAabbMin,bvhAabbMax;
|
||||
meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
|
||||
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
|
||||
|
||||
#endif //DISABLE_BVH
|
||||
|
||||
}
|
||||
|
||||
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
|
||||
:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
|
||||
{
|
||||
//construct bvh from meshInterface
|
||||
#ifndef DISABLE_BVH
|
||||
|
||||
m_bvh = new btOptimizedBvh();
|
||||
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
|
||||
|
||||
#endif //DISABLE_BVH
|
||||
|
||||
}
|
||||
|
||||
void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax)
|
||||
{
|
||||
m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax );
|
||||
|
||||
m_localAabbMin.setMin(aabbMin);
|
||||
m_localAabbMax.setMax(aabbMax);
|
||||
}
|
||||
|
||||
|
||||
void btBvhTriangleMeshShape::refitTree()
|
||||
{
|
||||
m_bvh->refit( m_meshInterface );
|
||||
@@ -140,8 +164,12 @@ void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
|
||||
{
|
||||
btTriangleMeshShape::setLocalScaling(scaling);
|
||||
delete m_bvh;
|
||||
///rescale aabb, instead of calculating?
|
||||
m_localAabbMin*=scaling;
|
||||
m_localAabbMax*=scaling;
|
||||
m_bvh = new btOptimizedBvh();
|
||||
m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression);
|
||||
//rebuild the bvh...
|
||||
m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@ public:
|
||||
btBvhTriangleMeshShape() :btTriangleMeshShape(0) {};
|
||||
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression);
|
||||
|
||||
///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
|
||||
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
|
||||
|
||||
virtual ~btBvhTriangleMeshShape();
|
||||
|
||||
|
||||
@@ -48,6 +51,9 @@ public:
|
||||
|
||||
void refitTree();
|
||||
|
||||
///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks
|
||||
void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax);
|
||||
|
||||
//debugging
|
||||
virtual char* getName()const {return "BVHTRIANGLEMESH";}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ btOptimizedBvh::btOptimizedBvh() : m_useQuantization(false),
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression)
|
||||
void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax)
|
||||
{
|
||||
m_useQuantization = useQuantizedAabbCompression;
|
||||
|
||||
@@ -114,7 +114,8 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized
|
||||
if (m_useQuantization)
|
||||
{
|
||||
|
||||
initQuantizationValues(triangles);
|
||||
//initialize quantization values
|
||||
setQuantizationValues(bvhAabbMin,bvhAabbMax);
|
||||
|
||||
QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this);
|
||||
|
||||
@@ -158,15 +159,53 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface)
|
||||
|
||||
void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax)
|
||||
{
|
||||
if (m_useQuantization)
|
||||
//incrementally initialize quantization values
|
||||
btAssert(m_useQuantization);
|
||||
|
||||
btAssert(aabbMin.getX() > m_bvhAabbMin.getX());
|
||||
btAssert(aabbMin.getY() > m_bvhAabbMin.getY());
|
||||
btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ());
|
||||
|
||||
btAssert(aabbMax.getX() < m_bvhAabbMax.getX());
|
||||
btAssert(aabbMax.getY() < m_bvhAabbMax.getY());
|
||||
btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ());
|
||||
|
||||
///we should update all quantization values, using updateBvhNodes(meshInterface);
|
||||
///but we only update chunks that overlap the given aabb
|
||||
|
||||
unsigned short quantizedQueryAabbMin[3];
|
||||
unsigned short quantizedQueryAabbMax[3];
|
||||
|
||||
quantizeWithClamp(&quantizedQueryAabbMin[0],aabbMin);
|
||||
quantizeWithClamp(&quantizedQueryAabbMax[0],aabbMax);
|
||||
|
||||
int i;
|
||||
for (i=0;i<this->m_SubtreeHeaders.size();i++)
|
||||
{
|
||||
int nodeSubPart=0;
|
||||
btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
|
||||
|
||||
initQuantizationValues(meshInterface);
|
||||
bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
|
||||
if (overlap)
|
||||
{
|
||||
updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize);
|
||||
|
||||
//get access info to trianglemesh data
|
||||
subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode)
|
||||
{
|
||||
btAssert(m_useQuantization);
|
||||
|
||||
int nodeSubPart=0;
|
||||
|
||||
//get access info to trianglemesh data
|
||||
const unsigned char *vertexbase;
|
||||
int numverts;
|
||||
PHY_ScalarType type;
|
||||
@@ -180,9 +219,9 @@ void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface)
|
||||
btVector3 triangleVerts[3];
|
||||
btVector3 aabbMin,aabbMax;
|
||||
const btVector3& meshScaling = meshInterface->getScaling();
|
||||
int numNodes = m_curNodeIndex;
|
||||
|
||||
int i;
|
||||
for (i=numNodes-1;i>=0;i--)
|
||||
for (i=endNode-1;i>=firstNode;i--)
|
||||
{
|
||||
|
||||
|
||||
@@ -250,61 +289,47 @@ void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface)
|
||||
|
||||
meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void btOptimizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
|
||||
{
|
||||
m_bvhAabbMin = bvhAabbMin;
|
||||
m_bvhAabbMax = bvhAabbMax;
|
||||
btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
|
||||
m_bvhQuantization = btVector3(btScalar(65535.0),btScalar(65535.0),btScalar(65535.0)) / aabbSize;
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface)
|
||||
{
|
||||
if (m_useQuantization)
|
||||
{
|
||||
//calculate new aabb
|
||||
btVector3 aabbMin,aabbMax;
|
||||
meshInterface->calculateAabbBruteForce(aabbMin,aabbMax);
|
||||
|
||||
setQuantizationValues(aabbMin,aabbMax);
|
||||
|
||||
updateBvhNodes(meshInterface,0,m_curNodeIndex);
|
||||
|
||||
///now update all subtree headers
|
||||
|
||||
|
||||
int i;
|
||||
for (i=0;i<m_SubtreeHeaders.size();i++)
|
||||
{
|
||||
btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
|
||||
subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]);
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btOptimizedBvh::initQuantizationValues(btStridingMeshInterface* triangles)
|
||||
{
|
||||
|
||||
struct AabbCalculationCallback : public btInternalTriangleIndexCallback
|
||||
{
|
||||
btVector3 m_aabbMin;
|
||||
btVector3 m_aabbMax;
|
||||
|
||||
AabbCalculationCallback()
|
||||
{
|
||||
m_aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
m_aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-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]);
|
||||
}
|
||||
};
|
||||
|
||||
//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);
|
||||
|
||||
//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;
|
||||
|
||||
|
||||
}
|
||||
btOptimizedBvh::~btOptimizedBvh()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -201,9 +201,7 @@ ATTRIBUTE_ALIGNED16(class) btOptimizedBvh
|
||||
|
||||
}
|
||||
|
||||
void initQuantizationValues(btStridingMeshInterface* triangles);
|
||||
|
||||
|
||||
void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
|
||||
|
||||
void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex)
|
||||
{
|
||||
@@ -287,7 +285,7 @@ public:
|
||||
|
||||
virtual ~btOptimizedBvh();
|
||||
|
||||
void build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression);
|
||||
void build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax);
|
||||
|
||||
void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
|
||||
|
||||
@@ -305,6 +303,11 @@ public:
|
||||
|
||||
void refit(btStridingMeshInterface* triangles);
|
||||
|
||||
void refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax);
|
||||
|
||||
void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode);
|
||||
|
||||
|
||||
QuantizedNodeArray& getQuantizedNodeArray()
|
||||
{
|
||||
return m_quantizedContiguousNodes;
|
||||
|
||||
@@ -83,3 +83,37 @@ void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleInde
|
||||
}
|
||||
}
|
||||
|
||||
void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
|
||||
{
|
||||
|
||||
struct AabbCalculationCallback : public btInternalTriangleIndexCallback
|
||||
{
|
||||
btVector3 m_aabbMin;
|
||||
btVector3 m_aabbMax;
|
||||
|
||||
AabbCalculationCallback()
|
||||
{
|
||||
m_aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
m_aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-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]);
|
||||
}
|
||||
};
|
||||
|
||||
//first calculate the total aabb for all triangles
|
||||
AabbCalculationCallback aabbCallback;
|
||||
aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
|
||||
aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
|
||||
InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
|
||||
|
||||
aabbMin = aabbCallback.m_aabbMin;
|
||||
aabbMax = aabbCallback.m_aabbMax;
|
||||
}
|
||||
@@ -49,6 +49,8 @@ class btStridingMeshInterface
|
||||
|
||||
void InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
|
||||
|
||||
///brute force method to calculate aabb
|
||||
void calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax);
|
||||
|
||||
/// get read and write access to a subpart of a triangle mesh
|
||||
/// this subpart has a continuous array of vertices and indices
|
||||
|
||||
Reference in New Issue
Block a user