style cleanup: comment format
[blender.git] / source / gameengine / Converter / BL_ArmatureActuator.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file gameengine/Converter/BL_ArmatureActuator.cpp
29  *  \ingroup bgeconv
30  */
31
32
33 #include "DNA_action_types.h"
34 #include "DNA_constraint_types.h"
35 #include "DNA_actuator_types.h"
36 #include "BKE_constraint.h"
37 #include "BL_ArmatureActuator.h"
38 #include "BL_ArmatureObject.h"
39 #include "BLI_math.h"
40
41 /**
42  * This class is the conversion of the Pose channel constraint.
43  * It makes a link between the pose constraint and the KX scene.
44  * The main purpose is to give access to the constraint target 
45  * to link it to a game object. 
46  * It also allows to activate/deactivate constraints during the game.
47  * Later it will also be possible to create constraint on the fly
48  */
49
50 BL_ArmatureActuator::BL_ArmatureActuator(SCA_IObject* obj,
51                                                 int type,
52                                                 const char *posechannel,
53                                                 const char *constraintname,
54                                                 KX_GameObject* targetobj,
55                                                 KX_GameObject* subtargetobj,
56                                                 float weight,
57                                                 float influence) :
58         SCA_IActuator(obj, KX_ACT_ARMATURE),
59         m_constraint(NULL),
60         m_gametarget(targetobj),
61         m_gamesubtarget(subtargetobj),
62         m_posechannel(posechannel),
63         m_constraintname(constraintname),
64         m_weight(weight),
65         m_influence(influence),
66         m_type(type)
67 {
68         if (m_gametarget)
69                 m_gametarget->RegisterActuator(this);
70         if (m_gamesubtarget)
71                 m_gamesubtarget->RegisterActuator(this);
72         FindConstraint();
73 }
74
75 BL_ArmatureActuator::~BL_ArmatureActuator()
76 {
77         if (m_gametarget)
78                 m_gametarget->UnregisterActuator(this);
79         if (m_gamesubtarget)
80                 m_gamesubtarget->UnregisterActuator(this);
81 }
82
83 void BL_ArmatureActuator::ProcessReplica()
84 {
85         // the replica is tracking the same object => register it (this may be changed in Relnk())
86         if (m_gametarget)
87                 m_gametarget->RegisterActuator(this);
88         if (m_gamesubtarget)
89                 m_gamesubtarget->UnregisterActuator(this);
90         SCA_IActuator::ProcessReplica();
91 }
92
93 void BL_ArmatureActuator::ReParent(SCA_IObject* parent)
94 {
95         SCA_IActuator::ReParent(parent);
96         // must remap the constraint
97         FindConstraint();
98 }
99
100 bool BL_ArmatureActuator::UnlinkObject(SCA_IObject* clientobj)
101 {
102         bool res=false;
103         if (clientobj == m_gametarget)
104         {
105                 // this object is being deleted, we cannot continue to track it.
106                 m_gametarget = NULL;
107                 res = true;
108         }
109         if (clientobj == m_gamesubtarget)
110         {
111                 // this object is being deleted, we cannot continue to track it.
112                 m_gamesubtarget = NULL;
113                 res = true;
114         }
115         return res;
116 }
117
118 void BL_ArmatureActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
119 {
120         void **h_obj = (*obj_map)[m_gametarget];
121         if (h_obj) {
122                 if (m_gametarget)
123                         m_gametarget->UnregisterActuator(this);
124                 m_gametarget = (KX_GameObject*)(*h_obj);
125                 m_gametarget->RegisterActuator(this);
126         }
127         h_obj = (*obj_map)[m_gamesubtarget];
128         if (h_obj) {
129                 if (m_gamesubtarget)
130                         m_gamesubtarget->UnregisterActuator(this);
131                 m_gamesubtarget = (KX_GameObject*)(*h_obj);
132                 m_gamesubtarget->RegisterActuator(this);
133         }
134 }
135
136 void BL_ArmatureActuator::FindConstraint()
137 {
138         m_constraint = NULL;
139
140         if (m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
141                 BL_ArmatureObject* armobj = (BL_ArmatureObject*)m_gameobj;
142                 m_constraint = armobj->GetConstraint(m_posechannel, m_constraintname);
143         }
144 }
145
146 bool BL_ArmatureActuator::Update(double curtime, bool frame)
147 {
148         // the only role of this actuator is to ensure that the armature pose will be evaluated
149         bool result = false;
150         bool bNegativeEvent = IsNegativeEvent();
151         RemoveAllEvents();
152
153         if (!bNegativeEvent) {
154                 BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
155                 switch (m_type) {
156                 case ACT_ARM_RUN:
157                         result = true;
158                         obj->SetActiveAction(NULL, 0, curtime);
159                         break;
160                 case ACT_ARM_ENABLE:
161                         if (m_constraint)
162                                 m_constraint->ClrConstraintFlag(CONSTRAINT_OFF);
163                         break;
164                 case ACT_ARM_DISABLE:
165                         if (m_constraint)
166                                 m_constraint->SetConstraintFlag(CONSTRAINT_OFF);
167                         break;
168                 case ACT_ARM_SETTARGET:
169                         if (m_constraint) {
170                                 m_constraint->SetTarget(m_gametarget);
171                                 m_constraint->SetSubtarget(m_gamesubtarget);
172                         }
173                         break;
174                 case ACT_ARM_SETWEIGHT:
175                         if (m_constraint)
176                                 m_constraint->SetWeight(m_weight);
177                         break;
178                 case ACT_ARM_SETINFLUENCE:
179                         if (m_constraint)
180                                 m_constraint->SetInfluence(m_influence);
181                         break;
182                 }
183         }
184         return result;
185 }
186
187 #ifdef WITH_PYTHON
188
189 /* ------------------------------------------------------------------------- */
190 /* Python Integration Hooks                                                                      */
191 /* ------------------------------------------------------------------------- */
192
193 PyTypeObject BL_ArmatureActuator::Type = {
194         PyVarObject_HEAD_INIT(NULL, 0)
195                 "BL_ArmatureActuator",
196                 sizeof(PyObjectPlus_Proxy),
197                 0,
198                 py_base_dealloc,
199                 0,
200                 0,
201                 0,
202                 0,
203                 py_base_repr,
204                 0,0,0,0,0,0,0,0,0,
205                 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
206                 0,0,0,0,0,0,0,
207                 Methods,
208                 0,
209                 0,
210                 &SCA_IActuator::Type,
211                 0,0,0,0,0,0,
212                 py_base_new
213 };
214
215
216 PyMethodDef BL_ArmatureActuator::Methods[] = {
217         {NULL,NULL} //Sentinel
218 };
219
220 PyAttributeDef BL_ArmatureActuator::Attributes[] = {
221         KX_PYATTRIBUTE_RO_FUNCTION("constraint", BL_ArmatureActuator, pyattr_get_constraint),
222         KX_PYATTRIBUTE_RW_FUNCTION("target", BL_ArmatureActuator, pyattr_get_object, pyattr_set_object),
223         KX_PYATTRIBUTE_RW_FUNCTION("subtarget", BL_ArmatureActuator, pyattr_get_object, pyattr_set_object),
224         KX_PYATTRIBUTE_FLOAT_RW("weight",0.0f,1.0f,BL_ArmatureActuator,m_weight),
225         KX_PYATTRIBUTE_FLOAT_RW("influence",0.0f,1.0f,BL_ArmatureActuator,m_influence),
226         KX_PYATTRIBUTE_INT_RW("type",0,ACT_ARM_MAXTYPE,false,BL_ArmatureActuator,m_type),
227         { NULL }        //Sentinel
228 };
229
230 PyObject *BL_ArmatureActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
231 {
232         BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
233         KX_GameObject *target = (!strcmp(attrdef->m_name, "target")) ? actuator->m_gametarget : actuator->m_gamesubtarget;
234         if (!target)
235                 Py_RETURN_NONE;
236         else
237                 return target->GetProxy();
238 }
239
240 int BL_ArmatureActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
241 {
242         BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
243         KX_GameObject* &target = (!strcmp(attrdef->m_name, "target")) ? actuator->m_gametarget : actuator->m_gamesubtarget;
244         KX_GameObject *gameobj;
245                 
246         if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: BL_ArmatureActuator"))
247                 return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
248                 
249         if (target != NULL)
250                 target->UnregisterActuator(actuator);
251
252         target = gameobj;
253                 
254         if (target)
255                 target->RegisterActuator(actuator);
256                 
257         return PY_SET_ATTR_SUCCESS;
258 }
259
260 PyObject *BL_ArmatureActuator::pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
261 {
262         BL_ArmatureActuator* actuator = static_cast<BL_ArmatureActuator*>(self);
263         BL_ArmatureConstraint* constraint = actuator->m_constraint;
264         if (!constraint)
265                 Py_RETURN_NONE;
266         else
267                 return constraint->GetProxy();
268 }
269
270 #endif // WITH_PYTHON
271