BGE : fix bugs with physics collision mask/group
authorPorteries Tristan <republicthunderbolt9@gmail.com>
Fri, 24 Apr 2015 09:56:58 +0000 (11:56 +0200)
committerThomas Szepe <HG1_public@gmx.net>
Fri, 24 Apr 2015 09:57:38 +0000 (11:57 +0200)
Currently there are bugs with physics objects in inactive layers,
character and softbody.
I added a function in CcdPhysicsEnvironement to know if a physics
controller is currently active and for soft body I added the correct function in UpdateCcdPhysicsController to re-add a softbody in the dynamics world.

The bug was introduced in D1243 commit 3d55859

Reviewers: hg1, scorpion81, lordloki, moguri, agoose77, sergof

Reviewed By: sergof

Subscribers: youle, moguri

Differential Revision: https://developer.blender.org/D1253

source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h

index 54bb6ee260547cb882debd47237264da76455a52..73dcae5a1a81954f59796eae1d91d64dd9696d57 100644 (file)
@@ -517,7 +517,14 @@ public:
         */
        void ActivateGraphicController(bool recurse);
 
+       /** Set the object's collison group
+        * \param filter The group bitfield
+        */
        void SetUserCollisionGroup(unsigned short filter);
+
+       /** Set the object's collison mask
+        * \param filter The mask bitfield
+        */
        void SetUserCollisionMask(unsigned short mask);
        unsigned short GetUserCollisionGroup();
        unsigned short GetUserCollisionMask();
index b2b8f30a7060301f3e9b6ef98a32d5bde99f7ee6..0a71c0a7aac7dc308498ef163f755f6c4ea1c9fb 100644 (file)
@@ -123,10 +123,8 @@ bool CleanPairCallback::processOverlap(btBroadphasePair &pair)
                m_pairCache->cleanOverlappingPair(pair, m_dispatcher);
                CcdPhysicsController *ctrl0 = (CcdPhysicsController*)(((btCollisionObject*)pair.m_pProxy0->m_clientObject)->getUserPointer());
                CcdPhysicsController *ctrl1 = (CcdPhysicsController*)(((btCollisionObject*)pair.m_pProxy1->m_clientObject)->getUserPointer());
-               if (ctrl0 && ctrl1) {
-                       ctrl0->GetRigidBody()->activate(true);
-                       ctrl1->GetRigidBody()->activate(true);
-               }
+               ctrl0->GetCollisionObject()->activate(false);
+               ctrl1->GetCollisionObject()->activate(false);
        }
        return false;
 }
@@ -1097,6 +1095,10 @@ void             CcdPhysicsController::ResolveCombinedVelocities(float linvelX,float linvel
 
 void CcdPhysicsController::RefreshCollisions()
 {
+       // the object is in an inactive layer so it's useless to update it and can cause problems
+       if (!GetPhysicsEnvironment()->IsActiveCcdPhysicsController(this))
+               return;
+
        btSoftRigidDynamicsWorld *dw = GetPhysicsEnvironment()->GetDynamicsWorld();
        btBroadphaseProxy *proxy = m_object->getBroadphaseHandle();
        btDispatcher *dispatcher = dw->getDispatcher();
@@ -1104,8 +1106,10 @@ void CcdPhysicsController::RefreshCollisions()
 
        CleanPairCallback cleanPairs(proxy, pairCache, dispatcher);
        pairCache->processAllOverlappingPairs(&cleanPairs, dispatcher);
+
        // Forcibly recreate the physics object
-       GetPhysicsEnvironment()->UpdateCcdPhysicsController(this, m_cci.m_mass, m_cci.m_collisionFlags, m_cci.m_collisionFilterGroup, m_cci.m_collisionFilterMask);
+       btBroadphaseProxy* handle = m_object->getBroadphaseHandle();
+       GetPhysicsEnvironment()->UpdateCcdPhysicsController(this, GetMass(), m_object->getCollisionFlags(), handle->m_collisionFilterGroup, handle->m_collisionFilterMask);
 }
 
 void   CcdPhysicsController::SuspendDynamics(bool ghost)
index 186abdfe5987786ec12aa4e8b1e1fdbf13f7848e..0ecb79d91ea886582bb66209041bc5b42f86694b 100644 (file)
@@ -569,6 +569,7 @@ void        CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctr
        // this function is used when the collisionning group of a controller is changed
        // remove and add the collistioning object
        btRigidBody* body = ctrl->GetRigidBody();
+       btSoftBody *softBody = ctrl->GetSoftBody();
        btCollisionObject* obj = ctrl->GetCollisionObject();
        if (obj)
        {
@@ -582,6 +583,9 @@ void        CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctr
                        body->setMassProps(newMass, inertia);
                        m_dynamicsWorld->addRigidBody(body, newCollisionGroup, newCollisionMask);
                }
+               else if (softBody) {
+                       m_dynamicsWorld->addSoftBody(softBody);
+               }
                else {
                        m_dynamicsWorld->addCollisionObject(obj, newCollisionGroup, newCollisionMask);
                }
@@ -643,6 +647,11 @@ void CcdPhysicsEnvironment::RefreshCcdPhysicsController(CcdPhysicsController* ct
        }
 }
 
+bool CcdPhysicsEnvironment::IsActiveCcdPhysicsController(CcdPhysicsController *ctrl)
+{
+       return (m_controllers.find(ctrl) != m_controllers.end());
+}
+
 void CcdPhysicsEnvironment::AddCcdGraphicController(CcdGraphicController* ctrl)
 {
        if (m_cullingTree && !ctrl->GetBroadphaseHandle())
index 113db3348cae80afa3f9f703698bfd458a125ce0..3b1fe63db0ba6d085387853730ffc13f4c944915 100644 (file)
@@ -227,6 +227,8 @@ protected:
 
                void    RefreshCcdPhysicsController(CcdPhysicsController* ctrl);
 
+               bool    IsActiveCcdPhysicsController(CcdPhysicsController *ctrl);
+
                void    AddCcdGraphicController(CcdGraphicController* ctrl);
 
                void    RemoveCcdGraphicController(CcdGraphicController* ctrl);