style cleanup
[blender.git] / source / gameengine / Ketsji / KX_ArmatureSensor.cpp
1 /*
2  * Armature sensor
3  *
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 /** \file gameengine/Ketsji/KX_ArmatureSensor.cpp
32  *  \ingroup ketsji
33  */
34
35
36 #include "DNA_action_types.h"
37 #include "DNA_constraint_types.h"
38 #include "BKE_constraint.h"
39 #include "DNA_sensor_types.h"
40
41 #include "BL_ArmatureObject.h"
42 #include "KX_ArmatureSensor.h"
43 #include "SCA_EventManager.h"
44 #include "SCA_LogicManager.h"
45
46 KX_ArmatureSensor::KX_ArmatureSensor(class SCA_EventManager* eventmgr,
47                                         SCA_IObject* gameobj,
48                                         const char *posechannel,
49                                         const char *constraintname,
50                                         int type,
51                                         float value)
52         : SCA_ISensor(gameobj,eventmgr),
53         m_constraint(NULL),
54         m_posechannel(posechannel),
55         m_constraintname(constraintname),
56         m_type(type),
57         m_value(value)
58 {
59         FindConstraint();
60 }
61
62 void KX_ArmatureSensor::Init()
63 {
64         m_lastresult = m_invert?true:false;
65         m_result = false;
66         m_reset = true;
67 }
68
69 void KX_ArmatureSensor::FindConstraint()
70 {
71         m_constraint = NULL;
72
73         if (m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
74                 BL_ArmatureObject* armobj = (BL_ArmatureObject*)m_gameobj;
75                 // get the persistent pose structure
76                 bPose* pose = armobj->GetOrigPose();
77                 bPoseChannel* pchan;
78                 bConstraint* pcon;
79                 // and locate the constraint
80                 for (pchan = (bPoseChannel*)pose->chanbase.first; pchan; pchan=(bPoseChannel*)pchan->next) {
81                         if (!strcmp(pchan->name, m_posechannel)) {
82                                 // now locate the constraint
83                                 for (pcon = (bConstraint *)pchan->constraints.first; pcon; pcon = (bConstraint *)pcon->next) {
84                                         if (!strcmp(pcon->name, m_constraintname)) {
85                                                 if (pcon->flag & CONSTRAINT_DISABLE)
86                                                         /* this constraint is not valid, can't use it */
87                                                         break;
88                                                 m_constraint = pcon;
89                                                 break;
90                                         }
91                                 }
92                                 break;
93                         }
94                 }
95         }
96 }
97
98
99 CValue* KX_ArmatureSensor::GetReplica()
100 {
101         KX_ArmatureSensor* replica = new KX_ArmatureSensor(*this);
102         // m_range_expr must be recalculated on replica!
103         replica->ProcessReplica();
104         return replica;
105 }
106
107 void KX_ArmatureSensor::ReParent(SCA_IObject* parent)
108 {
109         SCA_ISensor::ReParent(parent);
110         // must remap the constraint
111         FindConstraint();
112 }
113
114 bool KX_ArmatureSensor::IsPositiveTrigger()
115 {
116         return (m_invert) ? !m_result : m_result;
117 }
118
119
120 KX_ArmatureSensor::~KX_ArmatureSensor()
121 {
122 }
123
124 bool KX_ArmatureSensor::Evaluate()
125 {
126         bool reset = m_reset && m_level;
127
128         m_reset = false;
129         if (!m_constraint)
130                 return false;
131         switch (m_type) {
132         case SENS_ARM_STATE_CHANGED:
133                 m_result = !(m_constraint->flag & CONSTRAINT_OFF);
134                 break;
135         case SENS_ARM_LIN_ERROR_BELOW:
136                 m_result = (m_constraint->lin_error < m_value);
137                 break;
138         case SENS_ARM_LIN_ERROR_ABOVE:
139                 m_result = (m_constraint->lin_error > m_value);
140                 break;
141         case SENS_ARM_ROT_ERROR_BELOW:
142                 m_result = (m_constraint->rot_error < m_value);
143                 break;
144         case SENS_ARM_ROT_ERROR_ABOVE:
145                 m_result = (m_constraint->rot_error > m_value);
146                 break;
147         }
148         if (m_lastresult!=m_result)
149         {
150                 m_lastresult = m_result;
151                 return true;
152         }
153         return (reset) ? true : false;
154 }
155
156 #ifdef WITH_PYTHON
157
158 /* ------------------------------------------------------------------------- */
159 /* Python functions                                                          */
160 /* ------------------------------------------------------------------------- */
161
162 /* Integration hooks ------------------------------------------------------- */
163 PyTypeObject KX_ArmatureSensor::Type = {
164         PyVarObject_HEAD_INIT(NULL, 0)
165         "KX_ArmatureSensor",
166         sizeof(PyObjectPlus_Proxy),
167         0,
168         py_base_dealloc,
169         0,
170         0,
171         0,
172         0,
173         py_base_repr,
174         0,0,0,0,0,0,0,0,0,
175         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
176         0,0,0,0,0,0,0,
177         Methods,
178         0,
179         0,
180         &SCA_ISensor::Type,
181         0,0,0,0,0,0,
182         py_base_new
183 };
184
185 PyMethodDef KX_ArmatureSensor::Methods[] = {
186         {NULL,NULL} //Sentinel
187 };
188
189 PyAttributeDef KX_ArmatureSensor::Attributes[] = {
190         KX_PYATTRIBUTE_RO_FUNCTION("constraint", KX_ArmatureSensor, pyattr_get_constraint),
191         KX_PYATTRIBUTE_FLOAT_RW("value",-FLT_MAX,FLT_MAX,KX_ArmatureSensor,m_value),
192         KX_PYATTRIBUTE_INT_RW("type",0,SENS_ARM_MAXTYPE,false,KX_ArmatureSensor,m_type),
193         { NULL }        //Sentinel
194 };
195
196 PyObject *KX_ArmatureSensor::pyattr_get_constraint(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
197 {
198         KX_ArmatureSensor* sensor = static_cast<KX_ArmatureSensor*>(self);
199         if (sensor->m_gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) {
200                 BL_ArmatureObject* armobj = (BL_ArmatureObject*)sensor->m_gameobj;
201                 BL_ArmatureConstraint* constraint = armobj->GetConstraint(sensor->m_posechannel, sensor->m_constraintname);
202                 if (constraint)
203                         return constraint->GetProxy();
204         }
205         Py_RETURN_NONE;
206 }
207
208 #endif // WITH_PYTHON