BGE patch: dynamically update the coumpound parent shape when parenting to a compound...
authorBenoit Bolsee <benoit.bolsee@online.be>
Tue, 13 Jan 2009 22:59:18 +0000 (22:59 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Tue, 13 Jan 2009 22:59:18 +0000 (22:59 +0000)
This patch modifies the way the setParent actuator and KX_GameObject::setParent() function
works when parenting to a compound object: the collision shape of the object being parented
is dynamically added to the coumpound shape.
Similarly, unparenting an object from a compound object will cause the child collision shape
to be dynamically removed from the parent shape provided that is was previously added with
setParent.

Note: * This also works if the object is parented to a child of a compound object: the
        collision shape is added to the compound shape of the top parent.
      * The collision shape is added with the transformation (position, scale and orientation)
        it had at the time of the parenting.
      * The child shape is rigidly attached to the compound shape, the transformation is not
        affected by any further change in position/scale/orientation of the child object.
      * While the child shape is added to the compound shape, the child object is removed from
        the dynamic world to avoid superposition of shapes (one for the object itself and
        one for the compound child shape). This means that collision sensors on the child
        object are disabled while the child object is parent to a compound object.
      * There is no difference when setParent is used on a non-compound object: the child
        object is automatically changed to a static ghost object to avoid bad interaction
        with the parent shape; collision sensors on the child object continue to be active
        while the object is parented.
      * The child shape dynamically added to a compound shape modifies the inertia of the
        compound object but not the mass. It participates to collision detection as any other
        "static" child shape.

14 files changed:
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_IPhysicsController.cpp
source/gameengine/Ketsji/KX_IPhysicsController.h
source/gameengine/Ketsji/KX_OdePhysicsController.cpp
source/gameengine/Ketsji/KX_OdePhysicsController.h
source/gameengine/Ketsji/KX_SumoPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Physics/common/PHY_DynamicTypes.h

index 3a20bbfbb11393f589fd301744df41cbd085609f..a67f4a54b3fec0baebf87ef0a21b40aa197241ae 100644 (file)
 #include "BulletSoftBody/btSoftBody.h"
 
 
-KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna)
-: KX_IPhysicsController(dyna,(PHY_IPhysicsController*)this),
+KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound)
+: KX_IPhysicsController(dyna,compound,(PHY_IPhysicsController*)this),
 CcdPhysicsController(ci),
-m_savedCollisionFlags(0)
+m_savedCollisionFlags(0),
+m_bulletChildShape(NULL)
 {
 
 }
@@ -175,6 +176,133 @@ void      KX_BulletPhysicsController::setRigidBody(bool rigid)
 {
 }
 
