Created a KX_SoftBodyDeformer for real-time soft bodies.
authorErwin Coumans <blender@erwincoumans.com>
Wed, 24 Sep 2008 03:12:10 +0000 (03:12 +0000)
committerErwin Coumans <blender@erwincoumans.com>
Wed, 24 Sep 2008 03:12:10 +0000 (03:12 +0000)
Added SetDeformer/GetDeformer() to KX_GameObject.
Store mapping between graphics/soft body vertices (work-in-progress)
Real-time soft body integration is still very premature, but
for a quick preview, see this testfile:
http://bulletphysics.com/ftp/pub/test/index.php?dir=blender/&file=soft_test.blend

17 files changed:
extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
extern/bullet2/src/BulletSoftBody/btSoftBody.h
extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
extern/bullet2/src/LinearMath/btConvexHull.cpp
extern/bullet2/src/LinearMath/btConvexHull.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_DeformableGameObject.h
source/gameengine/Converter/BL_SkinMeshObject.cpp
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h

index e0bb67f8521e5714ef40a5823960bfd7dbf30164..a074a0b150bf61d5d40513d54d336646710e977f 100644 (file)
@@ -46,6 +46,7 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
 CONCAVE_SHAPES_START_HERE,
        //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
        TRIANGLE_MESH_SHAPE_PROXYTYPE,
+       SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
        ///used for demo integration FAST/Swift collision library and Bullet
        FAST_CONCAVE_MESH_PROXYTYPE,
        //terrain
index 845a5e3005d031ba621077b47c9c7eef79717a9b..2b81a02b557b02fd3bc5fea1a10d18b8a79bd41e 100644 (file)
@@ -117,5 +117,5 @@ const btVector3& btScaledBvhTriangleMeshShape::getLocalScaling() const
 void   btScaledBvhTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
 {
        ///don't make this a movable object!
-       btAssert(0);
+//     btAssert(0);
 }
index 8e1d29fc005325d08aa66ebef1730990c9e0333d..0a1ef8ce5cb9dff3f63be4478e934b6dc0ffb6af 100644 (file)
@@ -39,7 +39,7 @@ public:
        virtual int     getShapeType() const
        {
                //use un-used 'FAST_CONCAVE_MESH_PROXYTYPE' for now, later add SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE to btBroadphaseProxy.h
-               return FAST_CONCAVE_MESH_PROXYTYPE;
+               return SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
        }
 
        virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
@@ -49,6 +49,16 @@ public:
 
        virtual void    processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
 
+       btBvhTriangleMeshShape* getChildShape()
+       {
+               return m_bvhTriMeshShape;
+       }
+
+       const btBvhTriangleMeshShape*   getChildShape() const
+       {
+               return m_bvhTriMeshShape;
+       }
+
        //debugging
        virtual const char*     getName()const {return "SCALEDBVHTRIANGLEMESH";}
 
index 4306ed9c4714761e2b0516b88f7ac24c4d522732..e89bbcc4fa8c2c4c4c327ab7cfb0f23159b4f97d 100644 (file)
@@ -29,7 +29,7 @@ subject to the following restrictions:
 #include "BulletCollision/BroadphaseCollision/btDbvt.h"
 
 class btBroadphaseInterface;
-class btCollisionDispatcher;
+class btDispatcher;
 
 /* btSoftBodyWorldInfo */ 
 struct btSoftBodyWorldInfo
@@ -39,7 +39,7 @@ struct        btSoftBodyWorldInfo
        btScalar                                water_offset;
        btVector3                               water_normal;
        btBroadphaseInterface*  m_broadphase;
-       btCollisionDispatcher*  m_dispatcher;
+       btDispatcher*   m_dispatcher;
        btVector3                               m_gravity;
        btSparseSdf<3>                  m_sparsesdf;
 };     
@@ -607,6 +607,7 @@ public:
        virtual ~btSoftBody();
        /* Check for existing link                                                                                              */ 
 
