Fix for bug #3858: the game engine mouse focus sensor did not work
[blender.git] / source / gameengine / Converter / KX_ConvertSensors.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Conversion of Blender data blocks to KX sensor system
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #ifdef WIN32
36 #pragma warning (disable : 4786)
37 #endif //WIN32
38
39 #include "KX_BlenderSceneConverter.h"
40 #include "KX_ConvertSensors.h"
41
42 /* This little block needed for linking to Blender... */
43 #ifdef WIN32
44 #include "BLI_winstuff.h"
45 #endif
46
47 #include "DNA_object_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_sensor_types.h"
50 #include "DNA_actuator_types.h" /* for SENS_ALL_KEYS ? this define is
51 probably misplaced */
52 /* end of blender include block */
53
54 #include "RAS_IPolygonMaterial.h"
55 // Sensors
56 #include "KX_GameObject.h"
57 #include "RAS_MeshObject.h"
58 #include "SCA_KeyboardSensor.h"
59 #include "SCA_MouseSensor.h"
60 #include "SCA_AlwaysSensor.h"
61 #include "KX_TouchSensor.h"
62 #include "KX_NearSensor.h"
63 #include "KX_RadarSensor.h"
64 #include "KX_MouseFocusSensor.h"
65 #include "SCA_JoystickSensor.h"
66 #include "KX_NetworkMessageSensor.h"
67 #include "SCA_ActuatorSensor.h"
68 #include "SCA_DelaySensor.h"
69
70
71 #include "SCA_PropertySensor.h"
72 #include "SCA_RandomSensor.h"
73 #include "KX_RaySensor.h"
74 #include "SCA_EventManager.h"
75 #include "SCA_LogicManager.h"
76 #include "KX_BlenderInputDevice.h"
77 #include "KX_Scene.h"
78 #include "IntValue.h"
79 #include "KX_BlenderKeyboardDevice.h"
80 #include "KX_BlenderGL.h"
81 #include "RAS_ICanvas.h"
82 #include "PHY_IPhysicsEnvironment.h"
83
84 #include "KX_KetsjiEngine.h"
85 #include "KX_BlenderSceneConverter.h"
86
87 // this map is Blender specific: a conversion between blender and ketsji enums
88 std::map<int,SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable;
89
90
91 void BL_ConvertSensors(struct Object* blenderobject,
92                                            class KX_GameObject* gameobj,
93                                            SCA_LogicManager* logicmgr,
94                                            KX_Scene* kxscene,
95                                            KX_KetsjiEngine* kxengine,
96                                            SCA_IInputDevice* keydev,
97                                            int & executePriority,
98                                            int activeLayerBitInfo,
99                                            bool isInActiveLayer,
100                                            RAS_ICanvas* canvas,
101                                            KX_BlenderSceneConverter* converter
102                                            )
103 {
104         
105         
106         
107         /* The reverse table. In order to not confuse ourselves, we      */
108         /* immediately convert all events that come in to KX codes.      */
109         gReverseKeyTranslateTable[LEFTMOUSE                     ] =     SCA_IInputDevice::KX_LEFTMOUSE;
110         gReverseKeyTranslateTable[MIDDLEMOUSE           ] =     SCA_IInputDevice::KX_MIDDLEMOUSE;
111         gReverseKeyTranslateTable[RIGHTMOUSE            ] =     SCA_IInputDevice::KX_RIGHTMOUSE;
112         gReverseKeyTranslateTable[WHEELUPMOUSE          ] =     SCA_IInputDevice::KX_WHEELUPMOUSE;
113         gReverseKeyTranslateTable[WHEELDOWNMOUSE        ] =     SCA_IInputDevice::KX_WHEELDOWNMOUSE;
114         gReverseKeyTranslateTable[MOUSEX                        ] = SCA_IInputDevice::KX_MOUSEX;
115         gReverseKeyTranslateTable[MOUSEY                        ] =     SCA_IInputDevice::KX_MOUSEY;
116         
117         // TIMERS                                                                                                  
118         
119         gReverseKeyTranslateTable[TIMER0                        ] = SCA_IInputDevice::KX_TIMER0;                  
120         gReverseKeyTranslateTable[TIMER1                        ] = SCA_IInputDevice::KX_TIMER1;                  
121         gReverseKeyTranslateTable[TIMER2                        ] = SCA_IInputDevice::KX_TIMER2;                  
122         gReverseKeyTranslateTable[TIMER3                        ] = SCA_IInputDevice::KX_TIMER3;                  
123         
124         // SYSTEM                                                                                                  
125         
126         gReverseKeyTranslateTable[KEYBD                         ] = SCA_IInputDevice::KX_KEYBD;                  
127         gReverseKeyTranslateTable[RAWKEYBD                      ] = SCA_IInputDevice::KX_RAWKEYBD;                  
128         gReverseKeyTranslateTable[REDRAW                        ] = SCA_IInputDevice::KX_REDRAW;                  
129         gReverseKeyTranslateTable[INPUTCHANGE           ] = SCA_IInputDevice::KX_INPUTCHANGE;                  
130         gReverseKeyTranslateTable[QFULL                         ] = SCA_IInputDevice::KX_QFULL;                  
131         gReverseKeyTranslateTable[WINFREEZE                     ] = SCA_IInputDevice::KX_WINFREEZE;                  
132         gReverseKeyTranslateTable[WINTHAW                       ] = SCA_IInputDevice::KX_WINTHAW;                  
133         gReverseKeyTranslateTable[WINCLOSE                      ] = SCA_IInputDevice::KX_WINCLOSE;                  
134         gReverseKeyTranslateTable[WINQUIT                       ] = SCA_IInputDevice::KX_WINQUIT;                  
135         gReverseKeyTranslateTable[Q_FIRSTTIME           ] = SCA_IInputDevice::KX_Q_FIRSTTIME;                  
136         
137         // standard keyboard                                                                                       
138         
139         gReverseKeyTranslateTable[AKEY                          ] = SCA_IInputDevice::KX_AKEY;                  
140         gReverseKeyTranslateTable[BKEY                          ] = SCA_IInputDevice::KX_BKEY;                  
141         gReverseKeyTranslateTable[CKEY                          ] = SCA_IInputDevice::KX_CKEY;                  
142         gReverseKeyTranslateTable[DKEY                          ] = SCA_IInputDevice::KX_DKEY;                  
143         gReverseKeyTranslateTable[EKEY                          ] = SCA_IInputDevice::KX_EKEY;                  
144         gReverseKeyTranslateTable[FKEY                          ] = SCA_IInputDevice::KX_FKEY;                  
145         gReverseKeyTranslateTable[GKEY                          ] = SCA_IInputDevice::KX_GKEY;                  
146         gReverseKeyTranslateTable[HKEY                          ] = SCA_IInputDevice::KX_HKEY;                  
147         gReverseKeyTranslateTable[IKEY                          ] = SCA_IInputDevice::KX_IKEY;                  
148         gReverseKeyTranslateTable[JKEY                          ] = SCA_IInputDevice::KX_JKEY;                  
149         gReverseKeyTranslateTable[KKEY                          ] = SCA_IInputDevice::KX_KKEY;                  
150         gReverseKeyTranslateTable[LKEY                          ] = SCA_IInputDevice::KX_LKEY;                  
151         gReverseKeyTranslateTable[MKEY                          ] = SCA_IInputDevice::KX_MKEY;                  
152         gReverseKeyTranslateTable[NKEY                          ] = SCA_IInputDevice::KX_NKEY;                  
153         gReverseKeyTranslateTable[OKEY                          ] = SCA_IInputDevice::KX_OKEY;                  
154         gReverseKeyTranslateTable[PKEY                          ] = SCA_IInputDevice::KX_PKEY;                  
155         gReverseKeyTranslateTable[QKEY                          ] = SCA_IInputDevice::KX_QKEY;                  
156         gReverseKeyTranslateTable[RKEY                          ] = SCA_IInputDevice::KX_RKEY;                  
157         gReverseKeyTranslateTable[SKEY                          ] = SCA_IInputDevice::KX_SKEY;                  
158         gReverseKeyTranslateTable[TKEY                          ] = SCA_IInputDevice::KX_TKEY;                  
159         gReverseKeyTranslateTable[UKEY                          ] = SCA_IInputDevice::KX_UKEY;                  
160         gReverseKeyTranslateTable[VKEY                          ] = SCA_IInputDevice::KX_VKEY;                  
161         gReverseKeyTranslateTable[WKEY                          ] = SCA_IInputDevice::KX_WKEY;                  
162         gReverseKeyTranslateTable[XKEY                          ] = SCA_IInputDevice::KX_XKEY;                  
163         gReverseKeyTranslateTable[YKEY                          ] = SCA_IInputDevice::KX_YKEY;                  
164         gReverseKeyTranslateTable[ZKEY                          ] = SCA_IInputDevice::KX_ZKEY;                  
165         
166         gReverseKeyTranslateTable[ZEROKEY                       ] = SCA_IInputDevice::KX_ZEROKEY;                  
167         gReverseKeyTranslateTable[ONEKEY                        ] = SCA_IInputDevice::KX_ONEKEY;                  
168         gReverseKeyTranslateTable[TWOKEY                        ] = SCA_IInputDevice::KX_TWOKEY;                  
169         gReverseKeyTranslateTable[THREEKEY                      ] = SCA_IInputDevice::KX_THREEKEY;                  
170         gReverseKeyTranslateTable[FOURKEY                       ] = SCA_IInputDevice::KX_FOURKEY;                  
171         gReverseKeyTranslateTable[FIVEKEY                       ] = SCA_IInputDevice::KX_FIVEKEY;                  
172         gReverseKeyTranslateTable[SIXKEY                        ] = SCA_IInputDevice::KX_SIXKEY;                  
173         gReverseKeyTranslateTable[SEVENKEY                      ] = SCA_IInputDevice::KX_SEVENKEY;                  
174         gReverseKeyTranslateTable[EIGHTKEY                      ] = SCA_IInputDevice::KX_EIGHTKEY;                  
175         gReverseKeyTranslateTable[NINEKEY                       ] = SCA_IInputDevice::KX_NINEKEY;                  
176         
177         gReverseKeyTranslateTable[CAPSLOCKKEY           ] = SCA_IInputDevice::KX_CAPSLOCKKEY;                  
178         
179         gReverseKeyTranslateTable[LEFTCTRLKEY           ] = SCA_IInputDevice::KX_LEFTCTRLKEY;                  
180         gReverseKeyTranslateTable[LEFTALTKEY            ] = SCA_IInputDevice::KX_LEFTALTKEY;                  
181         gReverseKeyTranslateTable[RIGHTALTKEY           ] = SCA_IInputDevice::KX_RIGHTALTKEY;                  
182         gReverseKeyTranslateTable[RIGHTCTRLKEY          ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;                  
183         gReverseKeyTranslateTable[RIGHTSHIFTKEY         ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;                  
184         gReverseKeyTranslateTable[LEFTSHIFTKEY          ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;                  
185         
186         gReverseKeyTranslateTable[ESCKEY                        ] = SCA_IInputDevice::KX_ESCKEY;                  
187         gReverseKeyTranslateTable[TABKEY                        ] = SCA_IInputDevice::KX_TABKEY;                  
188         gReverseKeyTranslateTable[RETKEY                        ] = SCA_IInputDevice::KX_RETKEY;                  
189         gReverseKeyTranslateTable[SPACEKEY                      ] = SCA_IInputDevice::KX_SPACEKEY;                  
190         gReverseKeyTranslateTable[LINEFEEDKEY           ] = SCA_IInputDevice::KX_LINEFEEDKEY;                  
191         gReverseKeyTranslateTable[BACKSPACEKEY          ] = SCA_IInputDevice::KX_BACKSPACEKEY;                  
192         gReverseKeyTranslateTable[DELKEY                        ] = SCA_IInputDevice::KX_DELKEY;                  
193         gReverseKeyTranslateTable[SEMICOLONKEY          ] = SCA_IInputDevice::KX_SEMICOLONKEY;                  
194         gReverseKeyTranslateTable[PERIODKEY                     ] = SCA_IInputDevice::KX_PERIODKEY;                  
195         gReverseKeyTranslateTable[COMMAKEY                      ] = SCA_IInputDevice::KX_COMMAKEY;                  
196         gReverseKeyTranslateTable[QUOTEKEY                      ] = SCA_IInputDevice::KX_QUOTEKEY;                  
197         gReverseKeyTranslateTable[ACCENTGRAVEKEY        ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;                  
198         gReverseKeyTranslateTable[MINUSKEY                      ] = SCA_IInputDevice::KX_MINUSKEY;                  
199         gReverseKeyTranslateTable[SLASHKEY                      ] = SCA_IInputDevice::KX_SLASHKEY;                  
200         gReverseKeyTranslateTable[BACKSLASHKEY          ] = SCA_IInputDevice::KX_BACKSLASHKEY;                  
201         gReverseKeyTranslateTable[EQUALKEY                      ] = SCA_IInputDevice::KX_EQUALKEY;                  
202         gReverseKeyTranslateTable[LEFTBRACKETKEY        ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;                  
203         gReverseKeyTranslateTable[RIGHTBRACKETKEY       ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;                  
204         
205         gReverseKeyTranslateTable[LEFTARROWKEY          ] = SCA_IInputDevice::KX_LEFTARROWKEY;                  
206         gReverseKeyTranslateTable[DOWNARROWKEY          ] = SCA_IInputDevice::KX_DOWNARROWKEY;                  
207         gReverseKeyTranslateTable[RIGHTARROWKEY         ] = SCA_IInputDevice::KX_RIGHTARROWKEY;                  
208         gReverseKeyTranslateTable[UPARROWKEY            ] = SCA_IInputDevice::KX_UPARROWKEY;                  
209         
210         gReverseKeyTranslateTable[PAD2                          ] = SCA_IInputDevice::KX_PAD2;                  
211         gReverseKeyTranslateTable[PAD4                          ] = SCA_IInputDevice::KX_PAD4;                  
212         gReverseKeyTranslateTable[PAD6                          ] = SCA_IInputDevice::KX_PAD6;                  
213         gReverseKeyTranslateTable[PAD8                          ] = SCA_IInputDevice::KX_PAD8;                  
214         
215         gReverseKeyTranslateTable[PAD1                          ] = SCA_IInputDevice::KX_PAD1;                  
216         gReverseKeyTranslateTable[PAD3                          ] = SCA_IInputDevice::KX_PAD3;                  
217         gReverseKeyTranslateTable[PAD5                          ] = SCA_IInputDevice::KX_PAD5;                  
218         gReverseKeyTranslateTable[PAD7                          ] = SCA_IInputDevice::KX_PAD7;                  
219         gReverseKeyTranslateTable[PAD9                          ] = SCA_IInputDevice::KX_PAD9;                  
220         
221         gReverseKeyTranslateTable[PADPERIOD                     ] = SCA_IInputDevice::KX_PADPERIOD;                  
222         gReverseKeyTranslateTable[PADSLASHKEY           ] = SCA_IInputDevice::KX_PADSLASHKEY;                  
223         gReverseKeyTranslateTable[PADASTERKEY           ] = SCA_IInputDevice::KX_PADASTERKEY;                  
224         
225         gReverseKeyTranslateTable[PAD0                          ] = SCA_IInputDevice::KX_PAD0;                  
226         gReverseKeyTranslateTable[PADMINUS                      ] = SCA_IInputDevice::KX_PADMINUS;                  
227         gReverseKeyTranslateTable[PADENTER                      ] = SCA_IInputDevice::KX_PADENTER;                  
228         gReverseKeyTranslateTable[PADPLUSKEY            ] = SCA_IInputDevice::KX_PADPLUSKEY;                  
229         
230         
231         gReverseKeyTranslateTable[F1KEY                         ] = SCA_IInputDevice::KX_F1KEY;                  
232         gReverseKeyTranslateTable[F2KEY                         ] = SCA_IInputDevice::KX_F2KEY;                  
233         gReverseKeyTranslateTable[F3KEY                         ] = SCA_IInputDevice::KX_F3KEY;                  
234         gReverseKeyTranslateTable[F4KEY                         ] = SCA_IInputDevice::KX_F4KEY;                  
235         gReverseKeyTranslateTable[F5KEY                         ] = SCA_IInputDevice::KX_F5KEY;                  
236         gReverseKeyTranslateTable[F6KEY                         ] = SCA_IInputDevice::KX_F6KEY;                  
237         gReverseKeyTranslateTable[F7KEY                         ] = SCA_IInputDevice::KX_F7KEY;                  
238         gReverseKeyTranslateTable[F8KEY                         ] = SCA_IInputDevice::KX_F8KEY;                  
239         gReverseKeyTranslateTable[F9KEY                         ] = SCA_IInputDevice::KX_F9KEY;                  
240         gReverseKeyTranslateTable[F10KEY                        ] = SCA_IInputDevice::KX_F10KEY;                  
241         gReverseKeyTranslateTable[F11KEY                        ] = SCA_IInputDevice::KX_F11KEY;                  
242         gReverseKeyTranslateTable[F12KEY                        ] = SCA_IInputDevice::KX_F12KEY;                  
243         
244         gReverseKeyTranslateTable[PAUSEKEY                      ] = SCA_IInputDevice::KX_PAUSEKEY;                  
245         gReverseKeyTranslateTable[INSERTKEY                     ] = SCA_IInputDevice::KX_INSERTKEY;                  
246         gReverseKeyTranslateTable[HOMEKEY                       ] = SCA_IInputDevice::KX_HOMEKEY;                  
247         gReverseKeyTranslateTable[PAGEUPKEY                     ] = SCA_IInputDevice::KX_PAGEUPKEY;                  
248         gReverseKeyTranslateTable[PAGEDOWNKEY           ] = SCA_IInputDevice::KX_PAGEDOWNKEY;                  
249         gReverseKeyTranslateTable[ENDKEY                        ] = SCA_IInputDevice::KX_ENDKEY;
250         
251         int uniqueint = 0;
252         bSensor* sens = (bSensor*)blenderobject->sensors.first;
253         bool pos_pulsemode = false;
254         bool neg_pulsemode = false;
255         int frequency = 0;
256         bool invert = false;
257         bool level = false;
258         
259         while(sens)
260         {
261                 SCA_ISensor* gamesensor=NULL;
262                 /* All sensors have a pulse toggle, frequency, and invert field.     */
263                 /* These are extracted here, and set when the sensor is added to the */
264                 /* list.                                                             */
265                 pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0;
266                 neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0;
267                 
268                 frequency = sens->freq;
269                 invert    = !(sens->invert == 0);
270                 level     = !(sens->level == 0);
271
272                 switch (sens->type)
273                 {
274                 case  SENS_ALWAYS:
275                         {
276                                 
277                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR);
278                                 if (eventmgr)
279                                 {
280                                         gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
281                                 }
282                                 
283                                 break;
284                         }
285                         
286                 case  SENS_DELAY:
287                         {
288                                 // we can reuse the Always event manager for the delay sensor
289                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR);
290                                 if (eventmgr)
291                                 {
292                                         bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
293                                         gamesensor = new SCA_DelaySensor(eventmgr, 
294                                                 gameobj,
295                                                 delaysensor->delay,
296                                                 delaysensor->duration,
297                                                 (delaysensor->flag & SENS_DELAY_REPEAT) != 0);
298                                 }
299                                 break;
300                         }
301
302                 case SENS_COLLISION:
303                         {
304                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
305                                 if (eventmgr)
306                                 {
307                                         // collision sensor can sense both materials and properties. 
308                                         
309                                         bool bFindMaterial = false;
310                                         
311                                         bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
312                                         
313                                         bFindMaterial = (blendertouchsensor->mode 
314                                                 & SENS_COLLISION_MATERIAL);
315                                         
316                                         
317                                         STR_String touchPropOrMatName = ( bFindMaterial ? 
318                                                 blendertouchsensor->materialName:
319                                         (blendertouchsensor->name ? blendertouchsensor->name: ""));
320                                         
321                                         
322                                         if (gameobj->GetPhysicsController())
323                                         {       
324                                                 gamesensor = new KX_TouchSensor(eventmgr,
325                                                         gameobj,
326                                                         bFindMaterial,
327                                                         touchPropOrMatName);
328                                         }
329                                         
330                                 }
331                                 
332                                 break;
333                         }
334                 case SENS_TOUCH:
335                         {
336                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
337                                 if (eventmgr)
338                                 {
339                                         STR_String touchpropertyname;
340                                         bTouchSensor* blendertouchsensor = (bTouchSensor*)sens->data;
341                                         
342                                         if (blendertouchsensor->ma)
343                                         {
344                                                 touchpropertyname = (char*) (blendertouchsensor->ma->id.name+2);
345                                         }
346                                         bool bFindMaterial = true;
347                                         if (gameobj->GetPhysicsController())
348                                         {       
349                                                 gamesensor = new KX_TouchSensor(eventmgr,
350                                                         gameobj,
351                                                         bFindMaterial,
352                                                         touchpropertyname);
353                                         }
354                                 }
355                                 break;
356                         }
357                 case SENS_MESSAGE:
358                         {
359                                 KX_NetworkEventManager* eventmgr = (KX_NetworkEventManager*)
360                                         logicmgr->FindEventManager(SCA_EventManager::NETWORK_EVENTMGR);
361                                 if (eventmgr) {
362                                         bMessageSensor* msgSens = (bMessageSensor*) sens->data; 
363                                         
364                                         /* Get our NetworkScene */
365                                         NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
366                                         /* filter on the incoming subjects, might be empty */
367                                         STR_String subject = (msgSens->subject
368                                                 ? (char*)msgSens->subject
369                                                 : "");
370                                         
371                                         gamesensor = new KX_NetworkMessageSensor(
372                                                 eventmgr,               // our eventmanager
373                                                 NetworkScene,   // our NetworkScene
374                                                 gameobj,                // the sensor controlling object
375                                                 subject);               // subject to filter on
376                                 }
377                                 break;
378                         }
379                 case SENS_NEAR:
380                         {
381                                 
382                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
383                                 if (eventmgr)
384                                 {
385                                         STR_String nearpropertyname;    
386                                         bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
387                                         if (blendernearsensor->name)
388                                         {
389                                                 // only objects that own this property will be taken into account
390                                                 nearpropertyname = (char*) blendernearsensor->name;
391                                         }
392                                         
393                                         //DT_ShapeHandle shape  =       DT_Sphere(0.0);
394                                         
395                                         // this sumoObject is not deleted by a gameobj, so delete it ourself
396                                         // later (memleaks)!
397                                         float radius = blendernearsensor->dist;
398                                         PHY__Vector3 pos;
399                                         const MT_Vector3& wpos = gameobj->NodeGetWorldPosition();
400                                         pos[0] = wpos[0];
401                                         pos[1] = wpos[1];
402                                         pos[2] = wpos[2];
403                                         pos[3] = 0.f;
404                                         bool bFindMaterial = false;
405                                         PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,pos);
406
407                                         //will be done in KX_TouchEventManager::RegisterSensor()  
408                                         //if (isInActiveLayer)
409                                         //      kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
410
411                                                 
412
413                                         gamesensor = new KX_NearSensor(eventmgr,gameobj,
414                                                 blendernearsensor->dist,
415                                                 blendernearsensor->resetdist,
416                                                 bFindMaterial,
417                                                 nearpropertyname,kxscene,
418                                                 physCtrl
419                                                 );
420                                         
421                                 }
422                                 break;
423                         }
424                         
425                         
426                 case SENS_KEYBOARD:
427                         {
428                                 /* temporary input device, for converting the code for the keyboard sensor */
429                                 
430                                 bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data;
431                                 SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR);
432                                 if (eventmgr)
433                                 {
434                                         gamesensor = new SCA_KeyboardSensor(eventmgr,
435                                                 gReverseKeyTranslateTable[blenderkeybdsensor->key],
436                                                 blenderkeybdsensor->qual,
437                                                 blenderkeybdsensor->qual2,
438                                                 (blenderkeybdsensor->type == SENS_ALL_KEYS),
439                                                 blenderkeybdsensor->targetName,
440                                                 blenderkeybdsensor->toggleName,
441                                                 gameobj); //                    blenderkeybdsensor->pad);
442                                         
443                                 } 
444                                 
445                                 break;
446                         }
447                 case SENS_MOUSE:
448                         {
449                                 int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;                        
450                                 int trackfocus = 0;
451                                 bMouseSensor *bmouse = (bMouseSensor *)sens->data;
452                                 
453                                 /* There are two main types of mouse sensors. If there is
454                                 * no focus-related behaviour requested, we can make do
455                                 * with a basic sensor. This cuts down memory usage and
456                                 * gives a slight performance gain. */
457                                 
458                                 SCA_MouseManager *eventmgr 
459                                         = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
460                                 if (eventmgr) {
461                                         
462                                         /* Determine key mode. There is at most one active mode. */
463                                         switch (bmouse->type) {
464                                         case BL_SENS_MOUSE_LEFT_BUTTON:
465                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
466                                                 break;
467                                         case BL_SENS_MOUSE_MIDDLE_BUTTON:
468                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
469                                                 break;
470                                         case BL_SENS_MOUSE_RIGHT_BUTTON:
471                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
472                                                 break;
473                                         case BL_SENS_MOUSE_WHEEL_UP:
474                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELUP;
475                                                 break;
476                                         case BL_SENS_MOUSE_WHEEL_DOWN:
477                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELDOWN;
478                                                 break;
479                                         case BL_SENS_MOUSE_MOVEMENT:
480                                                 keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
481                                                 break;
482                                         case BL_SENS_MOUSE_MOUSEOVER:
483                                                 trackfocus = 1;
484                                                 break;
485                                         case BL_SENS_MOUSE_MOUSEOVER_ANY:
486                                                 trackfocus = 2;
487                                                 break;
488
489                                         default:
490                                                 ; /* error */
491                                         }
492                                         
493                                         /* initial mouse position */                             
494                                         int startx  = canvas->GetWidth()/2;
495                                         int starty = canvas->GetHeight()/2;
496                                         
497                                         if (!trackfocus) {
498                                                 /* plain, simple mouse sensor */
499                                                 gamesensor = new SCA_MouseSensor(eventmgr,
500                                                         startx,starty,
501                                                         keytype,
502                                                         gameobj);
503                                         } else {
504                                                 /* give us a focus-aware sensor */
505                                                 gamesensor = new KX_MouseFocusSensor(eventmgr,
506                                                         startx,
507                                                         starty,
508                                                         keytype,
509                                                         trackfocus,
510                                                         canvas,
511                                                         kxscene,
512                                                         kxengine,
513                                                         gameobj); 
514                                         }
515                                 } else {
516                                         //                              cout << "\n Could't find mouse event manager..."; - should throw an error here... 
517                                 }
518                                 break;
519                         }
520                 case SENS_PROPERTY:
521                         {
522                                 bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
523                                 SCA_EventManager* eventmgr 
524                                         = logicmgr->FindEventManager(SCA_EventManager::PROPERTY_EVENTMGR);
525                                 if (eventmgr)
526                                 {
527                                         STR_String propname=blenderpropsensor->name;
528                                         STR_String propval=blenderpropsensor->value;
529                                         STR_String propmaxval=blenderpropsensor->maxvalue;
530                                         
531                                         SCA_PropertySensor::KX_PROPSENSOR_TYPE 
532                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
533                                         
534                                         /* Better do an explicit conversion here! (was implicit      */
535                                         /* before...)                                                */
536                                         switch(blenderpropsensor->type) {
537                                         case SENS_PROP_EQUAL:
538                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
539                                                 break;
540                                         case SENS_PROP_NEQUAL:
541                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
542                                                 break;
543                                         case SENS_PROP_INTERVAL:
544                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
545                                                 break;
546                                         case SENS_PROP_CHANGED:
547                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
548                                                 break;
549                                         case SENS_PROP_EXPRESSION:
550                                                 propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
551                                                 /* error */
552                                                 break;
553                                         default:
554                                                 ; /* error */
555                                         }
556                                         gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
557                                 }
558                                 
559                                 break;
560                         }
561                 case SENS_ACTUATOR:
562                         {
563                                 bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data;
564                                 // we will reuse the property event manager, there is nothing special with this sensor
565                                 SCA_EventManager* eventmgr 
566                                         = logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR);
567                                 if (eventmgr)
568                                 {
569                                         STR_String propname=blenderactsensor->name;
570                                         gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname);
571                                 }
572                                 break;
573                         }
574                         
575                 case SENS_RADAR:
576                         {
577                                 
578                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
579                                 if (eventmgr)
580                                 {
581                                         STR_String radarpropertyname;
582                                         STR_String touchpropertyname;
583                                         bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
584                                         
585                                         int radaraxis = blenderradarsensor->axis;
586                                         
587                                         if (blenderradarsensor->name)
588                                         {
589                                                 // only objects that own this property will be taken into account
590                                                 radarpropertyname = (char*) blenderradarsensor->name;
591                                         }
592                                         
593                                         MT_Scalar coneheight = blenderradarsensor->range;
594                                         
595                                         // janco: the angle was doubled, so should I divide the factor in 2
596                                         // or the blenderradarsensor->angle?
597                                         // nzc: the angle is the opening angle. We need to init with 
598                                         // the axis-hull angle,so /2.0.
599                                         MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle)/2.0));
600                                         //MT_Scalar coneradius = coneheight * (factor / 2);
601                                         MT_Scalar coneradius = coneheight * factor;
602                                         
603                                         
604                                         // this sumoObject is not deleted by a gameobj, so delete it ourself
605                                         // later (memleaks)!
606                                         MT_Scalar smallmargin = 0.0;
607                                         MT_Scalar largemargin = 0.0;
608                                         
609                                         bool bFindMaterial = false;
610                                         PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController(coneradius,coneheight);
611
612                                         gamesensor = new KX_RadarSensor(
613                                                 eventmgr,
614                                                 gameobj,
615                                                 ctrl,
616                                                 coneradius,
617                                                 coneheight,
618                                                 radaraxis,
619                                                 smallmargin,
620                                                 largemargin,
621                                                 bFindMaterial,
622                                                 radarpropertyname,
623                                                 kxscene);
624                                                 
625                                 }
626                         
627                                 break;
628                         }
629                 case SENS_RAY:
630                         {
631                                 bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
632                                 
633                                 //blenderradarsensor->angle;
634                                 SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RAY_EVENTMGR);
635                                 if (eventmgr)
636                                 {
637                                         bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
638                                         bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY);
639                                         
640                                         STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
641
642                                         // don't want to get rays of length 0.0 or so
643                                         double distance = (blenderraysensor->range < 0.01 ? 0.01 : blenderraysensor->range );
644                                         int axis = blenderraysensor->axisflag;
645
646                                         
647                                         gamesensor = new KX_RaySensor(eventmgr,
648                                                                                                   gameobj,
649                                                                                                   checkname,
650                                                                                                   bFindMaterial,
651                                                                                                   bXRay,
652                                                                                                   distance,
653                                                                                                   axis,
654                                                                                                   kxscene);
655
656                                 }
657                                 break;
658                         }
659                         
660                 case SENS_RANDOM:
661                         {
662                                 bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
663                                 // some files didn't write randomsensor, avoid crash now for NULL ptr's
664                                 if (blenderrndsensor)
665                                 {
666                                         SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RANDOM_EVENTMGR);
667                                         if (eventmgr)
668                                         {
669                                                 int randomSeed = blenderrndsensor->seed;
670                                                 gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
671                                         }
672                                 }
673                                 break;
674                         }
675                 case SENS_JOYSTICK:
676                         {
677                                 int joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_NODEF;
678                                 
679                                 bJoystickSensor* bjoy = (bJoystickSensor*) sens->data;
680                                 
681                                 SCA_JoystickManager *eventmgr 
682                                         = (SCA_JoystickManager*) logicmgr->FindEventManager(SCA_EventManager::JOY_EVENTMGR);
683                                 if (eventmgr) 
684                                 {
685                                         int axis        =0;
686                                         int axisf       =0;
687                                         int button      =0;
688                                         int buttonf =0; 
689                                         int hat         =0; 
690                                         int hatf        =0;
691                                         int prec        =0;
692                                         
693                                         switch(bjoy->type)
694                                         {
695                                         case SENS_JOY_AXIS:
696                                                 axis    = bjoy->axis;
697                                                 axisf   = bjoy->axisf;
698                                                 prec    = bjoy->precision;
699                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS;
700                                                 break;
701                                         case SENS_JOY_BUTTON:
702                                                 button  = bjoy->button;
703                                                 buttonf = bjoy->buttonf;
704                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON;
705                                                 break;
706                                         case SENS_JOY_HAT:
707                                                 hat             = bjoy->hat;
708                                                 hatf    = bjoy->hatf;
709                                                 joysticktype  = SCA_JoystickSensor::KX_JOYSENSORMODE_HAT;
710                                                 break;
711                                         default:
712                                                 printf("Error: bad case statement\n");
713                                                 break;
714                                         }
715                                         gamesensor = new SCA_JoystickSensor(
716                                                 eventmgr,
717                                                 gameobj,
718                                                 bjoy->joyindex,
719                                                 joysticktype,
720                                                 axis,axisf,
721                                                 prec,
722                                                 button,buttonf,
723                                                 hat,hatf);
724                                 } 
725                                 else
726                                 {
727                                         printf("Error there was a problem finding the event manager\n");
728                                 }
729
730                                 break;
731                         }
732                 default:
733                         {
734                         }
735                 }
736
737                 if (gamesensor)
738                 {
739                         gamesensor->SetExecutePriority(executePriority++);
740                         STR_String uniquename = sens->name;
741                         uniquename += "#SENS#";
742                         uniqueint++;
743                         CIntValue* uniqueval = new CIntValue(uniqueint);
744                         uniquename += uniqueval->GetText();
745                         uniqueval->Release();
746                         
747                         /* Conversion succeeded, so we can set the generic props here.   */
748                         gamesensor->SetPulseMode(pos_pulsemode, 
749                                                                          neg_pulsemode, 
750                                                                          frequency);
751                         gamesensor->SetInvert(invert);
752                         gamesensor->SetLevel(level);
753                         gamesensor->SetName(STR_String(sens->name));                    
754                         
755                         gameobj->AddSensor(gamesensor);
756                         
757                         // only register to manager if it's in an active layer
758                         // Make registration dynamic: only when sensor is activated
759                         //if (isInActiveLayer)
760                         //      gamesensor->RegisterToManager();
761                         
762                         
763                         for (int i=0;i<sens->totlinks;i++)
764                         {
765                                 bController* linkedcont = (bController*) sens->links[i];
766                                 if (linkedcont) {
767                                         SCA_IController* gamecont = converter->FindGameController(linkedcont);
768
769                                         if (gamecont) {
770                                                 logicmgr->RegisterToSensor(gamecont,gamesensor);
771                                         } else {
772                                                 printf(
773                                                         "Warning, sensor \"%s\" could not find its controller "
774                                                         "(link %d of %d) from object \"%s\"\n"
775                                                         "\tthere has been an error converting the blender controller for the game engine,"
776                                                         "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
777                                         }
778                                 } else {
779                                         printf(
780                                                 "Warning, sensor \"%s\" has lost a link to a controller "
781                                                 "(link %d of %d) from object \"%s\"\n"
782                                                 "\tpossible causes are partially appended objects or an error reading the file,"
783                                                 "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
784                                 }
785                         }
786                         // special case: Keyboard sensor with no link
787                         // this combination is usually used for key logging. 
788                         if (sens->type == SENS_KEYBOARD && sens->totlinks == 0) {
789                                 // Force the registration so that the sensor runs
790                                 gamesensor->IncLink();
791                         }
792                                 
793                         // done with gamesensor
794                         gamesensor->Release();
795                         
796                 }
797                 sens=sens->next;
798         }
799 }
800