123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- /*
- * ***** 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/Converter/BL_ArmatureConstraint.cpp
- * \ingroup bgeconv
- */
- #include "DNA_constraint_types.h"
- #include "DNA_action_types.h"
- #include "BL_ArmatureConstraint.h"
- #include "BL_ArmatureObject.h"
- #include "BLI_math.h"
- #include "BLI_string.h"
- #include "KX_PythonInit.h"
- #ifdef WITH_PYTHON
- PyTypeObject BL_ArmatureConstraint::Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "BL_ArmatureConstraint",
- 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,
- &CValue::Type,
- 0,0,0,0,0,0,
- py_base_new
- };
- PyObject *BL_ArmatureConstraint::py_repr(void)
- {
- return PyUnicode_FromString(m_name);
- }
- #endif // WITH_PYTHON
- BL_ArmatureConstraint::BL_ArmatureConstraint(
- BL_ArmatureObject *armature,
- bPoseChannel *posechannel,
- bConstraint *constraint,
- KX_GameObject* target,
- KX_GameObject* subtarget)
- : PyObjectPlus(), m_constraint(constraint), m_posechannel(posechannel), m_armature(armature)
- {
- m_target = target;
- m_blendtarget = (target) ? target->GetBlenderObject() : NULL;
- m_subtarget = subtarget;
- m_blendsubtarget = (subtarget) ? subtarget->GetBlenderObject() : NULL;
- m_pose = m_subpose = NULL;
- if (m_blendtarget) {
- copy_m4_m4(m_blendmat, m_blendtarget->obmat);
- if (m_blendtarget->type == OB_ARMATURE)
- m_pose = m_blendtarget->pose;
- }
- if (m_blendsubtarget) {
- copy_m4_m4(m_blendsubmat, m_blendsubtarget->obmat);
- if (m_blendsubtarget->type == OB_ARMATURE)
- m_subpose = m_blendsubtarget->pose;
- }
- if (m_target)
- m_target->RegisterObject(m_armature);
- if (m_subtarget)
- m_subtarget->RegisterObject(m_armature);
- BLI_snprintf(m_name, sizeof(m_name), "%s:%s", m_posechannel->name, m_constraint->name);
- }
- BL_ArmatureConstraint::~BL_ArmatureConstraint()
- {
- if (m_target)
- m_target->UnregisterObject(m_armature);
- if (m_subtarget)
- m_subtarget->UnregisterObject(m_armature);
- }
- BL_ArmatureConstraint* BL_ArmatureConstraint::GetReplica() const
- {
- BL_ArmatureConstraint* replica = new BL_ArmatureConstraint(*this);
- replica->ProcessReplica();
- return replica;
- }
- void BL_ArmatureConstraint::ReParent(BL_ArmatureObject* armature)
- {
- m_armature = armature;
- if (m_target)
- m_target->RegisterObject(armature);
- if (m_subtarget)
- m_subtarget->RegisterObject(armature);
- // find the corresponding constraint in the new armature object
- if (m_constraint) {
- bPose* newpose = armature->GetOrigPose();
- char* constraint = m_constraint->name;
- char* posechannel = m_posechannel->name;
- bPoseChannel* pchan;
- bConstraint* pcon;
- m_constraint = NULL;
- m_posechannel = NULL;
- // and locate the constraint
- for (pchan = (bPoseChannel*)newpose->chanbase.first; pchan; pchan = (bPoseChannel*)pchan->next) {
- if (!strcmp(pchan->name, posechannel)) {
- // now locate the constraint
- for (pcon = (bConstraint *)pchan->constraints.first; pcon; pcon = (bConstraint *)pcon->next) {
- if (!strcmp(pcon->name, constraint)) {
- m_constraint = pcon;
- m_posechannel = pchan;
- break;
- }
- }
- break;
- }
- }
- }
- }
- void BL_ArmatureConstraint::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
- {
- void **h_obj = (*obj_map)[m_target];
- if (h_obj) {
- m_target->UnregisterObject(m_armature);
- m_target = (KX_GameObject*)(*h_obj);
- m_target->RegisterObject(m_armature);
- }
- h_obj = (*obj_map)[m_subtarget];
- if (h_obj) {
- m_subtarget->UnregisterObject(m_armature);
- m_subtarget = (KX_GameObject*)(*h_obj);
- m_subtarget->RegisterObject(m_armature);
- }
- }
- bool BL_ArmatureConstraint::UnlinkObject(SCA_IObject* clientobj)
- {
- bool res=false;
- if (clientobj == m_target) {
- m_target = NULL;
- res = true;
- }
- if (clientobj == m_subtarget) {
- m_subtarget = NULL;
- res = true;
- }
- return res;
- }
- void BL_ArmatureConstraint::UpdateTarget()
- {
- if (m_constraint && !(m_constraint->flag&CONSTRAINT_OFF) && (!m_blendtarget || m_target)) {
- if (m_blendtarget) {
- // external target, must be updated
- m_target->UpdateBlenderObjectMatrix(m_blendtarget);
- if (m_pose && m_target->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
- // update the pose in case a bone is specified in the constraint target
- m_blendtarget->pose = ((BL_ArmatureObject*)m_target)->GetOrigPose();
- }
- if (m_blendsubtarget && m_subtarget) {
- m_subtarget->UpdateBlenderObjectMatrix(m_blendsubtarget);
- if (m_subpose && m_subtarget->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
- m_blendsubtarget->pose = ((BL_ArmatureObject*)m_subtarget)->GetOrigPose();
- }
- }
- }
- void BL_ArmatureConstraint::RestoreTarget()
- {
- if (m_constraint && !(m_constraint->flag&CONSTRAINT_OFF) && (!m_blendtarget || m_target)) {
- if (m_blendtarget) {
- copy_m4_m4(m_blendtarget->obmat, m_blendmat);
- if (m_pose)
- m_blendtarget->pose = m_pose;
- }
- if (m_blendsubtarget && m_subtarget) {
- copy_m4_m4(m_blendsubtarget->obmat, m_blendsubmat);
- if (m_subpose)
- m_blendsubtarget->pose = m_subpose;
- }
- }
- }
- bool BL_ArmatureConstraint::Match(const char* posechannel, const char* constraint)
- {
- return (!strcmp(m_posechannel->name, posechannel) && !strcmp(m_constraint->name, constraint));
- }
- void BL_ArmatureConstraint::SetTarget(KX_GameObject* target)
- {
- if (m_blendtarget) {
- if (target != m_target) {
- m_target->UnregisterObject(m_armature);
- m_target = target;
- if (m_target)
- m_target->RegisterObject(m_armature);
- }
- }
- }
- void BL_ArmatureConstraint::SetSubtarget(KX_GameObject* subtarget)
- {
- if (m_blendsubtarget) {
- if (subtarget != m_subtarget) {
- m_subtarget->UnregisterObject(m_armature);
- m_subtarget = subtarget;
- if (m_subtarget)
- m_subtarget->RegisterObject(m_armature);
- }
- }
- }
- #ifdef WITH_PYTHON
- // PYTHON
- PyMethodDef BL_ArmatureConstraint::Methods[] = {
- {NULL,NULL} //Sentinel
- };
- // order of definition of attributes, must match Attributes[] array
- #define BCA_TYPE 0
- #define BCA_NAME 1
- #define BCA_ENFORCE 2
- #define BCA_HEADTAIL 3
- #define BCA_LINERROR 4
- #define BCA_ROTERROR 5
- #define BCA_TARGET 6
- #define BCA_SUBTARGET 7
- #define BCA_ACTIVE 8
- #define BCA_IKWEIGHT 9
- #define BCA_IKTYPE 10
- #define BCA_IKFLAG 11
- #define BCA_IKDIST 12
- #define BCA_IKMODE 13
- PyAttributeDef BL_ArmatureConstraint::Attributes[] = {
- // Keep these attributes in order of BCA_ defines!!! used by py_attr_getattr and py_attr_setattr
- KX_PYATTRIBUTE_RO_FUNCTION("type",BL_ArmatureConstraint,py_attr_getattr),
- KX_PYATTRIBUTE_RO_FUNCTION("name",BL_ArmatureConstraint,py_attr_getattr),
- KX_PYATTRIBUTE_RW_FUNCTION("enforce",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
- KX_PYATTRIBUTE_RW_FUNCTION("headtail",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
- KX_PYATTRIBUTE_RO_FUNCTION("lin_error",BL_ArmatureConstraint,py_attr_getattr),
- KX_PYATTRIBUTE_RO_FUNCTION("rot_error",BL_ArmatureConstraint,py_attr_getattr),
- KX_PYATTRIBUTE_RW_FUNCTION("target",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
- KX_PYATTRIBUTE_RW_FUNCTION("subtarget",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
- KX_PYATTRIBUTE_RW_FUNCTION("active",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
- KX_PYATTRIBUTE_RW_FUNCTION("ik_weight",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
- KX_PYATTRIBUTE_RO_FUNCTION("ik_type",BL_ArmatureConstraint,py_attr_getattr),
- KX_PYATTRIBUTE_RO_FUNCTION("ik_flag",BL_ArmatureConstraint,py_attr_getattr),
- KX_PYATTRIBUTE_RW_FUNCTION("ik_dist",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
- KX_PYATTRIBUTE_RW_FUNCTION("ik_mode",BL_ArmatureConstraint,py_attr_getattr,py_attr_setattr),
-
- { NULL } //Sentinel
- };
- PyObject *BL_ArmatureConstraint::py_attr_getattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
- {
- BL_ArmatureConstraint* self = static_cast<BL_ArmatureConstraint*>(self_v);
- bConstraint* constraint = self->m_constraint;
- bKinematicConstraint* ikconstraint = (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) ? (bKinematicConstraint*)constraint->data : NULL;
- int attr_order = attrdef-Attributes;
- if (!constraint) {
- PyErr_SetString(PyExc_AttributeError, "constraint is NULL");
- return NULL;
- }
- switch (attr_order) {
- case BCA_TYPE:
- return PyLong_FromLong(constraint->type);
- case BCA_NAME:
- return PyUnicode_FromString(constraint->name);
- case BCA_ENFORCE:
- return PyFloat_FromDouble(constraint->enforce);
- case BCA_HEADTAIL:
- return PyFloat_FromDouble(constraint->headtail);
- case BCA_LINERROR:
- return PyFloat_FromDouble(constraint->lin_error);
- case BCA_ROTERROR:
- return PyFloat_FromDouble(constraint->rot_error);
- case BCA_TARGET:
- if (!self->m_target)
- Py_RETURN_NONE;
- else
- return self->m_target->GetProxy();
- case BCA_SUBTARGET:
- if (!self->m_subtarget)
- Py_RETURN_NONE;
- else
- return self->m_subtarget->GetProxy();
- case BCA_ACTIVE:
- return PyBool_FromLong((constraint->flag & CONSTRAINT_OFF) == 0);
- case BCA_IKWEIGHT:
- case BCA_IKTYPE:
- case BCA_IKFLAG:
- case BCA_IKDIST:
- case BCA_IKMODE:
- if (!ikconstraint) {
- PyErr_SetString(PyExc_AttributeError, "constraint is not of IK type");
- return NULL;
- }
- switch (attr_order) {
- case BCA_IKWEIGHT:
- return PyFloat_FromDouble(ikconstraint->weight);
- case BCA_IKTYPE:
- return PyLong_FromLong(ikconstraint->type);
- case BCA_IKFLAG:
- return PyLong_FromLong(ikconstraint->flag);
- case BCA_IKDIST:
- return PyFloat_FromDouble(ikconstraint->dist);
- case BCA_IKMODE:
- return PyLong_FromLong(ikconstraint->mode);
- }
- // should not come here
- break;
- }
- PyErr_SetString(PyExc_AttributeError, "constraint unknown attribute");
- return NULL;
- }
- int BL_ArmatureConstraint::py_attr_setattr(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
- {
- BL_ArmatureConstraint* self = static_cast<BL_ArmatureConstraint*>(self_v);
- bConstraint* constraint = self->m_constraint;
- bKinematicConstraint* ikconstraint = (constraint && constraint->type == CONSTRAINT_TYPE_KINEMATIC) ? (bKinematicConstraint*)constraint->data : NULL;
- int attr_order = attrdef-Attributes;
- int ival;
- double dval;
- // char* sval;
- SCA_LogicManager *logicmgr = KX_GetActiveScene()->GetLogicManager();
- KX_GameObject *oval;
- if (!constraint) {
- PyErr_SetString(PyExc_AttributeError, "constraint is NULL");
- return PY_SET_ATTR_FAIL;
- }
-
- switch (attr_order) {
- case BCA_ENFORCE:
- dval = PyFloat_AsDouble(value);
- if (dval < 0.0 || dval > 1.0) { /* also accounts for non float */
- PyErr_SetString(PyExc_AttributeError, "constraint.enforce = float: BL_ArmatureConstraint, expected a float between 0 and 1");
- return PY_SET_ATTR_FAIL;
- }
- constraint->enforce = dval;
- return PY_SET_ATTR_SUCCESS;
- case BCA_HEADTAIL:
- dval = PyFloat_AsDouble(value);
- if (dval < 0.0 || dval > 1.0) { /* also accounts for non float */
- PyErr_SetString(PyExc_AttributeError, "constraint.headtail = float: BL_ArmatureConstraint, expected a float between 0 and 1");
- return PY_SET_ATTR_FAIL;
- }
- constraint->headtail = dval;
- return PY_SET_ATTR_SUCCESS;
- case BCA_TARGET:
- if (!ConvertPythonToGameObject(logicmgr, value, &oval, true, "constraint.target = value: BL_ArmatureConstraint"))
- return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
- self->SetTarget(oval);
- return PY_SET_ATTR_SUCCESS;
- case BCA_SUBTARGET:
- if (!ConvertPythonToGameObject(logicmgr, value, &oval, true, "constraint.subtarget = value: BL_ArmatureConstraint"))
- return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
- self->SetSubtarget(oval);
- return PY_SET_ATTR_SUCCESS;
- case BCA_ACTIVE:
- ival = PyObject_IsTrue( value );
- if (ival == -1) {
- PyErr_SetString(PyExc_AttributeError, "constraint.active = bool: BL_ArmatureConstraint, expected True or False");
- return PY_SET_ATTR_FAIL;
- }
- self->m_constraint->flag = (self->m_constraint->flag & ~CONSTRAINT_OFF) | ((ival)?0:CONSTRAINT_OFF);
- return PY_SET_ATTR_SUCCESS;
- case BCA_IKWEIGHT:
- case BCA_IKDIST:
- case BCA_IKMODE:
- if (!ikconstraint) {
- PyErr_SetString(PyExc_AttributeError, "constraint is not of IK type");
- return PY_SET_ATTR_FAIL;
- }
- switch (attr_order) {
- case BCA_IKWEIGHT:
- dval = PyFloat_AsDouble(value);
- if (dval < 0.0 || dval > 1.0) { /* also accounts for non float */
- PyErr_SetString(PyExc_AttributeError, "constraint.weight = float: BL_ArmatureConstraint, expected a float between 0 and 1");
- return PY_SET_ATTR_FAIL;
- }
- ikconstraint->weight = dval;
- return PY_SET_ATTR_SUCCESS;
- case BCA_IKDIST:
- dval = PyFloat_AsDouble(value);
- if (dval < 0.0) { /* also accounts for non float */
- PyErr_SetString(PyExc_AttributeError, "constraint.ik_dist = float: BL_ArmatureConstraint, expected a positive float");
- return PY_SET_ATTR_FAIL;
- }
- ikconstraint->dist = dval;
- return PY_SET_ATTR_SUCCESS;
- case BCA_IKMODE:
- ival = PyLong_AsLong(value);
- if (ival < 0) {
- PyErr_SetString(PyExc_AttributeError, "constraint.ik_mode = integer: BL_ArmatureConstraint, expected a positive integer");
- return PY_SET_ATTR_FAIL;
- }
- ikconstraint->mode = ival;
- return PY_SET_ATTR_SUCCESS;
- }
- // should not come here
- break;
- }
- PyErr_SetString(PyExc_AttributeError, "constraint unknown attribute");
- return PY_SET_ATTR_FAIL;
- }
- #endif // WITH_PYTHON
|