blender/source/gameengine/Converter/KX_ConvertSensors.cpp
2011-09-01 02:12:53 +00:00

865 lines
32 KiB
C++

/*
* $Id$
*
* ***** 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 *****
* Conversion of Blender data blocks to KX sensor system
*/
/** \file gameengine/Converter/KX_ConvertSensors.cpp
* \ingroup bgeconv
*/
#include <stdio.h>
#if defined(WIN32) && !defined(FREE_WINDOWS)
#pragma warning (disable : 4786)
#endif //WIN32
#include "wm_event_types.h"
#include "KX_BlenderSceneConverter.h"
#include "KX_ConvertSensors.h"
/* This little block needed for linking to Blender... */
#if defined(WIN32) && !defined(FREE_WINDOWS)
#include "BLI_winstuff.h"
#endif
#include "DNA_object_types.h"
#include "DNA_material_types.h"
#include "DNA_sensor_types.h"
#include "DNA_actuator_types.h" /* for SENS_ALL_KEYS ? this define is
probably misplaced */
/* end of blender include block */
#include "RAS_IPolygonMaterial.h"
// Sensors
#include "KX_GameObject.h"
#include "RAS_MeshObject.h"
#include "SCA_KeyboardSensor.h"
#include "SCA_MouseSensor.h"
#include "SCA_AlwaysSensor.h"
#include "KX_TouchSensor.h"
#include "KX_NearSensor.h"
#include "KX_RadarSensor.h"
#include "KX_MouseFocusSensor.h"
#include "KX_ArmatureSensor.h"
#include "SCA_JoystickSensor.h"
#include "KX_NetworkMessageSensor.h"
#include "SCA_ActuatorSensor.h"
#include "SCA_DelaySensor.h"
#include "SCA_PropertySensor.h"
#include "SCA_RandomSensor.h"
#include "KX_RaySensor.h"
#include "SCA_EventManager.h"
#include "SCA_LogicManager.h"
#include "KX_BlenderInputDevice.h"
#include "KX_Scene.h"
#include "IntValue.h"
#include "KX_BlenderKeyboardDevice.h"
#include "KX_BlenderGL.h"
#include "RAS_ICanvas.h"
#include "PHY_IPhysicsEnvironment.h"
#include "KX_KetsjiEngine.h"
#include "KX_BlenderSceneConverter.h"
// this map is Blender specific: a conversion between blender and ketsji enums
std::map<int,SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable;
void BL_ConvertSensors(struct Object* blenderobject,
class KX_GameObject* gameobj,
SCA_LogicManager* logicmgr,
KX_Scene* kxscene,
KX_KetsjiEngine* kxengine,
int activeLayerBitInfo,
bool isInActiveLayer,
RAS_ICanvas* canvas,
KX_BlenderSceneConverter* converter
)
{
static bool reverseTableConverted = false;
if (!reverseTableConverted)
{
reverseTableConverted = true;
/* The reverse table. In order to not confuse ourselves, we */
/* immediately convert all events that come in to KX codes. */
gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE;
gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE;
gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE;
gReverseKeyTranslateTable[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE;
gReverseKeyTranslateTable[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE;
gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX;
gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY;
// TIMERS
gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0;
gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1;
gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2;
// SYSTEM
#if 0
/* **** XXX **** */
gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD;
gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD;
gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW;
gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE;
gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL;
gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE;
gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW;
gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE;
gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT;
gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME;
/* **** XXX **** */
#endif
// standard keyboard
gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY;
gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY;
gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY;
gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY;
gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY;
gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY;
gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY;
//XXX clean up
#ifdef WIN32
#define HKEY 'h'
#endif
gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY;
//XXX clean up
#ifdef WIN32
#undef HKEY
#endif
gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY;
gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY;
gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY;
gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY;
gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY;
gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY;
gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY;
gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY;
gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY;
gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY;
gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY;
gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY;
gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY;
gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY;
gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY;
gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY;
gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY;
gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY;
gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY;
gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY;
gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY;
gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY;
gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY;
gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY;
gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY;
gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY;
gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY;
gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY;
gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY;
gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY;
gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY;
gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY;
gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;
gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;
gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;
gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY;
gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY;
gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY;
gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY;
gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY;
gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY;
gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY;
gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY;
gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY;
gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY;
gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY;
gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;
gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY;
gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY;
gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY;
gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY;
gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;
gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;
gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY;
gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY;
gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY;
gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY;
gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2;
gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4;
gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6;
gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8;
gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1;
gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3;
gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5;
gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7;
gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9;
gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD;
gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY;
gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY;
gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0;
gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS;
gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER;
gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY;
gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY;
gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY;
gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY;
gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY;
gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY;
gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY;
gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY;
gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY;
gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY;
gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY;
gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY;
gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY;
gReverseKeyTranslateTable[F13KEY ] = SCA_IInputDevice::KX_F13KEY;
gReverseKeyTranslateTable[F14KEY ] = SCA_IInputDevice::KX_F14KEY;
gReverseKeyTranslateTable[F15KEY ] = SCA_IInputDevice::KX_F15KEY;
gReverseKeyTranslateTable[F16KEY ] = SCA_IInputDevice::KX_F16KEY;
gReverseKeyTranslateTable[F17KEY ] = SCA_IInputDevice::KX_F17KEY;
gReverseKeyTranslateTable[F18KEY ] = SCA_IInputDevice::KX_F18KEY;
gReverseKeyTranslateTable[F19KEY ] = SCA_IInputDevice::KX_F19KEY;
gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY;
gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY;
gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY;
gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY;
gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY;
gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY;
}
int executePriority = 0;
int uniqueint = 0;
int count = 0;
bSensor* sens = (bSensor*)blenderobject->sensors.first;
bool pos_pulsemode = false;
bool neg_pulsemode = false;
int frequency = 0;
bool invert = false;
bool level = false;
bool tap = false;
while (sens)
{
sens = sens->next;
count++;
}
gameobj->ReserveSensor(count);
sens = (bSensor*)blenderobject->sensors.first;
while(sens)
{
SCA_ISensor* gamesensor=NULL;
/* All sensors have a pulse toggle, frequency, and invert field. */
/* These are extracted here, and set when the sensor is added to the */
/* list. */
pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0;
neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0;
frequency = sens->freq;
invert = !(sens->invert == 0);
level = !(sens->level == 0);
tap = !(sens->tap == 0);
switch (sens->type)
{
case SENS_ALWAYS:
{
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
}
break;
}
case SENS_DELAY:
{
// we can reuse the Always event manager for the delay sensor
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
gamesensor = new SCA_DelaySensor(eventmgr,
gameobj,
delaysensor->delay,
delaysensor->duration,
(delaysensor->flag & SENS_DELAY_REPEAT) != 0);
}
break;
}
case SENS_COLLISION:
{
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
if (eventmgr)
{
// collision sensor can sense both materials and properties.
bool bFindMaterial = false, bTouchPulse = false;
bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
bFindMaterial = (blendertouchsensor->mode & SENS_COLLISION_MATERIAL);
bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE);
STR_String touchPropOrMatName = ( bFindMaterial ?
blendertouchsensor->materialName:
(blendertouchsensor->name ? blendertouchsensor->name: ""));
if (gameobj->GetPhysicsController())
{
gamesensor = new KX_TouchSensor(eventmgr,
gameobj,
bFindMaterial,
bTouchPulse,
touchPropOrMatName);
}
}
break;
}
case SENS_TOUCH:
{
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
if (eventmgr)
{
STR_String touchpropertyname;
bTouchSensor* blendertouchsensor = (bTouchSensor*)sens->data;
if (blendertouchsensor->ma)
{
touchpropertyname = (char*) (blendertouchsensor->ma->id.name+2);
}
bool bFindMaterial = true;
if (gameobj->GetPhysicsController())
{
gamesensor = new KX_TouchSensor(eventmgr,
gameobj,
bFindMaterial,
false,
touchpropertyname);
}
}
break;
}
case SENS_MESSAGE:
{
KX_NetworkEventManager* eventmgr = (KX_NetworkEventManager*)
logicmgr->FindEventManager(SCA_EventManager::NETWORK_EVENTMGR);
if (eventmgr) {
bMessageSensor* msgSens = (bMessageSensor*) sens->data;
/* Get our NetworkScene */
NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
/* filter on the incoming subjects, might be empty */
STR_String subject = (msgSens->subject
? (char*)msgSens->subject
: "");
gamesensor = new KX_NetworkMessageSensor(
eventmgr, // our eventmanager
NetworkScene, // our NetworkScene
gameobj, // the sensor controlling object
subject); // subject to filter on
}
break;
}
case SENS_NEAR:
{
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
if (eventmgr)
{
STR_String nearpropertyname;
bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
if (blendernearsensor->name)
{
// only objects that own this property will be taken into account
nearpropertyname = (char*) blendernearsensor->name;
}
//DT_ShapeHandle shape = DT_Sphere(0.0);
// this sumoObject is not deleted by a gameobj, so delete it ourself
// later (memleaks)!
float radius = blendernearsensor->dist;
PHY__Vector3 pos;
const MT_Vector3& wpos = gameobj->NodeGetWorldPosition();
pos[0] = (float)wpos[0];
pos[1] = (float)wpos[1];
pos[2] = (float)wpos[2];
pos[3] = 0.f;
bool bFindMaterial = false;
PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,pos);
//will be done in KX_TouchEventManager::RegisterSensor()
//if (isInActiveLayer)
// kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
gamesensor = new KX_NearSensor(eventmgr,gameobj,
blendernearsensor->dist,
blendernearsensor->resetdist,
bFindMaterial,
nearpropertyname,
physCtrl);
}
break;
}
case SENS_KEYBOARD:
{
/* temporary input device, for converting the code for the keyboard sensor */
bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data;
SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR);
if (eventmgr)
{
gamesensor = new SCA_KeyboardSensor(eventmgr,
gReverseKeyTranslateTable[blenderkeybdsensor->key],
gReverseKeyTranslateTable[blenderkeybdsensor->qual],
gReverseKeyTranslateTable[blenderkeybdsensor->qual2],
(blenderkeybdsensor->type == SENS_ALL_KEYS),
blenderkeybdsensor->targetName,
blenderkeybdsensor->toggleName,
gameobj); // blenderkeybdsensor->pad);
}
break;
}
case SENS_MOUSE:
{
int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;
int trackfocus = 0;
bMouseSensor *bmouse = (bMouseSensor *)sens->data;
/* There are two main types of mouse sensors. If there is
* no focus-related behaviour requested, we can make do
* with a basic sensor. This cuts down memory usage and
* gives a slight performance gain. */
SCA_MouseManager *eventmgr
= (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
if (eventmgr) {
/* Determine key mode. There is at most one active mode. */
switch (bmouse->type) {
case BL_SENS_MOUSE_LEFT_BUTTON:
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
break;
case BL_SENS_MOUSE_MIDDLE_BUTTON:
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
break;
case BL_SENS_MOUSE_RIGHT_BUTTON:
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
break;
case BL_SENS_MOUSE_WHEEL_UP:
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELUP;
break;
case BL_SENS_MOUSE_WHEEL_DOWN:
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELDOWN;
break;
case BL_SENS_MOUSE_MOVEMENT:
keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
break;
case BL_SENS_MOUSE_MOUSEOVER:
trackfocus = 1;
break;
case BL_SENS_MOUSE_MOUSEOVER_ANY:
trackfocus = 2;
break;
default:
; /* error */
}
/* initial mouse position */
int startx = canvas->GetWidth()/2;
int starty = canvas->GetHeight()/2;
if (!trackfocus) {
/* plain, simple mouse sensor */
gamesensor = new SCA_MouseSensor(eventmgr,
startx,starty,
keytype,
gameobj);
} else {
/* give us a focus-aware sensor */
gamesensor = new KX_MouseFocusSensor(eventmgr,
startx,
starty,
keytype,
trackfocus,
(bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false,
kxscene,
kxengine,
gameobj);
}
} else {
// cout << "\n Could't find mouse event manager..."; - should throw an error here...
}
break;
}
case SENS_PROPERTY:
{
bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
SCA_EventManager* eventmgr
= logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
STR_String propname=blenderpropsensor->name;
STR_String propval=blenderpropsensor->value;
STR_String propmaxval=blenderpropsensor->maxvalue;
SCA_PropertySensor::KX_PROPSENSOR_TYPE
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
/* Better do an explicit conversion here! (was implicit */
/* before...) */
switch(blenderpropsensor->type) {
case SENS_PROP_EQUAL:
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
break;
case SENS_PROP_NEQUAL:
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
break;
case SENS_PROP_INTERVAL:
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
break;
case SENS_PROP_CHANGED:
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
break;
case SENS_PROP_EXPRESSION:
propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
/* error */
break;
default:
; /* error */
}
gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
}
break;
}
case SENS_ACTUATOR:
{
bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data;
// we will reuse the property event manager, there is nothing special with this sensor
SCA_EventManager* eventmgr
= logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR);
if (eventmgr)
{
STR_String propname=blenderactsensor->name;
gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname);
}
break;
}
case SENS_ARMATURE:
{
bArmatureSensor* blenderarmsensor = (bArmatureSensor*) sens->data;
// we will reuse the property event manager, there is nothing special with this sensor
SCA_EventManager* eventmgr
= logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
STR_String bonename=blenderarmsensor->posechannel;
STR_String constraintname=blenderarmsensor->constraint;
gamesensor = new KX_ArmatureSensor(eventmgr,gameobj,bonename,constraintname, blenderarmsensor->type, blenderarmsensor->value);
}
break;
}
case SENS_RADAR:
{
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
if (eventmgr)
{
STR_String radarpropertyname;
STR_String touchpropertyname;
bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
int radaraxis = blenderradarsensor->axis;
if (blenderradarsensor->name)
{
// only objects that own this property will be taken into account
radarpropertyname = (char*) blenderradarsensor->name;
}
MT_Scalar coneheight = blenderradarsensor->range;
// janco: the angle was doubled, so should I divide the factor in 2
// or the blenderradarsensor->angle?
// nzc: the angle is the opening angle. We need to init with
// the axis-hull angle,so /2.0.
MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle)/2.0));
//MT_Scalar coneradius = coneheight * (factor / 2);
MT_Scalar coneradius = coneheight * factor;
// this sumoObject is not deleted by a gameobj, so delete it ourself
// later (memleaks)!
MT_Scalar smallmargin = 0.0;
MT_Scalar largemargin = 0.0;
bool bFindMaterial = false;
PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController((float)coneradius, (float)coneheight);
gamesensor = new KX_RadarSensor(
eventmgr,
gameobj,
ctrl,
coneradius,
coneheight,
radaraxis,
smallmargin,
largemargin,
bFindMaterial,
radarpropertyname);
}
break;
}
case SENS_RAY:
{
bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
//blenderradarsensor->angle;
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY);
STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
// don't want to get rays of length 0.0 or so
double distance = (blenderraysensor->range < 0.01 ? 0.01 : blenderraysensor->range );
int axis = blenderraysensor->axisflag;
gamesensor = new KX_RaySensor(eventmgr,
gameobj,
checkname,
bFindMaterial,
bXRay,
distance,
axis,
kxscene);
}
break;
}
case SENS_RANDOM:
{
bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
// some files didn't write randomsensor, avoid crash now for NULL ptr's
if (blenderrndsensor)
{
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
int randomSeed = blenderrndsensor->seed;
if (randomSeed == 0)
{
randomSeed = (int)(kxengine->GetRealTime()*100000.0);
randomSeed ^= (intptr_t)blenderrndsensor;
}
gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
}
}
break;
}
case SENS_JOYSTICK:
{
int joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_NODEF;
bJoystickSensor* bjoy = (bJoystickSensor*) sens->data;
SCA_JoystickManager *eventmgr
= (SCA_JoystickManager*) logicmgr->FindEventManager(SCA_EventManager::JOY_EVENTMGR);
if (eventmgr)
{
int axis =0;
int axisf =0;
int button =0;
int hat =0;
int hatf =0;
int prec =0;
switch(bjoy->type)
{
case SENS_JOY_AXIS:
axis = bjoy->axis;
axisf = bjoy->axisf;
prec = bjoy->precision;
joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS;
break;
case SENS_JOY_BUTTON:
button = bjoy->button;
joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON;
break;
case SENS_JOY_HAT:
hat = bjoy->hat;
hatf = bjoy->hatf;
joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_HAT;
break;
case SENS_JOY_AXIS_SINGLE:
axis = bjoy->axis_single;
prec = bjoy->precision;
joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS_SINGLE;
break;
default:
printf("Error: bad case statement\n");
break;
}
gamesensor = new SCA_JoystickSensor(
eventmgr,
gameobj,
bjoy->joyindex,
joysticktype,
axis,axisf,
prec,
button,
hat,hatf,
(bjoy->flag & SENS_JOY_ANY_EVENT));
}
else
{
printf("Error there was a problem finding the event manager\n");
}
break;
}
default:
{
}
}
if (gamesensor)
{
gamesensor->SetExecutePriority(executePriority++);
STR_String uniquename = sens->name;
uniquename += "#SENS#";
uniqueint++;
CIntValue* uniqueval = new CIntValue(uniqueint);
uniquename += uniqueval->GetText();
uniqueval->Release();
/* Conversion succeeded, so we can set the generic props here. */
gamesensor->SetPulseMode(pos_pulsemode,
neg_pulsemode,
frequency);
gamesensor->SetInvert(invert);
gamesensor->SetLevel(level);
gamesensor->SetTap(tap);
gamesensor->SetName(sens->name);
gameobj->AddSensor(gamesensor);
// only register to manager if it's in an active layer
// Make registration dynamic: only when sensor is activated
//if (isInActiveLayer)
// gamesensor->RegisterToManager();
gamesensor->ReserveController(sens->totlinks);
for (int i=0;i<sens->totlinks;i++)
{
bController* linkedcont = (bController*) sens->links[i];
if (linkedcont) {
SCA_IController* gamecont = converter->FindGameController(linkedcont);
if (gamecont) {
logicmgr->RegisterToSensor(gamecont,gamesensor);
} else {
printf(
"Warning, sensor \"%s\" could not find its controller "
"(link %d of %d) from object \"%s\"\n"
"\tthere has been an error converting the blender controller for the game engine,"
"logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
}
} else {
printf(
"Warning, sensor \"%s\" has lost a link to a controller "
"(link %d of %d) from object \"%s\"\n"
"\tpossible causes are partially appended objects or an error reading the file,"
"logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
}
}
// special case: Keyboard sensor with no link
// this combination is usually used for key logging.
if (sens->type == SENS_KEYBOARD && sens->totlinks == 0) {
// Force the registration so that the sensor runs
gamesensor->IncLink();
}
// done with gamesensor
gamesensor->Release();
}
sens=sens->next;
}
}