+/* This function dynamically adds the collision shape of another controller to
+   the current controller shape provided it is a compound shape.
+   The idea is that dynamic parenting on a compound object will dynamically extend the shape
+*/
+void    KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* child)
+{ 
+       if (child == NULL || !IsCompound())
+               return;
+       // other controller must be a bullet controller too
+       // verify that body and shape exist and match
+       KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child);
+       btRigidBody* rootBody = GetRigidBody();
+       btRigidBody* childBody = childCtrl->GetRigidBody();
+       if (!rootBody || !childBody)
+               return;
+       const btCollisionShape* rootShape = rootBody->getCollisionShape();
+       const btCollisionShape* childShape = childBody->getCollisionShape();
+       if (!rootShape || 
+               !childShape || 
+               rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE ||
+               childShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
+               return;
+       btCompoundShape* compoundShape = (btCompoundShape*)rootShape;
+       // compute relative transformation between parent and child
+       btTransform rootTrans;
+       btTransform childTrans;
+       rootBody->getMotionState()->getWorldTransform(rootTrans);
+       childBody->getMotionState()->getWorldTransform(childTrans);
+       btVector3 rootScale = rootShape->getLocalScaling();
+       rootScale[0] = 1.0/rootScale[0];
+       rootScale[1] = 1.0/rootScale[1];
+       rootScale[2] = 1.0/rootScale[2];
+       // relative scale = child_scale/parent_scale
+       btVector3 relativeScale = childShape->getLocalScaling()*rootScale;
+       btMatrix3x3 rootRotInverse = rootTrans.getBasis().transpose();  
+       // relative pos = parent_rot^-1 * ((parent_pos-child_pos)/parent_scale)
+       btVector3 relativePos = rootRotInverse*((childTrans.getOrigin()-rootTrans.getOrigin())*rootScale);
+       // relative rot = parent_rot^-1 * child_rot
+       btMatrix3x3 relativeRot = rootRotInverse*childTrans.getBasis();
+       // create a proxy shape info to store the transformation
+       CcdShapeConstructionInfo* proxyShapeInfo = new CcdShapeConstructionInfo();
+       // store the transformation to this object shapeinfo
+       proxyShapeInfo->m_childTrans.setOrigin(relativePos);
+       proxyShapeInfo->m_childTrans.setBasis(relativeRot);
+       proxyShapeInfo->m_childScale.setValue(relativeScale[0], relativeScale[1], relativeScale[2]);
+       // we will need this to make sure that we remove the right proxy later when unparenting
+       proxyShapeInfo->m_userData = childCtrl;
+       proxyShapeInfo->SetProxy(childCtrl->GetShapeInfo()->AddRef());
+       // add to parent compound shapeinfo
+       GetShapeInfo()->AddShape(proxyShapeInfo);
+       // create new bullet collision shape from the object shapeinfo and set scaling
+       btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape();
+       newChildShape->setLocalScaling(relativeScale);
+       // add bullet collision shape to parent compound collision shape
+       compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape);
+       // remember we created this shape
+       childCtrl->m_bulletChildShape = newChildShape;
+       // recompute inertia of parent
+       if (!rootBody->isStaticOrKinematicObject())
+       {
+               btVector3 localInertia;
+               float mass = 1.f/rootBody->getInvMass();
+               compoundShape->calculateLocalInertia(mass,localInertia);
+               rootBody->setMassProps(mass,localInertia);
+       }
+       // must update the broadphase cache,
+       GetPhysicsEnvironment()->refreshCcdPhysicsController(this);
+       // remove the children
+       GetPhysicsEnvironment()->disableCcdPhysicsController(childCtrl);
+}
+
+/* Reverse function of the above, it will remove a shape from a compound shape
+   provided that the former was added to the later using  AddCompoundChild()
+*/
+void    KX_BulletPhysicsController::RemoveCompoundChild(KX_IPhysicsController* child)
+{ 
+       if (child == NULL || !IsCompound())
+               return;
+       // other controller must be a bullet controller too
+       // verify that body and shape exist and match
+       KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child);
+       btRigidBody* rootBody = GetRigidBody();
+       btRigidBody* childBody = childCtrl->GetRigidBody();
+       if (!rootBody || !childBody)
+               return;
+       const btCollisionShape* rootShape = rootBody->getCollisionShape();
+       if (!rootShape || 
+               rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE)
+               return;
+       btCompoundShape* compoundShape = (btCompoundShape*)rootShape;
+       // retrieve the shapeInfo
+       CcdShapeConstructionInfo* childShapeInfo = childCtrl->GetShapeInfo();
+       CcdShapeConstructionInfo* rootShapeInfo = GetShapeInfo();
+       // and verify that the child is part of the parent
+       int i = rootShapeInfo->FindChildShape(childShapeInfo, childCtrl);
+       if (i < 0)
+               return;
+       rootShapeInfo->RemoveChildShape(i);
+       if (childCtrl->m_bulletChildShape)
+       {
+               int numChildren = compoundShape->getNumChildShapes();
+               for (i=0; i<numChildren; i++)
+               {
+                       if (compoundShape->getChildShape(i) == childCtrl->m_bulletChildShape)
+                       {
+                               compoundShape->removeChildShapeByIndex(i);
+                               compoundShape->recalculateLocalAabb();
+                               break;
+                       }
+               }
+               delete childCtrl->m_bulletChildShape;
+               childCtrl->m_bulletChildShape = NULL;
+       }
+       // recompute inertia of parent
+       if (!rootBody->isStaticOrKinematicObject())
+       {
+               btVector3 localInertia;
+               float mass = 1.f/rootBody->getInvMass();
+               compoundShape->calculateLocalInertia(mass,localInertia);
+               rootBody->setMassProps(mass,localInertia);
+       }
+       // must update the broadphase cache,
+       GetPhysicsEnvironment()->refreshCcdPhysicsController(this);
+       // reactivate the children
+       GetPhysicsEnvironment()->enableCcdPhysicsController(childCtrl);
+}
+
 void   KX_BulletPhysicsController::SuspendDynamics(bool ghost)
 {
        btRigidBody *body = GetRigidBody();
@@ -251,6 +379,7 @@ SG_Controller*      KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)
        physicsreplica->setParentCtrl(ccdParent);
        physicsreplica->PostProcessReplica(motionstate,parentctrl);
        physicsreplica->m_userdata = (PHY_IPhysicsController*)physicsreplica;
