[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22825] branches/ge_dyn_load: - Support for loading a scene while the game runs

Campbell Barton ideasman42 at gmail.com
Thu Aug 27 21:31:14 CEST 2009


Revision: 22825
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22825
Author:   campbellbarton
Date:     2009-08-27 21:31:14 +0200 (Thu, 27 Aug 2009)

Log Message:
-----------
- Support for loading a scene while the game runs
- Scene merging (merges physics, logic, materials)
- Removing a scene thats been merged

- Not threaded (needed for smooth loading)
- Python api is rough
- Debug prints and checks currently left in.

demo video
http://www.graphicall.org/ftp/ideasman42/dyn_mesh.ogv

Modified Paths:
--------------
    branches/ge_dyn_load/intern/guardedalloc/cpp/mallocn.cpp
    branches/ge_dyn_load/source/gameengine/Converter/BL_BlenderDataConversion.cpp
    branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
    branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_ActuatorEventManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_ActuatorEventManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_ActuatorSensor.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_AlwaysEventManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_AlwaysEventManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_AlwaysSensor.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_DelaySensor.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_EventManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_EventManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_ILogicBrick.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_JoystickManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_JoystickManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_JoystickSensor.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_KeyboardManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_KeyboardManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_KeyboardSensor.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_MouseManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_MouseManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_PropertyEventManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_PropertyEventManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_PropertySensor.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_RandomEventManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_RandomEventManager.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_RandomSensor.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_TimeEventManager.cpp
    branches/ge_dyn_load/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp
    branches/ge_dyn_load/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_BlenderMaterial.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_GameActuator.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_GameObject.cpp
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_KetsjiEngine.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_MouseFocusSensor.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_PolygonMaterial.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_PythonInit.cpp
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_RayEventManager.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_RaySensor.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_Scene.cpp
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_Scene.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_SceneActuator.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_SoundActuator.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_TouchEventManager.cpp
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_TouchEventManager.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_TouchSensor.h
    branches/ge_dyn_load/source/gameengine/Physics/Bullet/CcdGraphicController.h
    branches/ge_dyn_load/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
    branches/ge_dyn_load/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
    branches/ge_dyn_load/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
    branches/ge_dyn_load/source/gameengine/Rasterizer/RAS_BucketManager.cpp
    branches/ge_dyn_load/source/gameengine/Rasterizer/RAS_BucketManager.h
    branches/ge_dyn_load/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
    branches/ge_dyn_load/source/gameengine/Rasterizer/RAS_MeshObject.cpp
    branches/ge_dyn_load/source/gameengine/Rasterizer/RAS_MeshObject.h
    branches/ge_dyn_load/source/gameengine/SceneGraph/SG_IObject.h

Modified: branches/ge_dyn_load/intern/guardedalloc/cpp/mallocn.cpp
===================================================================
--- branches/ge_dyn_load/intern/guardedalloc/cpp/mallocn.cpp	2009-08-27 19:28:36 UTC (rev 22824)
+++ branches/ge_dyn_load/intern/guardedalloc/cpp/mallocn.cpp	2009-08-27 19:31:14 UTC (rev 22825)
@@ -24,9 +24,30 @@
 #include <new>
 #include "../MEM_guardedalloc.h"
 
+// #define DEBUG_NUMBER
+
+#ifdef DEBUG_NUMBER
+#include <stdio.h>
+#include <cstdlib> // for malloc() and free()
+static int counter= 0;
+#endif
+
 void* operator new (size_t size)
 {
+#ifndef DEBUG_NUMBER
 	return MEM_mallocN(size, "c++/anonymous");
+#else
+	
+	
+	/* Option for testing, only enable if you want to find when some memory is allocated */
+	char *str= (char *)malloc(32); // a leak on its own, but only use this for testing
+#if 0
+	if(counter==800)
+		printf("we have a problem\n"); /* useful to insert breakpoints here */
+#endif
+	sprintf(str, "c++/<%d>", counter++);
+	return MEM_mallocN(size, str);
+#endif
 }
 
 /* not default but can be used when needing to set a string */

Modified: branches/ge_dyn_load/source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
--- branches/ge_dyn_load/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2009-08-27 19:28:36 UTC (rev 22824)
+++ branches/ge_dyn_load/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2009-08-27 19:31:14 UTC (rev 22825)
@@ -398,7 +398,7 @@
 
 					if(material->ras_mode & USE_LIGHT)
 						material->ras_mode &= ~USE_LIGHT;
-					if(tface->mode & TF_LIGHT)
+					if(tface->mode & TF_LIGHT || 1)
 						material->ras_mode |= USE_LIGHT;
 
 					valid_index++;
@@ -1059,8 +1059,8 @@
 	return meshobj;
 }
 
+
 	
