Revision: 16639
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16639
Author:   ben2610
Date:     2008-09-20 23:33:54 +0200 (Sat, 20 Sep 2008)

Log Message:
-----------
BGE patch: allow Bullet mesh shape sharing for objects copied with ALT-D.

Modified Paths:
--------------
    trunk/blender/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
    trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
    trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.h
    trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp

Modified: trunk/blender/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp 
2008-09-20 16:30:14 UTC (rev 16638)
+++ trunk/blender/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp 
2008-09-20 21:33:54 UTC (rev 16639)
@@ -767,7 +767,17 @@
                {
                        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);

Modified: 
trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
===================================================================
--- trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp     
2008-09-20 16:30:14 UTC (rev 16638)
+++ trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp     
2008-09-20 21:33:54 UTC (rev 16639)
@@ -902,9 +902,25 @@
 }
 
 // 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 @@
                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 @@
                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 @@
 
 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);
+               }
+       }
 }
 
 

Modified: trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.h
===================================================================
--- trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.h       
2008-09-20 16:30:14 UTC (rev 16638)
+++ trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.h       
2008-09-20 21:33:54 UTC (rev 16639)
@@ -18,6 +18,7 @@
 #define BULLET2_PHYSICSCONTROLLER_H
 
 #include <vector>
+#include <map>
 
 #include "PHY_IPhysicsController.h"
 
@@ -42,15 +43,17 @@
 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 @@
        {
                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 @@
        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
+       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
-       int                                             m_refCount;             
// this class is shared between replicas
-                                                                               
        // keep track of users so that we can release it 
+       std::vector<CcdShapeConstructionInfo*> m_shapeArray;    // for compound 
shapes
 };
 
 struct CcdConstructionInfo

Modified: 
trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
===================================================================
--- trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp    
2008-09-20 16:30:14 UTC (rev 16638)
+++ trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp    
2008-09-20 21:33:54 UTC (rev 16639)
@@ -865,7 +865,7 @@
                                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".


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to