diff options
author | Jorge Bernal <jbernalmartinez@gmail.com> | 2014-07-07 19:01:49 +0400 |
---|---|---|
committer | Mitchell Stokes <mogurijin@gmail.com> | 2014-07-07 19:06:39 +0400 |
commit | 1f43b083a97ee56b8b15692ef19d0e973b6d31ac (patch) | |
tree | 358346e602ab4be4ca8b1f650955d23b60c9e742 /source/gameengine | |
parent | ef22e972b1ad0bed1a79587b72d50c7da4c6b4e8 (diff) |
BGE: Fix for applyImpulse function
This is related to task T29419. Credit also goes to Goran Milovanovic
(goran) for proposing an initial fix for this issue.
The issue is the current behavior of applyImpulse doesn't match the behavior
described in the documentation as instead of a impulse point in world coordinates,
it seems to require a coordinate in a local space.
Additionally, applyImpulse function isn't consistent with similar functions (applyForce, applyTorque, etc)
as it doesn't allow to choose in which space (local or global) the impulse is applied.
Now, we have the following function:
applyImpulse(point, impulse, local=False)
being "point" the point to apply the impulse to (in world or local coordinates). When local is False will
have both point and impulse in World space and when local is True will have point and impulse in local space.
Reviewers: moguri, dfelinto, brita_
Reviewed By: moguri
Differential Revision: https://developer.blender.org/D567
Diffstat (limited to 'source/gameengine')
4 files changed, 20 insertions, 6 deletions
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 44646f17a6e..f61d08e7f71 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -3034,19 +3034,20 @@ PyObject *KX_GameObject::PyApplyImpulse(PyObject *args) { PyObject *pyattach; PyObject *pyimpulse; + int local = 0; if (!m_pPhysicsController) { PyErr_SetString(PyExc_RuntimeError, "This object has no physics controller"); return NULL; } - if (PyArg_ParseTuple(args, "OO:applyImpulse", &pyattach, &pyimpulse)) + if (PyArg_ParseTuple(args, "OO|i:applyImpulse", &pyattach, &pyimpulse, &local)) { MT_Point3 attach; MT_Vector3 impulse; if (PyVecTo(pyattach, attach) && PyVecTo(pyimpulse, impulse)) { - m_pPhysicsController->ApplyImpulse(attach, impulse); + m_pPhysicsController->ApplyImpulse(attach, impulse, (local!=0)); Py_RETURN_NONE; } diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index c98cf212265..72c3b13e301 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -1309,8 +1309,9 @@ void CcdPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool loc } } } -void CcdPhysicsController::ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulsein) +void CcdPhysicsController::ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulsein, bool local) { + btVector3 pos; btVector3 impulse(impulsein.x(), impulsein.y(), impulsein.z()); if (m_object && impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON)) @@ -1323,7 +1324,19 @@ void CcdPhysicsController::ApplyImpulse(const MT_Point3& attach, const MT_Vecto return; } - btVector3 pos(attach.x(), attach.y(), attach.z()); + btTransform xform = m_object->getWorldTransform(); + + if (local) + { + pos = btVector3(attach.x(), attach.y(), attach.z()); + impulse = xform.getBasis() * impulse; + } + else { + /* If the point of impulse application is not equal to the object position + * then an angular momentum is generated in the object*/ + pos = btVector3(attach.x()-xform.getOrigin().x(), attach.y()-xform.getOrigin().y(), attach.z()-xform.getOrigin().z()); + } + btRigidBody* body = GetRigidBody(); if (body) body->applyImpulse(impulse,pos); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 25a8f0306bd..4d0d96e07c6 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -565,7 +565,7 @@ protected: virtual void SetMass(MT_Scalar newmass); // physics methods - virtual void ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulsein); + virtual void ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulsein, bool local); virtual void ApplyTorque(const MT_Vector3& torque,bool local); virtual void ApplyForce(const MT_Vector3& force,bool local); virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h index 2ffb115e3b2..f9975484fa7 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsController.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h @@ -82,7 +82,7 @@ class PHY_IPhysicsController : public PHY_IController virtual void SetMass(MT_Scalar newmass)=0; // physics methods - virtual void ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulse)=0; + virtual void ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulse,bool local)=0; virtual void ApplyTorque(const MT_Vector3& torque,bool local)=0; virtual void ApplyForce(const MT_Vector3& force,bool local)=0; virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0; |