BGE patch: Add damping and clamping option to motion actuator.
authorBenoit Bolsee <benoit.bolsee@online.be>
Tue, 24 Jun 2008 19:37:43 +0000 (19:37 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Tue, 24 Jun 2008 19:37:43 +0000 (19:37 +0000)
This patch introduces two options for the motion actuator:

damping: number of frames to reach the target velocity. It takes
into account the startup velocityin the target velocity direction
and add 1/damping fraction of target velocity until the full
velocity is reached. Works only with linear and angular velocity.
It will be extended to delta and force motion method in a future
release.

clamping: apply the force and torque as long as the target velocity
is not reached. If this option is set, the velocity specified
in linV or angV are not applied to the object but used as target
velocity. You should also specify a force in force or torque field:
the force will be applied as long as the velocity along the axis of
the vector set in linV or angV is not reached. Works best in low
friction environment.

12 files changed:
source/blender/makesdna/DNA_actuator_types.h
source/blender/src/buttons_logic.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_IPhysicsController.h
source/gameengine/Ketsji/KX_ObjectActuator.cpp
source/gameengine/Ketsji/KX_ObjectActuator.h
source/gameengine/Ketsji/KX_SumoPhysicsController.h

index 70d603a6ed950d8210b594ecb4e601beed9c5c65..3f08ea05705acb968acc208fcb6d868b877448b0 100644 (file)
@@ -98,7 +98,8 @@ typedef struct bPropertyActuator {
 } bPropertyActuator;
 
 typedef struct bObjectActuator {
-       int flag, type;
+       short flag, type;
+       int   damping;
        float forceloc[3], forcerot[3];
        float loc[3], rot[3];
        float dloc[3], drot[3];
@@ -252,6 +253,7 @@ typedef struct FreeCamera {
 #define ACT_ANG_VEL_LOCAL              32
 //#define ACT_ADD_LIN_VEL_LOCAL        64
 #define ACT_ADD_LIN_VEL                        64
+#define ACT_CLAMP_VEL                  128
 
 #define ACT_OBJECT_FORCE       0
 #define ACT_OBJECT_TORQUE      1
index bfa451428c3a868a764f2cf29ef9aa05808fd1f8..ec85952a2f8d843ebca8f219d5cc480b628ee7fc 100644 (file)
@@ -1613,7 +1613,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
        {
        case ACT_OBJECT:
                {
-                       ysize= 129;
+                       ysize= 152;
                        
                        glRects(xco, yco-ysize, xco+width, yco);
                        uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
@@ -1651,6 +1651,10 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
                        uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-125, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
                        uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-125, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
                        
+                       uiDefBut(block, LABEL, 0, "damp",       xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
+                       uiDefButI(block, NUM, 0, "",            xco+45, yco-148, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
+                       uiDefButBitI(block, TOG, ACT_CLAMP_VEL, 0, "clamp",xco+45+wval, yco-148, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between SET and CLAMP Velocity");
+
                        uiDefButBitI(block, TOG, ACT_FORCE_LOCAL, 0, "L",               xco+45+3*wval, yco-22, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
                        uiDefButBitI(block, TOG, ACT_TORQUE_LOCAL, 0, "L",              xco+45+3*wval, yco-41, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
                        uiDefButBitI(block, TOG, ACT_DLOC_LOCAL, 0, "L",                xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
index 21c18634e21f30216c5020cf713cc6249c3911c4..665783a1ba51ac9f5ed50a3022a143e774f1aa6b 100644 (file)
@@ -1668,6 +1668,8 @@ static KX_GameObject *gameobject_from_blenderobject(
                        BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, 
                                                                                                                        ob, (BL_SkinMeshObject*)meshobj);
                        ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
+                       if (bHasArmature)
+                               dcont->LoadShapeDrivers(ob->parent);
                } else if (bHasArmature) {
                        BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj );                         
                        ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
@@ -2329,7 +2331,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
        {
                KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
                struct Object* blenderobj = converter->FindBlenderObject(gameobj);
-               gameobj->SetState(blenderobj->state);
+               gameobj->SetState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
        }
 
 #endif //CONVERT_LOGIC
index 89e2925a6c1e944460d5e5041d958779333e355f..f0b549594f2720f5438b4178e8c96d1da590c03f 100644 (file)
@@ -137,6 +137,7 @@ void BL_ConvertActuators(char* maggiename,
                                MT_Vector3 angvelvec ( KX_BLENDERTRUNC(obact->angularvelocity[0]),
                                        KX_BLENDERTRUNC(obact->angularvelocity[1]),
                                        KX_BLENDERTRUNC(obact->angularvelocity[2]));
+                               short damping = obact->damping;
                                
                                drotvec /=              BLENDER_HACK_DTIME;
                                //drotvec /=            BLENDER_HACK_DTIME;
@@ -157,7 +158,7 @@ void BL_ConvertActuators(char* maggiename,
                                bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0);
                                bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
                                bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
-                               
+                               bitLocalFlag.ClampVelocity = bool((obact->flag & ACT_CLAMP_VEL)!=0);
                                bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0);
                                
                                
@@ -168,6 +169,7 @@ void BL_ConvertActuators(char* maggiename,
                                        drotvec.getValue(),
                                        linvelvec.getValue(),
                                        angvelvec.getValue(),
+                                       damping,
                                        bitLocalFlag
                                        );
                                baseact = tmpbaseact;
index aa7c75e96337a6c76f75194d5da3ebe75c9ebee4..70443ced7a9c61399a7b3d1ada22fcf293c907a7 100644 (file)
@@ -102,6 +102,13 @@ MT_Vector3 KX_BulletPhysicsController::GetLinearVelocity()
        CcdPhysicsController::GetLinearVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz
        return MT_Vector3(angVel[0],angVel[1],angVel[2]);
 }
+MT_Vector3 KX_BulletPhysicsController::GetAngularVelocity()
+{
+       float angVel[3];
+       //CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);
+       CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz
+       return MT_Vector3(angVel[0],angVel[1],angVel[2]);
+}
 MT_Vector3 KX_BulletPhysicsController::GetVelocity(const MT_Point3& pos)
 {
        float linVel[3];
index 619ac42503fd7f9ad9be0c909ad660bec17b03f1..0853755dffa5efa3e8b43bdd39e6be1f7396a4f9 100644 (file)
@@ -25,6 +25,7 @@ public:
        virtual void    ApplyTorque(const MT_Vector3& torque,bool local);
        virtual void    ApplyForce(const MT_Vector3& force,bool local);
        virtual MT_Vector3 GetLinearVelocity();
+       virtual MT_Vector3 GetAngularVelocity();
        virtual MT_Vector3 GetVelocity(const MT_Point3& pos);
        virtual void    SetAngularVelocity(const MT_Vector3& ang_vel,bool local);
        virtual void    SetLinearVelocity(const MT_Vector3& lin_vel,bool local);
index eaa6564ba848e95cb6921b3474a2528911e89456..cdbce81d6101ea126ccb1c0d80dc88955df03de0 100644 (file)
@@ -664,6 +664,27 @@ MT_Vector3 KX_GameObject::GetLinearVelocity(bool local)
        return velocity;        
 }
 
+MT_Vector3 KX_GameObject::GetAngularVelocity(bool local)
+{
+       MT_Vector3 velocity(0.0,0.0,0.0), locvel;
+       MT_Matrix3x3 ori;
+       int i, j; 
+       if (m_pPhysicsController1)
+       {
+               velocity = m_pPhysicsController1->GetAngularVelocity();
+               
+               if (local)
+               {
+                       ori = GetSGNode()->GetWorldOrientation();
+                       
+                       locvel = velocity * ori;
+                       return locvel;
+               }
+       }
+       return velocity;        
+}
+
+
 
 // scenegraph node stuff
 
index 63a660617c486849f571b475b64946b38cc3981b..cab1f3167d53d46c231bff5c88d8fca53f8122bb 100644 (file)
@@ -258,6 +258,14 @@ public:
                bool local=false
        );
 
+       /** 
+        * Return the angular velocity of the game object.
+        */
+               MT_Vector3 
+       GetAngularVelocity(
+               bool local=false
+       );
+
        /** 
         * Align the object to a given normal.
         */
index 009db40d3e8ced8034b9b8259e827a07a0eca131..2ec66a883eb708fbdc993d693dbc4c22e42d43b2 100644 (file)
@@ -64,6 +64,7 @@ public:
        virtual void    ApplyTorque(const MT_Vector3& torque,bool local)=0;
        virtual void    ApplyForce(const MT_Vector3& force,bool local)=0;
        virtual MT_Vector3 GetLinearVelocity()=0;
+       virtual MT_Vector3 GetAngularVelocity()=0;
        virtual MT_Vector3 GetVelocity(const MT_Point3& pos)=0;
        virtual void    SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0;
        virtual void    SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0;
index 22a406792f9a708c2695a37f97d8ecf4595ff116..03ae14997aba93f81e95d66fa01095ec39c7dcbd 100644 (file)
@@ -50,6 +50,7 @@ KX_ObjectActuator(
        const MT_Vector3& drot,
        const MT_Vector3& linV,
        const MT_Vector3& angV,
+       const short damping,
        const KX_LocalFlags& flag,
        PyTypeObject* T
 ) : 
@@ -60,9 +61,16 @@ KX_ObjectActuator(
        m_drot(drot),
        m_linear_velocity(linV),
        m_angular_velocity(angV),
+       m_linear_length2(0.0),
+       m_current_linear_factor(0.0),
+       m_current_angular_factor(0.0),
+       m_damping(damping),
        m_bitLocalFlag (flag),
-       m_active_combined_velocity (false)
+       m_active_combined_velocity (false),
+       m_linear_damping_active(false),
+       m_angular_damping_active(false)
 {
+       UpdateFuzzyFlags();
 }
 
 bool KX_ObjectActuator::Update()
@@ -87,42 +95,98 @@ bool KX_ObjectActuator::Update()
                                );
                        m_active_combined_velocity = false;
                } 
+               m_linear_damping_active = false;
                return false; 
 
        } else 
        if (parent)
        {
-               /* Probably better to use some flags, so these MT_zero tests can be  */
-               /* skipped.                                                          */
-               if (!MT_fuzzyZero(m_force))
+               if (!m_bitLocalFlag.ZeroForce)
                {
-                       parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
+                       if (m_bitLocalFlag.ClampVelocity && !m_bitLocalFlag.ZeroLinearVelocity)
+                       {
+                               // The user is requesting not to exceed the velocity set in m_linear_velocity
+                               // The verification is done by projecting the actual speed along the linV direction
+                               // and comparing it with the linV vector length
+                               MT_Vector3 linV;
+                               linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
+                               if (linV.dot(m_linear_velocity) < m_linear_length2)
+                                       parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
+                       } else 
+                       {
+                               parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
+                       }
                }
-               if (!MT_fuzzyZero(m_torque))
+               if (!m_bitLocalFlag.ZeroTorque)
                {
-                       parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
+                       if (m_bitLocalFlag.ClampVelocity && !m_bitLocalFlag.ZeroAngularVelocity)
+                       {
+                               // The user is requesting not to exceed the velocity set in m_angular_velocity
+                               // The verification is done by projecting the actual speed in the 
+                               MT_Vector3 angV;
+                               angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity);
+                               if (angV.dot(m_angular_velocity) < m_angular_velocity.length2())
+                                       parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
+                       } else
+                       {
+                               parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
+                       }
                }
-               if (!MT_fuzzyZero(m_dloc))
+               if (!m_bitLocalFlag.ZeroDLoc)
                {
                        parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0);
                }
-               if (!MT_fuzzyZero(m_drot))
+               if (!m_bitLocalFlag.ZeroDRot)
                {
                        parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
                }
-               if (!MT_fuzzyZero(m_linear_velocity))
+               if (!m_bitLocalFlag.ZeroLinearVelocity && !m_bitLocalFlag.ClampVelocity)
                {
                        if (m_bitLocalFlag.AddOrSetLinV) {
                                parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
                        } else {
                                m_active_combined_velocity = true;
-                               parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
+                               if (m_damping > 0) {
+                                       MT_Vector3 linV;
+                                       if (!m_linear_damping_active) {
+                                               // delta and the start speed (depends on the existing speed in that direction)
+                                               linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
+                                               // keep only the projection along the desired direction
+                                               m_current_linear_factor = linV.dot(m_linear_velocity)/m_linear_length2;
+                                               m_linear_damping_active = true;
+                                       }
+                                       if (m_current_linear_factor < 1.0)
+                                               m_current_linear_factor += 1.0/m_damping;
+                                       if (m_current_linear_factor > 1.0)
+                                               m_current_linear_factor = 1.0;
+                                       linV = m_current_linear_factor * m_linear_velocity;
+                                       parent->setLinearVelocity(linV,(m_bitLocalFlag.LinearVelocity) != 0);
+                               } else {
+                                       parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
+                               }
                        }
                }
-               if (!MT_fuzzyZero(m_angular_velocity))
+               if (!m_bitLocalFlag.ZeroAngularVelocity && !m_bitLocalFlag.ClampVelocity)
                {
-                       parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0);
                        m_active_combined_velocity = true;
+                       if (m_damping > 0) {
+                               MT_Vector3 angV;
+                               if (!m_angular_damping_active) {
+                                       // delta and the start speed (depends on the existing speed in that direction)
+                                       angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity);
+                                       // keep only the projection along the desired direction
+                                       m_current_angular_factor = angV.dot(m_angular_velocity)/m_angular_length2;
+                                       m_angular_damping_active = true;
+                               }
+                               if (m_current_angular_factor < 1.0)
+                                       m_current_angular_factor += 1.0/m_damping;
+                               if (m_current_angular_factor > 1.0)
+                                       m_current_angular_factor = 1.0;
+                               angV = m_current_angular_factor * m_angular_velocity;
+                               parent->setAngularVelocity(angV,(m_bitLocalFlag.AngularVelocity) != 0);
+                       } else {
+                               parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0);
+                       }
                }
                
        }
@@ -199,6 +263,8 @@ PyMethodDef KX_ObjectActuator::Methods[] = {
        {"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS},
        {"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_VARARGS},
        {"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS},
+       {"setVelocityDamping", (PyCFunction) KX_ObjectActuator::sPySetVelocityDamping, METH_VARARGS},
+       {"getVelocityDamping", (PyCFunction) KX_ObjectActuator::sPyGetVelocityDamping, METH_VARARGS},
 
 
        {NULL,NULL} //Sentinel
@@ -238,6 +304,7 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* self,
        }
        m_force.setValue(vecArg);
        m_bitLocalFlag.Force = PyArgToBool(bToggle);
+       UpdateFuzzyFlags();
        Py_Return;
 }
 
@@ -268,6 +335,7 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* self,
        }
        m_torque.setValue(vecArg);
        m_bitLocalFlag.Torque = PyArgToBool(bToggle);
+       UpdateFuzzyFlags();
        Py_Return;
 }
 
@@ -298,6 +366,7 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self,
        }
        m_dloc.setValue(vecArg);
        m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
