/** * $Id$ * * ***** BEGIN GPL/BL DUAL 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. The Blender * Foundation also sells licenses for use in proprietary software under * the Blender License. See http://www.blender.org/BL/ for information * about this. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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/BL DUAL LICENSE BLOCK ***** * Conversion of Blender data blocks to KX sensor system */ #ifdef WIN32 #pragma warning (disable : 4786) #endif //WIN32 #include "KX_BlenderSceneConverter.h" #include "KX_ConvertSensors.h" /* This little block needed for linking to Blender... */ #ifdef WIN32 #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_NetworkMessageSensor.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 "KX_KetsjiEngine.h" #include "KX_BlenderSceneConverter.h" // this map is Blender specific: a conversion between blender and ketsji enums std::map gReverseKeyTranslateTable; void BL_ConvertSensors(struct Object* blenderobject, class KX_GameObject* gameobj, SCA_LogicManager* logicmgr, KX_Scene* kxscene, SCA_IInputDevice* keydev, int & executePriority, int activeLayerBitInfo, bool isInActiveLayer, RAS_ICanvas* canvas, KX_BlenderSceneConverter* converter ) { /* 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[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; gReverseKeyTranslateTable[TIMER3 ] = SCA_IInputDevice::KX_TIMER3; // SYSTEM 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; // 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; gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY; 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[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 uniqueint = 0; bSensor* sens = (bSensor*)blenderobject->sensors.first; bool pos_pulsemode = false; bool neg_pulsemode = false; int frequency = 0; bool invert = false; 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); switch (sens->type) { case SENS_ALWAYS: { SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR); if (eventmgr) { gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj); } 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; bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data; bFindMaterial = (blendertouchsensor->mode & SENS_COLLISION_MATERIAL); STR_String touchPropOrMatName = ( bFindMaterial ? blendertouchsensor->materialName: (blendertouchsensor->name ? blendertouchsensor->name: "")); //if (gameobj->GetSumoObject()) //{ // gamesensor = 0; //new KX_TouchSensor(eventmgr, //gameobj, //gameobj->GetSumoObject(), //bFindMaterial, //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->GetSumoObject()) //{ // gamesensor = 0; //new KX_TouchSensor(eventmgr, // gameobj, // gameobj->GetSumoObject(), // bFindMaterial, // 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)! //SM_Object* sumoObj = new SM_Object(shape,NULL,NULL,NULL); //sumoObj->setMargin(blendernearsensor->dist); //sumoObj->setPosition(gameobj->NodeGetWorldPosition()); bool bFindMaterial = false; gamesensor = 0;//new KX_NearSensor(eventmgr,gameobj,blendernearsensor->dist,blendernearsensor->resetdist,bFindMaterial,nearpropertyname,kxscene); } 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], blenderkeybdsensor->qual, 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; bool trackfocus = false; 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_MOVEMENT: keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT; break; case BL_SENS_MOUSE_MOUSEOVER: trackfocus = true; 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, canvas, kxscene, 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::PROPERTY_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_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; DT_ShapeHandle shape = DT_Cone(coneradius,coneheight); // this sumoObject is not deleted by a gameobj, so delete it ourself // later (memleaks)! SM_Object* sumoObj = new SM_Object(shape,NULL,NULL,NULL); sumoObj->setMargin(0.0); sumoObj->setPosition(gameobj->NodeGetWorldPosition()); MT_Scalar smallmargin = 0.0; MT_Scalar largemargin = 0.1; bool bFindMaterial = false; gamesensor = new KX_RadarSensor( eventmgr, gameobj, coneradius, coneheight, radaraxis, smallmargin, largemargin, sumoObj, bFindMaterial, radarpropertyname, kxscene); } */ break; } case SENS_RAY: { bRaySensor* blenderraysensor = (bRaySensor*) sens->data; //blenderradarsensor->angle; SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RAY_EVENTMGR); if (eventmgr) { bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL); 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 = 0; /*new KX_RaySensor(eventmgr, gameobj, checkname, bFindMaterial, distance, axis, kxscene->GetSumoScene()); */ } 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::RANDOM_EVENTMGR); if (eventmgr) { int randomSeed = blenderrndsensor->seed; gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed); } } 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->SetName(STR_String(sens->name)); gameobj->AddSensor(gamesensor); // only register to manager if it's in an active layer if (isInActiveLayer) gamesensor->RegisterToManager(); for (int i=0;itotlinks;i++) { bController* linkedcont = (bController*) sens->links[i]; SCA_IController* gamecont = converter->FindGameController(linkedcont); if (gamecont) { logicmgr->RegisterToSensor(gamecont,gamesensor); } } } sens=sens->next; } }