[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40059] branches/hive/source/gameengine: Initial commit of patch that gives main loop control to Python

Sjoerd de Vries sjdv1982 at gmail.com
Fri Sep 9 12:22:29 CEST 2011


Revision: 40059
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40059
Author:   sjoerddevries
Date:     2011-09-09 10:22:28 +0000 (Fri, 09 Sep 2011)
Log Message:
-----------
Initial commit of patch that gives main loop control to Python

Modified Paths:
--------------
    branches/hive/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
    branches/hive/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
    branches/hive/source/gameengine/Ketsji/CMakeLists.txt
    branches/hive/source/gameengine/Ketsji/KX_PythonInit.cpp
    branches/hive/source/gameengine/Ketsji/KX_PythonInit.h

Added Paths:
-----------
    branches/hive/source/gameengine/Ketsji/KX_PythonMain.cpp
    branches/hive/source/gameengine/Ketsji/KX_PythonMain.h

Modified: branches/hive/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
===================================================================
--- branches/hive/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp	2011-09-09 10:15:14 UTC (rev 40058)
+++ branches/hive/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp	2011-09-09 10:22:28 UTC (rev 40059)
@@ -56,6 +56,7 @@
 #include "KX_BlenderSceneConverter.h"
 #include "KX_PythonInit.h"
 #include "KX_PyConstraintBinding.h"
+#include "KX_PythonMain.h"
 
 #include "RAS_GLExtensionManager.h"
 #include "RAS_OpenGLRasterizer.h"
@@ -81,6 +82,9 @@
 #include "DNA_windowmanager_types.h"
 #include "BKE_global.h"
 #include "BKE_report.h"
+
+#include "MEM_guardedalloc.h"
+
 /* #include "BKE_screen.h" */ /* cant include this because of 'new' function name */
 extern float BKE_screen_view3d_zoom_to_fac(float camzoom);
 
@@ -114,7 +118,7 @@
 {
 	ReportList reports;
 	BlendFileData *bfd;
-	
+
 	BKE_reports_init(&reports, RPT_STORE);
 	bfd= BLO_read_from_file(filename, &reports);
 
@@ -128,6 +132,89 @@
 	return bfd;
 }
 