+       UpdateFuzzyFlags();
        Py_Return;
 }
 
@@ -328,6 +397,7 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* self,
        }
        m_drot.setValue(vecArg);
        m_bitLocalFlag.DRot = PyArgToBool(bToggle);
+       UpdateFuzzyFlags();
        Py_Return;
 }
 
@@ -341,6 +411,7 @@ PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self,
        PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
        PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
        PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity));
+       PyList_SetItem(retVal, 4, BoolToPyArg(m_bitLocalFlag.ClampVelocity));
        
        return retVal;
 }
@@ -351,12 +422,15 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self,
                                                                                                 PyObject* kwds) {
        float vecArg[3];
        int bToggle = 0;
-       if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], 
-                                                 &vecArg[2], &bToggle)) {
+       int bClamp = 0;
+       if (!PyArg_ParseTuple(args, "fffi|i", &vecArg[0], &vecArg[1], 
+                                                 &vecArg[2], &bToggle, &bClamp)) {
                return NULL;
        }
        m_linear_velocity.setValue(vecArg);
        m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle);
+       m_bitLocalFlag.ClampVelocity = PyArgToBool(bClamp);
+       UpdateFuzzyFlags();
        Py_Return;
 }
 
@@ -371,6 +445,7 @@ PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self,
        PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
        PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
        PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity));
