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:
authorBenoit Bolsee <benoit.bolsee@online.be>2008-09-21 01:33:54 +0400
committerBenoit Bolsee <benoit.bolsee@online.be>2008-09-21 01:33:54 +0400
commit22a50402efc1fd9b725d7760c90b343e63191ee4 (patch)
treea37957c7da0b6d4c7d64f6216526a6f3ab5d5834
parent768e12a064cf524a14a84203b100a33235bba30e (diff)
BGE patch: allow Bullet mesh shape sharing for objects copied with ALT-D.
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp12
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp58
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h37
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp2
4 files changed, 73 insertions, 36 deletions
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index b3f24d97281..6f5f9e22506 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -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);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index b1b97b5370f..1ec555f653d 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -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);
+ }
+ }
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 355c1d608b1..af146413c91 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -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
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 96caf885e7c..68b3df1695c 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -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".