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