BGE bug fix (for 2.47): setParent() fix, third part: set mass to 0 when parenting...
authorBenoit Bolsee <benoit.bolsee@online.be>
Sun, 20 Jul 2008 15:40:03 +0000 (15:40 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Sun, 20 Jul 2008 15:40:03 +0000 (15:40 +0000)
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h

index e25deaf05a929d22b6a1c765c43f58d0eea3c952..1553c4c61c2d62fc6acda463e85f1879aa7a11cb 100644 (file)
@@ -170,10 +170,12 @@ void      KX_BulletPhysicsController::SuspendDynamics(bool ghost)
        {
                btBroadphaseProxy* handle = body->getBroadphaseHandle();
                m_savedCollisionFlags = body->getCollisionFlags();
+               m_savedMass = GetMass();
                m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
                m_savedCollisionFilterMask = handle->m_collisionFilterMask;
                body->setActivationState(DISABLE_SIMULATION);
                GetPhysicsEnvironment()->updateCcdPhysicsController(this, 
+                       0.0,
                        btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
                        btBroadphaseProxy::StaticFilter, 
                        btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
@@ -185,11 +187,12 @@ void      KX_BulletPhysicsController::RestoreDynamics()
        btRigidBody *body = GetRigidBody();
        if (body->getActivationState() == DISABLE_SIMULATION)
        {
-               GetRigidBody()->forceActivationState(ACTIVE_TAG);
                GetPhysicsEnvironment()->updateCcdPhysicsController(this, 
+                       m_savedMass,
                        m_savedCollisionFlags,
                        m_savedCollisionFilterGroup,
                        m_savedCollisionFilterMask);
+               GetRigidBody()->forceActivationState(ACTIVE_TAG);
        }
 }
 
index 3d7c7e5b0303f19fa07d3c39a9d38cf12eb40396..93ee03660db94c140b273697e9e168bf306a1854 100644 (file)
@@ -11,6 +11,8 @@ private:
        int m_savedCollisionFlags;
        short int m_savedCollisionFilterGroup;
        short int m_savedCollisionFilterMask;
+       MT_Scalar m_savedMass;
+
 public:
 
        KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna);
index 1845fdd7b506e57af8ce8078e56b3e6a543bfbf3..6f2253044409851de45be7ba5d1067fddd1f97e5 100644 (file)
@@ -224,6 +224,10 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
                RemoveParent(scene);
                obj->GetSGNode()->AddChild(GetSGNode());
 
+               if (m_pPhysicsController1) 
+               {
+                       m_pPhysicsController1->SuspendDynamics(true);
+               }
                // Set us to our new scale, position, and orientation
                scale1[0] = scale1[0]/scale2[0];
                scale1[1] = scale1[1]/scale2[1];
@@ -240,10 +244,6 @@ 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 (m_pPhysicsController1) 
-               {
-                       m_pPhysicsController1->SuspendDynamics(true);
-               }
        }
 }
 
@@ -724,8 +724,12 @@ MT_Vector3 KX_GameObject::GetAngularVelocity(bool local)
 
 void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
 {
-       if (m_pPhysicsController1)
+       if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
        {
+               // don't update physic controller if the object is a child:
+               // 1) the transformation will not be right
+               // 2) in this case, the physic controller is necessarily a static object
+               //    that is updated from the normal kinematic synchronization
                m_pPhysicsController1->setPosition(trans);
        }
 
@@ -737,25 +741,22 @@ void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
 
 void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot)
 {
-       if (m_pPhysicsController1)
+       if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
        {
+               // see note above
                m_pPhysicsController1->setOrientation(rot.getRotation());
        }
        if (GetSGNode())
                GetSGNode()->SetLocalOrientation(rot);
-       else
-       {
-               int i;
-               i=0;
-       }
 }
 
 
 
 void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale)
 {
-       if (m_pPhysicsController1)
+       if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
        {
+               // see note above
                m_pPhysicsController1->setScaling(scale);
        }
        
index 37fa465351f5ff734d233641435806a072223676..abb71956f5a3cd029c04d29ef232c4a454603bb1 100644 (file)
@@ -106,6 +106,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
        btRigidBody* m_body;
        class PHY_IMotionState*         m_MotionState;
        btMotionState*  m_bulletMotionState;
+       friend class CcdPhysicsEnvironment;     // needed when updating the controller
 
 
        void*           m_newClientInfo;
@@ -194,7 +195,6 @@ class CcdPhysicsController : public PHY_IPhysicsController
                        return m_cci.m_collisionFilterMask;
                }
 
-
                virtual void    calcXform() {} ;
                virtual void SetMargin(float margin) {};
                virtual float GetMargin() const {return 0.f;};
index 7f5457121ea65b1b220869a5e8338ded11caeaa7..b773f40650b5c07097c151c91f6b9bb84fa5341d 100644 (file)
@@ -466,17 +466,39 @@ void      CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
 
 }
 
-void   CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
+void   CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
 {
        // this function is used when the collisionning group of a controller is changed
        // remove and add the collistioning object
        btRigidBody* body = ctrl->GetRigidBody();
+       btVector3 inertia;
 
        m_dynamicsWorld->removeCollisionObject(body);
        body->setCollisionFlags(newCollisionFlags);
+       body->getCollisionShape()->calculateLocalInertia(newMass, inertia);
+       body->setMassProps(newMass, inertia);
        m_dynamicsWorld->addCollisionObject(body, newCollisionGroup, newCollisionMask);
+       // to avoid nasty interaction, we must update the property of the controller as well
+       ctrl->m_cci.m_mass = newMass;
+       ctrl->m_cci.m_collisionFilterGroup = newCollisionGroup;
+       ctrl->m_cci.m_collisionFilterMask = newCollisionMask;
+       ctrl->m_cci.m_collisionFlags = newCollisionFlags;
 }
 
+void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctrl)
+{
+       std::vector<CcdPhysicsController*>::iterator i =
+               std::find(m_controllers.begin(), m_controllers.end(), ctrl);
+       if (i == m_controllers.end())
+       {
+               btRigidBody* body = ctrl->GetRigidBody();
+               m_dynamicsWorld->addCollisionObject(body, 
+                       ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
+       }
+}
+
+
+
 void   CcdPhysicsEnvironment::beginFrame()
 {
 
index dff17517b8518dfb294b494f02609d4d6ae0c98b..453749b27b38d60d7617080b2651340b30f10c1d 100644 (file)
@@ -183,7 +183,14 @@ protected:
 
                void    removeCcdPhysicsController(CcdPhysicsController* ctrl);
 
-               void    updateCcdPhysicsController(CcdPhysicsController* ctrl, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
+               void    updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
+
+               void    disableCcdPhysicsController(CcdPhysicsController* ctrl)
+               { 
+                       removeCcdPhysicsController(ctrl); 
+               }
+
+               void    enableCcdPhysicsController(CcdPhysicsController* ctrl);
 
                btBroadphaseInterface*  getBroadphase();