Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp')
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp221
1 files changed, 195 insertions, 26 deletions
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
index 8da554ef14d..819f6f7f97d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
@@ -18,32 +18,56 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
-
///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
-btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression)
-:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
+btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh)
+:btTriangleMeshShape(meshInterface),
+m_bvh(0),
+m_useQuantizedAabbCompression(useQuantizedAabbCompression),
+m_ownsBvh(false)
{
//construct bvh from meshInterface
#ifndef DISABLE_BVH
- m_bvh = new btOptimizedBvh();
btVector3 bvhAabbMin,bvhAabbMax;
- meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
- m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+ if(meshInterface->hasPremadeAabb())
+ {
+ meshInterface->getPremadeAabb(&bvhAabbMin, &bvhAabbMax);
+ }
+ else
+ {
+ meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
+ }
+
+ if (buildBvh)
+ {
+ void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+ m_bvh = new (mem) btOptimizedBvh();
+ m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+ m_ownsBvh = true;
+ }
#endif //DISABLE_BVH
}
-btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
-:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
+btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh)
+:btTriangleMeshShape(meshInterface),
+m_bvh(0),
+m_useQuantizedAabbCompression(useQuantizedAabbCompression),
+m_ownsBvh(false)
{
//construct bvh from meshInterface
#ifndef DISABLE_BVH
- m_bvh = new btOptimizedBvh();
- m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+ if (buildBvh)
+ {
+ void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+ m_bvh = new (mem) btOptimizedBvh();
+
+ m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+ m_ownsBvh = true;
+ }
#endif //DISABLE_BVH
@@ -58,16 +82,140 @@ void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btV
}
-void btBvhTriangleMeshShape::refitTree()
+void btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin,const btVector3& aabbMax)
{
- m_bvh->refit( m_meshInterface );
+ m_bvh->refit( m_meshInterface, aabbMin,aabbMax );
recalcLocalAabb();
}
btBvhTriangleMeshShape::~btBvhTriangleMeshShape()
{
- delete m_bvh;
+ if (m_ownsBvh)
+ {
+ m_bvh->~btOptimizedBvh();
+ btAlignedFree(m_bvh);
+ }
+}
+
+void btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget)
+{
+ struct MyNodeOverlapCallback : public btNodeOverlapCallback
+ {
+ btStridingMeshInterface* m_meshInterface;
+ btTriangleCallback* m_callback;
+
+ MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
+ :m_meshInterface(meshInterface),
+ m_callback(callback)
+ {
+ }
+
+ virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
+ {
+ btVector3 m_triangle[3];
+ const unsigned char *vertexbase;
+ int numverts;
+ PHY_ScalarType type;
+ int stride;
+ const unsigned char *indexbase;
+ int indexstride;
+ int numfaces;
+ PHY_ScalarType indicestype;
+
+ m_meshInterface->getLockedReadOnlyVertexIndexBase(
+ &vertexbase,
+ numverts,
+ type,
+ stride,
+ &indexbase,
+ indexstride,
+ numfaces,
+ indicestype,
+ nodeSubPart);
+
+ unsigned int* gfxbase = (unsigned 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 = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
+
+ btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
+
+ m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
+ }
+
+ /* Perform ray vs. triangle collision here */
+ m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
+ m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
+ }
+ };
+
+ MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface);
+
+ m_bvh->reportRayOverlappingNodex(&myNodeCallback,raySource,rayTarget);
+}
+
+void btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax)
+{
+ struct MyNodeOverlapCallback : public btNodeOverlapCallback
+ {
+ btStridingMeshInterface* m_meshInterface;
+ btTriangleCallback* m_callback;
+
+ MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
+ :m_meshInterface(meshInterface),
+ m_callback(callback)
+ {
+ }
+
+ virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
+ {
+ btVector3 m_triangle[3];
+ const unsigned char *vertexbase;
+ int numverts;
+ PHY_ScalarType type;
+ int stride;
+ const unsigned char *indexbase;
+ int indexstride;
+ int numfaces;
+ PHY_ScalarType indicestype;
+
+ m_meshInterface->getLockedReadOnlyVertexIndexBase(
+ &vertexbase,
+ numverts,
+ type,
+ stride,
+ &indexbase,
+ indexstride,
+ numfaces,
+ indicestype,
+ nodeSubPart);
+
+ unsigned int* gfxbase = (unsigned 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 = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
+
+ btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
+
+ m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
+ }
+
+ /* Perform ray vs. triangle collision here */
+ m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
+ m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
+ }
+ };
+
+ MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface);
+
+ m_bvh->reportBoxCastOverlappingNodex (&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax);
}
//perform bvh tree traversal and report overlapping triangles to 'callback'
@@ -118,13 +266,14 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
indicestype,
nodeSubPart);
- int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride);
+ unsigned int* gfxbase = (unsigned 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?((unsigned short*)gfxbase)[j]:gfxbase[j];
#ifdef DEBUG_TRIANGLE_MESH
@@ -157,17 +306,37 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
}
-
-void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
+void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
{
- if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
- {
- btTriangleMeshShape::setLocalScaling(scaling);
- delete m_bvh;
- ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
- m_bvh = new btOptimizedBvh();
- //rebuild the bvh...
- m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
+ if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
+ {
+ btTriangleMeshShape::setLocalScaling(scaling);
+ if (m_ownsBvh)
+ {
+ m_bvh->~btOptimizedBvh();
+ btAlignedFree(m_bvh);
+ }
+ ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
+ void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+ m_bvh = new(mem) btOptimizedBvh();
+ //rebuild the bvh...
+ m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
+ m_ownsBvh = true;
+ }
+}
- }
+void btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling)
+{
+ btAssert(!m_bvh);
+ btAssert(!m_ownsBvh);
+
+ m_bvh = bvh;
+ m_ownsBvh = false;
+ // update the scaling without rebuilding the bvh
+ if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
+ {
+ btTriangleMeshShape::setLocalScaling(scaling);
+ }
}
+
+