209 lines
5.3 KiB
C++
209 lines
5.3 KiB
C++
/*
|
|
* 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<KX_ArmatureSensor*>(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
|