[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24578] trunk/blender/source/gameengine: BGE: dynamic loading patch commited.

Benoit Bolsee benoit.bolsee at online.be
Mon Nov 16 00:58:56 CET 2009


Revision: 24578
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24578
Author:   ben2610
Date:     2009-11-16 00:58:56 +0100 (Mon, 16 Nov 2009)

Log Message:
-----------
BGE: dynamic loading patch commited. API and demo files available here: https://projects.blender.org/tracker/?func=detail&aid=19492&group_id=9&atid=127

Modified Paths:
--------------
    trunk/blender/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
    trunk/blender/source/gameengine/Converter/KX_BlenderSceneConverter.h
    trunk/blender/source/gameengine/GameLogic/SCA_EventManager.h
    trunk/blender/source/gameengine/GameLogic/SCA_ILogicBrick.h
    trunk/blender/source/gameengine/GameLogic/SCA_ISensor.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_ISensor.h
    trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.cpp
    trunk/blender/source/gameengine/GameLogic/SCA_LogicManager.h
    trunk/blender/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
    trunk/blender/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
    trunk/blender/source/gameengine/Ketsji/KX_BlenderMaterial.h
    trunk/blender/source/gameengine/Ketsji/KX_GameActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameActuator.h
    trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
    trunk/blender/source/gameengine/Ketsji/KX_KetsjiEngine.h
    trunk/blender/source/gameengine/Ketsji/KX_MouseFocusSensor.h
    trunk/blender/source/gameengine/Ketsji/KX_PolygonMaterial.h
    trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp
    trunk/blender/source/gameengine/Ketsji/KX_RaySensor.h
    trunk/blender/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
    trunk/blender/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
    trunk/blender/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
    trunk/blender/source/gameengine/Ketsji/KX_Scene.cpp
    trunk/blender/source/gameengine/Ketsji/KX_Scene.h
    trunk/blender/source/gameengine/Ketsji/KX_SceneActuator.h
    trunk/blender/source/gameengine/Ketsji/KX_TouchEventManager.h
    trunk/blender/source/gameengine/Ketsji/KX_TouchSensor.h
    trunk/blender/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
    trunk/blender/source/gameengine/Physics/Bullet/CcdGraphicController.h
    trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
    trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsController.h
    trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
    trunk/blender/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
    trunk/blender/source/gameengine/Physics/common/PHY_IController.h
    trunk/blender/source/gameengine/Physics/common/PHY_IGraphicController.h
    trunk/blender/source/gameengine/Physics/common/PHY_IPhysicsController.h
    trunk/blender/source/gameengine/Rasterizer/RAS_BucketManager.cpp
    trunk/blender/source/gameengine/Rasterizer/RAS_BucketManager.h
    trunk/blender/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
    trunk/blender/source/gameengine/Rasterizer/RAS_MeshObject.cpp
    trunk/blender/source/gameengine/Rasterizer/RAS_MeshObject.h
    trunk/blender/source/gameengine/SceneGraph/SG_IObject.h

Modified: trunk/blender/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/KX_BlenderSceneConverter.cpp	2009-11-15 23:48:21 UTC (rev 24577)
+++ trunk/blender/source/gameengine/Converter/KX_BlenderSceneConverter.cpp	2009-11-15 23:58:56 UTC (rev 24578)
@@ -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"
@@ -72,27 +76,48 @@
 {
 #include "DNA_object_types.h"
 #include "DNA_curve_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_material_types.h"
 #include "BLI_blenlib.h"
 #include "MEM_guardedalloc.h"
 //XXX #include "BSE_editipo.h"
 //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 "BKE_material.h" // copy_material
+#include "BKE_mesh.h" // copy_mesh
 #include "DNA_space_types.h"
 }
 
+/* Only for dynamic loading and merging */
+#include "RAS_BucketManager.h" // XXX cant stay
+#include "KX_BlenderSceneConverter.h"
+#include "BL_BlenderDataConversion.h"
+#include "KX_MeshProxy.h"
+#include "RAS_MeshObject.h"
+extern "C" {
+	#include "BKE_context.h"
+	#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"
+}
 
 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 = "";
 }
 
