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 a6d03dee1a1..09f48fb17d5 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 @@ -78,6 +78,27 @@ base class --- :class:`SCA_IObject` The object must have a physics controller for the mass to be applied, otherwise the mass value will be returned as 0.0. + .. attribute:: linearDamping + + The object's linear damping, also known as translational damping. Can be set simultaneously with angular damping using the :py:meth:`setDamping` method. + + :type: float between 0 and 1 inclusive. + + .. note:: + + The object must have a physics controller for the linear damping to be applied, otherwise the value will be returned as 0.0. + + .. attribute:: angularDamping + + The object's angular damping, also known as rotationation damping. Can be set simultaneously with linear damping using the :py:meth:`setDamping` method. + + :type: float between 0 and 1 inclusive. + + .. note:: + + The object must have a physics controller for the angular damping to be applied, otherwise the value will be returned as 0.0. + + .. attribute:: linVelocityMin Enforces the object keeps moving at a minimum velocity. @@ -580,6 +601,15 @@ base class --- :class:`SCA_IObject` * True: you get the "local" impulse ie: relative to local coordinates with object orientation. :type local: boolean + .. method:: setDamping(linear_damping, angular_damping) + + Sets both the :py:attr:`linearDamping` and :py:attr:`angularDamping` simultaneously. This is more efficient than setting both properties individually. + + :arg linear_damping: Linear ("translational") damping factor. + :type linear_damping: float ∈ [0, 1] + :arg angular_damping: Angular ("rotational") damping factor. + :type angular_damping: float ∈ [0, 1] + .. method:: suspendDynamics() Suspends physics for this object. diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 4ac889b1927..e8b68d20e84 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -575,6 +575,39 @@ CValue* KX_GameObject::GetReplica() return replica; } +float KX_GameObject::getLinearDamping() const +{ + if (m_pPhysicsController) + return m_pPhysicsController->GetLinearDamping(); + return 0; +} + +float KX_GameObject::getAngularDamping() const +{ + if (m_pPhysicsController) + return m_pPhysicsController->GetAngularDamping(); + return 0; +} + +void KX_GameObject::setLinearDamping(float damping) +{ + if (m_pPhysicsController) + m_pPhysicsController->SetLinearDamping(damping); +} + + +void KX_GameObject::setAngularDamping(float damping) +{ + if (m_pPhysicsController) + m_pPhysicsController->SetAngularDamping(damping); +} + + +void KX_GameObject::setDamping(float linear, float angular) +{ + if (m_pPhysicsController) + m_pPhysicsController->SetDamping(linear, angular); +} void KX_GameObject::ApplyForce(const MT_Vector3& force,bool local) @@ -1822,6 +1855,7 @@ PyMethodDef KX_GameObject::Methods[] = { {"getAngularVelocity", (PyCFunction) KX_GameObject::sPyGetAngularVelocity, METH_VARARGS}, {"setAngularVelocity", (PyCFunction) KX_GameObject::sPySetAngularVelocity, METH_VARARGS}, {"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS}, + {"setDamping", (PyCFunction) KX_GameObject::sPySetDamping, METH_VARARGS}, {"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_NOARGS}, {"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS}, {"getAxisVect",(PyCFunction) KX_GameObject::sPyGetAxisVect, METH_O}, @@ -1897,6 +1931,8 @@ PyAttributeDef KX_GameObject::Attributes[] = { KX_PYATTRIBUTE_RW_FUNCTION("angularVelocity", KX_GameObject, pyattr_get_localAngularVelocity, pyattr_set_worldAngularVelocity), KX_PYATTRIBUTE_RW_FUNCTION("localAngularVelocity", KX_GameObject, pyattr_get_localAngularVelocity, pyattr_set_localAngularVelocity), KX_PYATTRIBUTE_RW_FUNCTION("worldAngularVelocity", KX_GameObject, pyattr_get_worldAngularVelocity, pyattr_set_worldAngularVelocity), + KX_PYATTRIBUTE_RW_FUNCTION("linearDamping", KX_GameObject, pyattr_get_linearDamping, pyattr_set_linearDamping), + KX_PYATTRIBUTE_RW_FUNCTION("angularDamping", KX_GameObject, pyattr_get_angularDamping, pyattr_set_angularDamping), KX_PYATTRIBUTE_RO_FUNCTION("children", KX_GameObject, pyattr_get_children), KX_PYATTRIBUTE_RO_FUNCTION("childrenRecursive", KX_GameObject, pyattr_get_children_recursive), KX_PYATTRIBUTE_RO_FUNCTION("attrDict", KX_GameObject, pyattr_get_attrDict), @@ -2687,6 +2723,34 @@ int KX_GameObject::pyattr_set_localAngularVelocity(void *self_v, const KX_PYATTR return PY_SET_ATTR_SUCCESS; } +PyObject *KX_GameObject::pyattr_get_linearDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self = static_cast(self_v); + return PyFloat_FromDouble(self->getLinearDamping()); +} + +int KX_GameObject::pyattr_set_linearDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject* self = static_cast(self_v); + float val = PyFloat_AsDouble(value); + self->setLinearDamping(val); + return PY_SET_ATTR_SUCCESS; +} + +PyObject *KX_GameObject::pyattr_get_angularDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_GameObject* self = static_cast(self_v); + return PyFloat_FromDouble(self->getAngularDamping()); +} + +int KX_GameObject::pyattr_set_angularDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_GameObject* self = static_cast(self_v); + float val = PyFloat_AsDouble(value); + self->setAngularDamping(val); + return PY_SET_ATTR_SUCCESS; +} + PyObject *KX_GameObject::pyattr_get_timeOffset(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { @@ -2983,6 +3047,18 @@ PyObject *KX_GameObject::PySetAngularVelocity(PyObject *args) return NULL; } +PyObject *KX_GameObject::PySetDamping(PyObject *args) +{ + float linear; + float angular; + + if (!PyArg_ParseTuple(args,"ff|i:setDamping", &linear, &angular)) + return NULL; + + setDamping(linear, angular); + Py_RETURN_NONE; +} + PyObject *KX_GameObject::PySetVisible(PyObject *args) { int visible, recursive = 0; diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index cc84ab01342..4538679303f 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -684,6 +684,12 @@ public: bool local ); + virtual float getLinearDamping() const; + virtual float getAngularDamping() const; + virtual void setLinearDamping(float damping); + virtual void setAngularDamping(float damping); + virtual void setDamping(float linear, float angular); + /** * Update the physics object transform based upon the current SG_Node * position. @@ -965,6 +971,7 @@ public: KX_PYMETHOD_VARARGS(KX_GameObject,GetAngularVelocity); KX_PYMETHOD_VARARGS(KX_GameObject,SetAngularVelocity); KX_PYMETHOD_VARARGS(KX_GameObject,GetVelocity); + KX_PYMETHOD_VARARGS(KX_GameObject,SetDamping); KX_PYMETHOD_NOARGS(KX_GameObject,GetReactionForce); @@ -1070,6 +1077,10 @@ public: static int pyattr_set_debug(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); static PyObject* pyattr_get_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_linearDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_linearDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); + static PyObject* pyattr_get_angularDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_angularDamping(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); /* Experimental! */ static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 6b73f330c61..ff68021f09e 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -207,6 +207,11 @@ btRigidBody* CcdPhysicsController::GetRigidBody() { return btRigidBody::upcast(m_object); } +const btRigidBody* CcdPhysicsController::GetRigidBody() const +{ + return btRigidBody::upcast(m_object); +} + btCollisionObject* CcdPhysicsController::GetCollisionObject() { return m_object; @@ -1354,6 +1359,42 @@ void CcdPhysicsController::Jump() void CcdPhysicsController::SetActive(bool active) { } + +float CcdPhysicsController::GetLinearDamping() const +{ + const btRigidBody* body = GetRigidBody(); + if (body) + return body->getLinearDamping(); + return 0; +} + +float CcdPhysicsController::GetAngularDamping() const +{ + const btRigidBody* body = GetRigidBody(); + if (body) + return body->getAngularDamping(); + return 0; +} + +void CcdPhysicsController::SetLinearDamping(float damping) +{ + SetDamping(damping, GetAngularDamping()); +} + +void CcdPhysicsController::SetAngularDamping(float damping) +{ + SetDamping(GetLinearDamping(), damping); +} + +void CcdPhysicsController::SetDamping(float linear, float angular) +{ + btRigidBody* body = GetRigidBody(); + if (!body) return; + + body->setDamping(linear, angular); +} + + // reading out information from physics MT_Vector3 CcdPhysicsController::GetLinearVelocity() { diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 4d0d96e07c6..557a5fe603a 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -522,6 +522,7 @@ protected: btRigidBody* GetRigidBody(); + const btRigidBody* GetRigidBody() const; btCollisionObject* GetCollisionObject(); btSoftBody* GetSoftBody(); btKinematicCharacterController* GetCharacterController(); @@ -573,6 +574,12 @@ protected: virtual void Jump(); virtual void SetActive(bool active); + virtual float GetLinearDamping() const; + virtual float GetAngularDamping() const; + virtual void SetLinearDamping(float damping); + virtual void SetAngularDamping(float damping); + virtual void SetDamping(float linear, float angular); + // reading out information from physics virtual MT_Vector3 GetLinearVelocity(); virtual MT_Vector3 GetAngularVelocity(); diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h index f9975484fa7..1717f8d90cb 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsController.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h @@ -89,6 +89,12 @@ class PHY_IPhysicsController : public PHY_IController virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0; virtual void ResolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) = 0; + virtual float GetLinearDamping() const=0; + virtual float GetAngularDamping() const=0; + virtual void SetLinearDamping(float damping)=0; + virtual void SetAngularDamping(float damping)=0; + virtual void SetDamping(float linear, float angular)=0; + virtual void SuspendDynamics(bool ghost=false)=0; virtual void RestoreDynamics()=0;