+       btAlignedObjectArray<int>       m_userIndexMapping;
 
        virtual void    setCollisionShape(btCollisionShape* collisionShape)
        {
index 01b9fc0fd35c7b9c39c4b6a7f389e78755a0f8ff..b363a2efbc1d9478bcff2ade166a486a967a7656 100644 (file)
@@ -21,6 +21,10 @@ subject to the following restrictions:
 #include "btSoftBody.h"
 #include "btSoftBodyHelpers.h"
 
+
+
+
+
 btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
 :btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
 {
@@ -28,6 +32,11 @@ m_drawFlags                  =       fDrawFlags::Std;
 m_drawNodeTree         =       true;
 m_drawFaceTree         =       false;
 m_drawClusterTree      =       false;
+m_sbi.m_broadphase = pairCache;
+m_sbi.m_dispatcher = dispatcher;
+m_sbi.m_sparsesdf.Initialize();
+m_sbi.m_sparsesdf.Reset();
+
 }
                
 btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld()
index d0010b65aadbb1910d3f8b3b3d89fb85c32ba081..aa8795d897b6b10d8b745d07e3f374159c63bb36 100644 (file)
@@ -13,12 +13,12 @@ subject to the following restrictions:
 3. This notice may not be removed or altered from any source distribution.
 */
 
-#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
-
 #ifndef BT_SOFT_RIGID_DYNAMICS_WORLD_H
 #define BT_SOFT_RIGID_DYNAMICS_WORLD_H
 
-class btSoftBody;
+#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
+#include "btSoftBody.h"
+
 typedef        btAlignedObjectArray<btSoftBody*> btSoftBodyArray;
 
 class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld
@@ -29,7 +29,8 @@ class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld
        bool                    m_drawNodeTree;
        bool                    m_drawFaceTree;
        bool                    m_drawClusterTree;
-               
+       btSoftBodyWorldInfo m_sbi;
+
 protected:
        
        virtual void    predictUnconstraintMotion(btScalar timeStep);
@@ -40,7 +41,6 @@ protected:
 
        void    solveSoftBodiesConstraints();
 
-       
 
 public:
        
@@ -57,6 +57,15 @@ public:
        int             getDrawFlags() const { return(m_drawFlags); }
        void    setDrawFlags(int f)     { m_drawFlags=f; }
 
+       btSoftBodyWorldInfo&    getWorldInfo()
+       {
+               return m_sbi;
+       }
+       const btSoftBodyWorldInfo&      getWorldInfo() const
+       {
+               return m_sbi;
+       }
+
                        
        btSoftBodyArray& getSoftBodyArray()
        {
index a20b2059ae9df822cfb891b2e214426333f46c38..b8929a86808288416f4942b4a742978fc46ba8ed 100644 (file)
@@ -869,6 +869,8 @@ bool  HullLibrary::CleanupVertices(unsigned int svcount,
 {
        if ( svcount == 0 ) return false;
 
+       m_vertexIndexMapping.resize(0);
+
 
 #define EPSILON btScalar(0.000001) /* close enough to consider two btScalaring point numbers to be 'the same'. */
 
@@ -1027,6 +1029,7 @@ bool  HullLibrary::CleanupVertices(unsigned int svcount,
                                                v[0] = px;
                                                v[1] = py;
                                                v[2] = pz;
+                                               
                                        }
 
                                        break;
@@ -1041,6 +1044,7 @@ bool  HullLibrary::CleanupVertices(unsigned int svcount,
                                dest[2] = pz;
                                vcount++;
                        }
+                       m_vertexIndexMapping.push_back(j);
                }
        }
 
@@ -1116,13 +1120,22 @@ bool  HullLibrary::CleanupVertices(unsigned int svcount,
 
 void HullLibrary::BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount)
 {
+       btAlignedObjectArray<int>tmpIndices;
+       tmpIndices.resize(m_vertexIndexMapping.size());
+       int i;
+
+       for (i=0;i<m_vertexIndexMapping.size();i++)
+       {
+               tmpIndices[i] = m_vertexIndexMapping[i];
+       }
+
        TUIntArray usedIndices;
        usedIndices.resize(static_cast<int>(vcount));
        memset(&usedIndices[0],0,sizeof(unsigned int)*vcount);
 
        ocount = 0;
 
-       for (unsigned int i=0; i<indexcount; i++)
+       for (i=0; i<indexcount; i++)
        {
                unsigned int v = indices[i]; // original array index
 
@@ -1141,11 +1154,19 @@ void HullLibrary::BringOutYourDead(const btVector3* verts,unsigned int vcount, b
                        overts[ocount][1] = verts[v][1];
                        overts[ocount][2] = verts[v][2];
 
+                       for (int k=0;k<m_vertexIndexMapping.size();k++)
+                       {
+                               if (tmpIndices[k]==v)
+                                       m_vertexIndexMapping[k]=ocount;
+                       }
+
                        ocount++; // increment output vert count
 
                        btAssert( ocount >=0 && ocount <= vcount );
 
                        usedIndices[static_cast<int>(v)] = ocount; // assign new index remapping
+
+               
                }
        }
 
index 8bb80de0225e829d680c2d5749bc1b2d78fb2a90..8c36307dfd6ab1a6a5683b79594fd6151baebef8 100644 (file)
@@ -192,6 +192,9 @@ class HullLibrary
 
 public:
 
+       btAlignedObjectArray<int> m_vertexIndexMapping;
+
+
        HullError CreateConvexHull(const HullDesc& desc, // describes the input request
                                   HullResult&     result);        // contains the resulst
        HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.
index 9b9d5c95de9a9b51cb351a121620517027a4eddf..6a5048a9f15f73f047d96efdbc50ccb8d5674dcf 100644 (file)
@@ -743,7 +743,8 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
        }
 
        // Determine if we need to make a skinned mesh
-       if (mesh->dvert || mesh->key) {
+       if (mesh->dvert || mesh->key || ((blenderobj->gameflag & OB_SOFT_BODY) != 0)) 
+       {
                meshobj = new BL_SkinMeshObject(mesh, lightlayer);
                skinMesh = true;
        }
@@ -1554,20 +1555,20 @@ static KX_GameObject *gameobject_from_blenderobject(
                        // not that we can have shape keys without dvert! 
                        BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, 
                                                                                                                        ob, (BL_SkinMeshObject*)meshobj);
-                       ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
+                       ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
                        if (bHasArmature)
                                dcont->LoadShapeDrivers(ob->parent);
                } else if (bHasArmature) {
                        BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
                                                                                                                        ob, (BL_SkinMeshObject*)meshobj);
-                       ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
+                       ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
                } else if (bHasDvert) {
                        // this case correspond to a mesh that can potentially deform but not with the
                        // object to which it is attached for the moment. A skin mesh was created in
                        // BL_ConvertMesh() so must create a deformer too!
                        BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
                                                                                                                  ob, (BL_SkinMeshObject*)meshobj);
-                       ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
+                       ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
                }
                
                MT_Point3 min = MT_Point3(center) - MT_Vector3(extents);
