forked from bartvdbraak/blender
BGE patch: allow Bullet mesh shape sharing for objects copied with ALT-D.
This commit is contained in:
parent
768e12a064
commit
22a50402ef
@ -767,7 +767,17 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
|
||||
{
|
||||
if (!ci.m_mass)
|
||||
{
|
||||
shapeInfo->SetMesh(meshobj, false);
|
||||
// mesh shapes can be shared, check first if we already have a shape on that mesh
|
||||
class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, false);
|
||||
if (sharedShapeInfo != NULL)
|
||||
{
|
||||
delete shapeInfo;
|
||||
shapeInfo = sharedShapeInfo;
|
||||
shapeInfo->AddRef();
|
||||
} else
|
||||
{
|
||||
shapeInfo->SetMesh(meshobj, false);
|
||||
}
|
||||
bm = shapeInfo->CreateBulletShape();
|
||||
//no moving concave meshes, so don't bother calculating inertia
|
||||
//bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
|
||||
|
@ -902,9 +902,25 @@ void DefaultMotionState::calculateWorldTransformations()
|
||||
}
|
||||
|
||||
// Shape constructor
|
||||
std::map<RAS_MeshObject*, CcdShapeConstructionInfo*> CcdShapeConstructionInfo::m_meshShapeMap;
|
||||
|
||||
CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, bool polytope)
|
||||
{
|
||||
if (polytope)
|
||||
// not yet supported
|
||||
return NULL;
|
||||
|
||||
std::map<RAS_MeshObject*,CcdShapeConstructionInfo*>::const_iterator mit = m_meshShapeMap.find(mesh);
|
||||
if (mit != m_meshShapeMap.end())
|
||||
return mit->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope)
|
||||
{
|
||||
// assume no shape information
|
||||
// no support for dynamic change of shape yet
|
||||
assert(m_meshObject == NULL);
|
||||
m_shapeType = PHY_SHAPE_NONE;
|
||||
m_vertexArray.clear();
|
||||
m_polygonIndexArray.clear();
|
||||
@ -1006,6 +1022,11 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope)
|
||||
return false;
|
||||
}
|
||||
m_meshObject = meshobj;
|
||||
if (!polytope)
|
||||
{
|
||||
// triangle shape can be shared, store the mesh object in the map
|
||||
m_meshShapeMap.insert(std::pair<RAS_MeshObject*,CcdShapeConstructionInfo*>(meshobj,this));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1066,16 +1087,18 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
|
||||
break;
|
||||
|
||||
case PHY_SHAPE_COMPOUND:
|
||||
if (m_nextShape)
|
||||
if (m_shapeArray.size() > 0)
|
||||
{
|
||||
compoundShape = new btCompoundShape();
|
||||
for (nextShapeInfo=m_nextShape; nextShapeInfo; nextShapeInfo = nextShapeInfo->m_nextShape)
|
||||
for (std::vector<CcdShapeConstructionInfo*>::iterator sit = m_shapeArray.begin();
|
||||
sit != m_shapeArray.end();
|
||||
sit++)
|
||||
{
|
||||
collisionShape = nextShapeInfo->CreateBulletShape();
|
||||
collisionShape = (*sit)->CreateBulletShape();
|
||||
if (collisionShape)
|
||||
{
|
||||
collisionShape->setLocalScaling(nextShapeInfo->m_childScale);
|
||||
compoundShape->addChildShape(nextShapeInfo->m_childTrans, collisionShape);
|
||||
collisionShape->setLocalScaling((*sit)->m_childScale);
|
||||
compoundShape->addChildShape((*sit)->m_childTrans, collisionShape);
|
||||
}
|
||||
}
|
||||
collisionShape = compoundShape;
|
||||
@ -1086,28 +1109,31 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
|
||||
|
||||
void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo)
|
||||
{
|
||||
CcdShapeConstructionInfo* nextShape = this;
|
||||
while (nextShape->m_nextShape != NULL)
|
||||
nextShape = nextShape->m_nextShape;
|
||||
nextShape->m_nextShape = shapeInfo;
|
||||
m_shapeArray.push_back(shapeInfo);
|
||||
}
|
||||
|
||||
CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
|
||||
{
|
||||
CcdShapeConstructionInfo* childShape = m_nextShape;
|
||||
|
||||
while (childShape)
|
||||
for (std::vector<CcdShapeConstructionInfo*>::iterator sit = m_shapeArray.begin();
|
||||
sit != m_shapeArray.end();
|
||||
sit++)
|
||||
{
|
||||
CcdShapeConstructionInfo* nextShape = childShape->m_nextShape;
|
||||
childShape->m_nextShape = NULL;
|
||||
childShape->Release();
|
||||
childShape = nextShape;
|
||||
(*sit)->Release();
|
||||
}
|
||||
m_shapeArray.clear();
|
||||
if (m_unscaledShape)
|
||||
{
|
||||
DeleteBulletShape(m_unscaledShape);
|
||||
}
|
||||
m_vertexArray.clear();
|
||||
if (m_shapeType == PHY_SHAPE_MESH && m_meshObject != NULL)
|
||||
{
|
||||
std::map<RAS_MeshObject*,CcdShapeConstructionInfo*>::iterator mit = m_meshShapeMap.find(m_meshObject);
|
||||
if (mit != m_meshShapeMap.end() && mit->second == this)
|
||||
{
|
||||
m_meshShapeMap.erase(mit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@ subject to the following restrictions:
|
||||
#define BULLET2_PHYSICSCONTROLLER_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "PHY_IPhysicsController.h"
|
||||
|
||||
@ -42,15 +43,17 @@ class btCollisionShape;
|
||||
class CcdShapeConstructionInfo
|
||||
{
|
||||
public:
|
||||
static CcdShapeConstructionInfo* FindMesh(RAS_MeshObject* mesh, bool polytope);
|
||||
|
||||
CcdShapeConstructionInfo() :
|
||||
m_shapeType(PHY_SHAPE_NONE),
|
||||
m_radius(1.0),
|
||||
m_height(1.0),
|
||||
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_refCount(1),
|
||||
m_meshObject(NULL),
|
||||
m_unscaledShape(NULL)
|
||||
{
|
||||
m_childTrans.setIdentity();
|
||||
}
|
||||
@ -77,22 +80,19 @@ public:
|
||||
{
|
||||
return m_unscaledShape;
|
||||
}
|
||||
CcdShapeConstructionInfo* GetNextShape()
|
||||
{
|
||||
return m_nextShape;
|
||||
}
|
||||
CcdShapeConstructionInfo* GetChildShape(int i)
|
||||
{
|
||||
CcdShapeConstructionInfo* shape = m_nextShape;
|
||||
while (i > 0 && shape != NULL)
|
||||
{
|
||||
shape = shape->m_nextShape;
|
||||
i--;
|
||||
}
|
||||
return shape;
|
||||
if (i < 0 || i >= m_shapeArray.size())
|
||||
return NULL;
|
||||
|
||||
return m_shapeArray.at(i);
|
||||
}
|
||||
|
||||
bool SetMesh(RAS_MeshObject* mesh, bool polytope);
|
||||
RAS_MeshObject* GetMesh(void)
|
||||
{
|
||||
return m_meshObject;
|
||||
}
|
||||
|
||||
btCollisionShape* CreateBulletShape();
|
||||
|
||||
@ -109,14 +109,15 @@ public:
|
||||
std::vector<int> m_polygonIndexArray; // Contains the array of polygon index in the
|
||||
// original mesh that correspond to shape triangles.
|
||||
// only set for concave mesh shape.
|
||||
const RAS_MeshObject* m_meshObject; // Keep a pointer to the original mesh
|
||||
|
||||
protected:
|
||||
CcdShapeConstructionInfo* m_nextShape; // for compound shape
|
||||
btBvhTriangleMeshShape* m_unscaledShape;// holds the shared unscale BVH mesh shape,
|
||||
// the actual shape is of type btScaledBvhTriangleMeshShape
|
||||
static std::map<RAS_MeshObject*, CcdShapeConstructionInfo*> m_meshShapeMap;
|
||||
int m_refCount; // this class is shared between replicas
|
||||
// keep track of users so that we can release it
|
||||
RAS_MeshObject* m_meshObject; // Keep a pointer to the original mesh
|
||||
btBvhTriangleMeshShape* m_unscaledShape;// holds the shared unscale BVH mesh shape,
|
||||
// the actual shape is of type btScaledBvhTriangleMeshShape
|
||||
std::vector<CcdShapeConstructionInfo*> m_shapeArray; // for compound shapes
|
||||
};
|
||||
|
||||
struct CcdConstructionInfo
|
||||
|
@ -865,7 +865,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
|
||||
if (shape == rayCallback.m_hitTriangleShape &&
|
||||
rayCallback.m_hitTriangleIndex < shapeInfo->m_polygonIndexArray.size())
|
||||
{
|
||||
result.m_meshObject = shapeInfo->m_meshObject;
|
||||
result.m_meshObject = shapeInfo->GetMesh();
|
||||
result.m_polygon = shapeInfo->m_polygonIndexArray.at(rayCallback.m_hitTriangleIndex);
|
||||
|
||||
// Bullet returns the normal from "outside".
|
||||
|
Loading…
Reference in New Issue
Block a user