@@ -141,10 +166,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 +213,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;
 
 }
@@ -490,7 +528,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));
 }
 
@@ -925,3 +965,480 @@
 	return m_ketsjiEngine->GetPyNamespace();
 }
 #endif
+
+vector<Main*> &KX_BlenderSceneConverter::GetMainDynamic()
+{
+	return m_DynamicMaggie;
+}
+
+Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path)
+{
+	for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++)
+		if(strcmp((*it)->name, path)==0)
+			return *it;
+	
+	return NULL;
+}
+
+bool KX_BlenderSceneConverter::LinkBlendFile(const char *path, char *group, KX_Scene *scene_merge, char **err_str)
+{
+	bContext *C;
+	Main *main_newlib; /* stored as a dynamic 'main' until we free it */
+	Main *main_tmp= NULL; /* created only for linking, then freed */
+	LinkNode *names = NULL;
+	BlendHandle *bpy_openlib = NULL;	/* ptr to the open .blend file */	
+	int idcode= BLO_idcode_from_name(group);
+	short flag= 0; /* dont need any special options */
+	ReportList reports;
+	static char err_local[255];
+	
+	/* only scene and mesh supported right now */
+	if(idcode!=ID_SCE && idcode!=ID_ME) {
+		snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group);
+		return false;
+	}
+	
+	if(GetMainDynamicPath(path)) {
+		snprintf(err_local, sizeof(err_local), "blend file alredy open \"%s\"\n", path);
+		*err_str= err_local;
+		return false;
+	}
+
+	bpy_openlib = BLO_blendhandle_from_file( (char *)path );
+	if(bpy_openlib==NULL) {
+		snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path);
+		*err_str= err_local;
+		return false;
+	}
+	
+	main_newlib= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
+	C= CTX_create();
+	CTX_data_main_set(C, main_newlib);
+	BKE_reports_init(&reports, RPT_STORE);	
+
+	/* here appending/linking starts */
+	main_tmp = BLO_library_append_begin(C, &bpy_openlib, (char *)path);
+	
+	names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode);
+	
+	int i=0;
+	LinkNode *n= names;
+	while(n) {
+		BLO_library_append_named_part(C, main_tmp, &bpy_openlib, (char *)n->link, idcode, 0);
+		n= (LinkNode *)n->next;
+		i++;
+	}
+	BLI_linklist_free(names, free);	/* free linklist *and* each node's data */
+	
+	BLO_library_append_end(C, main_tmp, &bpy_openlib, idcode, flag);
+	BLO_blendhandle_close(bpy_openlib);
+	
+	CTX_free(C);
+	BKE_reports_clear(&reports);
+	/* done linking */	
+	
+	/* needed for lookups*/
+	GetMainDynamic().push_back(main_newlib);
+	strncpy(main_newlib->name, path, sizeof(main_newlib->name));	
+	
+	
+	if(idcode==ID_ME) {
+		/* Convert all new meshes into BGE meshes */
+		ID* mesh;
+		KX_Scene *kx_scene= m_currentScene;
+	
+		for(mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) {
+			RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this);
+			kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
+		}
+	}
+	else if(idcode==ID_SCE) {		
+		/* Merge all new linked in scene into the existing one */
+		ID *scene;
+		for(scene= (ID *)main_newlib->scene.first; scene; scene= (ID *)scene->next ) {
+			printf("SceneName: %s\n", scene->name);
+			
+			/* merge into the base  scene */
+			KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene);
+			scene_merge->MergeScene(other);
+			
+			// RemoveScene(other); // Dont run this, it frees the entire scene converter data, just delete the scene
+			delete other;
+		}
+	}
+	
+	return true;
+}
+
+/* Note m_map_*** are all ok and dont need to be freed
+ * most are temp and NewRemoveObject frees m_map_gameobject_to_blender */
+bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
+{
+	int maggie_index;
+	int i=0;
+
+	if(maggie==NULL)
+		return false;
+	
+	/* tag all false except the one we remove */
+	for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
+		Main *main= *it;
+		if(main != maggie) {
+			tag_main(main, 0);
+		}
+		else {
+			maggie_index= i;
+		}
+		i++;
+	}
+
+	m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index);
+	tag_main(maggie, 1);
+
+
+	/* free all tagged objects */
+	KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
+	int numScenes = scenes->size();
+
+
+	for (int scene_idx=0;scene_idx<numScenes;scene_idx++)
+	{
+		KX_Scene* scene = scenes->at(scene_idx);
+		if(IS_TAGGED(scene->GetBlenderScene())) {
+			RemoveScene(scene); // XXX - not tested yet
+			scene_idx--;
+			numScenes--;
+		}
+		else {
+			
+			/* incase the mesh might be refered to later */
+			{
+				GEN_Map<STR_HashedString,void*> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap();
+				
+				for(int i=0; i<mapStringToMeshes.size(); i++)
+				{
+					RAS_MeshObject *meshobj= (RAS_MeshObject *) *mapStringToMeshes.at(i);
+					if(meshobj && IS_TAGGED(meshobj->GetMesh()))
+					{	
+						STR_HashedString mn = meshobj->GetName();
+						mapStringToMeshes.remove(mn);
+						i--;
+					}
+				}
+			}
+			
+			//scene->FreeTagged(); /* removed tagged objects and meshes*/
+			CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL};
+
+			for(int ob_ls_idx=0; obj_lists[ob_ls_idx]; ob_ls_idx++)
+			{
+				CListValue *obs= obj_lists[ob_ls_idx];
+				RAS_MeshObject* mesh;
+
+				for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++)
+				{
+					KX_GameObject* gameobj = (KX_GameObject*)obs->GetValue(ob_idx);
+					if(IS_TAGGED(gameobj->GetBlenderObject())) {
+
+						int size_before = obs->GetCount();
+
+						/* Eventually calls RemoveNodeDestructObject
+						 * frees m_map_gameobject_to_blender from UnregisterGameObject */
+						scene->RemoveObject(gameobj);
+
+						if(size_before != obs->GetCount())
+							ob_idx--;
+						else {
+							printf("ERROR COULD NOT REMOVE \"%s\"\n", gameobj->GetName().ReadPtr());
+						}
+					}
+					else {
+						/* free the mesh, we could be referecing a linked one! */
+						int mesh_index= gameobj->GetMeshCount();
+						while(mesh_index--) {
+							mesh= gameobj->GetMesh(mesh_index);
+							if(IS_TAGGED(mesh->GetMesh())) {
+								gameobj->RemoveMeshes(); /* XXX - slack, should only remove meshes that are library items but mostly objects only have 1 mesh */
+								break;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+
+	int size;
+
+	// delete the entities of this scene
+	/* TODO - */
+	/*
+	vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
+	size = m_worldinfos.size();
+	for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
+		if ((*worldit).second) {
+			delete (*worldit).second;
+			*worldit = m_worldinfos.back();
+			m_worldinfos.pop_back();
+			size--;
+		} else {
+			i++;
+			worldit++;
+		}
+	}*/
+
+
+	/* Worlds dont reference original blender data so we need to make a set from them */
+	typedef std::set<KX_WorldInfo*> KX_WorldInfoSet;
+	KX_WorldInfoSet worldset;
+	for (int scene_idx=0;scene_idx<numScenes;scene_idx++)
+	{
+		KX_Scene* scene = scenes->at(scene_idx);
+		if(scene->GetWorldInfo())
+			worldset.insert( scene->GetWorldInfo() );
+	}
+
+	vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
+	size = m_worldinfos.size();
+	for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
+		if ((*worldit).second && (worldset.count((*worldit).second)) == 0) {
+			delete (*worldit).second;
+			*worldit = m_worldinfos.back();
+			m_worldinfos.pop_back();
+			size--;
+		} else {
+			i++;
+			worldit++;
+		}
+	}
+	worldset.clear();
+	/* done freeing the worlds */
+
+
+
+
+	vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit;
+	size = m_polymaterials.size();
+
+
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list