BGE patch: use new btScaledBvhTriangleMeshShape to allow shape sharing between replicas and avoid BVH rebuild in case of scaling. This will save memory and speed up greatly the instantiation of static mesh.
This commit is contained in:
parent
63ecf9966e
commit
8925ae6042
@ -15,7 +15,7 @@ subject to the following restrictions:
|
||||
|
||||
#include "CcdPhysicsController.h"
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
|
||||
#include "PHY_IMotionState.h"
|
||||
#include "CcdPhysicsEnvironment.h"
|
||||
#include "RAS_MeshObject.h"
|
||||
@ -904,15 +904,26 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
|
||||
break;
|
||||
|
||||
case PHY_SHAPE_MESH:
|
||||
collisionMeshData = new btTriangleMesh();
|
||||
// m_vertexArray is necessarily a multiple of 3
|
||||
for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
|
||||
// Let's use the latest btScaledBvhTriangleMeshShape: it allows true sharing of
|
||||
// triangle mesh information between duplicates => drastic performance increase when
|
||||
// duplicating complex mesh objects.
|
||||
// BUT it causes a small performance decrease when sharing is not required:
|
||||
// 9 multiplications/additions and one function call for each triangle that passes the mid phase filtering
|
||||
// One possible optimization is to use directly the btBvhTriangleMeshShape when the scale is 1,1,1
|
||||
// and btScaledBvhTriangleMeshShape otherwise.
|
||||
if (!m_unscaledShape)
|
||||
{
|
||||
collisionMeshData->addTriangle(*it++,*it++,*it++);
|
||||
collisionMeshData = new btTriangleMesh();
|
||||
// m_vertexArray is necessarily a multiple of 3
|
||||
for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
|
||||
{
|
||||
collisionMeshData->addTriangle(*it++,*it++,*it++);
|
||||
}
|
||||
// this shape will be shared and not deleted until shapeInfo is deleted
|
||||
m_unscaledShape = new btBvhTriangleMeshShape( collisionMeshData, true );
|
||||
m_unscaledShape->recalcLocalAabb();
|
||||
}
|
||||
concaveShape = new btBvhTriangleMeshShape( collisionMeshData, true );
|
||||
concaveShape->recalcLocalAabb();
|
||||
collisionShape = concaveShape;
|
||||
collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f));
|
||||
break;
|
||||
|
||||
case PHY_SHAPE_COMPOUND:
|
||||
@ -953,7 +964,10 @@ CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
|
||||
childShape->Release();
|
||||
childShape = nextShape;
|
||||
}
|
||||
|
||||
if (m_unscaledShape)
|
||||
{
|
||||
DeleteBulletShape(m_unscaledShape);
|
||||
}
|
||||
m_vertexArray.clear();
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
m_halfExtend(0.f,0.f,0.f),
|
||||
m_childScale(1.0f,1.0f,1.0f),
|
||||
m_nextShape(NULL),
|
||||
m_unscaledShape(NULL),
|
||||
m_refCount(1)
|
||||
{
|
||||
m_childTrans.setIdentity();
|
||||
@ -72,6 +73,10 @@ public:
|
||||
|
||||
void AddShape(CcdShapeConstructionInfo* shapeInfo);
|
||||
|
||||
btTriangleMeshShape* GetMeshShape(void)
|
||||
{
|
||||
return m_unscaledShape;
|
||||
}
|
||||
CcdShapeConstructionInfo* GetNextShape()
|
||||
{
|
||||
return m_nextShape;
|
||||
@ -108,6 +113,8 @@ public:
|
||||
|
||||
protected:
|
||||
CcdShapeConstructionInfo* m_nextShape; // for compound shape
|
||||
btBvhTriangleMeshShape* m_unscaledShape;// holds the shared unscale BVH mesh shape,
|
||||
// the actual shape is of type btScaledBvhTriangleMeshShape
|
||||
int m_refCount; // this class is shared between replicas
|
||||
// keep track of users so that we can release it
|
||||
};
|
||||
|
@ -816,44 +816,48 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
|
||||
// If the user requests the real normal, compute it now
|
||||
if (filterCallback.m_faceNormal)
|
||||
{
|
||||
// this code is copied from Bullet
|
||||
btVector3 triangle[3];
|
||||
const unsigned char *vertexbase;
|
||||
int numverts;
|
||||
PHY_ScalarType type;
|
||||
int stride;
|
||||
const unsigned char *indexbase;
|
||||
int indexstride;
|
||||
int numfaces;
|
||||
PHY_ScalarType indicestype;
|
||||
btTriangleMeshShape* triangleShape = (btTriangleMeshShape*)shape;
|
||||
btStridingMeshInterface* meshInterface = triangleShape->getMeshInterface();
|
||||
|
||||
meshInterface->getLockedReadOnlyVertexIndexBase(
|
||||
&vertexbase,
|
||||
numverts,
|
||||
type,
|
||||
stride,
|
||||
&indexbase,
|
||||
indexstride,
|
||||
numfaces,
|
||||
indicestype,
|
||||
0);
|
||||
|
||||
unsigned int* gfxbase = (unsigned int*)(indexbase+rayCallback.m_hitTriangleIndex*indexstride);
|
||||
const btVector3& meshScaling = meshInterface->getScaling();
|
||||
for (int j=2;j>=0;j--)
|
||||
// mesh shapes are shared and stored in the shapeInfo
|
||||
btTriangleMeshShape* triangleShape = shapeInfo->GetMeshShape();
|
||||
if (triangleShape)
|
||||
{
|
||||
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
|
||||
// this code is copied from Bullet
|
||||
btVector3 triangle[3];
|
||||
const unsigned char *vertexbase;
|
||||
int numverts;
|
||||
PHY_ScalarType type;
|
||||
int stride;
|
||||
const unsigned char *indexbase;
|
||||
int indexstride;
|
||||
int numfaces;
|
||||
PHY_ScalarType indicestype;
|
||||
btStridingMeshInterface* meshInterface = triangleShape->getMeshInterface();
|
||||
|
||||
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
|
||||
meshInterface->getLockedReadOnlyVertexIndexBase(
|
||||
&vertexbase,
|
||||
numverts,
|
||||
type,
|
||||
stride,
|
||||
&indexbase,
|
||||
indexstride,
|
||||
numfaces,
|
||||
indicestype,
|
||||
0);
|
||||
|
||||
triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
|
||||
unsigned int* gfxbase = (unsigned int*)(indexbase+rayCallback.m_hitTriangleIndex*indexstride);
|
||||
const btVector3& meshScaling = shape->getLocalScaling();
|
||||
for (int j=2;j>=0;j--)
|
||||
{
|
||||
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
|
||||
|
||||
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
|
||||
|
||||
triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
|
||||
}
|
||||
meshInterface->unLockReadOnlyVertexBase(0);
|
||||
btVector3 triangleNormal;
|
||||
triangleNormal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]);
|
||||
rayCallback.m_hitNormalWorld = rayCallback.m_collisionObject->getWorldTransform().getBasis()*triangleNormal;
|
||||
}
|
||||
meshInterface->unLockReadOnlyVertexBase(0);
|
||||
btVector3 triangleNormal;
|
||||
triangleNormal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]);
|
||||
rayCallback.m_hitNormalWorld = rayCallback.m_collisionObject->getWorldTransform().getBasis()*triangleNormal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user