+       physicsreplica->m_bulletChildShape = NULL;
        return physicsreplica;
        
 }
index d5fca4ec6d30ea26ddcb83358063d39de4a50322..a50af2699bfb596b1b755efd22a3e86c4331e88f 100644 (file)
@@ -13,10 +13,11 @@ private:
        short int m_savedCollisionFilterGroup;
        short int m_savedCollisionFilterMask;
        MT_Scalar m_savedMass;
+       btCollisionShape* m_bulletChildShape;
 
 public:
 
-       KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna);
+       KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool compound);
        virtual ~KX_BulletPhysicsController ();
 
        ///////////////////////////////////
@@ -42,6 +43,8 @@ public:
        virtual MT_Scalar       GetMass();
        virtual MT_Vector3      getReactionForce();
        virtual void    setRigidBody(bool rigid);
+       virtual void    AddCompoundChild(KX_IPhysicsController* child);
+       virtual void    RemoveCompoundChild(KX_IPhysicsController* child);
 
        virtual void    resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
 
index 0e7a6d92ec11d44de45f9b97eb37ae9f9a616c16..46e46b014b582342e93b5bf2dd6a67563d979249 100644 (file)
@@ -1084,7 +1084,7 @@ void      KX_ConvertBulletObject( class   KX_GameObject* gameobj,
        ci.m_bSoft = objprop->m_softbody;
        MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
        ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
-       KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna);
+       KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,objprop->m_hasCompoundChildren);
        // shapeInfo is reference counted, decrement now as we don't use it anymore
        if (shapeInfo)
                shapeInfo->Release();
index f2a554c6b2a6f9367f55b5752f7b5c132249e37c..706b80a1fab9afc10f0d1d9551634037db333eb8 100644 (file)
@@ -252,6 +252,20 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
                if (rootlist->RemoveValue(this))
                        // the object was in parent list, decrement ref count as it's now removed
                        Release();
+               // if the new parent is a compound object, add this object shape to the compound shape.
+               // step 0: verify this object has physical controller
+               if (m_pPhysicsController1)
+               {
+                       // step 1: find the top parent (not necessarily obj)
+                       KX_GameObject* rootobj = (KX_GameObject*)obj->GetSGNode()->GetRootSGParent()->GetSGClientObject();
+                       // step 2: verify it has a physical controller and compound shape
+                       if (rootobj != NULL && 
+                               rootobj->m_pPhysicsController1 != NULL &&
+                               rootobj->m_pPhysicsController1->IsCompound())
+                       {
+                               rootobj->m_pPhysicsController1->AddCompoundChild(m_pPhysicsController1);
+                       }
+               }
        }
 }
 
