Skip to content

Commit

Permalink
UPBGE: Fix shape replacement for character.
Browse files Browse the repository at this point in the history
Previously the shape replacement for character wasn't managed and the previous
shape was deleted without relink to the new shape.

To solve this issue CcdCharacter::ReplaceShape is implemented to replace the
shape, this function is called into ReplaceControllerShape.

As character could not use a non convex shape, some shape replacement may
fail (e.g with triangle mesh) the user notice it with the return value
of obj.replacePhysicsShape which is now a boolean.

Fix issue: #968.
  • Loading branch information
panzergame committed Dec 18, 2018
1 parent 670425e commit 4b89cfd
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 6 deletions.
6 changes: 6 additions & 0 deletions doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,12 @@ base class --- :class:`SCA_IObject`

:arg gameObject: set the physics shape from this gameObjets.
:type gameObject: string, :class:`KX_GameObject`
:return: True if replace succeeded, False if it failed.
:rtype: boolean

.. warning::

Triangle mesh shapes are not supported.

.. method:: get(key[, default])

Expand Down
6 changes: 4 additions & 2 deletions source/gameengine/Ketsji/KX_GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2129,8 +2129,10 @@ PyObject *KX_GameObject::PyReplacePhysicsShape(PyObject *value)
return nullptr;
}

m_physicsController->ReplacePhysicsShape(gameobj->GetPhysicsController());
Py_RETURN_NONE;
if (m_physicsController->ReplacePhysicsShape(gameobj->GetPhysicsController())) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
}

static PyObject *Map_GetItem(PyObject *self_v, PyObject *item)
Expand Down
20 changes: 18 additions & 2 deletions source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ void CcdCharacter::SetVelocity(const btVector3& vel, float time, bool local)
setVelocityForTimeInterval(v, time);
}

void CcdCharacter::ReplaceShape(btConvexShape* shape)
{
m_convexShape = shape;
m_ghostObject->setCollisionShape(m_convexShape);
}

void CcdCharacter::SetVelocity(const mt::vec3& vel, float time, bool local)
{
SetVelocity(ToBullet(vel), time, local);
Expand Down Expand Up @@ -675,6 +681,10 @@ bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape)
world->addSoftBody(newSoftBody);
}

if (m_characterController) {
m_characterController->ReplaceShape(static_cast<btConvexShape *>(newShape));
}

return true;
}

Expand Down Expand Up @@ -1676,7 +1686,7 @@ bool CcdPhysicsController::IsPhysicsSuspended()
*/
bool CcdPhysicsController::ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_Mesh *from_meshobj, bool dupli)
{
if (m_shapeInfo->m_shapeType != PHY_SHAPE_MESH) {
if (!ELEM(m_shapeInfo->m_shapeType, PHY_SHAPE_MESH, PHY_SHAPE_POLYTOPE)) {
return false;
}

Expand All @@ -1699,10 +1709,16 @@ bool CcdPhysicsController::ReinstancePhysicsShape(KX_GameObject *from_gameobj, R
return true;
}

void CcdPhysicsController::ReplacePhysicsShape(PHY_IPhysicsController *phyctrl)
bool CcdPhysicsController::ReplacePhysicsShape(PHY_IPhysicsController *phyctrl)
{
CcdShapeConstructionInfo *shapeInfo = ((CcdPhysicsController *)phyctrl)->GetShapeInfo();

if (m_characterController && ELEM(shapeInfo->m_shapeType,
PHY_SHAPE_COMPOUND, PHY_SHAPE_PROXY, PHY_SHAPE_EMPTY, PHY_SHAPE_COMPOUND, PHY_SHAPE_MESH))
{
return false;
}

// switch shape info
m_shapeInfo->Release();
m_shapeInfo = shapeInfo->AddRef();
Expand Down
5 changes: 4 additions & 1 deletion source/gameengine/Physics/Bullet/CcdPhysicsController.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,9 @@ class CcdCharacter : public btKinematicCharacterController, public PHY_ICharacte

void SetVelocity(const btVector3& vel, float time, bool local);

/// Replace current convex shape.
void ReplaceShape(btConvexShape *shape);

// PHY_ICharacter interface
virtual void Jump()
{
Expand Down Expand Up @@ -857,7 +860,7 @@ class CcdPhysicsController : public PHY_IPhysicsController, public mt::SimdClass
}

virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_Mesh *from_meshobj, bool dupli = false);
virtual void ReplacePhysicsShape(PHY_IPhysicsController *phyctrl);
virtual bool ReplacePhysicsShape(PHY_IPhysicsController *phyctrl);
};

/// DefaultMotionState implements standard motionstate, using btTransform
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Physics/Common/PHY_IPhysicsController.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class PHY_IPhysicsController : public PHY_IController
virtual bool IsPhysicsSuspended() = 0;

virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_Mesh *from_meshobj, bool dupli = false) = 0;
virtual void ReplacePhysicsShape(PHY_IPhysicsController *phyctrl) = 0;
virtual bool ReplacePhysicsShape(PHY_IPhysicsController *phyctrl) = 0;
};

#endif /* __PHY_IPHYSICSCONTROLLER_H__ */

0 comments on commit 4b89cfd

Please sign in to comment.