Skip to content

Commit

Permalink
UPBGE: Fix removed constraints when suspending physics.
Browse files Browse the repository at this point in the history
Previously when we was suspending physics of an object using constraints,
they were removed. This behaviour could be needed in some rare case but
for the most case where the user just want to optimize physics computation
the engine should keep the constraints.

To do so the constraints have to be removed from the dynamic world but not
removed from the controller or deleted in RemoveCcdPhysicsController. In
the same time AddCcdPhysicsController iterate over all the constraint in
the activated controller and add they in the dynamic world.

Unfortunately there's some limitation, first we could not do redundant
operation in removing and adding of the constraint in the world, second
we have to keep the disable collision between bodies flag used when adding
a constraint into world. To solve both of these issues the user pointer
of the constraint are used to store a new type: CcdConstraint (in
CcdPhysicsController). This new type only store the disable collision
flag and a boolean named m_active set to true when the constraint is added
in world else to false when removed.
Two functions are added to clean the code: RemoveConstraint and RestoreConstraint.

On python API side the user could specify to remove or not the constraints
when calling KX_GameObject.suspendPhysics(freeConstraints=False).
  • Loading branch information
panzergame committed Jun 3, 2017
1 parent 114230c commit 00836b4
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 158 deletions.
6 changes: 5 additions & 1 deletion doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
Original file line number Diff line number Diff line change
Expand Up @@ -741,10 +741,14 @@ base class --- :class:`SCA_IObject`
:arg angular_damping: Angular ("rotational") damping factor.
:type angular_damping: float ∈ [0, 1]

.. method:: suspendPhysics()
.. method:: suspendPhysics([freeConstraints])

Suspends physics for this object.

:arg freeConstraints: When set to `True` physics constraints used by the object are deleted.
Else when `False` (the default) constraints are restored when restoring physics.
:type freeConstraints: bool

.. method:: restorePhysics()

Resumes physics for this object. Also reinstates collisions.
Expand Down
12 changes: 9 additions & 3 deletions source/gameengine/Ketsji/KX_GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_NOARGS},
{"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
{"getAxisVect",(PyCFunction) KX_GameObject::sPyGetAxisVect, METH_O},
{"suspendPhysics", (PyCFunction)KX_GameObject::sPySuspendPhysics, METH_NOARGS},
{"suspendPhysics", (PyCFunction)KX_GameObject::sPySuspendPhysics, METH_VARARGS},
{"restorePhysics", (PyCFunction)KX_GameObject::sPyRestorePhysics,METH_NOARGS},
{"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics, METH_VARARGS},
{"restoreDynamics", (PyCFunction)KX_GameObject::sPyRestoreDynamics,METH_NOARGS},
Expand Down Expand Up @@ -3561,10 +3561,16 @@ PyObject *KX_GameObject::PyApplyImpulse(PyObject *args)
return nullptr;
}

PyObject *KX_GameObject::PySuspendPhysics()
PyObject *KX_GameObject::PySuspendPhysics(PyObject *args)
{
int freeConstraints = false;

if (!PyArg_ParseTuple(args, "|i:suspendPhysics", &freeConstraints)) {
return nullptr;
}

if (GetPhysicsController()) {
GetPhysicsController()->SuspendPhysics();
GetPhysicsController()->SuspendPhysics((bool)freeConstraints);
}
Py_RETURN_NONE;
}
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Ketsji/KX_GameObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ class KX_GameObject : public SCA_IObject
KX_PYMETHOD_O(KX_GameObject,SetState);
KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
KX_PYMETHOD_O(KX_GameObject,GetAxisVect);
KX_PYMETHOD_NOARGS(KX_GameObject,SuspendPhysics);
KX_PYMETHOD_VARARGS(KX_GameObject,SuspendPhysics);
KX_PYMETHOD_NOARGS(KX_GameObject,RestorePhysics);
KX_PYMETHOD_VARARGS(KX_GameObject,SuspendDynamics);
KX_PYMETHOD_NOARGS(KX_GameObject,RestoreDynamics);
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ static PyObject *gPyRemoveConstraint(PyObject *self,
{
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->RemoveConstraintById(constraintid);
PHY_GetActiveEnvironment()->RemoveConstraintById(constraintid, true);
}
}
else {
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ bool KX_SCA_DynamicActuator::Update()
}
case KX_DYN_DISABLE_PHYSICS:
{
controller->SuspendPhysics();
controller->SuspendPhysics(false);
break;
}
}
Expand Down
17 changes: 12 additions & 5 deletions source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,13 @@ class BlenderBulletMotionState : public btMotionState
}
};

