diff --git a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst index 4198641416f9..6ceb2928435e 100644 --- a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst +++ b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst @@ -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]) diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 971a3a96398c..be9cf5050bf6 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -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) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 20602b56a138..5167ecc89384 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -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); @@ -675,6 +681,10 @@ bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape) world->addSoftBody(newSoftBody); } + if (m_characterController) { + m_characterController->ReplaceShape(static_cast(newShape)); + } + return true; } @@ -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(); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index a2a7541e4669..a33594853df7 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -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() { @@ -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 diff --git a/source/gameengine/Physics/Common/PHY_IPhysicsController.h b/source/gameengine/Physics/Common/PHY_IPhysicsController.h index d79f924318a2..409978bb0def 100644 --- a/source/gameengine/Physics/Common/PHY_IPhysicsController.h +++ b/source/gameengine/Physics/Common/PHY_IPhysicsController.h @@ -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__ */