BGE: Fix for applyImpulse function
authorJorge Bernal <jbernalmartinez@gmail.com>
Mon, 7 Jul 2014 15:01:49 +0000 (08:01 -0700)
committerMitchell Stokes <mogurijin@gmail.com>
Mon, 7 Jul 2014 15:06:39 +0000 (08:06 -0700)
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

doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/common/PHY_IPhysicsController.h

index b314a47c8e9289c0868df20b76801440f05d8ed9..215ff40577c432a8212913fd6caaf1179e10ce80 100644 (file)
@@ -551,7 +551,7 @@ base class --- :class:`SCA_IObject`
 
          This is not implimented at the moment.
 
-   .. method:: applyImpulse(point, impulse)
+   .. method:: applyImpulse(point, impulse, local=False)
 
       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.
       Otherwise, only linear momentum will change.
 
-      :arg point: the point to apply the impulse to (in world coordinates)
-      :type 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: 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()
 
index 44646f17a6e6ded8bdb452e5599a01e375981b5d..f61d08e7f71967f32ac91f87c3b89edfbe46305d 100644 (file)
@@ -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;
                }
 
index c98cf21226592f996dce24c17734e8f8f3fa8d93..72c3b13e301a2d2687278cdc43196ce62bc852ab 100644 (file)
@@ -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);
index 25a8f0306bd19d75c7600a2fdca7bec7af290ad0..4d0d96e07c64053411e2b3b464d96e840751b761 100644 (file)
@@ -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);
index 2ffb115e3b2ed468faa985104470834e8ae19faf..f9975484fa7aa24b6cdddad70e4171fdd587376f 100644 (file)
@@ -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;