CcdPhysicsController::CcdConstraint::CcdConstraint(bool disableCollision)
:m_disableCollision(disableCollision),
m_active(false)
{
}


btRigidBody *CcdPhysicsController::GetRigidBody()
{
return btRigidBody::upcast(m_object);
Expand Down Expand Up @@ -650,7 +657,7 @@ CcdPhysicsController::~CcdPhysicsController()
{
//will be reference counted, due to sharing
if (m_cci.m_physicsEnv)
m_cci.m_physicsEnv->RemoveCcdPhysicsController(this);
m_cci.m_physicsEnv->RemoveCcdPhysicsController(this, true);

if (m_MotionState)
delete m_MotionState;
Expand Down Expand Up @@ -833,7 +840,7 @@ void CcdPhysicsController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *
// since the environment is changing, we must also move the controler to the
// new environment. Note that we don't handle sensor explicitly: this
// function can be called on sensor but only when they are not registered
if (m_cci.m_physicsEnv->RemoveCcdPhysicsController(this))
if (m_cci.m_physicsEnv->RemoveCcdPhysicsController(this, true))
{
physicsEnv->AddCcdPhysicsController(this);

Expand Down Expand Up @@ -1015,9 +1022,9 @@ void CcdPhysicsController::RefreshCollisions()
GetPhysicsEnvironment()->UpdateCcdPhysicsController(this, GetMass(), m_object->getCollisionFlags(), handle->m_collisionFilterGroup, handle->m_collisionFilterMask);
}

void CcdPhysicsController::SuspendPhysics()
void CcdPhysicsController::SuspendPhysics(bool freeConstraints)
{
GetPhysicsEnvironment()->RemoveCcdPhysicsController(this);
GetPhysicsEnvironment()->RemoveCcdPhysicsController(this, freeConstraints);
}

void CcdPhysicsController::RestorePhysics()
Expand Down Expand Up @@ -1508,7 +1515,7 @@ void CcdPhysicsController::AddCompoundChild(PHY_IPhysicsController *child)
// must update the broadphase cache,
GetPhysicsEnvironment()->RefreshCcdPhysicsController(this);
// remove the children
GetPhysicsEnvironment()->RemoveCcdPhysicsController(childCtrl);
GetPhysicsEnvironment()->RemoveCcdPhysicsController(childCtrl, true);
}

/* Reverse function of the above, it will remove a shape from a compound shape
Expand Down
13 changes: 12 additions & 1 deletion source/gameengine/Physics/Bullet/CcdPhysicsController.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,17 @@ class CleanPairCallback : public btOverlapCallback
/// CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
class CcdPhysicsController : public PHY_IPhysicsController
{
public:
/// Constraint user data.
struct CcdConstraint
{
CcdConstraint(bool m_disableCollision);
/// Disable collision between constrained objects?
bool m_disableCollision;
/// The constraint is added in dynamic world?
bool m_active;
};

protected:
btCollisionObject *m_object;
BlenderBulletCharacterController *m_characterController;
Expand Down Expand Up @@ -683,7 +694,7 @@ class CcdPhysicsController : public PHY_IPhysicsController

virtual void ResolveCombinedVelocities(float linvelX, float linvelY, float linvelZ, float angVelX, float angVelY, float angVelZ);
virtual void RefreshCollisions();
virtual void SuspendPhysics();
virtual void SuspendPhysics(bool freeConstraints);
virtual void RestorePhysics();
virtual void SuspendDynamics(bool ghost);
virtual void RestoreDynamics();
Expand Down
Loading

0 comments on commit 00836b4

Please sign in to comment.