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
@ -766,8 +766,18 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
|
|||||||
case KX_BOUNDMESH:
|
case KX_BOUNDMESH:
|
||||||
{
|
{
|
||||||
if (!ci.m_mass)
|
if (!ci.m_mass)
|
||||||
|
{
|
||||||
|
// 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);
|
shapeInfo->SetMesh(meshobj, false);
|
||||||
|
}
|
||||||
bm = shapeInfo->CreateBulletShape();
|
bm = shapeInfo->CreateBulletShape();
|
||||||
//no moving concave meshes, so don't bother calculating inertia
|
//no moving concave meshes, so don't bother calculating inertia
|
||||||
//bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
|
//bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
|
||||||
|
@ -902,9 +902,25 @@ void DefaultMotionState::calculateWorldTransformations()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Shape constructor
|
// 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)
|
bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope)
|
||||||
{
|
{
|
||||||
// assume no shape information
|
// assume no shape information
|
||||||
|
// no support for dynamic change of shape yet
|
||||||
|
assert(m_meshObject == NULL);
|
||||||
m_shapeType = PHY_SHAPE_NONE;
|
m_shapeType = PHY_SHAPE_NONE;
|
||||||
m_vertexArray.clear();
|
m_vertexArray.clear();
|
||||||
m_polygonIndexArray.clear();
|
m_polygonIndexArray.clear();
|
||||||
@ -1006,6 +1022,11 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_meshObject = meshobj;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1066,16 +1087,18 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PHY_SHAPE_COMPOUND:
|
case PHY_SHAPE_COMPOUND:
|
||||||
if (m_nextShape)
|
if (m_shapeArray.size() > 0)
|
||||||
{
|
{
|
||||||
compoundShape = new btCompoundShape();
|
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)
|
if (collisionShape)
|
||||||
{
|
{
|
||||||
collisionShape->setLocalScaling(nextShapeInfo->m_childScale);
|
collisionShape->setLocalScaling((*sit)->m_childScale);
|
||||||
compoundShape->addChildShape(nextShapeInfo->m_childTrans, collisionShape);
|
compoundShape->addChildShape((*sit)->m_childTrans, collisionShape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
collisionShape = compoundShape;
|
collisionShape = compoundShape;
|
||||||
@ -1086,28 +1109,31 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
|
|||||||
|
|
||||||
void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo)
|
void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo)
|
||||||
{
|
{
|
||||||
CcdShapeConstructionInfo* nextShape = this;
|
m_shapeArray.push_back(shapeInfo);
|
||||||
while (nextShape->m_nextShape != NULL)
|
|
||||||
nextShape = nextShape->m_nextShape;
|
|
||||||
nextShape->m_nextShape = shapeInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
|
CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
|
||||||
{
|
{
|
||||||
CcdShapeConstructionInfo* childShape = m_nextShape;
|
for (std::vector<CcdShapeConstructionInfo*>::iterator sit = m_shapeArray.begin();
|
||||||
|
sit != m_shapeArray.end();
|
||||||
while (childShape)
|
sit++)
|
||||||
{
|
{
|
||||||
CcdShapeConstructionInfo* nextShape = childShape->m_nextShape;
|
(*sit)->Release();
|
||||||
childShape->m_nextShape = NULL;
|
|
||||||
childShape->Release();
|
|
||||||
childShape = nextShape;
|
|
||||||
}
|
}
|
||||||
|
m_shapeArray.clear();
|
||||||
if (m_unscaledShape)
|
if (m_unscaledShape)
|
||||||
{
|
{
|
||||||
DeleteBulletShape(m_unscaledShape);
|
DeleteBulletShape(m_unscaledShape);
|
||||||
}
|
}
|
||||||
m_vertexArray.clear();
|
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
|
#define BULLET2_PHYSICSCONTROLLER_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "PHY_IPhysicsController.h"
|
#include "PHY_IPhysicsController.h"
|
||||||
|
|
||||||
@ -42,15 +43,17 @@ class btCollisionShape;
|
|||||||
class CcdShapeConstructionInfo
|
class CcdShapeConstructionInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static CcdShapeConstructionInfo* FindMesh(RAS_MeshObject* mesh, bool polytope);
|
||||||
|
|
||||||
CcdShapeConstructionInfo() :
|
CcdShapeConstructionInfo() :
|
||||||
m_shapeType(PHY_SHAPE_NONE),
|
m_shapeType(PHY_SHAPE_NONE),
|
||||||
m_radius(1.0),
|
m_radius(1.0),
|
||||||
m_height(1.0),
|
m_height(1.0),
|
||||||
m_halfExtend(0.f,0.f,0.f),
|
m_halfExtend(0.f,0.f,0.f),
|
||||||
m_childScale(1.0f,1.0f,1.0f),
|
m_childScale(1.0f,1.0f,1.0f),
|
||||||
m_nextShape(NULL),
|
m_refCount(1),
|
||||||
m_unscaledShape(NULL),
|
m_meshObject(NULL),
|
||||||
m_refCount(1)
|
m_unscaledShape(NULL)
|
||||||
{
|
{
|
||||||
m_childTrans.setIdentity();
|
m_childTrans.setIdentity();
|
||||||
}
|
}
|
||||||
@ -77,22 +80,19 @@ public:
|
|||||||
{
|
{
|
||||||
return m_unscaledShape;
|
return m_unscaledShape;
|
||||||
}
|
}
|
||||||
CcdShapeConstructionInfo* GetNextShape()
|
|
||||||
{
|
|
||||||
return m_nextShape;
|
|
||||||
}
|
|
||||||
CcdShapeConstructionInfo* GetChildShape(int i)
|
CcdShapeConstructionInfo* GetChildShape(int i)
|
||||||
{
|
{
|
||||||
CcdShapeConstructionInfo* shape = m_nextShape;
|
if (i < 0 || i >= m_shapeArray.size())
|
||||||
while (i > 0 && shape != NULL)
|
return NULL;
|
||||||
{
|
|
||||||
shape = shape->m_nextShape;
|
return m_shapeArray.at(i);
|
||||||
i--;
|
|
||||||
}
|
|
||||||
return shape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetMesh(RAS_MeshObject* mesh, bool polytope);
|
bool SetMesh(RAS_MeshObject* mesh, bool polytope);
|
||||||
|
RAS_MeshObject* GetMesh(void)
|
||||||
|
{
|
||||||
|
return m_meshObject;
|
||||||
|
}
|
||||||
|
|
||||||
btCollisionShape* CreateBulletShape();
|
btCollisionShape* CreateBulletShape();
|
||||||
|
|
||||||
@ -109,14 +109,15 @@ public:
|
|||||||
std::vector<int> m_polygonIndexArray; // Contains the array of polygon index in the
|
std::vector<int> m_polygonIndexArray; // Contains the array of polygon index in the
|
||||||
// original mesh that correspond to shape triangles.
|
// original mesh that correspond to shape triangles.
|
||||||
// only set for concave mesh shape.
|
// only set for concave mesh shape.
|
||||||
const RAS_MeshObject* m_meshObject; // Keep a pointer to the original mesh
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CcdShapeConstructionInfo* m_nextShape; // for compound shape
|
static std::map<RAS_MeshObject*, CcdShapeConstructionInfo*> m_meshShapeMap;
|
||||||
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
|
int m_refCount; // this class is shared between replicas
|
||||||
// keep track of users so that we can release it
|
// 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
|
struct CcdConstructionInfo
|
||||||
|
@ -865,7 +865,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
|
|||||||
if (shape == rayCallback.m_hitTriangleShape &&
|
if (shape == rayCallback.m_hitTriangleShape &&
|
||||||
rayCallback.m_hitTriangleIndex < shapeInfo->m_polygonIndexArray.size())
|
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);
|
result.m_polygon = shapeInfo->m_polygonIndexArray.at(rayCallback.m_hitTriangleIndex);
|
||||||
|
|
||||||
// Bullet returns the normal from "outside".
|
// Bullet returns the normal from "outside".
|
||||||
|
Loading…
Reference in New Issue
Block a user