Commit: 1f43b083a97ee56b8b15692ef19d0e973b6d31ac
Author: Jorge Bernal
Date:   Mon Jul 7 08:01:49 2014 -0700
https://developer.blender.org/rB1f43b083a97ee56b8b15692ef19d0e973b6d31ac

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

===================================================================

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

===================================================================

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 b314a47..215ff40 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
@@ -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()
 
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp 
b/source/gameengine/Ketsji/KX_GameObject.cpp
index 44646f1..f61d08e 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 c98cf21..72c3b13 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 25a8f03..4d0d96e 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 2ffb115..f997548 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;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to