From 546031b6944cd517d518b7ede5fca489c44c3d29 Mon Sep 17 00:00:00 2001 From: Porteries Tristan Date: Fri, 24 Apr 2015 11:56:58 +0200 Subject: BGE : fix bugs with physics collision mask/group 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 | 7 +++++++ source/gameengine/Physics/Bullet/CcdPhysicsController.cpp | 14 +++++++++----- source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp | 9 +++++++++ source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h | 2 ++ 4 files changed, 27 insertions(+), 5 deletions(-) (limited to 'source/gameengine') diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 54bb6ee2605..73dcae5a1a8 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -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(); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index b2b8f30a706..0a71c0a7aac 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -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) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 186abdfe598..0ecb79d91ea 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -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()) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 113db3348ca..3b1fe63db0b 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -227,6 +227,8 @@ protected: void RefreshCcdPhysicsController(CcdPhysicsController* ctrl); + bool IsActiveCcdPhysicsController(CcdPhysicsController *ctrl); + void AddCcdGraphicController(CcdGraphicController* ctrl); void RemoveCcdGraphicController(CcdGraphicController* ctrl); -- cgit v1.2.3