-	
 static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject)
 {
 	PHY_MaterialProps *materialProps = new PHY_MaterialProps;

Modified: branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
===================================================================
--- branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.cpp	2009-08-27 19:28:36 UTC (rev 22824)
+++ branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.cpp	2009-08-27 19:31:14 UTC (rev 22825)
@@ -40,6 +40,10 @@
 #include "KX_KetsjiEngine.h"
 #include "KX_IPhysicsController.h"
 #include "BL_Material.h"
+#include "KX_BlenderMaterial.h"
+#include "KX_PolygonMaterial.h"
+
+
 #include "SYS_System.h"
 
 #include "DummyPhysicsEnvironment.h"
@@ -78,24 +82,31 @@
 //XXX #include "BSE_editipo_types.h"
 #include "DNA_ipo_types.h"
 #include "BKE_global.h"
+#include "BKE_library.h"
 #include "BKE_ipo.h" // eval_icu
 #include "DNA_space_types.h"
 }
 
+#include "RAS_BucketManager.h" // XXX cant stay
 
 KX_BlenderSceneConverter::KX_BlenderSceneConverter(
 							struct Main* maggie,
 							class KX_KetsjiEngine* engine
 							)
 							: m_maggie(maggie),
+							/*m_maggie_dyn(NULL),*/
 							m_ketsjiEngine(engine),
 							m_alwaysUseExpandFraming(false),
 							m_usemat(false),
 							m_useglslmat(false)
 {
+	tag_main(maggie, 0); /* avoid re-tagging later on */
 	m_newfilename = "";
 }
 
+extern "C" { /* free_main */
+	#include "BKE_library.h"
+}
 
 KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
 {
@@ -141,10 +152,15 @@
 	KX_ClearBulletSharedShapes();
 #endif
 
+	/* free any data that was dynamically loaded */
+	for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
+		Main *main= *it;
+		free_main(main);
+	}
+
+	m_DynamicMaggie.clear();
 }
 
-
-
 void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
 {
 	m_newfilename = filename;
@@ -183,6 +199,14 @@
 		if (name == (sce->id.name+2))
 			return sce;
 
+	for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
+		Main *main= *it;
+
+		for (sce= (Scene*) main->scene.first; sce; sce= (Scene*) sce->id.next)
+			if (name == (sce->id.name+2))
+				return sce;
+	}
+
 	return (Scene*)m_maggie->scene.first;
 
 }
@@ -296,13 +320,16 @@
 #ifdef USE_BULLET
 		case UseBullet:
 			{
+				if (destinationscene->GetPhysicsEnvironment())
+					break;
+
 				CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling);
 				ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw());
 				ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python
 				ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python
 
 				SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
-				int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
+				int visualizePhysics = 0; // SYS_GetCommandLineInt(syshandle,"show_physics",0);
 				if (visualizePhysics)
 					ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints);
 		
@@ -492,7 +519,9 @@
 									RAS_MeshObject *gamemesh,
 									struct Mesh *for_blendermesh)
 {
-	m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
+	if(for_blendermesh) { /* dynamically loaded meshes we dont want to keep lookups for */
+		m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
+	}
 	m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh));
 }
 
@@ -920,3 +949,585 @@
 
 
 }
