Blender V2.61 - r43446

KX_ArmatureSensor.cpp

Go to the documentation of this file.
00001 /*
00002  * Armature sensor
00003  *
00004  *
00005  * ***** BEGIN GPL LICENSE BLOCK *****
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software Foundation,
00019  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00022  * All rights reserved.
00023  *
00024  * The Original Code is: all of this file.
00025  *
00026  * Contributor(s): none yet.
00027  *
00028  * ***** END GPL LICENSE BLOCK *****
00029  */
00030 
00036 #include "DNA_action_types.h"
00037 #include "DNA_constraint_types.h"
00038 #include "BKE_constraint.h"
00039 #include "DNA_sensor_types.h"
00040 
00041 #include "BL_ArmatureObject.h"
00042 #include "KX_ArmatureSensor.h"
00043 #include "SCA_EventManager.h"
00044 #include "SCA_LogicManager.h"
00045 
00046 KX_ArmatureSensor::KX_ArmatureSensor(class SCA_EventManager* eventmgr,
00047                     SCA_IObject* gameobj,
00048                     const char *posechannel,
00049                     const char *constraintname,
00050                     int type,
00051                     float value)
00052     : SCA_ISensor(gameobj,eventmgr),
00053     m_constraint(NULL),
00054     m_posechannel(posechannel),
00055     m_constraintname(constraintname),
00056     m_type(type),
00057     m_value(value)
00058 {
00059     FindConstraint();
00060 }
00061 
00062 void KX_ArmatureSensor::Init()
00063 {
00064     m_lastresult = m_invert?true:false;
00065     m_result = false;
00066     m_reset = true;
00067 }
00068 
00069 void KX_ArmatureSensor::FindConstraint()
00070 {
00071     m_constraint = NULL;
00072 
00073     if (m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
00074         BL_ArmatureObject* armobj = (BL_ArmatureObject*)m_gameobj;
00075         // get the persistent pose structure
00076         bPose* pose = armobj->GetOrigPose();
00077         bPoseChannel* pchan;
00078         bConstraint* pcon;
00079         // and locate the constraint
00080         for (pchan = (bPoseChannel*)pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
00081             if (!strcmp(pchan->name, m_posechannel)) {
00082                 // now locate the constraint
00083                 for (pcon = (bConstraint*)pchan->constraints.first; pcon; pcon=(bConstraint*)pcon->next) {
00084                     if (!strcmp(pcon->name, m_constraintname)) {
00085                         if (pcon->flag & CONSTRAINT_DISABLE)
00086                             /* this constraint is not valid, can't use it */
00087                             break;
00088                         m_constraint = pcon;
00089                         break;  
00090                     }
00091                 }
00092                 break;
00093             }
00094         }
00095     }
00096 }
00097 
00098 
00099 CValue* KX_ArmatureSensor::GetReplica()
00100 {
00101     KX_ArmatureSensor* replica = new KX_ArmatureSensor(*this);
00102     // m_range_expr must be recalculated on replica!
00103     replica->ProcessReplica();
00104     return replica;
00105 }
00106 
00107 void KX_ArmatureSensor::ReParent(SCA_IObject* parent)
00108 {
00109     SCA_ISensor::ReParent(parent);
00110     // must remap the constraint
00111     FindConstraint();
00112 }
00113 
00114 bool KX_ArmatureSensor::IsPositiveTrigger()
00115 {
00116     return (m_invert) ? !m_result : m_result;
00117 }
00118 
00119 
00120 KX_ArmatureSensor::~KX_ArmatureSensor()
00121 {
00122 }
00123 
00124 bool KX_ArmatureSensor::Evaluate()
00125 {
00126     bool reset = m_reset && m_level;
00127 
00128     m_reset = false;
00129     if (!m_constraint)
00130         return false;
00131     switch (m_type) {
00132     case SENS_ARM_STATE_CHANGED:
00133         m_result = !(m_constraint->flag & CONSTRAINT_OFF);
00134         break;
00135     case SENS_ARM_LIN_ERROR_BELOW:
00136         m_result = (m_constraint->lin_error < m_value);
00137         break;
00138     case SENS_ARM_LIN_ERROR_ABOVE:
00139         m_result = (m_constraint->lin_error > m_value);
00140         break;
00141     case SENS_ARM_ROT_ERROR_BELOW:
00142         m_result = (m_constraint->rot_error < m_value);
00143         break;
00144     case SENS_ARM_ROT_ERROR_ABOVE:
00145         m_result = (m_constraint->rot_error > m_value);
00146         break;
00147     }
00148     if (m_lastresult!=m_result)
00149     {
00150         m_lastresult = m_result;
00151         return true;
00152     }
00153     return (reset) ? true : false;
00154 }
00155 
00156 #ifdef WITH_PYTHON
00157 
00158 /* ------------------------------------------------------------------------- */
00159 /* Python functions                                                          */
00160 /* ------------------------------------------------------------------------- */
00161 
00162 /* Integration hooks ------------------------------------------------------- */
00163 PyTypeObject KX_ArmatureSensor::Type = {
00164     PyVarObject_HEAD_INIT(NULL, 0)
00165     "KX_ArmatureSensor",
00166     sizeof(PyObjectPlus_Proxy),
00167     0,
00168     py_base_dealloc,
00169     0,
00170     0,
00171     0,
00172     0,
00173     py_base_repr,
00174     0,0,0,0,0,0,0,0,0,
00175     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00176     0,0,0,0,0,0,0,
00177     Methods,
00178     0,
00179     0,
00180     &SCA_ISensor::Type,
00181     0,0,0,0,0,0,
00182     py_base_new
00183 };
00184 
00185 PyMethodDef KX_ArmatureSensor::Methods[] = {
00186     {NULL,NULL} //Sentinel
00187 };
00188 
00189 PyAttributeDef KX_ArmatureSensor::Attributes[] = {
00190     KX_PYATTRIBUTE_RO_FUNCTION("constraint", KX_ArmatureSensor, pyattr_get_constraint),
00191     KX_PYATTRIBUTE_FLOAT_RW("value",-FLT_MAX,FLT_MAX,KX_ArmatureSensor,m_value),
00192     KX_PYATTRIBUTE_INT_RW("type",0,SENS_ARM_MAXTYPE,false,KX_ArmatureSensor,m_type),
00193     { NULL }    //Sentinel
00194 };
00195 
00196 PyObject* KX_ArmatureSensor::pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
00197 {
00198     KX_ArmatureSensor* sensor = static_cast<KX_ArmatureSensor*>(self);
00199     if (sensor->m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
00200         BL_ArmatureObject* armobj = (BL_ArmatureObject*)sensor->m_gameobj;
00201         BL_ArmatureConstraint* constraint = armobj->GetConstraint(sensor->m_posechannel, sensor->m_constraintname);
00202         if (constraint) 
00203             return constraint->GetProxy();
00204     }
00205     Py_RETURN_NONE;
00206 }
00207 
00208 #endif // WITH_PYTHON