Blender  V2.59
BL_ArmatureActuator.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: BL_ArmatureActuator.cpp 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 #include "DNA_action_types.h"
00036 #include "DNA_constraint_types.h"
00037 #include "DNA_actuator_types.h"
00038 #include "BKE_constraint.h"
00039 #include "BL_ArmatureActuator.h"
00040 #include "BL_ArmatureObject.h"
00041 #include "BLI_math.h"
00042 
00052 BL_ArmatureActuator::BL_ArmatureActuator(SCA_IObject* obj,
00053                                                 int type,
00054                                                 const char *posechannel,
00055                                                 const char *constraintname,
00056                                                 KX_GameObject* targetobj,
00057                                                 KX_GameObject* subtargetobj,
00058                                                 float weight) :
00059         SCA_IActuator(obj, KX_ACT_ARMATURE),
00060         m_constraint(NULL),
00061         m_gametarget(targetobj),
00062         m_gamesubtarget(subtargetobj),
00063         m_posechannel(posechannel),
00064         m_constraintname(constraintname),
00065         m_weight(weight),
00066         m_type(type)
00067 {
00068         if (m_gametarget)
00069                 m_gametarget->RegisterActuator(this);
00070         if (m_gamesubtarget)
00071                 m_gamesubtarget->RegisterActuator(this);
00072         FindConstraint();
00073 }
00074 
00075 BL_ArmatureActuator::~BL_ArmatureActuator()
00076 {
00077         if (m_gametarget)
00078                 m_gametarget->UnregisterActuator(this);
00079         if (m_gamesubtarget)
00080                 m_gamesubtarget->UnregisterActuator(this);
00081 }
00082 
00083 void BL_ArmatureActuator::ProcessReplica()
00084 {
00085         // the replica is tracking the same object => register it (this may be changed in Relnk())
00086         if (m_gametarget)
00087                 m_gametarget->RegisterActuator(this);
00088         if (m_gamesubtarget)
00089                 m_gamesubtarget->UnregisterActuator(this);
00090         SCA_IActuator::ProcessReplica();
00091 }
00092 
00093 void BL_ArmatureActuator::ReParent(SCA_IObject* parent)
00094 {
00095         SCA_IActuator::ReParent(parent);
00096         // must remap the constraint
00097         FindConstraint();
00098 }
00099 
00100 bool BL_ArmatureActuator::UnlinkObject(SCA_IObject* clientobj)
00101 {
00102         bool res=false;
00103         if (clientobj == m_gametarget)
00104         {
00105                 // this object is being deleted, we cannot continue to track it.
00106                 m_gametarget = NULL;
00107                 res = true;
00108         }
00109         if (clientobj == m_gamesubtarget)
00110         {
00111                 // this object is being deleted, we cannot continue to track it.
00112                 m_gamesubtarget = NULL;
00113                 res = true;
00114         }
00115         return res;
00116 }
00117 
00118 void BL_ArmatureActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
00119 {
00120         void **h_obj = (*obj_map)[m_gametarget];
00121         if (h_obj) {
00122                 if (m_gametarget)
00123                         m_gametarget->UnregisterActuator(this);
00124                 m_gametarget = (KX_GameObject*)(*h_obj);
00125                 m_gametarget->RegisterActuator(this);
00126         }
00127         h_obj = (*obj_map)[m_gamesubtarget];
00128         if (h_obj) {
00129                 if (m_gamesubtarget)
00130                         m_gamesubtarget->UnregisterActuator(this);
00131                 m_gamesubtarget = (KX_GameObject*)(*h_obj);
00132                 m_gamesubtarget->RegisterActuator(this);
00133         }
00134 }
00135 
00136 void BL_ArmatureActuator::FindConstraint()
00137 {
00138         m_constraint = NULL;
00139 
00140         if (m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
00141                 BL_ArmatureObject* armobj = (BL_ArmatureObject*)m_gameobj;
00142                 m_constraint = armobj->GetConstraint(m_posechannel, m_constraintname);
00143         }
00144 }
00145 
00146 bool BL_ArmatureActuator::Update(double curtime, bool frame)
00147 {
00148         // the only role of this actuator is to ensure that the armature pose will be evaluated
00149         bool result = false;    
00150         bool bNegativeEvent = IsNegativeEvent();
00151         RemoveAllEvents();
00152 
00153         if (!bNegativeEvent) {
00154                 BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
00155                 switch (m_type) {
00156                 case ACT_ARM_RUN:
00157                         result = true;
00158                         obj->SetActiveAction(NULL, 0, curtime);
00159                         break;
00160                 case ACT_ARM_ENABLE:
00161                         if (m_constraint)
00162                                 m_constraint->ClrConstraintFlag(CONSTRAINT_OFF);
00163                         break;
00164                 case ACT_ARM_DISABLE:
00165                         if (m_constraint)
00166                                 m_constraint->SetConstraintFlag(CONSTRAINT_OFF);
00167                         break;
00168                 case ACT_ARM_SETTARGET:
00169                         if (m_constraint) {
00170                                 m_constraint->SetTarget(m_gametarget);
00171                                 m_constraint->SetSubtarget(m_gamesubtarget);
00172                         }
00173                         break;
00174                 case ACT_ARM_SETWEIGHT:
00175                         if (m_constraint)
00176                                 m_constraint->SetWeight(m_weight);
00177                         break;
00178                 }
00179         }
00180         return result;
00181 }
00182 
00183 #ifdef WITH_PYTHON
00184 
00185 /* ------------------------------------------------------------------------- */
00186 /* Python Integration Hooks                                                                      */
00187 /* ------------------------------------------------------------------------- */
00188 
00189 PyTypeObject BL_ArmatureActuator::Type = {
00190         PyVarObject_HEAD_INIT(NULL, 0)
00191                 "BL_ArmatureActuator",
00192                 sizeof(PyObjectPlus_Proxy),
00193                 0,
00194                 py_base_dealloc,
00195                 0,
00196                 0,
00197                 0,
00198                 0,
00199                 py_base_repr,
00200                 0,0,0,0,0,0,0,0,0,
00201                 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00202                 0,0,0,0,0,0,0,
00203                 Methods,
00204                 0,
00205                 0,
00206                 &SCA_IActuator::Type,
00207                 0,0,0,0,0,0,
00208                 py_base_new
00209 };
00210 
00211 
00212 PyMethodDef BL_ArmatureActuator::Methods[] = {
00213         {NULL,NULL} //Sentinel
00214 };
00215 
00216 PyAttributeDef BL_ArmatureActuator::Attributes[] = {
00217         KX_PYATTRIBUTE_RO_FUNCTION("constraint", BL_ArmatureActuator, pyattr_get_constraint),
00218         KX_PYATTRIBUTE_RW_FUNCTION("target", BL_ArmatureActuator, pyattr_get_object, pyattr_set_object),
00219         KX_PYATTRIBUTE_RW_FUNCTION("subtarget", BL_ArmatureActuator, pyattr_get_object, pyattr_set_object),
00220         KX_PYATTRIBUTE_FLOAT_RW("weight",0.0f,1.0f,BL_ArmatureActuator,m_weight),
00221         KX_PYATTRIBUTE_INT_RW("type",0,ACT_ARM_MAXTYPE,false,BL_ArmatureActuator,m_type),
00222         { NULL }        //Sentinel
00223 };
00224 
00225 PyObject* BL_ArmatureActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
00226 {
00227         BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
00228         KX_GameObject *target = (!strcmp(attrdef->m_name, "target")) ? actuator->m_gametarget : actuator->m_gamesubtarget;
00229         if (!target)    
00230                 Py_RETURN_NONE;
00231         else
00232                 return target->GetProxy();
00233 }
00234 
00235 int BL_ArmatureActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
00236 {
00237         BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
00238         KX_GameObject* &target = (!strcmp(attrdef->m_name, "target")) ? actuator->m_gametarget : actuator->m_gamesubtarget;
00239         KX_GameObject *gameobj;
00240                 
00241         if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: BL_ArmatureActuator"))
00242                 return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
00243                 
00244         if (target != NULL)
00245                 target->UnregisterActuator(actuator);   
00246 
00247         target = gameobj;
00248                 
00249         if (target)
00250                 target->RegisterActuator(actuator);
00251                 
00252         return PY_SET_ATTR_SUCCESS;
00253 }
00254 
00255 PyObject* BL_ArmatureActuator::pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
00256 {
00257         BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
00258         BL_ArmatureConstraint* constraint = actuator->m_constraint;
00259         if (!constraint)        
00260                 Py_RETURN_NONE;
00261         else
00262                 return constraint->GetProxy();
00263 }
00264 
00265 #endif // WITH_PYTHON
00266