@@ -260,6 +274,8 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
        // check on valid node in case a python controller holds a reference to a deleted object
        if (GetSGNode() && GetSGNode()->GetSGParent())
        {
+               // get the root object to remove us from compound object if needed
+               KX_GameObject* rootobj = (KX_GameObject*)GetSGNode()->GetRootSGParent()->GetSGClientObject();
                // Set us to the right spot 
                GetSGNode()->SetLocalScale(GetSGNode()->GetWorldScaling());
                GetSGNode()->SetLocalOrientation(GetSGNode()->GetWorldOrientation());
@@ -275,6 +291,13 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
                        rootlist->Add(AddRef());
                if (m_pPhysicsController1) 
                {
+                       // in case this controller was added as a child shape to the parent
+                       if (rootobj != NULL && 
+                               rootobj->m_pPhysicsController1 != NULL &&
+                               rootobj->m_pPhysicsController1->IsCompound())
+                       {
+                               rootobj->m_pPhysicsController1->RemoveCompoundChild(m_pPhysicsController1);
+                       }
                        m_pPhysicsController1->RestoreDynamics();
                }
        }
index 5cd66efd965c2c83cfd53903d55cee3cae2d22a6..a38222c5f7ea56308786e9e866f0d9274b25009f 100644 (file)
 
 #include "PHY_DynamicTypes.h"
 
-KX_IPhysicsController::KX_IPhysicsController(bool dyna,void* userdata)
+KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool compound, void* userdata)
 
 :      m_bDyna(dyna),
+       m_bCompound(compound),
        m_suspendDynamics(false),
        m_userdata(userdata)
 {
index 4ea283e9f98071ca07e21a2c4fdf2bacbe2428dd..fed71735becd26526d6128b50b3f3f1f1a36ad53 100644 (file)
@@ -32,6 +32,7 @@
 #include "SG_Controller.h"
 #include "MT_Vector3.h"
 #include "MT_Point3.h"
+#include "MT_Transform.h"
 #include "MT_Matrix3x3.h"
 
 struct KX_ClientObjectInfo;
@@ -48,10 +49,11 @@ class KX_IPhysicsController : public SG_Controller
 {
 protected:
        bool            m_bDyna;
+       bool            m_bCompound;
        bool            m_suspendDynamics;
        void*           m_userdata;
 public:
-       KX_IPhysicsController(bool dyna,void* userdata);
+       KX_IPhysicsController(bool dyna,bool compound, void* userdata);
        virtual ~KX_IPhysicsController();
 
 
@@ -78,6 +80,8 @@ public:
        virtual MT_Scalar       GetMass()=0;
        virtual MT_Vector3      getReactionForce()=0;
        virtual void    setRigidBody(bool rigid)=0;
+       virtual void    AddCompoundChild(KX_IPhysicsController* child) = 0;
+       virtual void    RemoveCompoundChild(KX_IPhysicsController* child) = 0;
 
        virtual void    SuspendDynamics(bool ghost=false)=0;
        virtual void    RestoreDynamics()=0;
@@ -92,6 +96,10 @@ public:
                return m_bDyna;
        }
 
+       bool    IsCompound(void) {
+               return m_bCompound;
+       }
+
        virtual MT_Scalar GetRadius()=0;
        virtual void    SetSumoTransform(bool nondynaonly)=0;
        // todo: remove next line !
index 6a701a5f25b72e05b42a70f08bd859acd929b3e2..dc6990267d42c1893d0d773a3316bfe06977f738 100644 (file)
@@ -50,7 +50,7 @@ KX_OdePhysicsController::KX_OdePhysicsController(
                                                                                                 float  extends[3],
                                                                                                 float  radius
                                                                                                 ) 
-: KX_IPhysicsController(dyna,(PHY_IPhysicsController*)this),
+: KX_IPhysicsController(dyna,false,(PHY_IPhysicsController*)this),
 ODEPhysicsController(
 dyna,fullRigidBody,phantom,motionstate,
 space,world,mass,friction,restitution,
index 53050f6ce3e6ed89d6f1e258eda36bd1198cdc22..e3b5336c0b55ba2f1e0e9e9cf3054bb9e26b8c33 100644 (file)
@@ -73,6 +73,8 @@ public:
        virtual MT_Scalar       GetMass();
        virtual MT_Vector3      getReactionForce();
        virtual void    setRigidBody(bool rigid);
+       virtual void    AddCompoundChild(KX_IPhysicsController* child) { }
+       virtual void    RemoveCompoundChild(KX_IPhysicsController* child) { }
 
        virtual void    SuspendDynamics(bool);
        virtual void    RestoreDynamics();
index abe48d99043ee640e5fa0d7a11fc0b5fc960449e..a684b6378945bc0e4aef02b5c3e8167437495774 100644 (file)
@@ -53,7 +53,7 @@ public:
                class SM_Object* sumoObj,       
                class PHY_IMotionState* motionstate
                ,bool dyna) 
-               : KX_IPhysicsController(dyna,NULL) ,
+               : KX_IPhysicsController(dyna,false,NULL) ,
                  SumoPhysicsController(sumoScene,/*solidscene,*/sumoObj,motionstate,dyna)
        {
        };
@@ -78,6 +78,9 @@ public:
 
        void    SuspendDynamics(bool);
        void    RestoreDynamics();
+       virtual void    AddCompoundChild(KX_IPhysicsController* child) { }
+       virtual void    RemoveCompoundChild(KX_IPhysicsController* child) { }
+
        virtual void    getOrientation(MT_Quaternion& orn);
        virtual void setOrientation(const MT_Matrix3x3& orn);
        
index c9c30c1b4500d25f5eba1e50eaf482ef8a50f9fa..fafce5cf5cc3d5b56543624c95fa6f78f5341090 100644 (file)
@@ -1276,7 +1276,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
 
        // assume no shape information
        // no support for dynamic change of shape yet
-       assert(m_meshObject == NULL);
+       assert(IsUnused());
        m_shapeType = PHY_SHAPE_NONE;
        m_vertexArray.clear();
        m_polygonIndexArray.clear();
@@ -1398,6 +1398,17 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
        return true;
 }
 
+bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo)
+{
+       if (shapeInfo == NULL)
+               return false;
+       // no support for dynamic change
+       assert(IsUnused());
+       m_shapeType = PHY_SHAPE_PROXY;
+       m_shapeProxy = shapeInfo;
+       return true;
+}
+
 btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
 {
        btCollisionShape* collisionShape = 0;
@@ -1406,9 +1417,12 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
        btCompoundShape* compoundShape = 0;
        CcdShapeConstructionInfo* nextShapeInfo;
 
+       if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL)
+               return m_shapeProxy->CreateBulletShape();
+
        switch (m_shapeType) 
        {
-       case PHY_SHAPE_NONE:
+       default:
                break;
 
        case PHY_SHAPE_BOX:
@@ -1522,6 +1536,10 @@ CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
                        m_meshShapeMap.erase(mit);
                }
        }
+       if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL)
+       {
+               m_shapeProxy->Release();
+       }
 }
 
 
index 054ec91122af81e463e31c29236bbbe63c3a2202..c771aa2624bf3ba2ae9aee1c0743b46adc9e47b1 100644 (file)
@@ -67,11 +67,13 @@ public:
                m_height(1.0),
                m_halfExtend(0.f,0.f,0.f),
                m_childScale(1.0f,1.0f,1.0f),
+               m_userData(NULL),
                m_refCount(1),
                m_meshObject(NULL),
                m_unscaledShape(NULL),
                m_useGimpact(false),
-               m_weldingThreshold(0.f)
+               m_weldingThreshold(0.f),
+               m_shapeProxy(NULL)
        {
                m_childTrans.setIdentity();
        }
@@ -92,6 +94,11 @@ public:
                return 0;
        }
 
+       bool IsUnused(void)
+       {
+               return (m_meshObject==NULL && m_shapeArray.size() == 0 && m_shapeProxy == NULL);
+       }
+
        void AddShape(CcdShapeConstructionInfo* shapeInfo);
 
        btTriangleMeshShape* GetMeshShape(void)
@@ -105,6 +112,32 @@ public:
 
                return m_shapeArray.at(i);
        }
