[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20326] trunk/blender/source: BGE: GUI control over frame rate, logic rate, physics rate and physics subrate.

Benoit Bolsee benoit.bolsee at online.be
Thu May 21 20:10:32 CEST 2009


Revision: 20326
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20326
Author:   ben2610
Date:     2009-05-21 20:10:19 +0200 (Thu, 21 May 2009)

Log Message:
-----------
BGE: GUI control over frame rate, logic rate, physics rate and physics subrate.

Four new buttons in World settings to control frame rate:
fps:  Nominal frame rate in frame per second.
      Also sets the physics timestep = 1/fps
phys: Maximum number of physics timestep per game frame in case
      the actual fps is less than nominal. This allows the 
      physics to keep up with real time even if the graphics slows
      down the game.
sub:  Fixed number of simulation substeps per physic timestep.
      Improves the precision of the physics simulation. Useful for
      fast moving objects for example.
log:  Maximum number of logic steps per game frame in case the 
      actual fps is less than nominal. This allows the logic
      system to follow the physics simulation. 
      Upper bound = phys 
      (setting the value higher than phys has no effect).
      On games with heavy logic system, it is useful to set this
      value to 1, to keep logic time under control.

All these values were already accessible from Python except phys:

GameLogic.getMaxPhysicsFrame():
	Gets the maximum number of physics frame per render frame.

GameLogic.setMaxPhysicsFrame(phys):
	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.
      phys: integer

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/world.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/makesdna/DNA_world_types.h
    trunk/blender/source/blender/src/buttons_shading.c
    trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp
    trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
    trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.h
    trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp
    trunk/blender/source/gameengine/PyDoc/GameLogic.py

Modified: trunk/blender/source/blender/blenkernel/intern/world.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/world.c	2009-05-21 17:54:45 UTC (rev 20325)
+++ trunk/blender/source/blender/blenkernel/intern/world.c	2009-05-21 18:10:19 UTC (rev 20326)
@@ -109,6 +109,10 @@
 	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;
 }

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2009-05-21 17:54:45 UTC (rev 20325)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2009-05-21 18:10:19 UTC (rev 20326)
@@ -8108,6 +8108,7 @@
 		
 	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 @@
 					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) {

Modified: trunk/blender/source/blender/makesdna/DNA_world_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_world_types.h	2009-05-21 17:54:45 UTC (rev 20325)
+++ trunk/blender/source/blender/makesdna/DNA_world_types.h	2009-05-21 18:10:19 UTC (rev 20326)
@@ -90,6 +90,7 @@
 	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;
 	

Modified: trunk/blender/source/blender/src/buttons_shading.c
===================================================================
--- trunk/blender/source/blender/src/buttons_shading.c	2009-05-21 17:54:45 UTC (rev 20325)
+++ trunk/blender/source/blender/src/buttons_shading.c	2009-05-21 18:10:19 UTC (rev 20326)
@@ -2198,16 +2198,25 @@
 	
 	/* 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 @@
 	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);

Modified: trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2009-05-21 17:54:45 UTC (rev 20325)
+++ trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2009-05-21 18:10:19 UTC (rev 20326)
@@ -2499,6 +2499,8 @@
 		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

Modified: trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.cpp	2009-05-21 17:54:45 UTC (rev 20325)
+++ trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.cpp	2009-05-21 18:10:19 UTC (rev 20326)
@@ -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 @@
 
 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 @@
 
 	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 @@
 //		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 @@
 	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;

Modified: trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.h
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.h	2009-05-21 17:54:45 UTC (rev 20325)
+++ trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.h	2009-05-21 18:10:19 UTC (rev 20326)
@@ -104,6 +104,7 @@
 	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 @@
 	 * 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)

Modified: trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp	2009-05-21 17:54:45 UTC (rev 20325)
+++ trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp	2009-05-21 18:10:19 UTC (rev 20326)
@@ -308,6 +308,21 @@
 	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 @@
 	{"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"},

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list