/* * Armature sensor * * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL LICENSE BLOCK ***** */ /** \file gameengine/Ketsji/KX_ArmatureSensor.cpp * \ingroup ketsji */ #include "DNA_action_types.h" #include "DNA_constraint_types.h" #include "BKE_constraint.h" #include "DNA_sensor_types.h" #include "BL_ArmatureObject.h" #include "KX_ArmatureSensor.h" #include "SCA_EventManager.h" #include "SCA_LogicManager.h" KX_ArmatureSensor::KX_ArmatureSensor(class SCA_EventManager* eventmgr, SCA_IObject* gameobj, const char *posechannel, const char *constraintname, int type, float value) : SCA_ISensor(gameobj,eventmgr), m_constraint(NULL), m_posechannel(posechannel), m_constraintname(constraintname), m_type(type), m_value(value) { FindConstraint(); } void KX_ArmatureSensor::Init() { m_lastresult = m_invert?true:false; m_result = false; m_reset = true; } void KX_ArmatureSensor::FindConstraint() { m_constraint = NULL; if (m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) { BL_ArmatureObject* armobj = (BL_ArmatureObject*)m_gameobj; // get the persistent pose structure bPose* pose = armobj->GetOrigPose(); bPoseChannel* pchan; bConstraint* pcon; // and locate the constraint for (pchan = (bPoseChannel*)pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) { if (!strcmp(pchan->name, m_posechannel)) { // now locate the constraint for (pcon = (bConstraint *)pchan->constraints.first; pcon; pcon = (bConstraint *)pcon->next) { if (!strcmp(pcon->name, m_constraintname)) { if (pcon->flag & CONSTRAINT_DISABLE) /* this constraint is not valid, can't use it */ break; m_constraint = pcon; break; } } break; } } } } CValue* KX_ArmatureSensor::GetReplica() { KX_ArmatureSensor* replica = new KX_ArmatureSensor(*this); // m_range_expr must be recalculated on replica! replica->ProcessReplica(); return replica; } void KX_ArmatureSensor::ReParent(SCA_IObject* parent) { SCA_ISensor::ReParent(parent); // must remap the constraint FindConstraint(); } bool KX_ArmatureSensor::IsPositiveTrigger() { return (m_invert) ? !m_result : m_result; } KX_ArmatureSensor::~KX_ArmatureSensor() { } bool KX_ArmatureSensor::Evaluate() { bool reset = m_reset && m_level; m_reset = false; if (!m_constraint) return false; switch (m_type) { case SENS_ARM_STATE_CHANGED: m_result = !(m_constraint->flag & CONSTRAINT_OFF); break; case SENS_ARM_LIN_ERROR_BELOW: m_result = (m_constraint->lin_error < m_value); break; case SENS_ARM_LIN_ERROR_ABOVE: m_result = (m_constraint->lin_error > m_value); break; case SENS_ARM_ROT_ERROR_BELOW: m_result = (m_constraint->rot_error < m_value); break; case SENS_ARM_ROT_ERROR_ABOVE: m_result = (m_constraint->rot_error > m_value); break; } if (m_lastresult!=m_result) { m_lastresult = m_result; return true; } return (reset) ? true : false; } #ifdef WITH_PYTHON /* ------------------------------------------------------------------------- */ /* Python functions */ /* ------------------------------------------------------------------------- */ /* Integration hooks ------------------------------------------------------- */ PyTypeObject KX_ArmatureSensor::Type = { PyVarObject_HEAD_INIT(NULL, 0) "KX_ArmatureSensor", sizeof(PyObjectPlus_Proxy), 0, py_base_dealloc, 0, 0, 0, 0, py_base_repr, 0,0,0,0,0,0,0,0,0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, 0,0,0,0,0,0,0, Methods, 0, 0, &SCA_ISensor::Type, 0,0,0,0,0,0, py_base_new }; PyMethodDef KX_ArmatureSensor::Methods[] = { {NULL,NULL} //Sentinel }; PyAttributeDef KX_ArmatureSensor::Attributes[] = { KX_PYATTRIBUTE_RO_FUNCTION("constraint", KX_ArmatureSensor, pyattr_get_constraint), KX_PYATTRIBUTE_FLOAT_RW("value",-FLT_MAX,FLT_MAX,KX_ArmatureSensor,m_value), KX_PYATTRIBUTE_INT_RW("type",0,SENS_ARM_MAXTYPE,false,KX_ArmatureSensor,m_type), { NULL } //Sentinel }; PyObject *KX_ArmatureSensor::pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) { KX_ArmatureSensor* sensor = static_cast(self); if (sensor->m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) { BL_ArmatureObject* armobj = (BL_ArmatureObject*)sensor->m_gameobj; BL_ArmatureConstraint* constraint = armobj->GetConstraint(sensor->m_posechannel, sensor->m_constraintname); if (constraint) return constraint->GetProxy(); } Py_RETURN_NONE; } #endif // WITH_PYTHON