@@ -2193,8 +2194,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
        
                                if (obj && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE && blenderobj->partype==PARSKEL){
                                        KX_GameObject *par = converter->FindGameObject(blenderobj->parent);
-                                       if (par && obj->m_pDeformer)
-                                               ((BL_SkinDeformer*)obj->m_pDeformer)->SetArmature((BL_ArmatureObject*) par);
+                                       if (par && obj->GetDeformer())
+                                               ((BL_SkinDeformer*)obj->GetDeformer())->SetArmature((BL_ArmatureObject*) par);
                                }
                        }
                }
index 315ad18c42c95ae4c4a3a49ebfb0cdecee04efcd..126a1fcb1e70857c0162094211b8933877c017ee 100644 (file)
@@ -83,9 +83,21 @@ public:
                return (m_pDeformer) ? ((BL_MeshDeformer*)m_pDeformer)->GetMesh()->key : NULL;
        }
        
+       virtual void    SetDeformer(class RAS_Deformer* deformer)
+       {
+               m_pDeformer = deformer;
+       }
+       virtual class RAS_Deformer* GetDeformer()
+       {
+               return m_pDeformer;
+       }
+
 public:
-       RAS_Deformer            *m_pDeformer;   
+       
 protected:     
+       
+       RAS_Deformer            *m_pDeformer;
+
        class BL_ShapeActionActuator *m_activeAct;
        double          m_lastframe;
        Object*         m_blendobj;
