diff options
-rw-r--r-- | source/blender/blenkernel/intern/world.c | 4 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 7 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_world_types.h | 1 | ||||
-rw-r--r-- | source/blender/src/buttons_shading.c | 17 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 2 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 36 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_KetsjiEngine.h | 9 | ||||
-rw-r--r-- | source/gameengine/Ketsji/KX_PythonInit.cpp | 17 | ||||
-rw-r--r-- | source/gameengine/PyDoc/GameLogic.py | 19 |
9 files changed, 102 insertions, 10 deletions
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 6635ef29d51..d47f4efeb4e 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -109,6 +109,10 @@ World *add_world(char *name) wrld->mode = WO_DBVT_CULLING; // DBVT culling by default wrld->occlusionRes = 128; wrld->preview = NULL; + wrld->ticrate = 60; + wrld->maxlogicstep = 5; + wrld->physubstep = 1; + wrld->maxphystep = 5; return wrld; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 25c8a928a3b..bda0348f2ca 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8108,6 +8108,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 5)) { Object *ob; + World *wrld; for(ob = main->object.first; ob; ob= ob->id.next) { if(ob->parent) { /* check if top parent has compound shape set and if yes, set this object @@ -8120,6 +8121,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ob->gameflag |= OB_CHILD; } } + for(wrld=main->world.first; wrld; wrld= wrld->id.next) { + wrld->ticrate = 60; + wrld->maxlogicstep = 5; + wrld->physubstep = 1; + wrld->maxphystep = 5; + } } if (main->versionfile < 249) { diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index f599364ed66..5f6e47acac4 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -90,6 +90,7 @@ typedef struct World { short mode; short occlusionRes; /* resolution of occlusion Z buffer in pixel */ short physicsEngine; /* here it's aligned */ + short ticrate, maxlogicstep, physubstep, maxphystep; float misi, miststa, mistdist, misthi; diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 79f95d1bf5f..12219944945 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -2198,16 +2198,25 @@ static void world_panel_mistaph(World *wrld) /* Gravitation for the game worlds */ uiDefButF(block, NUMSLI,0, "Grav ", 150,180,150,19, &(wrld->gravity), 0.0, 25.0, 0, 0, "Sets the gravitation constant of the game world"); + uiDefButS(block, NUM, B_REDR, "fps:", + 10, 160, 70, 19, &wrld->ticrate, 1.0, 120.0, 0, 0, "Sets the nominal number of game frames per second. Physics fixed timestep = 1/fps, independently of actual frame rate"); + uiDefButS(block, NUM, B_REDR, "log:", + 80, 160, 70, 19, &wrld->maxlogicstep, 1.0, 5.0, 0, 0, "Sets the maxmimum number of logic frame per game frame if graphics slows down the game, higher value allows better synchronization with physics"); + uiDefButS(block, NUM, B_REDR, "phys:", + 150, 160, 75, 19, &wrld->maxphystep, 1.0, 5.0, 0, 0, "Sets the maximum number of physics step per game frame if graphics slows down the game, higher value allows physics to keep up with realtime"); + uiDefButS(block, NUM, B_REDR, "sub:", + 225, 160, 75, 19, &wrld->physubstep, 1.0, 5.0, 0, 0, "Sets the number of simulation substep per physic timestep, higher value give better physics precision"); + if (wrld->physicsEngine == WOPHY_BULLET) { - uiDefButBitS(block, TOG, WO_DBVT_CULLING, B_REDR, "DBVT culling", 10,160,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles use of optimized Bullet DBVT tree for view frustrum and occlusion culling"); + uiDefButBitS(block, TOG, WO_DBVT_CULLING, B_REDR, "DBVT culling", 10,140,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles use of optimized Bullet DBVT tree for view frustrum and occlusion culling"); if (wrld->mode & WO_DBVT_CULLING) uiDefButS(block, NUM, B_REDR, "Occlu Res:", - 150, 160, 150, 19, &wrld->occlusionRes, 128.0, 1024.0, 0, 0, "Sets the size of the occlusion buffer in pixel, use higher value for better precsion (slower)"); + 150, 140, 150, 19, &wrld->occlusionRes, 128.0, 1024.0, 0, 0, "Sets the size of the occlusion buffer in pixel, use higher value for better precsion (slower)"); } #endif uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitS(block, TOG, WO_MIST, B_WORLDPRV2,"Mist", 10,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles mist simulation"); + uiDefButBitS(block, TOG, WO_MIST, B_WORLDPRV2,"Mist", 10,115,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles mist simulation"); uiBlockSetCol(block, TH_AUTO); uiBlockBeginAlign(block); @@ -2222,7 +2231,7 @@ static void world_panel_mistaph(World *wrld) uiBlockEndAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitS(block, TOG, WO_STARS, B_WORLDPRV2, "Stars",160,120,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles starfield generation"); + uiDefButBitS(block, TOG, WO_STARS, B_WORLDPRV2, "Stars",160,115,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles starfield generation"); uiBlockSetCol(block, TH_AUTO); uiBlockBeginAlign(block); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 82edd4f218b..f3024197a8a 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -2499,6 +2499,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if (occlusion) kxscene->SetDbvtOcclusionRes(blenderscene->world->occlusionRes); } + if (blenderscene->world) + kxscene->GetPhysicsEnvironment()->setNumTimeSubSteps(blenderscene->world->physubstep); // now that the scenegraph is complete, let's instantiate the deformers. // We need that to create reusable derived mesh and physic shapes diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 4107ed7d82e..983059d0c70 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -77,6 +77,8 @@ #include "RAS_FramingManager.h" #include "stdio.h" +#include "DNA_world_types.h" +#include "DNA_scene_types.h" // If define: little test for Nzc: guarded drawing. If the canvas is // not valid, skip rendering this frame. @@ -98,6 +100,7 @@ const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = { double KX_KetsjiEngine::m_ticrate = DEFAULT_LOGIC_TIC_RATE; int KX_KetsjiEngine::m_maxLogicFrame = 5; +int KX_KetsjiEngine::m_maxPhysicsFrame = 5; double KX_KetsjiEngine::m_anim_framerate = 25.0; double KX_KetsjiEngine::m_suspendedtime = 0.0; double KX_KetsjiEngine::m_suspendeddelta = 0.0; @@ -393,8 +396,20 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo) m_firstframe = true; m_bInitialized = true; - m_ticrate = DEFAULT_LOGIC_TIC_RATE; - m_maxLogicFrame = 5; + // there is always one scene enabled at startup + World* world = m_scenes[0]->GetBlenderScene()->world; + if (world) + { + m_ticrate = world->ticrate; + m_maxLogicFrame = world->maxlogicstep; + m_maxPhysicsFrame = world->maxphystep; + } + else + { + m_ticrate = DEFAULT_LOGIC_TIC_RATE; + m_maxLogicFrame = 5; + m_maxPhysicsFrame = 5; + } if (m_game2ipo) { @@ -545,14 +560,13 @@ else // PIL_sleep_ms(1); KX_SceneList::iterator sceneit; - int frameOut = 5; - if (frames>frameOut) + if (frames>m_maxPhysicsFrame) { // printf("framedOut: %d\n",frames); - m_frameTime+=(frames-frameOut)*timestep; - frames = frameOut; + m_frameTime+=(frames-m_maxPhysicsFrame)*timestep; + frames = m_maxPhysicsFrame; } @@ -1736,6 +1750,16 @@ void KX_KetsjiEngine::SetMaxLogicFrame(int frame) m_maxLogicFrame = frame; } +int KX_KetsjiEngine::GetMaxPhysicsFrame() +{ + return m_maxPhysicsFrame; +} + +void KX_KetsjiEngine::SetMaxPhysicsFrame(int frame) +{ + m_maxPhysicsFrame = frame; +} + double KX_KetsjiEngine::GetAnimFrameRate() { return m_anim_framerate; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index cc9b9198db7..5c14c63dd04 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -104,6 +104,7 @@ private: double m_remainingTime; static int m_maxLogicFrame; /* maximum number of consecutive logic frame */ + static int m_maxPhysicsFrame; /* maximum number of consecutive physics frame */ static double m_ticrate; static double m_anim_framerate; /* for animation playback only - ipo and action */ @@ -292,6 +293,14 @@ public: * Sets the maximum number of logic frame before render frame */ static void SetMaxLogicFrame(int frame); + /** + * Gets the maximum number of physics frame before render frame + */ + static int GetMaxPhysicsFrame(); + /** + * Sets the maximum number of physics frame before render frame + */ + static void SetMaxPhysicsFrame(int frame); /** * Gets the framerate for playing animations. (actions and ipos) diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index fb99eab7747..3626d7baa9a 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -308,6 +308,21 @@ static PyObject* gPyGetMaxLogicFrame(PyObject*) return PyInt_FromLong(KX_KetsjiEngine::GetMaxLogicFrame()); } +static PyObject* gPySetMaxPhysicsFrame(PyObject*, PyObject* args) +{ + int frame; + if (!PyArg_ParseTuple(args, "i:setMaxPhysicsFrame", &frame)) + return NULL; + + KX_KetsjiEngine::SetMaxPhysicsFrame(frame); + Py_RETURN_NONE; +} + +static PyObject* gPyGetMaxPhysicsFrame(PyObject*) +{ + return PyInt_FromLong(KX_KetsjiEngine::GetMaxPhysicsFrame()); +} + static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args) { float ticrate; @@ -501,6 +516,8 @@ static struct PyMethodDef game_methods[] = { {"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS, (PY_METHODCHAR)"stop using the audio dsp (for performance reasons)"}, {"getMaxLogicFrame", (PyCFunction) gPyGetMaxLogicFrame, METH_NOARGS, (PY_METHODCHAR)"Gets the max number of logic frame per render frame"}, {"setMaxLogicFrame", (PyCFunction) gPySetMaxLogicFrame, METH_VARARGS, (PY_METHODCHAR)"Sets the max number of logic frame per render frame"}, + {"getMaxPhysicsFrame", (PyCFunction) gPyGetMaxPhysicsFrame, METH_NOARGS, (PY_METHODCHAR)"Gets the max number of physics frame per render frame"}, + {"setMaxPhysicsFrame", (PyCFunction) gPySetMaxPhysicsFrame, METH_VARARGS, (PY_METHODCHAR)"Sets the max number of physics farme per render frame"}, {"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the logic tic rate"}, {"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, (PY_METHODCHAR)"Sets the logic tic rate"}, {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the physics tic rate"}, diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py index 1bc406daf09..3ec30a63c58 100644 --- a/source/gameengine/PyDoc/GameLogic.py +++ b/source/gameengine/PyDoc/GameLogic.py @@ -387,6 +387,23 @@ def setMaxLogicFrame(maxlogic): @param maxlogic: The new maximum number of logic frame per render frame. Valid values: 1..5 @type maxlogic: integer """ +def getMaxPhysicsFrame(): + """ + Gets the maximum number of physics frame per render frame. + + @return: The maximum number of physics frame per render frame + @rtype: interger + """ +def setMaxPhysicsFrame(maxphysics): + """ + Sets the maximum number of physics timestep that are executed per render frame. + Higher value allows physics to keep up with realtime even if graphics slows down the game. + Physics timestep is fixed and equal to 1/tickrate (see setLogicTicRate) + maxphysics/ticrate is the maximum delay of the renderer that physics can compensate. + + @param maxphysics: The new maximum number of physics timestep per render frame. Valid values: 1..5. + @type maxphysics: integer + """ def getLogicTicRate(): """ Gets the logic update frequency. @@ -406,6 +423,7 @@ def setLogicTicRate(ticrate): """ def getPhysicsTicRate(): """ + NOT IMPLEMENTED Gets the physics update frequency @return: The physics update frequency in Hz @@ -413,6 +431,7 @@ def getPhysicsTicRate(): """ def setPhysicsTicRate(ticrate): """ + NOT IMPLEMENTED Sets the physics update frequency The physics update frequency is the number of times the physics system is executed every second. |