+int BL_KetsjiNextFrame(struct KX_KetsjiEngine* ketsjiengine, struct bContext *C, struct wmWindow* win, struct Scene* scene, struct ARegion *ar,
+                    KX_BlenderKeyboardDevice* keyboarddevice, KX_BlenderMouseDevice* mousedevice, int draw_letterbox)
+{
+    int exitrequested;
+
+    // first check if we want to exit
+    exitrequested = ketsjiengine->GetExitCode();
+
+    // kick the engine
+    bool render = ketsjiengine->NextFrame();
+
+    if (render)
+    {
+        if(draw_letterbox) {
+            // Clear screen to border color
+            // We do this here since we set the canvas to be within the frames. This means the engine
+            // itself is unaware of the extra space, so we clear the whole region for it.
+            glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f);
+            glViewport(ar->winrct.xmin, ar->winrct.ymin,
+                ar->winrct.xmax - ar->winrct.xmin, ar->winrct.ymax - ar->winrct.ymin);
+            glClear(GL_COLOR_BUFFER_BIT);
+        }
+
+        // render the frame
+        ketsjiengine->Render();
+    }
+
+    wm_window_process_events_nosleep();
+
+    // test for the ESC key
+    //XXX while (qtest())
+    while(wmEvent *event= (wmEvent *)win->queue.first)
+    {
+        short val = 0;
+        //unsigned short event = 0; //XXX extern_qread(&val);
+
+        if (keyboarddevice->ConvertBlenderEvent(event->type,event->val))
+            exitrequested = KX_EXIT_REQUEST_BLENDER_ESC;
+
+            /* Coordinate conversion... where
+            * should this really be?
+        */
+        if (event->type==MOUSEMOVE) {
+            /* Note, not nice! XXX 2.5 event hack */
+            val = event->x - ar->winrct.xmin;
+            mousedevice->ConvertBlenderEvent(MOUSEX, val);
+
+            val = ar->winy - (event->y - ar->winrct.ymin) - 1;
+            mousedevice->ConvertBlenderEvent(MOUSEY, val);
+        }
+        else {
+            mousedevice->ConvertBlenderEvent(event->type,event->val);
+        }
+
+        BLI_remlink(&win->queue, event);
+        wm_event_free(event);
+    }
+
+    if(win != CTX_wm_window(C)) {
+        exitrequested= KX_EXIT_REQUEST_OUTSIDE; /* window closed while bge runs */
+    }
+    return exitrequested;
+}
+
+struct BL_KetsjiNextFrameState {
+	struct KX_KetsjiEngine* ketsjiengine;
+	struct bContext *C;
+	struct wmWindow* win;
+	struct Scene* scene;
+	struct ARegion *ar;
+        KX_BlenderKeyboardDevice* keyboarddevice;
+	KX_BlenderMouseDevice* mousedevice;
+	int draw_letterbox;
+} ketsjinextframestate;
+
+int BL_KetsjiPyNextFrame(void *state0) {
+	BL_KetsjiNextFrameState *state = (BL_KetsjiNextFrameState *) state0;
+	return BL_KetsjiNextFrame(
+		state->ketsjiengine, state->C, state->win, state->scene, state->ar,
+		state->keyboarddevice, state->mousedevice, state->draw_letterbox
+		);
+}
+
 extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing)
 {
 	/* context values */
@@ -159,10 +246,10 @@
 	// Acquire Python's GIL (global interpreter lock)
 	// so we can safely run Python code and API calls
 	PyGILState_STATE gilstate = PyGILState_Ensure();
-	
+
 	PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */
 #endif
-	
+
 	bgl::InitExtensions(true);
 
 	// VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable
@@ -193,7 +280,7 @@
 
 		// create the canvas, rasterizer and rendertools
 		RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar);
-		
+
 		// default mouse state set on render panel
 		if (mouse_state)
 			canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
@@ -201,7 +288,7 @@
 			canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
 		RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
 		RAS_IRasterizer* rasterizer = NULL;
-		
+
 		if(displaylists) {
 			if (GLEW_VERSION_1_1 && !novertexarrays)
 				rasterizer = new RAS_ListRasterizer(canvas, true, true);
@@ -212,11 +299,11 @@
 			rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
 		else
 			rasterizer = new RAS_OpenGLRasterizer(canvas);
-		
+
 		// create the inputdevices
 		KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
 		KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();
-		
+
 		// create a networkdevice
 		NG_NetworkDeviceInterface* networkdevice = new
 			NG_LoopBackNetworkDeviceInterface();
@@ -224,10 +311,10 @@
 		//
 		// create a ketsji/blendersystem (only needed for timing and stuff)
 		KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
-		
+
 		// create the ketsjiengine
 		KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem);
-		
+
 		// set the devices
 		ketsjiengine->SetKeyboardDevice(keyboarddevice);
 		ketsjiengine->SetMouseDevice(mousedevice);
@@ -255,7 +342,7 @@
 		// some blender stuff
 		float camzoom;
 		int draw_letterbox = 0;
