Skip to content

Commit 4b89cfd

Browse files
committed
UPBGE: Fix shape replacement for character.
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.
1 parent 670425e commit 4b89cfd

File tree

5 files changed

+33
-6
lines changed

5 files changed

+33
-6
lines changed

doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,12 @@ base class --- :class:`SCA_IObject`
10641064

10651065
:arg gameObject: set the physics shape from this gameObjets.
10661066
:type gameObject: string, :class:`KX_GameObject`
1067+
:return: True if replace succeeded, False if it failed.
1068+
:rtype: boolean
1069+
1070+
.. warning::
1071+
1072+
Triangle mesh shapes are not supported.
10671073

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

source/gameengine/Ketsji/KX_GameObject.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,8 +2129,10 @@ PyObject *KX_GameObject::PyReplacePhysicsShape(PyObject *value)
21292129
return nullptr;
21302130
}
21312131

2132-
m_physicsController->ReplacePhysicsShape(gameobj->GetPhysicsController());
2133-
Py_RETURN_NONE;
2132+
if (m_physicsController->ReplacePhysicsShape(gameobj->GetPhysicsController())) {
2133+
Py_RETURN_TRUE;
2134+
}
2135+
Py_RETURN_FALSE;
21342136
}
21352137

21362138
static PyObject *Map_GetItem(PyObject *self_v, PyObject *item)

source/gameengine/Physics/Bullet/CcdPhysicsController.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ void CcdCharacter::SetVelocity(const btVector3& vel, float time, bool local)
157157
setVelocityForTimeInterval(v, time);
158158
}
159159

160+
void CcdCharacter::ReplaceShape(btConvexShape* shape)
161+
{
162+
m_convexShape = shape;
163+
m_ghostObject->setCollisionShape(m_convexShape);
164+
}
165+
160166
void CcdCharacter::SetVelocity(const mt::vec3& vel, float time, bool local)
161167
{
162168
SetVelocity(ToBullet(vel), time, local);
@@ -675,6 +681,10 @@ bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape)
675681
world->addSoftBody(newSoftBody);
676682
}
677683

684+
if (m_characterController) {
685+
m_characterController->ReplaceShape(static_cast<btConvexShape *>(newShape));
686+
}
687+
678688
return true;
679689
}
680690

@@ -1676,7 +1686,7 @@ bool CcdPhysicsController::IsPhysicsSuspended()
16761686
*/
16771687
bool CcdPhysicsController::ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_Mesh *from_meshobj, bool dupli)
16781688
{
1679-
if (m_shapeInfo->m_shapeType != PHY_SHAPE_MESH) {
1689+
if (!ELEM(m_shapeInfo->m_shapeType, PHY_SHAPE_MESH, PHY_SHAPE_POLYTOPE)) {
16801690
return false;
16811691
}
16821692

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

1702-
void CcdPhysicsController::ReplacePhysicsShape(PHY_IPhysicsController *phyctrl)
1712+
bool CcdPhysicsController::ReplacePhysicsShape(PHY_IPhysicsController *phyctrl)
17031713
{
17041714
CcdShapeConstructionInfo *shapeInfo = ((CcdPhysicsController *)phyctrl)->GetShapeInfo();
17051715

1716+
if (m_characterController && ELEM(shapeInfo->m_shapeType,
1717+
PHY_SHAPE_COMPOUND, PHY_SHAPE_PROXY, PHY_SHAPE_EMPTY, PHY_SHAPE_COMPOUND, PHY_SHAPE_MESH))
1718+
{
1719+
return false;
1720+
}
1721+
17061722
// switch shape info
17071723
m_shapeInfo->Release();
17081724
m_shapeInfo = shapeInfo->AddRef();

source/gameengine/Physics/Bullet/CcdPhysicsController.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ class CcdCharacter : public btKinematicCharacterController, public PHY_ICharacte
467467

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

470+
/// Replace current convex shape.
471+
void ReplaceShape(btConvexShape *shape);
472+
470473
// PHY_ICharacter interface
471474
virtual void Jump()
472475
{
@@ -857,7 +860,7 @@ class CcdPhysicsController : public PHY_IPhysicsController, public mt::SimdClass
857860
}
858861

859862
virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_Mesh *from_meshobj, bool dupli = false);
860-
virtual void ReplacePhysicsShape(PHY_IPhysicsController *phyctrl);
863+
virtual bool ReplacePhysicsShape(PHY_IPhysicsController *phyctrl);
861864
};
862865

863866
/// DefaultMotionState implements standard motionstate, using btTransform

source/gameengine/Physics/Common/PHY_IPhysicsController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class PHY_IPhysicsController : public PHY_IController
151151
virtual bool IsPhysicsSuspended() = 0;
152152

153153
virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_Mesh *from_meshobj, bool dupli = false) = 0;
154-
virtual void ReplacePhysicsShape(PHY_IPhysicsController *phyctrl) = 0;
154+
virtual bool ReplacePhysicsShape(PHY_IPhysicsController *phyctrl) = 0;
155155
};
156156

157157
#endif /* __PHY_IPHYSICSCONTROLLER_H__ */

0 commit comments

Comments
 (0)