index 4f9f1a434b5437b1f21f105b733849b2ce11065e..eb3f9d0588d033d6ed7741cf605cebffcd602d18 100644 (file)
@@ -87,7 +87,7 @@ void BL_SkinMeshObject::UpdateBuckets(void* clientobj,double* oglmatrix,bool use
                        continue;
 
                RAS_MeshSlot *slot = *it->m_slots[clientobj];
-               slot->m_pDeformer = ((BL_DeformableGameObject*)clientobj)->m_pDeformer;
+               slot->m_pDeformer = ((BL_DeformableGameObject*)clientobj)->GetDeformer();
        }
 
        RAS_MeshObject::UpdateBuckets(clientobj, oglmatrix, useObjectColor, rgbavec, visible, culled);
index 46b53d07efc6f68f0989ae283b47a05425c6c6cd..c4411a58856259b08e84f00f90710fec3553962b 100644 (file)
@@ -38,6 +38,8 @@
 #include "RAS_MeshObject.h"
 #include "KX_Scene.h"
 #include "SYS_System.h"
+#include "BL_SkinMeshObject.h"
+#include "BulletSoftBody/btSoftBody.h"
 
 #include "PHY_Pro.h" //todo cleanup
 #include "KX_ClientObjectInfo.h"
@@ -765,7 +767,7 @@ void        KX_ConvertBulletObject( class   KX_GameObject* gameobj,
                }
        case KX_BOUNDMESH:
                {
-                       if (!ci.m_mass)
+                       if (!ci.m_mass ||objprop->m_softbody)
                        {                               
                                // mesh shapes can be shared, check first if we already have a shape on that mesh
                                class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, false);
@@ -988,6 +990,112 @@ void      KX_ConvertBulletObject( class   KX_GameObject* gameobj,
 
        physicscontroller->SetObject(gameobj->GetSGNode());
 
+       class KX_SoftBodyDeformer : public RAS_Deformer
+       {
+               btSoftBody*     m_softBody;
+               class BL_SkinMeshObject*        m_pMeshObject;
+               class BL_DeformableGameObject*  m_gameobj;
+
+
+       public:
+               KX_SoftBodyDeformer(btSoftBody* softBody,BL_SkinMeshObject*     pMeshObject,BL_DeformableGameObject*    gameobj)
+                       : m_softBody(softBody),
+                       m_pMeshObject(pMeshObject),
+                       m_gameobj(gameobj)
+               {
+                       //printf("KX_SoftBodyDeformer\n");
+               };
+
+               virtual ~KX_SoftBodyDeformer()
+               {
+                       //printf("~KX_SoftBodyDeformer\n");
+               };
+               virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
+               {
+                       //printf("relink\n");
+               }
+               virtual bool Apply(class RAS_IPolyMaterial *polymat)
+               {
+                       //printf("apply\n");
+                       RAS_MeshSlot::iterator it;
+                       RAS_MeshMaterial *mmat;
+                       RAS_MeshSlot *slot;
+                       size_t i;
+
+                       // update the vertex in m_transverts
+                       Update();
+
+                       // The vertex cache can only be updated for this deformer:
+                       // Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
+                       // share the same mesh (=the same cache). As the rendering is done per polymaterial
+                       // cycling through the objects, the entire mesh cache cannot be updated in one shot.
+                       mmat = m_pMeshObject->GetMeshMaterial(polymat);
+                       if(!mmat->m_slots[(void*)m_gameobj])
+                               return true;
+
+                       slot = *mmat->m_slots[(void*)m_gameobj];
+
+                       // for each array
+                       for(slot->begin(it); !slot->end(it); slot->next(it)) 
+                       {
+                               // for each vertex
+                               // copy the untransformed data from the original mvert
+                               int count = 0;
+                               {
+
+                                       for(i=it.startvertex; i<it.endvertex; i++,count++)
+                                       {
+                                       }
+                               }
+                               btSoftBody::tNodeArray&   nodes(m_softBody->m_nodes);
+
+                               if (count == m_softBody->m_userIndexMapping.size())
+                               {
+                                       int index = 0;
+                                       for(i=it.startvertex; i<it.endvertex; i++,index++) {
+                                               RAS_TexVert& v = it.vertex[i];
+
+                                               MT_Point3 pt (
+                                                       nodes[m_softBody->m_userIndexMapping[index]].m_x.getX(),
+                                                       nodes[m_softBody->m_userIndexMapping[index]].m_x.getY(),
+                                                       nodes[m_softBody->m_userIndexMapping[index]].m_x.getZ());
+                                               v.SetXYZ(pt);
+
+                                               //(m_transverts[v.getOrigIndex()]);
+                                       }
+                               }
+
+                       }
+
+                       return true;
+               }
+               virtual bool Update(void)
+               {
+                       //printf("update\n");
+                       return true;//??
+               }
+               virtual RAS_Deformer *GetReplica()
+               {
+                       //printf("getReplica\n");
+                       return 0;
+               }
+       protected:
+               //class RAS_MeshObject  *m_pMesh;
+       };
+
+       ///test for soft bodies
+       if (objprop->m_softbody && physicscontroller)
+       {
+               btSoftBody* softBody = physicscontroller->GetSoftBody();
+               if (softBody && gameobj->GetMesh(0))
+               {
+                       //should be a mesh then, so add a soft body deformer
+                       KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer(softBody, (BL_SkinMeshObject*)gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
+                       gameobj->SetDeformer(softbodyDeformer);
+                       
+               }
+       }
+
 }
 
 
index 2da0be4df251721230484d32df91c4defd427b00..12e29cf32946b1d70d0983ad763198d04cd3c63e 100644 (file)
@@ -332,6 +332,14 @@ public:
                m_pPhysicsController1 = physicscontroller;
        }
 
+       virtual class RAS_Deformer* GetDeformer()
+       {
+               return 0;
+       }
+       virtual void    SetDeformer(class RAS_Deformer* deformer)
+       {
+
+       }
 
        /**
         * @section Coordinate system manipulation functions
index 04db96c298cf75dd0bf08fb620163c1545c93e15..6eeb732c1e32c9e8c31cbfa3eb149c50d5b69ef2 100644 (file)
@@ -977,10 +977,10 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
        {
                BL_DeformableGameObject* newobj = static_cast<BL_DeformableGameObject*>( gameobj );
                
-               if (newobj->m_pDeformer)
+               if (newobj->GetDeformer())
                {
-                       delete newobj->m_pDeformer;
-                       newobj->m_pDeformer = NULL;
+                       delete newobj->GetDeformer();
+                       newobj->SetDeformer(NULL);
                }
 
                if (mesh->IsDeformed())
@@ -1030,7 +1030,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
                                                NULL
                                        );
                                }
-                               newobj->m_pDeformer = shapeDeformer;
+                               newobj->SetDeformer( shapeDeformer);
                        }
                        else if (bHasArmature) 
                        {
@@ -1042,14 +1042,14 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
                                        static_cast<BL_ArmatureObject*>( parentobj )
                                );
                                releaseParent= false;
-                               newobj->m_pDeformer = skinDeformer;
+                               newobj->SetDeformer(skinDeformer);
                        }
                        else if (bHasDvert)
                        {
                                BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(
                                        newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
                                );
-                               newobj->m_pDeformer = meshdeformer;
+                               newobj->SetDeformer(meshdeformer);
                        }
 
                        // release parent reference if its not being used 
index 41ae5e38309467d670a8aefe7a215009aaa70915..ad79db16dc4509518a2d7cb46083fb78eeef2783 100644 (file)
@@ -20,7 +20,11 @@ subject to the following restrictions:
 #include "CcdPhysicsEnvironment.h"
 #include "RAS_MeshObject.h"
 #include "BulletSoftBody/btSoftBody.h"
+#include "BulletSoftBody//btSoftBodyInternals.h"
+#include "BulletSoftBody/btSoftBodyHelpers.h"
+#include "LinearMath/btConvexHull.h"
 
+#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
 
 class BP_Proxy;
 
@@ -135,11 +139,7 @@ btSoftBody* CcdPhysicsController::GetSoftBody()
 
 #include "BulletSoftBody/btSoftBodyHelpers.h"
 
-btVector3 pts[3] = {btVector3(0,0,0),
-btVector3(0,1,0),
-btVector3(1,1,0)};
-int triangles[3] = {0,1,2};
-btSoftBodyWorldInfo sbi;
+
 
 void CcdPhysicsController::CreateRigidbody()
 {
@@ -151,8 +151,13 @@ void CcdPhysicsController::CreateRigidbody()
 
        //create a collision object
 
+       int shapeType = m_cci.m_collisionShape ? m_cci.m_collisionShape->getShapeType() : 0;
+
        //disable soft body until first sneak preview is ready
-       if (0)//m_cci.m_bSoft)
+       if (m_cci.m_bSoft && m_cci.m_collisionShape && 
+               (shapeType == CONVEX_HULL_SHAPE_PROXYTYPE))
+               //(shapeType == TRIANGLE_MESH_SHAPE_PROXYTYPE) |
+               //(shapeType == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)))
        {
                btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
                rbci.m_linearDamping = m_cci.m_linearDamping;
@@ -161,54 +166,161 @@ void CcdPhysicsController::CreateRigidbody()
                rbci.m_restitution = m_cci.m_restitution;
 
                
-               sbi.m_broadphase = this->m_cci.m_physicsEnv->getBroadphase();
-               sbi.m_dispatcher = (btCollisionDispatcher*) m_cci.m_physicsEnv->getDispatcher();
-               
                int nodecount = 0;
                
-               
                int numtriangles = 1;
                
-               btVector3 p = trans.getOrigin();
+               btVector3 p(0,0,0);// = getOrigin();
                btScalar h = 1.f;
                
+               btSoftRigidDynamicsWorld* softDynaWorld = (btSoftRigidDynamicsWorld*)m_cci.m_physicsEnv->getDynamicsWorld();
+
                PHY__Vector3    grav;
-               m_cci.m_physicsEnv->getGravity(grav);
-               sbi.m_gravity.setValue(grav[0],grav[1],grav[2]);
-
-               const btVector3 c[]={   p+h*btVector3(-1,-1,-1),
-               p+h*btVector3(+1,-1,-1),
-               p+h*btVector3(-1,+1,-1),
-               p+h*btVector3(+1,+1,-1),
-               p+h*btVector3(-1,-1,+1),
-               p+h*btVector3(+1,-1,+1),
-               p+h*btVector3(-1,+1,+1),
-               p+h*btVector3(+1,+1,+1)};
-
-               int i=0;
-               const int n=15;
+               grav[0] = softDynaWorld->getGravity().getX();
+               grav[1] = softDynaWorld->getGravity().getY();
+               grav[2] = softDynaWorld->getGravity().getZ();
+               softDynaWorld->getWorldInfo().m_gravity.setValue(grav[0],grav[1],grav[2]); //??
+
+       
                //btSoftBody*   psb=btSoftBodyHelpers::CreateRope(sbi,  btVector3(-10,0,i*0.25),btVector3(10,0,i*0.25), 16,1+2);
-               btSoftBody* psb = btSoftBodyHelpers::CreateFromConvexHull(sbi,c,8);
 
-               m_object = psb;//btSoftBodyHelpers::CreateFromTriMesh(sbi,&pts[0].getX(),triangles,numtriangles);
+               btSoftBody* psb  = 0;
+
+               if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE)
+               {
+                       btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape;
+                       btAlignedObjectArray<btVector3> transformedVertices;
+                       transformedVertices.resize(convexHull->getNumPoints());
+                       for (int i=0;i<convexHull->getNumPoints();i++)
+                       {
+                               transformedVertices[i] = trans(convexHull->getPoints()[i]);
+                       }
+
+                       //psb = btSoftBodyHelpers::CreateFromConvexHull(sbi,&transformedVertices[0],convexHull->getNumPoints());
+
+                       {
+                               int nvertices = convexHull->getNumPoints();
+                               const btVector3* vertices = &transformedVertices[0];
+                               btSoftBodyWorldInfo& worldInfo = softDynaWorld->getWorldInfo();
+
+                               HullDesc                hdsc(QF_TRIANGLES,nvertices,vertices);
+                               HullResult              hres;
+                               HullLibrary             hlib;/*??*/ 
+                               hdsc.mMaxVertices=nvertices;
+                               hlib.CreateConvexHull(hdsc,hres);
+                               
+                               psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices,
+                                       &hres.m_OutputVertices[0],0);
+                               for(int i=0;i<(int)hres.mNumFaces;++i)
+                               {
+                                       const int idx[]={       hres.m_Indices[i*3+0],
+                                               hres.m_Indices[i*3+1],
+                                               hres.m_Indices[i*3+2]};
+                                       if(idx[0]<idx[1]) psb->appendLink(      idx[0],idx[1]);
+                                       if(idx[1]<idx[2]) psb->appendLink(      idx[1],idx[2]);
+                                       if(idx[2]<idx[0]) psb->appendLink(      idx[2],idx[0]);
+                                       psb->appendFace(idx[0],idx[1],idx[2]);
+                               }
+                               
+                               {
+                                       for (int i=0;i<hlib.m_vertexIndexMapping.size();i++)
+                                               psb->m_userIndexMapping.push_back(hlib.m_vertexIndexMapping[i]);
+                                               //psb->m_userIndexMapping.push_back(hres.m_Indices[i]);
+                               }
+
+                               hlib.ReleaseResult(hres);
+                               psb->randomizeConstraints();
+                               
+                       }
+
+
 