+       PyList_SetItem(retVal, 4, BoolToPyArg(m_bitLocalFlag.ClampVelocity));
        
        return retVal;
 }
@@ -380,15 +455,37 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self,
                                                                                                  PyObject* kwds) {
        float vecArg[3];
        int bToggle = 0;
-       if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], 
-                                                 &vecArg[2], &bToggle)) {
+       int bClamp = 0;
+       if (!PyArg_ParseTuple(args, "fffi|i", &vecArg[0], &vecArg[1], 
+                                                 &vecArg[2], &bToggle, &bClamp)) {
                return NULL;
        }
        m_angular_velocity.setValue(vecArg);
        m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle);
+       m_bitLocalFlag.ClampVelocity = PyArgToBool(bClamp);
+       UpdateFuzzyFlags();
        Py_Return;
 }
 
+/* 13. setVelocityDamping                                                */
+PyObject* KX_ObjectActuator::PySetVelocityDamping(PyObject* self, 
+                                                                                                 PyObject* args, 
+                                                                                                 PyObject* kwds) {
+       int damping = 0;
+       if (!PyArg_ParseTuple(args, "i", &damping) || damping < 0 || damping > 1000) {
+               return NULL;
+       }
+       m_damping = damping;
+       Py_Return;
+}
+
+/* 13. getVelocityDamping                                                */
+PyObject* KX_ObjectActuator::PyGetVelocityDamping(PyObject* self, 
+                                                                                                 PyObject* args, 
+                                                                                                 PyObject* kwds) {
+       return Py_BuildValue("i",m_damping);
+}
+
 
 
 
