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
This commit is contained in:

committed by
Mitchell Stokes

parent
ef22e972b1
commit
1f43b083a9
@@ -551,7 +551,7 @@ base class --- :class:`SCA_IObject`
|
|||||||
|
|
||||||
This is not implimented at the moment.
|
This is not implimented at the moment.
|
||||||
|
|
||||||
.. method:: applyImpulse(point, impulse)
|
.. method:: applyImpulse(point, impulse, local=False)
|
||||||
|
|
||||||
Applies an impulse to the game object.
|
Applies an impulse to the game object.
|
||||||
|
|
||||||
@@ -559,8 +559,14 @@ base class --- :class:`SCA_IObject`
|
|||||||
If point != position, applyImpulse will also change the object's angular momentum.
|
If point != position, applyImpulse will also change the object's angular momentum.
|
||||||
Otherwise, only linear momentum will change.
|
Otherwise, only linear momentum will change.
|
||||||
|
|
||||||
:arg point: the point to apply the impulse to (in world coordinates)
|
:arg point: the point to apply the impulse to (in world or local coordinates)
|
||||||
:type point: the point to apply the impulse to (in world coordinates)
|
:type point: point [ix, iy, iz] the point to apply the impulse to (in world or local coordinates)
|
||||||
|
:arg impulse: impulse vector.
|
||||||
|
:type impulse: 3D Vector
|
||||||
|
:arg local:
|
||||||
|
* False: you get the "global" impulse ie: relative to world coordinates with world orientation.
|
||||||
|
* True: you get the "local" impulse ie: relative to local coordinates with object orientation.
|
||||||
|
:type local: boolean
|
||||||
|
|
||||||
.. method:: suspendDynamics()
|
.. method:: suspendDynamics()
|
||||||
|
|
||||||
|
@@ -3034,19 +3034,20 @@ PyObject *KX_GameObject::PyApplyImpulse(PyObject *args)
|
|||||||
{
|
{
|
||||||
PyObject *pyattach;
|
PyObject *pyattach;
|
||||||
PyObject *pyimpulse;
|
PyObject *pyimpulse;
|
||||||
|
int local = 0;
|
||||||
|
|
||||||
if (!m_pPhysicsController) {
|
if (!m_pPhysicsController) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "This object has no physics controller");
|
PyErr_SetString(PyExc_RuntimeError, "This object has no physics controller");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyArg_ParseTuple(args, "OO:applyImpulse", &pyattach, &pyimpulse))
|
if (PyArg_ParseTuple(args, "OO|i:applyImpulse", &pyattach, &pyimpulse, &local))
|
||||||
{
|
{
|
||||||
MT_Point3 attach;
|
MT_Point3 attach;
|
||||||
MT_Vector3 impulse;
|
MT_Vector3 impulse;
|
||||||
if (PyVecTo(pyattach, attach) && PyVecTo(pyimpulse, impulse))
|
if (PyVecTo(pyattach, attach) && PyVecTo(pyimpulse, impulse))
|
||||||
{
|
{
|
||||||
m_pPhysicsController->ApplyImpulse(attach, impulse);
|
m_pPhysicsController->ApplyImpulse(attach, impulse, (local!=0));
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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());
|
btVector3 impulse(impulsein.x(), impulsein.y(), impulsein.z());
|
||||||
|
|
||||||
if (m_object && impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON))
|
if (m_object && impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON))
|
||||||
@@ -1323,7 +1324,19 @@ void CcdPhysicsController::ApplyImpulse(const MT_Point3& attach, const MT_Vecto
|
|||||||
return;
|
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();
|
btRigidBody* body = GetRigidBody();
|
||||||
if (body)
|
if (body)
|
||||||
body->applyImpulse(impulse,pos);
|
body->applyImpulse(impulse,pos);
|
||||||
|
@@ -565,7 +565,7 @@ protected:
|
|||||||
virtual void SetMass(MT_Scalar newmass);
|
virtual void SetMass(MT_Scalar newmass);
|
||||||
|
|
||||||
// physics methods
|
// 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 ApplyTorque(const MT_Vector3& torque,bool local);
|
||||||
virtual void ApplyForce(const MT_Vector3& force,bool local);
|
virtual void ApplyForce(const MT_Vector3& force,bool local);
|
||||||
virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local);
|
virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local);
|
||||||
|
@@ -82,7 +82,7 @@ class PHY_IPhysicsController : public PHY_IController
|
|||||||
virtual void SetMass(MT_Scalar newmass)=0;
|
virtual void SetMass(MT_Scalar newmass)=0;
|
||||||
|
|
||||||
// physics methods
|
// 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 ApplyTorque(const MT_Vector3& torque,bool local)=0;
|
||||||
virtual void ApplyForce(const MT_Vector3& force,bool local)=0;
|
virtual void ApplyForce(const MT_Vector3& force,bool local)=0;
|
||||||
virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0;
|
virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0;
|
||||||
|
Reference in New Issue
Block a user