+       int FindChildShape(CcdShapeConstructionInfo* shapeInfo, void* userData)
+       {
+               if (shapeInfo == NULL)
+                       return -1;
+               for (int i=0; i<m_shapeArray.size(); i++)
+               {
+                       CcdShapeConstructionInfo* childInfo = m_shapeArray.at(i);
+                       if ((userData == NULL || userData == childInfo->m_userData) &&
+                               (childInfo == shapeInfo ||
+                                (childInfo->m_shapeType == PHY_SHAPE_PROXY && 
+                                 childInfo->m_shapeProxy == shapeInfo)))
+                               return i;
+               }
+               return -1;
+       }
+
+       bool RemoveChildShape(int i)
+       {
+               if (i < 0 || i >= m_shapeArray.size())
+                       return false;
+               m_shapeArray.at(i)->Release();
+               if (i < m_shapeArray.size()-1)
+                       m_shapeArray[i] = m_shapeArray.back();
+               m_shapeArray.pop_back();
+               return true;
+       }
 
        bool SetMesh(RAS_MeshObject* mesh, bool polytope,bool useGimpact);
        RAS_MeshObject* GetMesh(void)
@@ -112,6 +145,12 @@ public:
                return m_meshObject;
        }
 
+       bool SetProxy(CcdShapeConstructionInfo* shapeInfo);
+       CcdShapeConstructionInfo* GetProxy(void)
+       {
+               return m_shapeProxy;
+       }
+
        btCollisionShape* CreateBulletShape();
 
        // member variables
@@ -121,6 +160,7 @@ public:
        btVector3                               m_halfExtend;
        btTransform                             m_childTrans;
        btVector3                               m_childScale;
+       void*                                   m_userData;     
        std::vector<btPoint3>   m_vertexArray;  // Contains both vertex array for polytope shape and
                                                                                        // triangle array for concave mesh shape.
                                                                                        // In this case a triangle is made of 3 consecutive points
@@ -146,7 +186,7 @@ protected:
        std::vector<CcdShapeConstructionInfo*> m_shapeArray;    // for compound shapes
        bool    m_useGimpact; //use gimpact for concave dynamic/moving collision detection
        float   m_weldingThreshold;     //welding closeby vertices together can improve softbody stability etc.
-
+       CcdShapeConstructionInfo* m_shapeProxy; // only used for PHY_SHAPE_PROXY, pointer to actual shape info
 };
 
 struct CcdConstructionInfo
index 4fe356307841978c137beba0e2cfa77c88e2e3dd..d2274c1e8d66fa057ec0d321a2bd7b4c8a9e6185 100644 (file)
@@ -536,12 +536,24 @@ void CcdPhysicsEnvironment::disableCcdPhysicsController(CcdPhysicsController* ct
                        {
                        } else
                        {
-                               m_dynamicsWorld->removeCollisionObject(body);
+                               m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject());
                        }
                }
        }
 }
 
+void CcdPhysicsEnvironment::refreshCcdPhysicsController(CcdPhysicsController* ctrl)
+{
+       btCollisionObject* obj = ctrl->GetCollisionObject();
+       if (obj)
+       {
+               btBroadphaseProxy* proxy = obj->getBroadphaseHandle();
+               if (proxy)
+               {
+                       m_dynamicsWorld->getPairCache()->cleanProxyFromPairs(proxy,m_dynamicsWorld->getDispatcher());
+               }
+       }
+}
 
 void   CcdPhysicsEnvironment::beginFrame()
 {
index 74384dd8cf2ea8915b594dbdaddcd8f3075ee1ec..4b28d3fddfca88a106bb5de128cdc28ddc6d29ff 100644 (file)
@@ -196,6 +196,8 @@ protected:
 
                void    enableCcdPhysicsController(CcdPhysicsController* ctrl);
 
+               void    refreshCcdPhysicsController(CcdPhysicsController* ctrl);
+
                btBroadphaseInterface*  getBroadphase();
 
                btDispatcher*   getDispatcher();
index 3b3e42c38d241e5be44936f441865247af08878c..09126264dccb2bf216ea79c3ba6ffe7c8e983b87 100644 (file)
@@ -95,7 +95,8 @@ typedef enum PHY_ShapeType {
        PHY_SHAPE_CONE,
        PHY_SHAPE_MESH,
        PHY_SHAPE_POLYTOPE,
-       PHY_SHAPE_COMPOUND
+       PHY_SHAPE_COMPOUND,
+       PHY_SHAPE_PROXY
 } PHY_ShapeType;