-		
+
 		if(rv3d->persp==RV3D_CAMOB) {
 			if(startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */
 				camzoom = 1.0f;
@@ -272,13 +359,13 @@
 
 		ketsjiengine->SetDrawType(v3d->drawtype);
 		ketsjiengine->SetCameraZoom(camzoom);
-		
+
 		// if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
 		if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME)
 		{
 			exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
 			if (bfd) BLO_blendfiledata_free(bfd);
-			
+
 			char basedpath[240];
 			// base the actuator filename with respect
 			// to the original file working directory
@@ -292,7 +379,7 @@
 			// that happened to be loaded first
 			BLI_path_abs(basedpath, pathname);
 			bfd = load_game_data(basedpath);
-			
+
 			// if it wasn't loaded, try it forced relative
 			if (!bfd)
 			{
@@ -300,11 +387,11 @@
 				char temppath[242];
 				strcpy(temppath, "//");
 				strcat(temppath, basedpath);
-				
+
 				BLI_path_abs(temppath, pathname);
 				bfd = load_game_data(temppath);
 			}
-			
+
 			// if we got a loaded blendfile, proceed
 			if (bfd)
 			{
@@ -332,7 +419,7 @@
 		{
 			int startFrame = scene->r.cfra;
 			ketsjiengine->SetAnimRecordMode(animation_record, startFrame);
-			
+
 			// Quad buffered needs a special window.
 			if(scene->gm.stereoflag == STEREO_ENABLED){
 				if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
@@ -343,7 +430,8 @@
 
 			rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f);
 		}
-		
+
+		char *python_main = NULL;
 		if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
 		{
 			if (rv3d->persp != RV3D_CAMOB)
@@ -355,7 +443,7 @@
 				ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
 				ketsjiengine->SetCameraOverrideLens(v3d->lens);
 			}
-			
+
 			// create a scene converter, create and convert the startingscene
 			KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
 			ketsjiengine->SetSceneConverter(sceneconverter);
@@ -377,7 +465,7 @@
 				sceneconverter->SetMaterials(true);
 			if(useglslmat && (scene->gm.matmode == GAME_MAT_GLSL))
 				sceneconverter->SetGLSLMaterials(true);
-					
+
 			KX_Scene* startscene = new KX_Scene(keyboarddevice,
 				mousedevice,
 				networkdevice,
@@ -418,84 +506,62 @@
 					rendertools,
 					canvas);
 				ketsjiengine->AddScene(startscene);
-				
+
 				// init the rasterizer
 				rasterizer->Init();
-				
+
 				// start the engine
 				ketsjiengine->StartEngine(true);
-				
 
+
 				// Set the animation playback rate for ipo's and actions
 				// the framerate below should patch with FPS macro defined in blendef.h
 				// Could be in StartEngine set the framerate, we need the scene to do this
 				ketsjiengine->SetAnimFrameRate(FPS);
-				
+
+                        	char *python_main = NULL;
+				pynextframestate.state = NULL;
+				pynextframestate.func = NULL;
+#ifdef WITH_PYTHON
+                        	python_main = KX_GetPythonMain(scene);
+#endif // WITH_PYTHON
+
 				// the mainloop
 				printf("\nBlender Game Engine Started\n");
-				while (!exitrequested)
-				{
-					// first check if we want to exit
-					exitrequested = ketsjiengine->GetExitCode();
-					
-					// kick the engine
-					bool render = ketsjiengine->NextFrame();
-					
-					if (render)
+				if (python_main) {
+                            		char *python_code = KX_GetPythonCode(blenderdata, python_main);
+                            		if (python_code) {
+#ifdef WITH_PYTHON			    
+						ketsjinextframestate.ketsjiengine = ketsjiengine;
+						ketsjinextframestate.C = C;
+						ketsjinextframestate.win = win;
+						ketsjinextframestate.scene = scene;
+						ketsjinextframestate.ar = ar;
+					        ketsjinextframestate.keyboarddevice = keyboarddevice;
+						ketsjinextframestate.mousedevice = mousedevice;
+						ketsjinextframestate.draw_letterbox = draw_letterbox;
+			
+						pynextframestate.state = &ketsjinextframestate;
+						pynextframestate.func = &BL_KetsjiPyNextFrame;			
+                                		printf("Yielding control to Python script '%s'...\n", python_main);
+                                		PyRun_SimpleString(python_code);
+                                		printf("Exit Python script '%s'\n", python_main);
+#endif // WITH_PYTHON				
+                                		MEM_freeN(python_code);
+					}				
+				}
+				else {
+					while (!exitrequested)
 					{

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list