[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