BGE Python API
[blender.git] / source / gameengine / Ketsji / KX_RadarSensor.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include "KX_RadarSensor.h"
30 #include "KX_GameObject.h"
31 #include "KX_PyMath.h"
32 #include "PHY_IPhysicsController.h"
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 /**
39  *      RadarSensor constructor. Creates a near-sensor derived class, with a cone collision shape.
40  */
41 KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr,
42                 KX_GameObject* gameobj,
43                 PHY_IPhysicsController* physCtrl,
44                         double coneradius,
45                         double coneheight,
46                         int     axis,
47                         double margin,
48                         double resetmargin,
49                         bool bFindMaterial,
50                         const STR_String& touchedpropname,
51                         class KX_Scene* kxscene,
52                         PyTypeObject* T)
53
54                         : KX_NearSensor(
55                                 eventmgr,
56                                 gameobj,
57                                 //DT_NewCone(coneradius,coneheight),
58                                 margin,
59                                 resetmargin,
60                                 bFindMaterial,
61                                 touchedpropname,
62                                 kxscene,
63                                 physCtrl,
64                                 T),
65                                 m_coneradius(coneradius),
66                                 m_coneheight(coneheight),
67                                 m_axis(axis)
68 {
69         m_client_info->m_type = KX_ClientObjectInfo::RADAR;
70         //m_client_info->m_clientobject = gameobj;
71         //m_client_info->m_auxilary_info = NULL;
72         //sumoObj->setClientObject(&m_client_info);
73 }
74                         
75 KX_RadarSensor::~KX_RadarSensor()
76 {
77         
78 }
79
80 CValue* KX_RadarSensor::GetReplica()
81 {
82         KX_RadarSensor* replica = new KX_RadarSensor(*this);
83         replica->m_colliders = new CListValue();
84         replica->Init();
85         // this will copy properties and so on...
86         CValue::AddDataToReplica(replica);
87         
88         replica->m_client_info = new KX_ClientObjectInfo(m_client_info->m_gameobject, KX_ClientObjectInfo::RADAR);
89         
90         if (replica->m_physCtrl)
91         {
92                 replica->m_physCtrl = replica->m_physCtrl->GetReplica();
93                 if (replica->m_physCtrl)
94                 {
95                         replica->m_physCtrl->setNewClientInfo(replica->m_client_info);
96                 }
97         }
98
99         //todo: make sure replication works fine!
100         //>m_sumoObj = new SM_Object(DT_NewCone(m_coneradius, m_coneheight),NULL,NULL,NULL);
101         //replica->m_sumoObj->setMargin(m_Margin);
102         //replica->m_sumoObj->setClientObject(replica->m_client_info);
103         //Wrong: see KX_TouchSensor
104         //bool parentUpdated = false;
105         //((KX_GameObject*)replica->GetParent())->GetSGNode()->ComputeWorldTransforms(NULL,parentUpdated);
106         replica->SynchronizeTransform();
107         
108         return replica;
109 }
110
111
112 /**
113  *      Transforms the collision object. A cone is not correctly centered
114  *      for usage.  */
115 void KX_RadarSensor::SynchronizeTransform()
116 {
117         // Getting the parent location was commented out. Why?
118         MT_Transform trans;
119         trans.setOrigin(((KX_GameObject*)GetParent())->NodeGetWorldPosition());
120         trans.setBasis(((KX_GameObject*)GetParent())->NodeGetWorldOrientation());
121         // What is the default orientation? pointing in the -y direction?
122         // is the geometry correctly converted?
123
124         // a collision cone is oriented
125         // center the cone correctly 
126         // depends on the radar 'axis'
127         switch (m_axis)
128         {
129         case 0: // +X Axis
130                 {
131                         MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90));
132                         trans.rotate(rotquatje);
133                         trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
134                         break;
135                 };
136         case 1: // +Y Axis
137                 {
138                         MT_Quaternion rotquatje(MT_Vector3(1,0,0),MT_radians(-180));
139                         trans.rotate(rotquatje);
140                         trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
141                         break;
142                 };
143         case 2: // +Z Axis
144                 {
145                         MT_Quaternion rotquatje(MT_Vector3(1,0,0),MT_radians(-90));
146                         trans.rotate(rotquatje);
147                         trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
148                         break;
149                 };
150         case 3: // -X Axis
151                 {
152                         MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(-90));
153                         trans.rotate(rotquatje);
154                         trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
155                         break;
156                 };
157         case 4: // -Y Axis
158                 {
159                         //MT_Quaternion rotquatje(MT_Vector3(1,0,0),MT_radians(-180));
160                         //trans.rotate(rotquatje);
161                         trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
162                         break;
163                 };
164         case 5: // -Z Axis
165                 {
166                         MT_Quaternion rotquatje(MT_Vector3(1,0,0),MT_radians(90));
167                         trans.rotate(rotquatje);
168                         trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0));
169                         break;
170                 };
171         default:
172                 {
173                 }
174         }
175         
176         //Using a temp variable to translate MT_Point3 to float[3].
177         //float[3] works better for the Python interface.
178         MT_Point3 temp = trans.getOrigin();
179         m_cone_origin[0] = temp[0];
180         m_cone_origin[1] = temp[1];
181         m_cone_origin[2] = temp[2];
182
183         temp = trans(MT_Point3(0, -m_coneheight/2.0 ,0));
184         m_cone_target[0] = temp[0];
185         m_cone_target[1] = temp[1];
186         m_cone_target[2] = temp[2];
187
188
189         if (m_physCtrl)
190         {
191                 MT_Quaternion orn = trans.getRotation();
192                 MT_Point3 pos = trans.getOrigin();
193                 m_physCtrl->setPosition(pos[0],pos[1],pos[2]);
194                 m_physCtrl->setOrientation(orn[0],orn[1],orn[2],orn[3]);
195                 m_physCtrl->calcXform();
196         }
197
198 }
199
200 /* ------------------------------------------------------------------------- */
201 /* Python Functions                                                                                                                      */
202 /* ------------------------------------------------------------------------- */
203
204 //Deprecated ----->
205 /* getConeOrigin */
206 const char KX_RadarSensor::GetConeOrigin_doc[] = 
207 "getConeOrigin()\n"
208 "\tReturns the origin of the cone with which to test. The origin\n"
209 "\tis in the middle of the cone.";
210 PyObject* KX_RadarSensor::PyGetConeOrigin() {
211         ShowDeprecationWarning("getConeOrigin()", "the coneOrigin property");
212
213         PyObject *retVal = PyList_New(3);
214         
215         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0]));
216         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1]));
217         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2]));
218         
219         return retVal;
220 }
221
222 /* getConeOrigin */
223 const char KX_RadarSensor::GetConeTarget_doc[] = 
224 "getConeTarget()\n"
225 "\tReturns the center of the bottom face of the cone with which to test.\n";
226 PyObject* KX_RadarSensor::PyGetConeTarget() {
227         ShowDeprecationWarning("getConeTarget()", "the coneTarget property");
228
229         PyObject *retVal = PyList_New(3);
230         
231         PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0]));
232         PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1]));
233         PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2]));
234         
235         return retVal;
236 }
237
238 /* getConeHeight */
239 const char KX_RadarSensor::GetConeHeight_doc[] = 
240 "getConeHeight()\n"
241 "\tReturns the height of the cone with which to test.\n";
242 PyObject* KX_RadarSensor::PyGetConeHeight() {
243                                                                                           
244         ShowDeprecationWarning("getConeHeight()", "the distance property");
245
246         return PyFloat_FromDouble(m_coneheight);
247 }
248 //<----- Deprecated
249
250 /* ------------------------------------------------------------------------- */
251 /* Python Integration Hooks                                                  */
252 /* ------------------------------------------------------------------------- */
253 PyTypeObject KX_RadarSensor::Type = {
254         PyObject_HEAD_INIT(NULL)
255         0,
256         "KX_RadarSensor",
257         sizeof(PyObjectPlus_Proxy),
258         0,
259         py_base_dealloc,
260         0,
261         0,
262         0,
263         0,
264         py_base_repr,
265         0,0,0,0,0,0,
266         py_base_getattro,
267         py_base_setattro,
268         0,0,0,0,0,0,0,0,0,
269         Methods
270 };
271
272 PyParentObject KX_RadarSensor::Parents[] = {
273         &KX_RadarSensor::Type,
274         &KX_NearSensor::Type,
275         &KX_TouchSensor::Type,
276         &SCA_ISensor::Type,
277         &SCA_ILogicBrick::Type,
278         &CValue::Type,
279         NULL
280 };
281
282 PyMethodDef KX_RadarSensor::Methods[] = {
283         //Deprecated ----->
284         {"getConeOrigin", (PyCFunction) KX_RadarSensor::sPyGetConeOrigin, 
285          METH_VARARGS, (PY_METHODCHAR)GetConeOrigin_doc},
286         {"getConeTarget", (PyCFunction) KX_RadarSensor::sPyGetConeTarget, 
287          METH_VARARGS, (PY_METHODCHAR)GetConeTarget_doc},
288         {"getConeHeight", (PyCFunction) KX_RadarSensor::sPyGetConeHeight, 
289          METH_VARARGS, (PY_METHODCHAR)GetConeHeight_doc},
290          //<-----
291         {NULL} //Sentinel
292 };
293
294 PyAttributeDef KX_RadarSensor::Attributes[] = {
295         KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneOrigin", KX_RadarSensor, m_cone_origin, 3),
296         KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneTarget", KX_RadarSensor, m_cone_target, 3),
297         KX_PYATTRIBUTE_FLOAT_RW("angle", 0, 360, KX_RadarSensor, m_coneradius),
298         KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RadarSensor, m_axis),
299         {NULL} //Sentinel
300 };
301
302 PyObject* KX_RadarSensor::py_getattro(PyObject *attr)
303 {
304         py_getattro_up(KX_NearSensor);
305 }
306
307 int KX_RadarSensor::py_setattro(PyObject *attr, PyObject* value)
308 {
309         py_setattro_up(KX_NearSensor);
310 }