-               psb->m_cfg.collisions   =       btSoftBody::fCollision::SDF_RS;//btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS;
 
-               sbi.m_sparsesdf.Reset();
-               sbi.m_sparsesdf.Initialize();
 
-               psb->generateBendingConstraints(2);
 
-               psb->m_cfg.kDF=1;
-               psb->activate();
-               psb->setActivationState(1);
-               psb->setDeactivationTime(1.f);
-               psb->m_cfg.piterations          =       4;
+               } else
+               {
+                       /*
+                       if (m_cci.m_collisionShape->getShapeType() ==SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
+                       {
+                               btScaledBvhTriangleMeshShape* scaledtrimeshshape = (btScaledBvhTriangleMeshShape*) m_cci.m_collisionShape;
+                               btBvhTriangleMeshShape* trimeshshape = scaledtrimeshshape->getChildShape();
+
+                               ///only deal with meshes that have 1 sub part/component, for now
+                               if (trimeshshape->getMeshInterface()->getNumSubParts()==1)
+                               {
+                                       unsigned char* vertexBase;
+                                       PHY_ScalarType vertexType;
+                                       int numverts;
+                                       int vertexstride;
+                                       unsigned char* indexbase;
+                                       int indexstride;
+                                       int numtris;
+                                       PHY_ScalarType indexType;
+                                       trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType);
+                                       
+                                       psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,(const btScalar*)vertexBase,(const int*)indexbase,numtris);
+                               }
+                       } else
+                       {
+                               btBvhTriangleMeshShape* trimeshshape = (btBvhTriangleMeshShape*) m_cci.m_collisionShape;
+                               ///only deal with meshes that have 1 sub part/component, for now
+                               if (trimeshshape->getMeshInterface()->getNumSubParts()==1)
+                               {
+                                       unsigned char* vertexBase;
+                                       PHY_ScalarType vertexType;
+                                       int numverts;
+                                       int vertexstride;
+                                       unsigned char* indexbase;
+                                       int indexstride;
+                                       int numtris;
+                                       PHY_ScalarType indexType;
+                                       trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType);
+                                       
+                                       psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,(const btScalar*)vertexBase,(const int*)indexbase,numtris);
+                               }
+                       
+
+                               //psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,&pts[0].getX(),triangles,numtriangles);
+                       }
+                       */
+
+               }
+               
+               
+               m_object = psb;
+
+               //psb->m_cfg.collisions =       btSoftBody::fCollision::SDF_RS;//btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS;
+               psb->m_cfg.collisions   =       btSoftBody::fCollision::SDF_RS + btSoftBody::fCollision::CL_SS;
+               
+               //btSoftBody::Material* pm=psb->appendMaterial();
+               btSoftBody::Material*   pm=psb->m_materials[0];
+               pm->m_kLST                              =       0.1f;
+               //pm->m_kAST = 0.01f;
+               //pm->m_kVST = 0.001f;
+               psb->generateBendingConstraints(2,pm);
+/*
+               psb->m_cfg.kDF = 0.1f;//1.f;
+               psb->m_cfg.kDP          =       0.0001;
+               //psb->m_cfg.kDP                =       0.005;
+               psb->m_cfg.kCHR         =       0.1;
+               //psb->m_cfg.kVCF = 0.1f;
+               psb->m_cfg.kVCF = 0.0001f;
+               //psb->m_cfg.kAHR = 0.1f;
+               psb->m_cfg.kAHR = 0.0001f;
+               psb->m_cfg.kMT = 0.1f;
+               //psb->m_cfg.kDF=1;
+               */
+
+//             psb->activate();
+//             psb->setActivationState(1);
+//             psb->setDeactivationTime(1.f);
+               //psb->m_cfg.piterations                =       4;
                //psb->m_materials[0]->m_kLST   =       0.1+(i/(btScalar)(n-1))*0.9;