+
+
+
+
+
+
+
+
+#include "KX_BlenderSceneConverter.h"
+#include "BL_BlenderDataConversion.h"
+#include "KX_MeshProxy.h"
+#include "RAS_MeshObject.h"
+extern "C" {
+	#include "BLO_readfile.h"
+	#include "BKE_report.h"
+	#include "DNA_space_types.h"
+	#include "DNA_windowmanager_types.h" /* report api */
+	#include "../../blender/blenlib/BLI_linklist.h"
+}
+
+
+vector<Main*> &KX_BlenderSceneConverter::GetMainDynamic()
+{
+	return m_DynamicMaggie;
+}
+
+
+bool KX_BlenderSceneConverter::LinkBlendFile(const char *path)
+{
+
+	for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
+		if(strcmp((*it)->name, path)==0) {
+			printf( "blend file alredy open \"%s\"\n", path);
+			return false;
+		}
+	}
+
+	BlendHandle *bpy_openlib = NULL;	/* ptr to the open .blend file */
+	bpy_openlib = BLO_blendhandle_from_file( (char *)path );
+
+	if(bpy_openlib==NULL) {
+		printf( "could not open blendfile\n");
+		return false;
+	}
+
+	char *group, *name;
+	int blocktype = 0;
+	LinkNode *l, *n, *names = NULL;
+	PyObject *list = NULL;
+
+	ReportList reports;
+	Scene *scene= NULL; /* scene CAN be null, its ok! */
+	//Main *maggie= (Main *)MEM_callocN( sizeof(Main), "Main");
+	//Main *maggie= GetMain();
+
+	Main *maggie= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
+	GetMainDynamic().push_back(maggie);
+
+	BKE_reports_init(&reports, RPT_STORE);
+
+	LinkNode *groups = BLO_blendhandle_get_linkable_groups( bpy_openlib );
+	for( l = groups; l; l = l->next ) {
+		blocktype = BLO_idcode_from_name((char *)l->link);
+
+//if(ID_ME==blocktype) {
+if(ID_SCE==blocktype) {
+
+		names = BLO_blendhandle_get_datablock_names( bpy_openlib, blocktype);
+
+
+		int i= 0;
+		for(n= names; n; n= n->next, i++) {
+			BLO_script_library_append(&bpy_openlib, (char *)path, (char *)n->link, blocktype, FILE_LINK, maggie, scene, &reports); /* scene is NULL */
+		}
+
+		BLI_linklist_free(names, free);	/* free linklist *and* each node's data */
+
+}
+
+	}
+	BLI_linklist_free(groups, free);	/* free linklist *and* each node's data */
+
+	BKE_reports_clear(&reports);
+
+
+	/* needed for lookups*/
+	strncpy(maggie->name, path, sizeof(maggie->name));
+
+#if 0
+	ID* mesh;
+	KX_Scene *kx_scene= m_currentScene;
+
+	for(mesh= (ID *)maggie->mesh.first; mesh; mesh= (ID *)mesh->next ) {
+
+		RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, kx_scene, this);
+		kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
+
+		/*
+		KX_MeshProxy* meshproxy = new KX_MeshProxy(meshobj);
+		PyObject *item= meshproxy->NewProxy(true);
+		PyList_Append(ret, item);
+		Py_DECREF(item);
+		*/
+	}
+#endif
+
+
+
+
+
+
+
+
+
+
+	{
+
+		ID *scene;
+
+		for(scene= (ID *)maggie->scene.first; scene; scene= (ID *)scene->next ) {
+			//KX_Scene *kx_scene_new = m_ketsjiEngine->CreateScene(scene);
+
+			printf("ES: %s\n", scene->name);
+
+			/*GetBlenderSceneForName looks up the m_maggie_dyn now */
+
+			if (0) {
+				m_ketsjiEngine->ConvertAndAddScene(scene->name+2, true);
+			}
+			else if(0) { // WORSK NICE BUT USES HACK
+				KX_Scene *kx_scene= m_ketsjiEngine->CurrentScenes()->at(0); //XXX hack
+
+				PHY_IPhysicsEnvironment *physEnv = kx_scene->GetPhysicsEnvironment();
+
+				KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene, physEnv);
+
+				kx_scene->MergeScene(other);
+
+				other->SetPhysicsEnvironment(NULL);
+				//
+				other= NULL;
+			}
+			else {
+				// m_ketsjiEngine->AddScene();
+
+				/* attempt propper merge */
+				KX_Scene *kx_scene= m_ketsjiEngine->CurrentScenes()->at(0); //XXX hack
+				KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene);
+
+				kx_scene->MergeScene(other);
+
+				// RemoveScene(other); // Dont run this, it frees the entire scene converter data.
+				// just delete the scene
+
+				delete other;
+			}
+		}
+	}
+
+	BLO_blendhandle_close( bpy_openlib );
+	// free_main(maggie); // keep as long as the scene is loaded.
+
+
+#if 0
+	PyObject *callback= NULL;
+
+	if (!PyArg_ParseTuple(args,"s|O:LoadLibrary",&path, &callback))
+		return NULL;
+
+	if(callback && !PyCallable_Check(callback)) {
+		PyErr_SetString(PyExc_TypeError, "expected a callable second arg");
+		return NULL;
+	}
+
+	BlendHandle *bpy_openlib = NULL;	/* ptr to the open .blend file */
+	bpy_openlib = BLO_blendhandle_from_file( path );
+
+	if(bpy_openlib==NULL) {
+		PyErr_SetString(PyExc_TypeError, "could not open blendfile");
+		return NULL;
+	}
+
+	/* Create args from library data */
+	PyObject *dict_arg= PyDict_New();
+
+
+	char *group, *name;
+	int blocktype = 0;
+	LinkNode *l, *n, *names = NULL;
+	PyObject *list = NULL;
+
+	LinkNode *groups = BLO_blendhandle_get_linkable_groups( bpy_openlib );
+	for( l = groups; l; l = l->next ) {
+		blocktype = BLO_idcode_from_name((char *)l->next);
+		names = BLO_blendhandle_get_datablock_names( bpy_openlib, blocktype);
+
+		list= PyList_New(BLI_linklist_length(names));
+		PyDict_SetItemString(dict_arg, (char*)l->link, list);
+
+		int i= 0;
+		for(n= names; n; n= n->next, i++)
+			PyList_SET_ITEM( list, i, PyUnicode_FromString((char *)n->link));
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list