diff options
author | Martin Poirier <theeth@yahoo.com> | 2008-10-20 04:48:10 +0400 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2008-10-20 04:48:10 +0400 |
commit | a806c1eb7f53cca7c65775b7ce849d31c12902f9 (patch) | |
tree | f4554b9212dc021b6f932dd1093a66da30cbef26 /source/gameengine | |
parent | d16a8649ff6c2b65492a78eab80bcdbefa9dbe9d (diff) | |
parent | 90721f3f835fca7fed7dce99a2b7b447eba50e26 (diff) |
merge 16951:17122
Diffstat (limited to 'source/gameengine')
38 files changed, 692 insertions, 358 deletions
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 1110c4e0b48..9fbdc3fa1c9 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -70,6 +70,7 @@ #include "DNA_view3d_types.h" #include "DNA_screen_types.h" #include "BKE_global.h" +#include "BKE_utildefines.h" #include "BIF_screen.h" #include "BIF_scrarea.h" @@ -110,11 +111,14 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, Main* blenderdata = maggie1; char* startscenename = scenename; - char pathname[160]; - strcpy (pathname, blenderdata->name); + char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; BlendFileData *bfd= NULL; + BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); + BLI_strncpy(oldsce, G.sce, sizeof(oldsce)); + setGamePythonPath(G.sce); + // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls PyGILState_STATE gilstate = PyGILState_Ensure(); @@ -191,7 +195,16 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, ketsjiengine->SetUseFixedTime(usefixed); ketsjiengine->SetTimingDisplay(frameRate, profile, properties); - + + //lock frame and camera enabled - storing global values + int tmp_lay= G.scene->lay; + Object *tmp_camera = G.scene->camera; + + if (G.vd->scenelock==0){ + G.scene->lay= v3d->lay; + G.scene->camera= v3d->camera; + } + // some blender stuff MT_CmMatrix4x4 projmat; @@ -231,9 +244,14 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, char basedpath[240]; // base the actuator filename with respect // to the original file working directory + if (exitstring != "") strcpy(basedpath, exitstring.Ptr()); + // load relative to the last loaded file, this used to be relative + // to the first file but that makes no sense, relative paths in + // blend files should be relative to that file, not some other file + // that happened to be loaded first BLI_convertstringcode(basedpath, pathname); bfd = load_game_data(basedpath); @@ -254,6 +272,11 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, { blenderdata = bfd->main; startscenename = bfd->curscene->id.name + 2; + + if(blenderdata) { + BLI_strncpy(G.sce, blenderdata->name, sizeof(G.sce)); + BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); + } } // else forget it, we can't find it else @@ -317,8 +340,10 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, else if(G.fileflags & G_FILE_GAME_MAT_GLSL) usemat = false; - sceneconverter->SetMaterials(usemat && (G.fileflags & G_FILE_GAME_MAT)); - sceneconverter->SetGLSLMaterials(useglslmat && (G.fileflags & G_FILE_GAME_MAT_GLSL)); + if(usemat && (G.fileflags & G_FILE_GAME_MAT)) + sceneconverter->SetMaterials(true); + if(useglslmat && (G.fileflags & G_FILE_GAME_MAT_GLSL)) + sceneconverter->SetGLSLMaterials(true); KX_Scene* startscene = new KX_Scene(keyboarddevice, mousedevice, @@ -403,7 +428,8 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, } printf("\nBlender Game Engine Finished\n\n"); exitstring = ketsjiengine->GetExitString(); - + + // when exiting the mainloop // Clears the dictionary by hand: @@ -439,6 +465,12 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, Py_DECREF(gameLogic_keys); gameLogic_keys = NULL; } + //lock frame and camera enabled - restoring global values + if (G.vd->scenelock==0){ + G.scene->lay= tmp_lay; + G.scene->camera= tmp_camera; + } + // set the cursor back to normal canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); @@ -491,6 +523,8 @@ extern "C" void StartKetsjiShell(struct ScrArea *area, if (bfd) BLO_blendfiledata_free(bfd); + BLI_strncpy(G.sce, oldsce, sizeof(G.sce)); + // Release Python's GIL PyGILState_Release(gilstate); } @@ -506,10 +540,10 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, Main* blenderdata = maggie; char* startscenename = scenename; - char pathname[160]; - strcpy (pathname, maggie->name); + char pathname[FILE_MAXDIR+FILE_MAXFILE]; STR_String exitstring = ""; - BlendFileData *bfd= NULL; + + BLI_strncpy(pathname, blenderdata->name, sizeof(pathname)); // Acquire Python's GIL (global interpreter lock) // so we can safely run Python code and API calls @@ -567,20 +601,17 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem); Scene *blscene = NULL; - if (!bfd) + + blscene = (Scene*) maggie->scene.first; + for (Scene *sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next) { - blscene = (Scene*) maggie->scene.first; - for (Scene *sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next) + if (startscenename == (sce->id.name+2)) { - if (startscenename == (sce->id.name+2)) - { - blscene = sce; - break; - } + blscene = sce; + break; } - } else { - blscene = bfd->curscene; } + int cframe = 1, startFrame; if (blscene) { @@ -701,7 +732,6 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area, SND_DeviceManager::Unsubscribe(); } while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME); - if (bfd) BLO_blendfiledata_free(bfd); // Release Python's GIL PyGILState_Release(gilstate); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index 669e7bd1b3f..54d1eb7e011 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -102,16 +102,28 @@ void DisableForText() glDisable(GL_COLOR_MATERIAL); } - if(GLEW_ARB_multitexture) - for(int i=0; i<MAXTEX; i++) + if(GLEW_ARB_multitexture) { + for(int i=0; i<MAXTEX; i++) { glActiveTextureARB(GL_TEXTURE0_ARB+i); - if(GLEW_ARB_texture_cube_map) - if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB)) - glDisable(GL_TEXTURE_CUBE_MAP_ARB); + if(GLEW_ARB_texture_cube_map) + if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB)) + glDisable(GL_TEXTURE_CUBE_MAP_ARB); - if(glIsEnabled(GL_TEXTURE_2D)) - glDisable(GL_TEXTURE_2D); + if(glIsEnabled(GL_TEXTURE_2D)) + glDisable(GL_TEXTURE_2D); + } + + glActiveTextureARB(GL_TEXTURE0_ARB); + } + else { + if(GLEW_ARB_texture_cube_map) + if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB)) + glDisable(GL_TEXTURE_CUBE_MAP_ARB); + + if(glIsEnabled(GL_TEXTURE_2D)) + glDisable(GL_TEXTURE_2D); + } } void BL_print_gamedebug_line(char* text, int xco, int yco, int width, int height) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 97ed6f4002a..9c699b67b28 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2478,7 +2478,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, (float)dat->pivY,(float)dat->pivZ, (float)axis0.x(),(float)axis0.y(),(float)axis0.z(), (float)axis1.x(),(float)axis1.y(),(float)axis1.z(), - (float)axis2.x(),(float)axis2.y(),(float)axis2.z()); + (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),dat->flag); if (constraintId) { //if it is a generic 6DOF constraint, set all the limits accordingly diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp index f58d60b026a..4d79febb7b4 100644 --- a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp +++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp @@ -28,13 +28,10 @@ #include "KX_BlenderScalarInterpolator.h" -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -extern "C" int IPO_GetChannels(struct Ipo *ipo, short *channels); -extern "C" float IPO_GetFloatValue(struct Ipo *ipo, /*IPO_Channel*/ short channel, float ctime); - +extern "C" { +#include "DNA_ipo_types.h" +#include "BKE_ipo.h" +} static const int BL_MAX_CHANNELS = 32; @@ -42,7 +39,7 @@ float BL_ScalarInterpolator::GetValue(float currentTime) const { return IPO_GetFloatValue(m_blender_ipo, m_channel, currentTime); } -typedef short IPO_Channel; + BL_InterpolatorList::BL_InterpolatorList(struct Ipo *ipo) { IPO_Channel channels[BL_MAX_CHANNELS]; diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index be0bb8103c0..13b7f43195d 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -433,8 +433,8 @@ void BL_ConvertSensors(struct Object* blenderobject, { gamesensor = new SCA_KeyboardSensor(eventmgr, gReverseKeyTranslateTable[blenderkeybdsensor->key], - blenderkeybdsensor->qual, - blenderkeybdsensor->qual2, + gReverseKeyTranslateTable[blenderkeybdsensor->qual], + gReverseKeyTranslateTable[blenderkeybdsensor->qual2], (blenderkeybdsensor->type == SENS_ALL_KEYS), blenderkeybdsensor->targetName, blenderkeybdsensor->toggleName, @@ -685,7 +685,6 @@ void BL_ConvertSensors(struct Object* blenderobject, int axis =0; int axisf =0; int button =0; - int buttonf =0; int hat =0; int hatf =0; int prec =0; @@ -700,7 +699,6 @@ void BL_ConvertSensors(struct Object* blenderobject, break; case SENS_JOY_BUTTON: button = bjoy->button; - buttonf = bjoy->buttonf; joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON; break; case SENS_JOY_HAT: @@ -719,8 +717,9 @@ void BL_ConvertSensors(struct Object* blenderobject, joysticktype, axis,axisf, prec, - button,buttonf, - hat,hatf); + button, + hat,hatf, + (bjoy->flag & SENS_JOY_ANY_EVENT)); } else { diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp index 092956e6489..e8e29fb2769 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp @@ -24,7 +24,11 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#ifndef DISABLE_SDL #include <SDL.h> +#endif + +#include <stdio.h> #include "SCA_Joystick.h" #include "SCA_JoystickPrivate.h" @@ -40,7 +44,12 @@ SCA_Joystick::SCA_Joystick(short int index) m_buttonnum(-2), m_hatdir(-2), m_isinit(0), - m_istrig(0) + m_istrig_axis(0), + m_istrig_button(0), + m_istrig_hat(0), + m_axismax(-1), + m_buttonmax(-1), + m_hatmax(-1) { #ifndef DISABLE_SDL m_private = new PrivateData(); @@ -116,12 +125,19 @@ void SCA_Joystick::cSetPrecision(int val) } +bool SCA_Joystick::aAnyAxisIsPositive(int axis) +{ + bool result; + int res = pAxisTest(axis); + res > m_prec? result = true: result = false; + return result; +} + bool SCA_Joystick::aRightAxisIsPositive(int axis) { bool result; int res = pGetAxis(axis,1); res > m_prec? result = true: result = false; - m_istrig = result; return result; } @@ -131,7 +147,6 @@ bool SCA_Joystick::aUpAxisIsPositive(int axis) bool result; int res = pGetAxis(axis,0); res < -m_prec? result = true : result = false; - m_istrig = result; return result; } @@ -141,7 +156,6 @@ bool SCA_Joystick::aLeftAxisIsPositive(int axis) bool result; int res = pGetAxis(axis,1); res < -m_prec ? result = true : result = false; - m_istrig = result; return result; } @@ -151,10 +165,18 @@ bool SCA_Joystick::aDownAxisIsPositive(int axis) bool result; int res = pGetAxis(axis,0); res > m_prec ? result = true:result = false; - m_istrig = result; return result; } +bool SCA_Joystick::aAnyButtonPressIsPositive(void) +{ + return (m_buttonnum==-2) ? false : true; +} + +bool SCA_Joystick::aAnyButtonReleaseIsPositive(void) +{ + return (m_buttonnum==-2) ? true : false; +} bool SCA_Joystick::aButtonPressIsPositive(int button) { @@ -163,7 +185,6 @@ bool SCA_Joystick::aButtonPressIsPositive(int button) #else bool result; SDL_JoystickGetButton(m_private->m_joystick, button)? result = true:result = false; - m_istrig = result; return result; #endif } @@ -176,7 +197,6 @@ bool SCA_Joystick::aButtonReleaseIsPositive(int button) #else bool result; SDL_JoystickGetButton(m_private->m_joystick, button)? result = false : result = true; - m_istrig = result; return result; #endif } @@ -187,27 +207,9 @@ bool SCA_Joystick::aHatIsPositive(int dir) bool result; int res = pGetHat(dir); res == dir? result = true : result = false; - m_istrig = result; return result; } - -int SCA_Joystick::pGetButtonPress(int button) -{ - if(button == m_buttonnum) - return m_buttonnum; - return -2; -} - - -int SCA_Joystick::pGetButtonRelease(int button) -{ - if(button == m_buttonnum) - return m_buttonnum; - return -2; -} - - int SCA_Joystick::pGetHat(int direction) { if(direction == m_hatdir){ @@ -218,52 +220,19 @@ int SCA_Joystick::pGetHat(int direction) int SCA_Joystick::GetNumberOfAxes() { -#ifdef DISABLE_SDL - return -1; -#else - int number; - if(m_isinit){ - if(m_private->m_joystick){ - number = SDL_JoystickNumAxes(m_private->m_joystick); - return number; - } - } - return -1; -#endif + return m_axismax; } int SCA_Joystick::GetNumberOfButtons() { -#ifdef DISABLE_SDL - return -1; -#else - int number; - if(m_isinit){ - if(m_private->m_joystick){ - number = SDL_JoystickNumButtons(m_private->m_joystick); - return number; - } - } - return -1; -#endif + return m_buttonmax; } int SCA_Joystick::GetNumberOfHats() { -#ifdef DISABLE_SDL - return -1; -#else - int number; - if(m_isinit){ - if(m_private->m_joystick){ - number = SDL_JoystickNumHats(m_private->m_joystick); - return number; - } - } - return -1; -#endif + return m_hatmax; } bool SCA_Joystick::CreateJoystickDevice(void) @@ -280,9 +249,14 @@ bool SCA_Joystick::CreateJoystickDevice(void) m_private->m_joystick = SDL_JoystickOpen(m_joyindex); SDL_JoystickEventState(SDL_ENABLE); - - echo("Joystick " << m_joyindex << " initialized"); m_isinit = true; + + echo("Joystick " << m_joyindex << " initialized"); + + /* must run after being initialized */ + m_axismax = SDL_JoystickNumAxes(m_private->m_joystick); + m_buttonmax = SDL_JoystickNumButtons(m_private->m_joystick); + m_hatmax = SDL_JoystickNumHats(m_private->m_joystick); } return true; #endif @@ -314,10 +288,10 @@ int SCA_Joystick::Connected(void) void SCA_Joystick::pFillAxes() { #ifndef DISABLE_SDL - if(GetNumberOfAxes() == 1){ + if(m_axismax == 1){ m_axis10 = SDL_JoystickGetAxis(m_private->m_joystick, 0); m_axis11 = SDL_JoystickGetAxis(m_private->m_joystick, 1); - }else if(GetNumberOfAxes() > 1){ + }else if(m_axismax > 1){ m_axis10 = SDL_JoystickGetAxis(m_private->m_joystick, 0); m_axis11 = SDL_JoystickGetAxis(m_private->m_joystick, 1); m_axis20 = SDL_JoystickGetAxis(m_private->m_joystick, 2); @@ -340,3 +314,25 @@ int SCA_Joystick::pGetAxis(int axisnum, int udlr) return 0; } +int SCA_Joystick::pAxisTest(int axisnum) +{ +#ifndef DISABLE_SDL + short i1,i2; + if(axisnum == 1) { + i1 = m_axis10; i2 = m_axis11; + } + else if(axisnum == 2) { + i1 = m_axis20; i2 = m_axis21; + } + /* long winded way to do + * return MAX2(abs(i1), abs(i2)) + * avoid abs from math.h */ + if (i1 < 0) i1 = -i1; + if (i2 < 0) i2 = -i2; + if (i1 <i2) return i2; + else return i1; +#else + return 0; +#endif +} + diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h index ea7ecf7cefe..8335d5538ad 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.h +++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.h @@ -29,7 +29,9 @@ #define _SCA_JOYSTICK_H_ #include "SCA_JoystickDefines.h" +#ifndef DISABLE_SDL #include "SDL.h" +#endif /* * Basic Joystick class @@ -83,9 +85,12 @@ class SCA_Joystick /* * max # of buttons avail */ - + + int m_axismax; int m_buttonmax; - /* + int m_hatmax; + + /* * hat values stored here */ int m_hatnum; @@ -101,8 +106,10 @@ class SCA_Joystick bool m_isinit; - /* is triggered */ - bool m_istrig; + /* is triggered for each event type */ + bool m_istrig_axis; + bool m_istrig_button; + bool m_istrig_hat; #ifndef DISABLE_SDL /* @@ -134,18 +141,12 @@ class SCA_Joystick /* * returns m_axis10,m_axis11... */ - int pGetAxis(int axisnum, int udlr); - - /* - * gets the current button - */ - - int pGetButtonPress(int button); + int pAxisTest(int axisnum); /* - * returns if no button is pressed + * returns m_axis10,m_axis11... */ - int pGetButtonRelease(int button); + int pGetAxis(int axisnum, int udlr); /* * gets the current hat direction @@ -165,11 +166,14 @@ public: /* */ - + bool aAnyAxisIsPositive(int axis); bool aUpAxisIsPositive(int axis); bool aDownAxisIsPositive(int axis); bool aLeftAxisIsPositive(int axis); bool aRightAxisIsPositive(int axis); + + bool aAnyButtonPressIsPositive(void); + bool aAnyButtonReleaseIsPositive(void); bool aButtonPressIsPositive(int button); bool aButtonReleaseIsPositive(int button); bool aHatIsPositive(int dir); @@ -210,8 +214,16 @@ public: return m_prec; } - bool IsTrig(void){ - return m_istrig; + bool IsTrigAxis(void){ + return m_istrig_axis; + } + + bool IsTrigButton(void){ + return m_istrig_button; + } + + bool IsTrigHat(void){ + return m_istrig_hat; } /* diff --git a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp index 0e2078265c9..73ca288861d 100644 --- a/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp +++ b/source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp @@ -24,7 +24,10 @@ * * ***** END GPL LICENSE BLOCK ***** */ +#ifndef DISABLE_SDL #include <SDL.h> +#endif + #include "SCA_Joystick.h" #include "SCA_JoystickPrivate.h" @@ -35,7 +38,7 @@ void SCA_Joystick::OnAxisMotion(SDL_Event* sdl_event) pFillAxes(); m_axisnum = sdl_event->jaxis.axis; m_axisvalue = sdl_event->jaxis.value; - m_istrig = 1; + m_istrig_axis = 1; } @@ -43,22 +46,31 @@ void SCA_Joystick::OnHatMotion(SDL_Event* sdl_event) { m_hatdir = sdl_event->jhat.value; m_hatnum = sdl_event->jhat.hat; - m_istrig = 1; + m_istrig_hat = 1; } - void SCA_Joystick::OnButtonUp(SDL_Event* sdl_event) { + m_istrig_button = 1; + + /* this is needed for the "all events" option + * so we know if there are no buttons pressed */ + int i; + for (i=0; i<m_buttonmax; i++) { + if (SDL_JoystickGetButton(m_private->m_joystick, i)) { + m_buttonnum = i; + return; + } + } m_buttonnum = -2; } void SCA_Joystick::OnButtonDown(SDL_Event* sdl_event) { - m_buttonmax = GetNumberOfButtons(); - if(sdl_event->jbutton.button >= 1 || sdl_event->jbutton.button <= m_buttonmax) + if(sdl_event->jbutton.button >= 0 || sdl_event->jbutton.button <= m_buttonmax) { - m_istrig = 1; + m_istrig_button = 1; m_buttonnum = sdl_event->jbutton.button; } } @@ -66,7 +78,7 @@ void SCA_Joystick::OnButtonDown(SDL_Event* sdl_event) void SCA_Joystick::OnNothing(SDL_Event* sdl_event) { - m_istrig = 0; + m_istrig_axis = m_istrig_button = m_istrig_hat = 0; } /* only handle events for 1 joystick */ @@ -74,7 +86,13 @@ void SCA_Joystick::OnNothing(SDL_Event* sdl_event) void SCA_Joystick::HandleEvents(void) { SDL_Event sdl_event; - + + int i; + for (i=0; i<JOYINDEX_MAX; i++) { + if(SCA_Joystick::m_instance[i]) + SCA_Joystick::m_instance[i]->OnNothing(&sdl_event); + } + if(SDL_PollEvent(&sdl_event)) { /* Note! m_instance[sdl_event.jaxis.which] diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 0d65270dc7b..d1872009291 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -116,8 +116,8 @@ public: /** set the level detection on or off */ void SetLevel(bool lvl); - void RegisterToManager(); - void UnregisterToManager(); + virtual void RegisterToManager(); + virtual void UnregisterToManager(); virtual float GetNumber(); diff --git a/source/gameengine/GameLogic/SCA_JoystickManager.cpp b/source/gameengine/GameLogic/SCA_JoystickManager.cpp index d874b5b013a..f3ce549a637 100644 --- a/source/gameengine/GameLogic/SCA_JoystickManager.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickManager.cpp @@ -51,7 +51,8 @@ SCA_JoystickManager::~SCA_JoystickManager() { int i; for (i=0; i<JOYINDEX_MAX; i++) { - m_joystick[i]->ReleaseInstance(); + if(m_joystick[i]) + m_joystick[i]->ReleaseInstance(); } } diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp index 58818240009..8b96840b149 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp @@ -45,27 +45,26 @@ SCA_JoystickSensor::SCA_JoystickSensor(class SCA_JoystickManager* eventmgr, short int joyindex, short int joymode, int axis, int axisf,int prec, - int button, int buttonf, - int hat, int hatf, + int button, + int hat, int hatf, bool allevents, PyTypeObject* T ) :SCA_ISensor(gameobj,eventmgr,T), m_pJoystickMgr(eventmgr), m_axis(axis), m_axisf(axisf), m_button(button), - m_buttonf(buttonf), m_hat(hat), m_hatf(hatf), m_precision(prec), m_joymode(joymode), - m_joyindex(joyindex) + m_joyindex(joyindex), + m_bAllEvents(allevents) { /* std::cout << " axis " << m_axis << std::endl; std::cout << " axis flag " << m_axisf << std::endl; std::cout << " precision " << m_precision << std::endl; std::cout << " button " << m_button << std::endl; -std::cout << " button flag "<< m_buttonf << std::endl; std::cout << " hat " << m_hat << std::endl; std::cout << " hat flag " << m_hatf << std::endl; */ @@ -75,6 +74,7 @@ std::cout << " hat flag " << m_hatf << std::endl; void SCA_JoystickSensor::Init() { m_istrig=(m_invert)?1:0; + m_istrig_prev=0; m_reset = true; } @@ -108,7 +108,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) bool result = false; bool reset = m_reset && m_level; - if(js==NULL) + if(js==NULL) /* no joystick - dont do anything */ return false; m_reset = false; @@ -123,8 +123,23 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) m_axisf == 3 == down numberof== m_axis -- max 2 */ + + if (!js->IsTrigAxis() && !reset) /* No events from SDL? - dont bother */ + return false; + js->cSetPrecision(m_precision); - if(m_axisf == 1){ + if (m_bAllEvents) { + if(js->aAnyAxisIsPositive(m_axis)){ + m_istrig = 1; + result = true; + }else{ + if(m_istrig){ + m_istrig = 0; + result = true; + } + } + } + else if(m_axisf == 1){ if(js->aUpAxisIsPositive(m_axis)){ m_istrig = 1; result = true; @@ -135,7 +150,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } } } - if(m_axisf == 3){ + else if(m_axisf == 3){ if(js->aDownAxisIsPositive(m_axis)){ m_istrig = 1; result = true; @@ -146,7 +161,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } } } - if(m_axisf == 2){ + else if(m_axisf == 2){ if(js->aLeftAxisIsPositive(m_axis)){ m_istrig = 1; result = true; @@ -157,7 +172,7 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } } } - if(m_axisf == 0){ + else if(m_axisf == 0){ if(js->aRightAxisIsPositive(m_axis)){ m_istrig = 1; result = true; @@ -173,32 +188,20 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) case KX_JOYSENSORMODE_BUTTON: { /* what is what! - pressed = m_buttonf == 0 - released = m_buttonf == 1 m_button = the actual button in question */ - if(m_buttonf == 0){ - if(js->aButtonPressIsPositive(m_button)){ - m_istrig = 1; + if (!js->IsTrigButton() && !reset) /* No events from SDL? - dont bother */ + return false; + + if(( m_bAllEvents && js->aAnyButtonPressIsPositive()) || (!m_bAllEvents && js->aButtonPressIsPositive(m_button))) { + m_istrig = 1; + result = true; + }else { + if(m_istrig){ + m_istrig = 0; result = true; - }else { - if(m_istrig){ - m_istrig = 0; - result = true; - } } } - if(m_buttonf == 1){ - if(js->aButtonReleaseIsPositive(m_button)){ - m_istrig = 1; - result = true; - }else { - if(m_istrig){ - m_istrig = 0; - result = true; - } - } - } break; } case KX_JOYSENSORMODE_HAT: @@ -207,6 +210,10 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) numberof = m_hat -- max 2 direction= m_hatf -- max 12 */ + + if (!js->IsTrigHat() && !reset) /* No events from SDL? - dont bother */ + return false; + if(m_hat == 1){ if(js->aHatIsPositive(m_hatf)){ m_istrig = 1; @@ -229,19 +236,6 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) } } } - /* - if(m_hat == 3){ - if(js->aHatIsPositive(m_hatf)){ - m_istrig = 1; - result = true; - }else{ - if(m_istrig){ - m_istrig = 0; - result = true; - } - } - } - */ break; } /* test for ball anyone ?*/ @@ -250,25 +244,14 @@ bool SCA_JoystickSensor::Evaluate(CValue* event) break; } - if (js->IsTrig()) { - /* The if below detects changes with the joystick trigger state. - * js->IsTrig() will stay true as long as the key is held. - * even though the event from SDL will only be sent once. - * (js->IsTrig() && m_istrig_lastjs) - when true it means this sensor - * had the same joystick trigger state last time, - * Setting the result false this time means it wont run the sensors - * controller every time (like a pulse sensor) - * - * This is not done with the joystick its self incase other sensors use - * it or become active. - */ - if (m_istrig_lastjs) { + /* if not all events are enabled, only send a positive pulse when + * the button state changes */ + if (!m_bAllEvents) { + if (m_istrig_prev == m_istrig) { result = false; + } else { + m_istrig_prev = m_istrig; } - m_istrig_lastjs = true; - } else { - m_istrig = 0; - m_istrig_lastjs = false; } if (reset) @@ -325,11 +308,12 @@ PyMethodDef SCA_JoystickSensor::Methods[] = { {"setIndex", (PyCFunction) SCA_JoystickSensor::sPySetIndex, METH_O, (PY_METHODCHAR)SetIndex_doc}, {"getAxis", (PyCFunction) SCA_JoystickSensor::sPyGetAxis, METH_NOARGS, (PY_METHODCHAR)GetAxis_doc}, {"setAxis", (PyCFunction) SCA_JoystickSensor::sPySetAxis, METH_VARARGS, (PY_METHODCHAR)SetAxis_doc}, - {"getAxisValue", (PyCFunction) SCA_JoystickSensor::sPyGetRealAxis, METH_NOARGS, (PY_METHODCHAR)GetRealAxis_doc}, + {"getAxisValue", (PyCFunction) SCA_JoystickSensor::sPyGetAxisValue, METH_NOARGS, (PY_METHODCHAR)GetAxisValue_doc}, {"getThreshold", (PyCFunction) SCA_JoystickSensor::sPyGetThreshold, METH_NOARGS, (PY_METHODCHAR)GetThreshold_doc}, {"setThreshold", (PyCFunction) SCA_JoystickSensor::sPySetThreshold, METH_VARARGS, (PY_METHODCHAR)SetThreshold_doc}, {"getButton", (PyCFunction) SCA_JoystickSensor::sPyGetButton, METH_NOARGS, (PY_METHODCHAR)GetButton_doc}, - {"setButton", (PyCFunction) SCA_JoystickSensor::sPySetButton, METH_VARARGS, (PY_METHODCHAR)SetButton_doc}, + {"setButton", (PyCFunction) SCA_JoystickSensor::sPySetButton, METH_O, (PY_METHODCHAR)SetButton_doc}, + {"getButtonValue",(PyCFunction) SCA_JoystickSensor::sPyGetButtonValue, METH_NOARGS,(PY_METHODCHAR)GetButtonValue_doc}, {"getHat", (PyCFunction) SCA_JoystickSensor::sPyGetHat, METH_NOARGS, (PY_METHODCHAR)GetHat_doc}, {"setHat", (PyCFunction) SCA_JoystickSensor::sPySetHat, METH_VARARGS, (PY_METHODCHAR)SetHat_doc}, {"getNumAxes", (PyCFunction) SCA_JoystickSensor::sPyNumberOfAxes, METH_NOARGS, (PY_METHODCHAR)NumberOfAxes_doc}, @@ -372,16 +356,16 @@ PyObject* SCA_JoystickSensor::PySetIndex( PyObject* self, PyObject* value ) { /* get axis ---------------------------------------------------------- */ const char SCA_JoystickSensor::GetAxis_doc[] = "getAxis\n" -"\tReturns the current state of the axis.\n"; +"\tReturns the current axis this sensor reacts to.\n"; PyObject* SCA_JoystickSensor::PyGetAxis( PyObject* self) { - return PyInt_FromLong(m_joyindex); + return Py_BuildValue("[ii]",m_axis, m_axisf); } /* set axis ---------------------------------------------------------- */ const char SCA_JoystickSensor::SetAxis_doc[] = "setAxis\n" -"\tSets the current state of the axis.\n"; +"\tSets the current axis this sensor reacts to.\n"; PyObject* SCA_JoystickSensor::PySetAxis( PyObject* self, PyObject* args ) { int axis,axisflag; @@ -395,10 +379,10 @@ PyObject* SCA_JoystickSensor::PySetAxis( PyObject* self, PyObject* args ) { /* get axis value ----------------------------------------------------- */ -const char SCA_JoystickSensor::GetRealAxis_doc[] = +const char SCA_JoystickSensor::GetAxisValue_doc[] = "getAxisValue\n" -"\tReturns a list of the values for each axis .\n"; -PyObject* SCA_JoystickSensor::PyGetRealAxis( PyObject* self) { +"\tReturns a list of the values for the current state of each axis.\n"; +PyObject* SCA_JoystickSensor::PyGetAxisValue( PyObject* self) { SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); if(joy) return Py_BuildValue("[iiii]", joy->GetAxis10(), joy->GetAxis11(), joy->GetAxis20(), joy->GetAxis21()); @@ -429,30 +413,49 @@ PyObject* SCA_JoystickSensor::PySetThreshold( PyObject* self, PyObject* args ) { Py_RETURN_NONE; } - /* get button -------------------------------------------------------- */ const char SCA_JoystickSensor::GetButton_doc[] = "getButton\n" -"\tReturns the currently pressed button.\n"; +"\tReturns the current button this sensor is checking.\n"; PyObject* SCA_JoystickSensor::PyGetButton( PyObject* self) { - return Py_BuildValue("[ii]",m_button, m_buttonf); + return PyInt_FromLong(m_button); } - /* set button -------------------------------------------------------- */ const char SCA_JoystickSensor::SetButton_doc[] = "setButton\n" "\tSets the button the sensor reacts to.\n"; -PyObject* SCA_JoystickSensor::PySetButton( PyObject* self, PyObject* args ) { - int button,buttonflag; - if(!PyArg_ParseTuple(args, "ii", &button, &buttonflag)){ +PyObject* SCA_JoystickSensor::PySetButton( PyObject* self, PyObject* value ) { + int button = PyInt_AsLong(value); + if(button==-1 && PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, "expected an int"); return NULL; } m_button = button; - m_buttonf = buttonflag; Py_RETURN_NONE; } +/* get button value -------------------------------------------------- */ +const char SCA_JoystickSensor::GetButtonValue_doc[] = +"getButtonValue\n" +"\tReturns a list containing the indicies of the current pressed state of each button.\n"; +PyObject* SCA_JoystickSensor::PyGetButtonValue( PyObject* self) { + SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex); + PyObject *ls = PyList_New(0); + PyObject *value; + int i; + + if(joy) { + for (i=0; i < joy->GetNumberOfButtons(); i++) { + if (joy->aButtonPressIsPositive(i)) { + value = PyInt_FromLong(i); + PyList_Append(ls, value); + Py_DECREF(value); + } + } + } + return ls; +} /* get hat ----------------------------------------------------------- */ const char SCA_JoystickSensor::GetHat_doc[] = diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index 8b74f6e0296..d316ad1119c 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -73,7 +73,7 @@ class SCA_JoystickSensor :public SCA_ISensor * Otherwise it will trigger all the time * this is used to see if the trigger state changes. */ - bool m_istrig_lastjs; + bool m_istrig_prev; /** * The mode to determine axis,button or hat */ @@ -83,6 +83,11 @@ class SCA_JoystickSensor :public SCA_ISensor */ short int m_joyindex; + /** + * Detect all events for the currently selected type + */ + bool m_bAllEvents; + enum KX_JOYSENSORMODE { KX_JOYSENSORMODE_NODEF = 0, KX_JOYSENSORMODE_AXIS, @@ -98,8 +103,8 @@ public: short int joyindex, short int joymode, int axis, int axisf,int prec, - int button, int buttonf, - int hat, int hatf, + int button, + int hat, int hatf, bool allevents, PyTypeObject* T=&Type ); virtual ~SCA_JoystickSensor(); virtual CValue* GetReplica(); @@ -124,12 +129,13 @@ public: /* Axes*/ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetAxis); KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,SetAxis); - KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetRealAxis); + KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetAxisValue); KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetThreshold); KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,SetThreshold); /* Buttons */ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetButton); - KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,SetButton); + KX_PYMETHOD_DOC_O(SCA_JoystickSensor,SetButton); + KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetButtonValue); /* Hats */ KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetHat); KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,SetHat); diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp index d09a5394965..fa39a13679f 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp @@ -122,6 +122,10 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval) { bool result = false; bool reset = m_reset && m_level; + bool qual = true; + bool qual_change = false; + short int m_val_orig = m_val; + SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice(); // cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n"; @@ -202,7 +206,43 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval) (SCA_IInputDevice::KX_EnumInputs) m_hotkey); // cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl; - + + + /* Check qualifier keys + * - see if the qualifiers we request are pressed - 'qual' true/false + * - see if the qualifiers we request changed their state - 'qual_change' true/false + */ + if (m_qual > 0) { + const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual); + switch(qualevent.m_status) { + case SCA_InputEvent::KX_NO_INPUTSTATUS: + qual = false; + break; + case SCA_InputEvent::KX_JUSTRELEASED: + qual_change = true; + qual = false; + break; + case SCA_InputEvent::KX_JUSTACTIVATED: + qual_change = true; + } + } + if (m_qual2 > 0 && qual==true) { + const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual2); + /* copy of above */ + switch(qualevent.m_status) { + case SCA_InputEvent::KX_NO_INPUTSTATUS: + qual = false; + break; + case SCA_InputEvent::KX_JUSTRELEASED: + qual_change = true; + qual = false; + break; + case SCA_InputEvent::KX_JUSTACTIVATED: + qual_change = true; + } + } + /* done reading qualifiers */ + if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS) { if (m_val == 1) @@ -240,7 +280,33 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval) } } } + + /* Modify the key state based on qual(s) + * Tested carefuly. dont touch unless your really sure. + * note, this will only change the results if key modifiers are set. + * + * When all modifiers and keys are positive + * - pulse true + * + * When ANY of the modifiers or main key become inactive, + * - pulse false + */ + if (qual==false) { /* one of the qualifiers are not pressed */ + if (m_val_orig && qual_change) { /* we were originally enabled, but a qualifier changed */ + result = true; + } else { + result = false; + } + m_val = 0; /* since one of the qualifiers is not on, set the state to false */ + } else { /* we done have any qualifiers or they are all pressed */ + if (m_val && qual_change) { /* the main key state is true and our qualifier just changed */ + result = true; + } + } + /* done with key quals */ + } + if (reset) // force an event result = true; diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index fbb8d6530ba..0bf0317d8f2 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -44,6 +44,7 @@ #endif // __APPLE__ #include "GEN_messaging.h" #include "KX_KetsjiEngine.h" +#include "KX_PythonInit.h" /********************************** * Begin Blender include block @@ -599,8 +600,8 @@ int main(int argc, char** argv) GPG_Application app(system); bool firstTimeRunning = true; char filename[FILE_MAXDIR + FILE_MAXFILE]; + char pathname[FILE_MAXDIR + FILE_MAXFILE]; char *titlename; - char pathname[160]; get_filename(argc, argv, filename); if(filename[0]) @@ -616,8 +617,7 @@ int main(int argc, char** argv) { char basedpath[240]; - // base the actuator filename with respect - // to the original file working directory + // base the actuator filename relative to the last file strcpy(basedpath, exitstring.Ptr()); BLI_convertstringcode(basedpath, pathname); @@ -700,15 +700,14 @@ int main(int argc, char** argv) // GPG_Application app (system, maggie, startscenename); app.SetGameEngineData(maggie, scene); + BLI_strncpy(pathname, maggie->name, sizeof(pathname)); + BLI_strncpy(G.sce, maggie->name, sizeof(G.sce)); + if (firstTimeRunning) { + setGamePythonPath(G.sce); firstTimeRunning = false; - // set the filename only the first time as in KetsjiEmbedded - strcpy (pathname, maggie->name); - // also copy here (used by GameLogic.getBaseDirectory) - strcpy (G.sce, maggie->name); - if (fullScreen) { #ifdef WIN32 diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 1b57b9acc1d..8b2feca53a3 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -214,7 +214,8 @@ KX_GameObject* KX_GameObject::GetParent() void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj) { - if (obj && GetSGNode()->GetSGParent() != obj->GetSGNode()) + // check on valid node in case a python controller holds a reference to a deleted object + if (obj && GetSGNode() && obj->GetSGNode() && GetSGNode()->GetSGParent() != obj->GetSGNode()) { // Make sure the objects have some scale MT_Vector3 scale1 = NodeGetWorldScaling(); @@ -256,7 +257,8 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj) void KX_GameObject::RemoveParent(KX_Scene *scene) { - if (GetSGNode()->GetSGParent()) + // check on valid node in case a python controller holds a reference to a deleted object + if (GetSGNode() && GetSGNode()->GetSGParent()) { // Set us to the right spot GetSGNode()->SetLocalScale(GetSGNode()->GetWorldScaling()); @@ -642,6 +644,10 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac) MT_Vector3 vect,ori,z,x,y; MT_Scalar len; + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + vect = dir; len = vect.length(); if (MT_fuzzyZero(len)) @@ -785,7 +791,11 @@ MT_Vector3 KX_GameObject::GetVelocity(const MT_Point3& point) void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans) { - if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent())) + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + + if (m_pPhysicsController1 && !GetSGNode()->GetSGParent()) { // don't update physic controller if the object is a child: // 1) the transformation will not be right @@ -794,35 +804,39 @@ void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans) m_pPhysicsController1->setPosition(trans); } - if (GetSGNode()) - GetSGNode()->SetLocalPosition(trans); + GetSGNode()->SetLocalPosition(trans); } void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot) { - if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent())) + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + + if (m_pPhysicsController1 && !GetSGNode()->GetSGParent()) { // see note above m_pPhysicsController1->setOrientation(rot); } - if (GetSGNode()) - GetSGNode()->SetLocalOrientation(rot); + GetSGNode()->SetLocalOrientation(rot); } void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale) { - if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent())) + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return; + + if (m_pPhysicsController1 && !GetSGNode()->GetSGParent()) { // see note above m_pPhysicsController1->setScaling(scale); } - - if (GetSGNode()) - GetSGNode()->SetLocalScale(scale); + GetSGNode()->SetLocalScale(scale); } @@ -880,6 +894,13 @@ void KX_GameObject::NodeUpdateGS(double time,bool bInitiator) const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const { + static MT_Matrix3x3 defaultOrientation = MT_Matrix3x3( 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0); + + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return defaultOrientation; return GetSGNode()->GetWorldOrientation(); } @@ -887,6 +908,12 @@ const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const { + static MT_Vector3 defaultScaling = MT_Vector3(1.0, 1.0, 1.0); + + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return defaultScaling; + return GetSGNode()->GetWorldScaling(); } @@ -894,6 +921,12 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const const MT_Point3& KX_GameObject::NodeGetWorldPosition() const { + static MT_Point3 defaultPosition = MT_Point3(0.0, 0.0, 0.0); + + // check on valid node in case a python controller holds a reference to a deleted object + if (!GetSGNode()) + return defaultPosition; + return GetSGNode()->GetWorldPosition(); } diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp index 397aedb3fa3..bae87c28123 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.cpp +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -252,8 +252,10 @@ bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData client_info->m_gameobject : NULL); - // these checks are done already in BroadPhaseFilterCollision() - if (gameobj /*&& (gameobj != parent)*/) + // Add the same check as in SCA_ISensor::Activate(), + // we don't want to record collision when the sensor is not active. + if (m_links && !m_suspended && + gameobj /* done in BroadPhaseFilterCollision() && (gameobj != parent)*/) { if (!m_colliders->SearchValue(gameobj)) m_colliders->Add(gameobj->AddRef()); diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index dea6225edc2..fb37eded450 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -435,7 +435,7 @@ static PyObject* gPyCreateConstraint(PyObject* self, PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2; if (physctrl) //TODO:check for existance of this pointer! { - int constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ); + int constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ,0); KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment()); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index cdf7ebd0943..a30d9f4022d 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -97,6 +97,7 @@ static RAS_ICanvas* gp_Canvas = NULL; static KX_Scene* gp_KetsjiScene = NULL; static KX_KetsjiEngine* gp_KetsjiEngine = NULL; static RAS_IRasterizer* gp_Rasterizer = NULL; +static char gp_GamePythonPath[FILE_MAXDIR + FILE_MAXFILE] = ""; void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color) { @@ -155,7 +156,7 @@ static PyObject* gPyExpandPath(PyObject*, PyObject* args) return NULL; BLI_strncpy(expanded, filename, FILE_MAXDIR + FILE_MAXFILE); - BLI_convertstringcode(expanded, G.sce); + BLI_convertstringcode(expanded, gp_GamePythonPath); return PyString_FromString(expanded); } @@ -281,7 +282,7 @@ static PyObject* gPyGetAverageFrameRate(PyObject*) static PyObject* gPyGetBlendFileList(PyObject*, PyObject* args) { - char cpath[sizeof(G.sce)]; + char cpath[sizeof(gp_GamePythonPath)]; char *searchpath = NULL; PyObject* list, *value; @@ -295,10 +296,10 @@ static PyObject* gPyGetBlendFileList(PyObject*, PyObject* args) if (searchpath) { BLI_strncpy(cpath, searchpath, FILE_MAXDIR + FILE_MAXFILE); - BLI_convertstringcode(cpath, G.sce); + BLI_convertstringcode(cpath, gp_GamePythonPath); } else { /* Get the dir only */ - BLI_split_dirfile_basic(G.sce, cpath, NULL); + BLI_split_dirfile_basic(gp_GamePythonPath, cpath, NULL); } if((dp = opendir(cpath)) == NULL) { @@ -1541,9 +1542,10 @@ int loadGamePythonConfig(char *marshal_buffer, int marshal_length) void pathGamePythonConfig( char *path ) { - int len = strlen(G.sce); + int len = strlen(gp_GamePythonPath); - strncpy(path, G.sce, sizeof(G.sce)); + BLI_strncpy(path, gp_GamePythonPath, sizeof(gp_GamePythonPath)); + /* replace extension */ if (BLI_testextensie(path, ".blend")) { strcpy(path+(len-6), ".bgeconf"); @@ -1551,3 +1553,9 @@ void pathGamePythonConfig( char *path ) strcpy(path+len, ".bgeconf"); } } + +void setGamePythonPath(char *path) +{ + BLI_strncpy(gp_GamePythonPath, path, sizeof(gp_GamePythonPath)); +} + diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 28d9d72a4c3..36e3db6ec35 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -49,6 +49,7 @@ void exitGamePlayerPythonScripting(); PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level); void exitGamePythonScripting(); +void setGamePythonPath(char *path); void pathGamePythonConfig( char *path ); int saveGamePythonConfig( char **marshal_buffer); int loadGamePythonConfig(char *marshal_buffer, int marshal_length); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index f5d6d7e8e0a..caa71441b1d 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -614,7 +614,8 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level) GroupObject *go; vector<KX_GameObject*> duplilist; - if (!groupobj->IsDupliGroup() || + if (!groupobj->GetSGNode() || + !groupobj->IsDupliGroup() || level>MAX_DUPLI_RECUR) return; @@ -1232,7 +1233,7 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam,int layer) { // User (Python/Actuator) has forced object invisible... - if (!gameobj->GetVisible()) + if (!gameobj->GetSGNode() || !gameobj->GetVisible()) return; // Shadow lamp layers diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp index f75a1ee5c62..afa5af3bc04 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.cpp +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -110,6 +110,9 @@ bool KX_SoundActuator::Update(double curtime, bool frame) if (!m_soundObject) return false; + // actual audio device playing state + bool isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED) ? true : false; + if (m_pino) { bNegativeEvent = true; @@ -119,30 +122,40 @@ bool KX_SoundActuator::Update(double curtime, bool frame) if (bNegativeEvent) { // here must be a check if it is still playing - m_isplaying = false; - - switch (m_type) + if (m_isplaying && isplaying) { - case KX_SOUNDACT_PLAYSTOP: - case KX_SOUNDACT_LOOPSTOP: - case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP: - { - m_soundScene->RemoveActiveObject(m_soundObject); - break; - } - case KX_SOUNDACT_PLAYEND: + switch (m_type) { - m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED); + case KX_SOUNDACT_PLAYSTOP: + case KX_SOUNDACT_LOOPSTOP: + case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP: + { + m_soundScene->RemoveActiveObject(m_soundObject); + break; + } + case KX_SOUNDACT_PLAYEND: + { + m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED); + break; + } + case KX_SOUNDACT_LOOPEND: + case KX_SOUNDACT_LOOPBIDIRECTIONAL: + { + m_soundObject->SetLoopMode(SND_LOOP_OFF); + m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED); + break; + } + default: + // implement me !! break; } - default: - // implement me !! - break; } + // remember that we tried to stop the actuator + m_isplaying = false; } else { - if (m_soundObject && !m_isplaying) + if (!m_isplaying) { switch (m_type) { @@ -179,8 +192,10 @@ bool KX_SoundActuator::Update(double curtime, bool frame) } } } + // verify that the sound is still playing + isplaying = (m_soundObject->GetPlaystate() != SND_STOPPED) ? true : false; - if (m_isplaying) + if (isplaying) { m_soundObject->SetPosition(((KX_GameObject*)this->GetParent())->NodeGetWorldPosition()); m_soundObject->SetVelocity(((KX_GameObject*)this->GetParent())->GetLinearVelocity()); @@ -189,14 +204,15 @@ bool KX_SoundActuator::Update(double curtime, bool frame) } else { + m_isplaying = false; result = false; } - + /* if (result && (m_soundObject->IsLifeSpanOver(curtime)) && ((m_type == KX_SOUNDACT_PLAYEND) || (m_type == KX_SOUNDACT_PLAYSTOP))) { m_pino = true; } - + */ return result; } @@ -312,6 +328,9 @@ PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObje PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObject* kwds) { if (m_soundObject) + // This has no effect if the actuator is not active. + // To start the sound you must activate the actuator. + // This function is to restart the sound. m_soundObject->StartSound(); Py_Return; } @@ -321,6 +340,7 @@ PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObjec PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObject* kwds) { if (m_soundObject) + // unfortunately, openal does not implement pause correctly, it is equivalent to a stop m_soundObject->PauseSound(); Py_Return; } diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp index 41757a23f7a..1935a0bde39 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.cpp +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -55,9 +55,17 @@ void KX_TouchSensor::SynchronizeTransform() void KX_TouchSensor::EndFrame() { m_colliders->ReleaseAndRemoveAll(); + m_hitObject = NULL; m_bTriggered = false; } +void KX_TouchSensor::UnregisterToManager() +{ + // before unregistering the sensor, make sure we release all references + EndFrame(); + m_eventmgr->RemoveSensor(this); +} + bool KX_TouchSensor::Evaluate(CValue* event) { bool result = false; @@ -176,7 +184,10 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll client_info->m_gameobject : NULL); - if (gameobj && (gameobj != parent) && client_info->isActor()) + // add the same check as in SCA_ISensor::Activate(), + // we don't want to record collision when the sensor is not active. + if (m_links && !m_suspended && + gameobj && (gameobj != parent) && client_info->isActor()) { if (!m_colliders->SearchValue(gameobj)) m_colliders->Add(gameobj->AddRef()); diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index b611d296939..8fbb1c676ba 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -77,6 +77,7 @@ public: virtual void RegisterSumo(KX_TouchEventManager* touchman); virtual void UnregisterSumo(KX_TouchEventManager* touchman); + virtual void UnregisterToManager(); // virtual DT_Bool HandleCollision(void* obj1,void* obj2, // const DT_CollData * coll_data); diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp index 342e71c5093..028f96f6c5b 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp @@ -49,26 +49,29 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self, if (PyArg_ParseTuple(args,"OOOOffi",&wheelGameObject,&pylistPos,&pylistDir,&pylistAxleDir,&suspensionRestLength,&wheelRadius,&hasSteering)) { KX_GameObject* gameOb = (KX_GameObject*) wheelGameObject; - - PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode()); - - MT_Vector3 attachPos,attachDir,attachAxle; - PyVecTo(pylistPos,attachPos); - PyVecTo(pylistDir,attachDir); - PyVecTo(pylistAxleDir,attachAxle); - PHY__Vector3 aPos,aDir,aAxle; - aPos[0] = attachPos[0]; - aPos[1] = attachPos[1]; - aPos[2] = attachPos[2]; - aDir[0] = attachDir[0]; - aDir[1] = attachDir[1]; - aDir[2] = attachDir[2]; - aAxle[0] = -attachAxle[0];//someone reverse some conventions inside Bullet (axle winding) - aAxle[1] = -attachAxle[1]; - aAxle[2] = -attachAxle[2]; - - printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering); - m_vehicle->AddWheel(motionState,aPos,aDir,aAxle,suspensionRestLength,wheelRadius,hasSteering); + + if (gameOb->GetSGNode()) + { + PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode()); + + MT_Vector3 attachPos,attachDir,attachAxle; + PyVecTo(pylistPos,attachPos); + PyVecTo(pylistDir,attachDir); + PyVecTo(pylistAxleDir,attachAxle); + PHY__Vector3 aPos,aDir,aAxle; + aPos[0] = attachPos[0]; + aPos[1] = attachPos[1]; + aPos[2] = attachPos[2]; + aDir[0] = attachDir[0]; + aDir[1] = attachDir[1]; + aDir[2] = attachDir[2]; + aAxle[0] = -attachAxle[0];//someone reverse some conventions inside Bullet (axle winding) + aAxle[1] = -attachAxle[1]; + aAxle[2] = -attachAxle[2]; + + printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering); + m_vehicle->AddWheel(motionState,aPos,aDir,aAxle,suspensionRestLength,wheelRadius,hasSteering); + } } else { return NULL; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 91655e96101..4fe35630784 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -33,6 +33,7 @@ subject to the following restrictions: #include "PHY_IMotionState.h" +#define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80 bool useIslands = true; @@ -882,13 +883,16 @@ int CcdPhysicsEnvironment::createUniversalD6Constraint( const btVector3& linearMinLimits, const btVector3& linearMaxLimits, const btVector3& angularMinLimits, - const btVector3& angularMaxLimits + const btVector3& angularMaxLimits,int flags ) { + bool disableCollisionBetweenLinkedBodies = (0!=(flags & CCD_CONSTRAINT_DISABLE_LINKED_COLLISION)); + //we could either add some logic to recognize ball-socket and hinge, or let that up to the user //perhaps some warning or hint that hinge/ball-socket is more efficient? + btGeneric6DofConstraint* genericConstraint = 0; CcdPhysicsController* ctrl0 = (CcdPhysicsController*) ctrlRef; CcdPhysicsController* ctrl1 = (CcdPhysicsController*) ctrlOther; @@ -918,7 +922,7 @@ int CcdPhysicsEnvironment::createUniversalD6Constraint( if (genericConstraint) { // m_constraints.push_back(genericConstraint); - m_dynamicsWorld->addConstraint(genericConstraint); + m_dynamicsWorld->addConstraint(genericConstraint,disableCollisionBetweenLinkedBodies); genericConstraint->setUserConstraintId(gConstraintUid++); genericConstraint->setUserConstraintType(PHY_GENERIC_6DOF_CONSTRAINT); @@ -1488,10 +1492,13 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl float pivotX,float pivotY,float pivotZ, float axisX,float axisY,float axisZ, float axis1X,float axis1Y,float axis1Z, - float axis2X,float axis2Y,float axis2Z + float axis2X,float axis2Y,float axis2Z,int flags ) { + bool disableCollisionBetweenLinkedBodies = (0!=(flags & CCD_CONSTRAINT_DISABLE_LINKED_COLLISION)); + + CcdPhysicsController* c0 = (CcdPhysicsController*)ctrl0; CcdPhysicsController* c1 = (CcdPhysicsController*)ctrl1; @@ -1574,7 +1581,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl { if (rb1) { - sb0->appendAnchor(node,rb1); + sb0->appendAnchor(node,rb1,disableCollisionBetweenLinkedBodies); } else { sb0->setMass(node,0.f); @@ -1636,7 +1643,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl { if (rb0) { - sb1->appendAnchor(node,rb0); + sb1->appendAnchor(node,rb0,disableCollisionBetweenLinkedBodies); } else { sb1->setMass(node,0.f); @@ -1683,7 +1690,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl pivotInA); } - m_dynamicsWorld->addConstraint(p2p); + m_dynamicsWorld->addConstraint(p2p,disableCollisionBetweenLinkedBodies); // m_constraints.push_back(p2p); p2p->setUserConstraintId(gConstraintUid++); @@ -1753,7 +1760,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl if (genericConstraint) { //m_constraints.push_back(genericConstraint); - m_dynamicsWorld->addConstraint(genericConstraint); + m_dynamicsWorld->addConstraint(genericConstraint,disableCollisionBetweenLinkedBodies); genericConstraint->setUserConstraintId(gConstraintUid++); genericConstraint->setUserConstraintType(type); //64 bit systems can't cast pointer to int. could use size_t instead. @@ -1819,7 +1826,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl if (coneTwistContraint) { //m_constraints.push_back(genericConstraint); - m_dynamicsWorld->addConstraint(coneTwistContraint); + m_dynamicsWorld->addConstraint(coneTwistContraint,disableCollisionBetweenLinkedBodies); coneTwistContraint->setUserConstraintId(gConstraintUid++); coneTwistContraint->setUserConstraintType(type); //64 bit systems can't cast pointer to int. could use size_t instead. @@ -1858,7 +1865,7 @@ int CcdPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl hinge->setAngularOnly(angularOnly); //m_constraints.push_back(hinge); - m_dynamicsWorld->addConstraint(hinge); + m_dynamicsWorld->addConstraint(hinge,disableCollisionBetweenLinkedBodies); hinge->setUserConstraintId(gConstraintUid++); hinge->setUserConstraintType(type); //64 bit systems can't cast pointer to int. could use size_t instead. diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 3d9d5442b8f..74384dd8cf2 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -127,7 +127,7 @@ protected: float pivotX,float pivotY,float pivotZ, float axisX,float axisY,float axisZ, float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0 + float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 ); @@ -139,7 +139,7 @@ protected: const btVector3& linearMinLimits, const btVector3& linearMaxLimits, const btVector3& angularMinLimits, - const btVector3& angularMaxLimits + const btVector3& angularMaxLimits,int flags ); virtual void setConstraintParam(int constraintId,int param,float value,float value1); diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp index d78958b746c..ba196b5cf55 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp @@ -92,8 +92,7 @@ void DummyPhysicsEnvironment::setGravity(float x,float y,float z) int DummyPhysicsEnvironment::createConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, float pivotX,float pivotY,float pivotZ,float axisX,float axisY,float axisZ, float axis1X,float axis1Y,float axis1Z, - float axis2X,float axis2Y,float axis2Z - + float axis2X,float axis2Y,float axis2Z,int flag ) { diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index 975be84f2a7..a92b1e7f4a6 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -58,7 +58,7 @@ public: float pivotX,float pivotY,float pivotZ, float axisX,float axisY,float axisZ, float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0 + float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 ); virtual void removeConstraint(int constraintid); diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp index 80e4dc4044e..3be5e027345 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp @@ -111,8 +111,8 @@ int SumoPhysicsEnvironment::createConstraint( float pivotX,float pivotY,float pivotZ, float axisX,float axisY,float axisZ, float axis1X,float axis1Y,float axis1Z, - float axis2X,float axis2Y,float axis2Z - + float axis2X,float axis2Y,float axis2Z, + int flag ) { int constraintid = 0; diff --git a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h index 100adf969d5..65b07a7a0be 100644 --- a/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h +++ b/source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h @@ -63,7 +63,7 @@ public: float pivotX,float pivotY,float pivotZ, float axisX,float axisY,float axisZ, float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0 + float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 ); diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 98496fb7f9e..0e9c571924c 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -129,7 +129,7 @@ class PHY_IPhysicsEnvironment float pivotX,float pivotY,float pivotZ, float axis0X,float axis0Y,float axis0Z, float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0 + float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 )=0; virtual void removeConstraint(int constraintid)=0; virtual float getAppliedImpulse(int constraintid){ return 0.f;} diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index af3d2810553..9dab7db6081 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -13,10 +13,10 @@ Documentation for the GameLogic Module. See L{WhatsNew} for updates, changes and new functionality in the Game Engine Python API. Examples:: - # To get a controller: + # To get the controller thats running this python script: co = GameLogic.getCurrentController() # GameLogic is automatically imported - # To get the game object associated with this controller: + # To get the game object this controller is on: obj = co.getOwner() L{KX_GameObject} and L{KX_Camera} or L{KX_Light} methods are available depending on the type of object:: @@ -31,17 +31,18 @@ Documentation for the GameLogic Module. sensors = co.getSensors() See the sensor's reference for available methods: - - L{KX_NetworkMessageSensor} - - L{KX_RaySensor} - - L{KX_MouseFocusSensor} - - L{KX_NearSensor} - - L{KX_RadarSensor} - - L{KX_TouchSensor} - - L{SCA_KeyboardSensor} - - L{SCA_MouseSensor} - - L{SCA_PropertySensor} - - L{SCA_RandomSensor} - - L{SCA_DelaySensor} + - L{DelaySensor<SCA_DelaySensor.SCA_DelaySensor>} + - L{JoystickSensor<SCA_JoystickSensor.SCA_JoystickSensor>} + - L{KeyboardSensor<SCA_KeyboardSensor.SCA_KeyboardSensor>} + - L{MouseFocusSensor<KX_MouseFocusSensor.KX_MouseFocusSensor>} + - L{MouseSensor<SCA_MouseSensor.SCA_MouseSensor>} + - L{NearSensor<KX_NearSensor.KX_NearSensor>} + - L{NetworkMessageSensor<KX_NetworkMessageSensor.KX_NetworkMessageSensor>} + - L{PropertySensor<SCA_PropertySensor.SCA_PropertySensor>} + - L{RadarSensor<KX_RadarSensor.KX_RadarSensor>} + - L{RandomSensor<SCA_RandomSensor.SCA_RandomSensor>} + - L{RaySensor<KX_RaySensor.KX_RaySensor>} + - L{TouchSensor<KX_TouchSensor.KX_TouchSensor>} You can also access actuators linked to the controller:: # To get an actuator attached to the controller: @@ -54,23 +55,23 @@ Documentation for the GameLogic Module. GameLogic.addActiveActuator(actuator, True) See the actuator's reference for available methods: - - L{BL_ActionActuator} - - L{KX_CameraActuator} - - L{KX_CDActuator} - - L{KX_ConstraintActuator} - - L{KX_GameActuator} - - L{KX_IpoActuator} - - L{KX_NetworkMessageActuator} - - L{KX_ObjectActuator} - - L{KX_SCA_AddObjectActuator} - - L{KX_SCA_EndObjectActuator} - - L{KX_SCA_ReplaceMeshActuator} - - L{KX_SceneActuator} - - L{KX_SoundActuator} - - L{KX_TrackToActuator} - - L{KX_VisibilityActuator} - - L{SCA_PropertyActuator} - - L{SCA_RandomActuator} + - L{ActionActuator<BL_ActionActuator.BL_ActionActuator>} + - L{AddObjectActuator<KX_SCA_AddObjectActuator.KX_SCA_AddObjectActuator>} + - L{CameraActuator<KX_CameraActuator.KX_CameraActuator>} + - L{CDActuator<KX_CDActuator.KX_CDActuator>} + - L{ConstraintActuator<KX_ConstraintActuator.KX_ConstraintActuator>} + - L{EndObjectActuator<KX_SCA_EndObjectActuator.KX_SCA_EndObjectActuator>} + - L{GameActuator<KX_GameActuator.KX_GameActuator>} + - L{IpoActuator<KX_IpoActuator.KX_IpoActuator>} + - L{NetworkMessageActuator<KX_NetworkMessageActuator.KX_NetworkMessageActuator>} + - L{ObjectActuator<KX_ObjectActuator.KX_ObjectActuator>} + - L{PropertyActuator<SCA_PropertyActuator.SCA_PropertyActuator>} + - L{RandomActuator<SCA_RandomActuator.SCA_RandomActuator>} + - L{ReplaceMeshActuator<KX_SCA_ReplaceMeshActuator.KX_SCA_ReplaceMeshActuator>} + - L{SceneActuator<KX_SceneActuator.KX_SceneActuator>} + - L{SoundActuator<KX_SoundActuator.KX_SoundActuator>} + - L{TrackToActuator<KX_TrackToActuator.KX_TrackToActuator>} + - L{VisibilityActuator<KX_VisibilityActuator.KX_VisibilityActuator>} Most logic brick's methods are accessors for the properties available in the logic buttons. Consult the logic bricks documentation for more information on how each logic brick works. diff --git a/source/gameengine/PyDoc/KX_ActuatorSensor.py b/source/gameengine/PyDoc/KX_ActuatorSensor.py index f9aef86f7f0..cdfbf27576e 100644 --- a/source/gameengine/PyDoc/KX_ActuatorSensor.py +++ b/source/gameengine/PyDoc/KX_ActuatorSensor.py @@ -1,6 +1,7 @@ # $Id$ # Documentation for KX_ActuatorSensor from SCA_IActuator import * +from SCA_ISensor import * class KX_ActuatorSensor(SCA_ISensor): """ diff --git a/source/gameengine/PyDoc/KX_ConstraintActuator.py b/source/gameengine/PyDoc/KX_ConstraintActuator.py index b1c6f3c0f4e..7c7ad5aa0fa 100644 --- a/source/gameengine/PyDoc/KX_ConstraintActuator.py +++ b/source/gameengine/PyDoc/KX_ConstraintActuator.py @@ -58,11 +58,11 @@ class KX_ConstraintActuator(SCA_IActuator): See module L{GameLogic} for valid constraint types. - @param limit: Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ, - Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY or KX_CONSTRAINTACT_ROTZ - Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ, - KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ, - Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ + @param limit: + Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ + Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY or KX_CONSTRAINTACT_ROTZ + Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ, KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ + Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ """ def getLimit(): """ @@ -70,11 +70,11 @@ class KX_ConstraintActuator(SCA_IActuator): See module L{GameLogic} for valid constraints. - @return: Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ, - Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY, KX_CONSTRAINTACT_ROTZ, - Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ, - KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ, - Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ + @return: + Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ, + Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY, KX_CONSTRAINTACT_ROTZ, + Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ, KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ, + Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ """ def setRotDamp(duration): """ @@ -107,7 +107,7 @@ class KX_ConstraintActuator(SCA_IActuator): @type option: integer @param option: Binary combination of the following values: - 64 : Activate alignment to surface + 64 : Activate alignment to surface 128 : Detect material rather than property 256 : No deactivation if ray does not hit target 512 : Activate distance control diff --git a/source/gameengine/PyDoc/KX_IpoActuator.py b/source/gameengine/PyDoc/KX_IpoActuator.py index 1cdab829385..e2fe3b289e3 100644 --- a/source/gameengine/PyDoc/KX_IpoActuator.py +++ b/source/gameengine/PyDoc/KX_IpoActuator.py @@ -6,7 +6,7 @@ class KX_IpoActuator(SCA_IActuator): """ IPO actuator activates an animation. """ - def set(mode, startframe, endframe, mode): + def set(mode, startframe, endframe, force): """ Sets the properties of the actuator. @@ -16,8 +16,8 @@ class KX_IpoActuator(SCA_IActuator): @type startframe: integer @param endframe: last frame to use @type endframe: integer - @param mode: special mode - @type mode: integer (0=normal, 1=interpret location as force, 2=additive) + @param force: special mode + @type force: integer (0=normal, 1=interpret location as force, 2=additive) """ def setProperty(property): """ diff --git a/source/gameengine/PyDoc/Rasterizer.py b/source/gameengine/PyDoc/Rasterizer.py index cdda87fcb49..6a67cdcc71b 100644 --- a/source/gameengine/PyDoc/Rasterizer.py +++ b/source/gameengine/PyDoc/Rasterizer.py @@ -40,8 +40,8 @@ Example Uses an L{SCA_MouseSensor}, and two L{KX_ObjectActuator}s to implement M @group Material Types: KX_TEXFACE_MATERIAL, KX_BLENDER_MULTITEX_MATERIAL, KX_BLENDER_GLSL_MATERIAL @var KX_TEXFACE_MATERIAL: Materials as defined by the texture face settings. @var KX_BLENDER_MULTITEX_MATERIAL: Materials approximating blender materials with multitexturing. -@var KX_BLENDER_BLENDER_MATERIAL: Materials approximating blender materials with GLSL. - +@var KX_BLENDER_GLSL_MATERIAL: Materials approximating blender materials with GLSL. + """ def getWindowWidth(): @@ -181,14 +181,15 @@ def getGLSLMaterialSetting(setting, enable): @type setting: string (lights, shaders, shadows, ramps, nodes, extra_textures) @rtype: boolean """ -def drawLine(from,to,color): + +def drawLine(fromVec,toVec,color): """ Draw a line in the 3D scene. - @param from: the origin of the line - @type from: list [x, y, z] - @param to: the end of the line - @type to: list [x, y, z] + @param fromVec: the origin of the line + @type fromVec: list [x, y, z] + @param toVec: the end of the line + @type toVec: list [x, y, z] @param color: the color of the line @type color: list [r, g, b] """ diff --git a/source/gameengine/PyDoc/SCA_JoystickSensor.py b/source/gameengine/PyDoc/SCA_JoystickSensor.py new file mode 100644 index 00000000000..d1dab9afcaf --- /dev/null +++ b/source/gameengine/PyDoc/SCA_JoystickSensor.py @@ -0,0 +1,106 @@ +# $Id: SCA_RandomSensor.py 15444 2008-07-05 17:05:05Z lukep $ +# Documentation for SCA_RandomSensor +from SCA_ISensor import * + +class SCA_JoystickSensor(SCA_ISensor): + """ + This sensor detects player joystick events. + """ + + def getIndex(): + """ + Returns the joystick index to use (from 1 to 8). + @rtype: integer + """ + def setIndex(index): + """ + Sets the joystick index to use. + @param index: The index of this joystick sensor, Clamped between 1 and 8. + @type index: integer + @note: This is only useful when you have more then 1 joystick connected to your computer - multiplayer games. + """ + def getAxis(): + """ + Returns the current axis this sensor reacts to. See L{getAxisValue()<SCA_JoystickSensor.getAxisValue>} for the current axis state. + @rtype: list + @return: 2 values returned are [axisIndex, axisDirection] - see L{setAxis()<SCA_JoystickSensor.setAxis>} for their purpose. + @note: When the "All Events" toggle is set, this option has no effect. + """ + def setAxis(axisIndex, axisDirection): + """ + @param axisIndex: Set the axis index to use when detecting axis movement. + @type axisIndex: integer from 1 to 2 + @param axisDirection: Set the axis direction used for detecting motion. 0:right, 1:up, 2:left, 3:down. + @type axisDirection: integer from 0 to 3 + @note: When the "All Events" toggle is set, this option has no effect. + """ + def getAxisValue(): + """ + Returns the state of the joysticks axis. See differs to L{getAxis()<SCA_JoystickSensor.getAxis>} returning the current state of the joystick. + @rtype: list + @return: 4 values, each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing. + + The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls. + + left:[-32767, 0, ...], right:[32767, 0, ...], up:[0, -32767, ...], down:[0, 32767, ...] + @note: Some gamepads only set the axis on and off like a button. + """ + def getThreshold(): + """ + Get the axis threshold. See L{setThreshold()<SCA_JoystickSensor.setThreshold>} for details. + @rtype: integer + """ + def setThreshold(threshold): + """ + Set the axis threshold. + @param threshold: Joystick axis motion below this threshold wont trigger an event. Use values between (0 and 32767), lower values are more sensitive. + @type threshold: integer + """ + def getButton(): + """ + Returns the button index the sensor reacts to. See L{getButtonValue()<SCA_JoystickSensor.getButtonValue>} for a list of pressed buttons. + @rtype: integer + @note: When the "All Events" toggle is set, this option has no effect. + """ + def setButton(index): + """ + Sets the button index the sensor reacts to when the "All Events" option is not set. + @note: When the "All Events" toggle is set, this option has no effect. + """ + def getButtonValue(): + """ + Returns a list containing the indicies of the currently pressed buttons. + @rtype: list + """ + def getHat(): + """ + Returns the current hat direction this sensor is set to. + [hatNumber, hatDirection]. + @rtype: list + @note: When the "All Events" toggle is set, this option has no effect. + """ + def setHat(index): + """ + Sets the hat index the sensor reacts to when the "All Events" option is not set. + @type index: integer + """ + def getNumAxes(): + """ + Returns the number of axes for the joystick at this index. + @rtype: integer + """ + def getNumButtons(): + """ + Returns the number of buttons for the joystick at this index. + @rtype: integer + """ + def getNumHats(): + """ + Returns the number of hats for the joystick at this index. + @rtype: integer + """ + def isConnected(): + """ + Returns True if a joystick is detected at this joysticks index. + @rtype: bool + """ diff --git a/source/gameengine/PyDoc/epy_docgen.sh b/source/gameengine/PyDoc/epy_docgen.sh index 7fb5e49c996..b243101ddcb 100644 --- a/source/gameengine/PyDoc/epy_docgen.sh +++ b/source/gameengine/PyDoc/epy_docgen.sh @@ -7,5 +7,5 @@ # set posix locale so regex works properly for [A-Z]*.py LC_ALL=POSIX -epydoc -v -o BPY_GE --url "http://www.blender.org" --top GameLogic \ +epydoc --debug -v -o BPY_GE --url "http://www.blender.org" --top GameLogic \ --name "Blender GameEngine" --no-private --no-frames *.py |