-               psb->setTotalMass(20);
+               psb->setTotalMass(m_cci.m_mass);
+               psb->generateClusters(64);              
                psb->setCollisionFlags(0);
-
-               m_object->setCollisionShape(rbci.m_collisionShape);
+//             m_object->setCollisionShape(rbci.m_collisionShape);
                btTransform startTrans;
 
                if (rbci.m_motionState)
@@ -218,8 +330,13 @@ void CcdPhysicsController::CreateRigidbody()
                {
                        startTrans = rbci.m_startWorldTransform;
                }
+               startTrans.setIdentity();
+
                m_object->setWorldTransform(startTrans);
                m_object->setInterpolationWorldTransform(startTrans);
+               m_MotionState->setWorldPosition(0,0,0);
+               m_MotionState->setWorldOrientation(0,0,0,1);
+
 
        } else
        {
index 96aa9ad164e9b103e914469bfe61b9c05e853d71..8c5aae3f8c92affea657ce1e81aa05bb62377971 100644 (file)
@@ -452,6 +452,8 @@ void        CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
 
 }
 
+               
+
 void   CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
 {
        //also remove constraint
index 9b6a76d49eec16bcf51ba8c54f62b12e4bfb0522..56a639509c5938da43a854badf6ac7c07500f63f 100644 (file)
@@ -216,7 +216,10 @@ protected:
        
                void    SyncMotionStates(float timeStep);
 
-               
+               class   btSoftRigidDynamicsWorld*       getDynamicsWorld()
+               {
+                       return m_dynamicsWorld;
+               }
        
                class btConstraintSolver*       GetConstraintSolver();