index edbae154b8beaa12ae56193cdc9147e79b7d12a9..ec6dab5cd4843714c7dde7b30d581f04161f8ef9 100644 (file)
@@ -46,7 +46,13 @@ struct KX_LocalFlags {
                DLoc(false),
                LinearVelocity(false),
                AngularVelocity(false),
-               AddOrSetLinV(false)
+               AddOrSetLinV(false),
+               ClampVelocity(false),
+               ZeroForce(false),
+               ZeroDRot(false),
+               ZeroDLoc(false),
+               ZeroLinearVelocity(false),
+               ZeroAngularVelocity(false)
        {
        }
 
@@ -57,6 +63,13 @@ struct KX_LocalFlags {
        unsigned short LinearVelocity : 1;
        unsigned short AngularVelocity : 1;
        unsigned short AddOrSetLinV : 1;
+       unsigned short ClampVelocity : 1;
+       unsigned short ZeroForce : 1;
+       unsigned short ZeroTorque : 1;
+       unsigned short ZeroDRot : 1;
+       unsigned short ZeroDLoc : 1;
+       unsigned short ZeroLinearVelocity : 1;
+       unsigned short ZeroAngularVelocity : 1;
 };
 
 class KX_ObjectActuator : public SCA_IActuator
@@ -69,6 +82,11 @@ class KX_ObjectActuator : public SCA_IActuator
        MT_Vector3              m_drot;
        MT_Vector3              m_linear_velocity;
        MT_Vector3              m_angular_velocity;     
+       MT_Scalar               m_linear_length2;
+       MT_Scalar               m_angular_length2;
+       MT_Scalar               m_current_linear_factor;
+       MT_Scalar               m_current_angular_factor;
+       short                   m_damping;
        KX_LocalFlags   m_bitLocalFlag;
 
        // A hack bool -- oh no sorry everyone
@@ -77,6 +95,8 @@ class KX_ObjectActuator : public SCA_IActuator
        // setting linear velocity.
 
        bool m_active_combined_velocity;
+       bool m_linear_damping_active;
+       bool m_angular_damping_active;
        
 public:
        enum KX_OBJECT_ACT_VEC_TYPE {
@@ -103,6 +123,7 @@ public:
                const MT_Vector3& drot,
                const MT_Vector3& linV,
                const MT_Vector3& angV,
+               const short damping,
                const KX_LocalFlags& flag,
                PyTypeObject* T=&Type
        );
@@ -110,6 +131,17 @@ public:
        CValue* GetReplica();
 
        void SetForceLoc(const double force[3]) { /*m_force=force;*/ }
+       void UpdateFuzzyFlags()
+               { 
+                       m_bitLocalFlag.ZeroForce = MT_fuzzyZero(m_force);
+                       m_bitLocalFlag.ZeroTorque = MT_fuzzyZero(m_torque);
+                       m_bitLocalFlag.ZeroDLoc = MT_fuzzyZero(m_dloc);
+                       m_bitLocalFlag.ZeroDRot = MT_fuzzyZero(m_drot);
+                       m_bitLocalFlag.ZeroLinearVelocity = MT_fuzzyZero(m_linear_velocity);
+                       m_linear_length2 = (m_bitLocalFlag.ZeroLinearVelocity) ? 0.0 : m_linear_velocity.length2();
+                       m_bitLocalFlag.ZeroAngularVelocity = MT_fuzzyZero(m_angular_velocity);
+                       m_angular_length2 = (m_bitLocalFlag.ZeroAngularVelocity) ? 0.0 : m_angular_velocity.length2();
+               }
        virtual bool Update();
 
 
@@ -132,6 +164,8 @@ public:
        KX_PYMETHOD(KX_ObjectActuator,SetLinearVelocity);
        KX_PYMETHOD(KX_ObjectActuator,GetAngularVelocity);
        KX_PYMETHOD(KX_ObjectActuator,SetAngularVelocity);
+       KX_PYMETHOD(KX_ObjectActuator,SetVelocityDamping);
+       KX_PYMETHOD(KX_ObjectActuator,GetVelocityDamping);
 };
 
 #endif //__KX_OBJECTACTUATOR
index 868465c8f10bb83b8cb4c0c7b5f10e7cda12bd4a..8c061ae4056c1ee8e917f1ef661ecd68211ad2b4 100644 (file)
@@ -68,6 +68,8 @@ public:
        void    ApplyTorque(const MT_Vector3& torque,bool local);
        void    ApplyForce(const MT_Vector3& force,bool local);
        MT_Vector3 GetLinearVelocity();
+       MT_Vector3 GetAngularVelocity()         // to keep compiler happy
+               { return MT_Vector3(0.0,0.0,0.0); }
        MT_Vector3 GetVelocity(const MT_Point3& pos);
        void    SetAngularVelocity(const MT_Vector3& ang_vel,bool local);
        void    SetLinearVelocity(const MT_Vector3& lin_vel,bool local);