Blender V2.61 - r43446

KX_ObjectActuator.h

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #ifndef __KX_OBJECTACTUATOR
00034 #define __KX_OBJECTACTUATOR
00035 
00036 #include "SCA_IActuator.h"
00037 #include "MT_Vector3.h"
00038 
00039 #ifdef USE_MATHUTILS
00040 void KX_ObjectActuator_Mathutils_Callback_Init(void);
00041 #endif
00042 
00043 class KX_GameObject;
00044 
00045 //
00046 // Stores the flags for each CValue derived class
00047 //
00048 struct KX_LocalFlags {
00049     KX_LocalFlags() :
00050         Force(false),
00051         Torque(false),
00052         DRot(false),
00053         DLoc(false),
00054         LinearVelocity(false),
00055         AngularVelocity(false),
00056         AddOrSetLinV(false),
00057         ZeroForce(false),
00058         ZeroDRot(false),
00059         ZeroDLoc(false),
00060         ZeroLinearVelocity(false),
00061         ZeroAngularVelocity(false)
00062     {
00063     }
00064 
00065     bool Force;
00066     bool Torque;
00067     bool DRot;
00068     bool DLoc;
00069     bool LinearVelocity;
00070     bool AngularVelocity;
00071     bool AddOrSetLinV;
00072     bool ServoControl;
00073     bool ZeroForce;
00074     bool ZeroTorque;
00075     bool ZeroDRot;
00076     bool ZeroDLoc;
00077     bool ZeroLinearVelocity;
00078     bool ZeroAngularVelocity;
00079 };
00080 
00081 class KX_ObjectActuator : public SCA_IActuator
00082 {
00083     Py_Header
00084 
00085     MT_Vector3      m_force;
00086     MT_Vector3      m_torque;
00087     MT_Vector3      m_dloc;
00088     MT_Vector3      m_drot;
00089     MT_Vector3      m_linear_velocity;
00090     MT_Vector3      m_angular_velocity;
00091     MT_Vector3      m_pid;
00092     MT_Scalar       m_linear_length2;
00093     MT_Scalar       m_angular_length2;
00094     // used in damping
00095     MT_Scalar       m_current_linear_factor;
00096     MT_Scalar       m_current_angular_factor;
00097     short           m_damping;
00098     // used in servo control
00099     MT_Vector3      m_previous_error;
00100     MT_Vector3      m_error_accumulator;
00101     KX_LocalFlags   m_bitLocalFlag;
00102     KX_GameObject*  m_reference;
00103     // A hack bool -- oh no sorry everyone
00104     // This bool is used to check if we have informed 
00105     // the physics object that we are no longer 
00106     // setting linear velocity.
00107 
00108     bool m_active_combined_velocity;
00109     bool m_linear_damping_active;
00110     bool m_angular_damping_active;
00111     
00112 public:
00113     enum KX_OBJECT_ACT_VEC_TYPE {
00114         KX_OBJECT_ACT_NODEF = 0,
00115         KX_OBJECT_ACT_FORCE,
00116         KX_OBJECT_ACT_TORQUE,
00117         KX_OBJECT_ACT_DLOC,
00118         KX_OBJECT_ACT_DROT,
00119         KX_OBJECT_ACT_LINEAR_VELOCITY,
00120         KX_OBJECT_ACT_ANGULAR_VELOCITY,
00121         KX_OBJECT_ACT_MAX
00122     };
00123         
00127     bool isValid(KX_OBJECT_ACT_VEC_TYPE type);
00128 
00129     KX_ObjectActuator(
00130         SCA_IObject* gameobj,
00131         KX_GameObject* refobj,
00132         const MT_Vector3& force,
00133         const MT_Vector3& torque,
00134         const MT_Vector3& dloc,
00135         const MT_Vector3& drot,
00136         const MT_Vector3& linV,
00137         const MT_Vector3& angV,
00138         const short damping,
00139         const KX_LocalFlags& flag
00140     );
00141     ~KX_ObjectActuator();
00142     CValue* GetReplica();
00143     void ProcessReplica();
00144     bool UnlinkObject(SCA_IObject* clientobj);
00145     void Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map);
00146 
00147     void SetForceLoc(const double force[3]) { /*m_force=force;*/ }
00148     void UpdateFuzzyFlags()
00149         { 
00150             m_bitLocalFlag.ZeroForce = MT_fuzzyZero(m_force);
00151             m_bitLocalFlag.ZeroTorque = MT_fuzzyZero(m_torque);
00152             m_bitLocalFlag.ZeroDLoc = MT_fuzzyZero(m_dloc);
00153             m_bitLocalFlag.ZeroDRot = MT_fuzzyZero(m_drot);
00154             m_bitLocalFlag.ZeroLinearVelocity = MT_fuzzyZero(m_linear_velocity);
00155             m_linear_length2 = (m_bitLocalFlag.ZeroLinearVelocity) ? 0.0 : m_linear_velocity.length2();
00156             m_bitLocalFlag.ZeroAngularVelocity = MT_fuzzyZero(m_angular_velocity);
00157             m_angular_length2 = (m_bitLocalFlag.ZeroAngularVelocity) ? 0.0 : m_angular_velocity.length2();
00158         }
00159     virtual bool Update();
00160 
00161 #ifdef WITH_PYTHON
00162 
00163     /* --------------------------------------------------------------------- */
00164     /* Python interface ---------------------------------------------------- */
00165     /* --------------------------------------------------------------------- */
00166 
00167     /* Attributes */
00168     static PyObject*    pyattr_get_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
00169     static int          pyattr_set_forceLimitX(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
00170     static PyObject*    pyattr_get_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
00171     static int          pyattr_set_forceLimitY(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
00172     static PyObject*    pyattr_get_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
00173     static int          pyattr_set_forceLimitZ(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
00174     static PyObject*    pyattr_get_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
00175     static int          pyattr_set_reference(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
00176 
00177 #ifdef USE_MATHUTILS
00178     static PyObject*    pyattr_get_linV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
00179     static int          pyattr_set_linV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
00180     static PyObject*    pyattr_get_angV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
00181     static int          pyattr_set_angV(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
00182 #endif
00183 
00184     // This lets the attribute macros use UpdateFuzzyFlags()
00185     static int PyUpdateFuzzyFlags(void *self, const PyAttributeDef *attrdef)
00186     {
00187         KX_ObjectActuator* act = reinterpret_cast<KX_ObjectActuator*>(self);
00188         act->UpdateFuzzyFlags();
00189         return 0;
00190     }
00191 
00192     // This is the keep the PID values in check after they are assigned with Python
00193     static int PyCheckPid(void *self, const PyAttributeDef *attrdef)
00194     {
00195         KX_ObjectActuator* act = reinterpret_cast<KX_ObjectActuator*>(self);
00196 
00197         //P 0 to 200
00198         if (act->m_pid[0] < 0) {
00199             act->m_pid[0] = 0;
00200         } else if (act->m_pid[0] > 200) {
00201             act->m_pid[0] = 200;
00202         }
00203 
00204         //I 0 to 3
00205         if (act->m_pid[1] < 0) {
00206             act->m_pid[1] = 0;
00207         } else if (act->m_pid[1] > 3) {
00208             act->m_pid[1] = 3;
00209         }
00210 
00211         //D -100 to 100
00212         if (act->m_pid[2] < -100) {
00213             act->m_pid[2] = -100;
00214         } else if (act->m_pid[2] > 100) {
00215             act->m_pid[2] = 100;
00216         }
00217 
00218         return 0;
00219     }
00220 
00221 #endif // WITH_PYTHON
00222 
00223 };
00224 
00225 #endif //__KX_OBJECTACTUATOR
00226