BGE: dynamic loading patch commited. API and demo files available here: https://proje...
authorBenoit Bolsee <benoit.bolsee@online.be>
Sun, 15 Nov 2009 23:58:56 +0000 (23:58 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Sun, 15 Nov 2009 23:58:56 +0000 (23:58 +0000)
42 files changed:
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Converter/KX_BlenderSceneConverter.h
source/gameengine/GameLogic/SCA_EventManager.h
source/gameengine/GameLogic/SCA_ILogicBrick.h
source/gameengine/GameLogic/SCA_ISensor.cpp
source/gameengine/GameLogic/SCA_ISensor.h
source/gameengine/GameLogic/SCA_LogicManager.cpp
source/gameengine/GameLogic/SCA_LogicManager.h
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_GameActuator.cpp
source/gameengine/Ketsji/KX_GameActuator.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.h
source/gameengine/Ketsji/KX_MouseFocusSensor.h
source/gameengine/Ketsji/KX_PolygonMaterial.h
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_RaySensor.h
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_SceneActuator.h
source/gameengine/Ketsji/KX_TouchEventManager.h
source/gameengine/Ketsji/KX_TouchSensor.h
source/gameengine/Physics/Bullet/CcdGraphicController.cpp
source/gameengine/Physics/Bullet/CcdGraphicController.h
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Physics/common/PHY_IController.h
source/gameengine/Physics/common/PHY_IGraphicController.h
source/gameengine/Physics/common/PHY_IPhysicsController.h
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_BucketManager.h
source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h
source/gameengine/SceneGraph/SG_IObject.h

index 8e7560cdcbd8fd1532f6183b4473fefe6d7c06c7..e599b89a2bb26646ac146901f96ab018ade81366 100644 (file)
 #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 @@ extern "C"
 {
 #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,9 +166,14 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
        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)
 {
@@ -183,6 +213,14 @@ Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
                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 @@ void KX_BlenderSceneConverter::RegisterGameMesh(
                                                                        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 @@ PyObject *KX_BlenderSceneConverter::GetPyNamespace()
        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();
+
+
+
+       for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
+               RAS_IPolyMaterial *mat= (*polymit).second;
+               Material *bmat= NULL;
+
+               /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */
+               if(mat->GetFlag() & RAS_BLENDERMAT) {
+                       KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat);
+                       bmat= bl_mat->GetBlenderMaterial();
+
+               } else {
+                       KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat);
+                       bmat= kx_mat->GetBlenderMaterial();
+               }
+
+               if (IS_TAGGED(bmat)) {
+                       /* only remove from bucket */
+                       ((*polymit).first)->GetBucketManager()->RemoveMaterial(mat);
+               }
+
+               i++;
+               polymit++;
+       }
+
+
+
+       for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
+               RAS_IPolyMaterial *mat= (*polymit).second;
+               Material *bmat= NULL;
+
+               /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */
+               if(mat->GetFlag() & RAS_BLENDERMAT) {
+                       KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat);
+                       bmat= bl_mat->GetBlenderMaterial();
+
+               } else {
+                       KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat);
+                       bmat= kx_mat->GetBlenderMaterial();
+               }
+
+               if(bmat) {
+                       //printf("FOUND MAT '%s' !!! ", ((ID*)bmat)->name+2);
+               }
+               else {
+                       //printf("LOST MAT  !!!");
+               }
+
+               if (IS_TAGGED(bmat)) {
+
+                       delete (*polymit).second;
+                       *polymit = m_polymaterials.back();
+                       m_polymaterials.pop_back();
+                       size--;
+                       //printf("tagged !\n");
+               } else {
+                       i++;
+                       polymit++;
+                       //printf("(un)tagged !\n");
+               }
+       }
+
+       vector<pair<KX_Scene*,BL_Material*> >::iterator matit;
+       size = m_materials.size();
+       for (i=0, matit=m_materials.begin(); i<size; ) {
+               BL_Material *mat= (*matit).second;
+               if (IS_TAGGED(mat->material)) {
+                       delete (*matit).second;
+                       *matit = m_materials.back();
+                       m_materials.pop_back();
+                       size--;
+               } else {
+                       i++;
+                       matit++;
+               }
+       }
+
+       vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
+       size = m_meshobjects.size();
+       for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
+               RAS_MeshObject *me= (*meshit).second;
+               if (IS_TAGGED(me->GetMesh())) {
+                       delete (*meshit).second;
+                       *meshit = m_meshobjects.back();
+                       m_meshobjects.pop_back();
+                       size--;
+               } else {
+                       i++;
+                       meshit++;
+               }
+       }
+
+       free_main(maggie);
+
+       return true;
+}
+
+bool KX_BlenderSceneConverter::FreeBlendFile(const char *path)
+{
+       return FreeBlendFile(GetMainDynamicPath(path));
+}
+
+bool KX_BlenderSceneConverter::MergeScene(KX_Scene *to, KX_Scene *from)
+{
+
+       {
+               vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itp = m_worldinfos.begin();
+               while (itp != m_worldinfos.end()) {
+                       if ((*itp).first==from)
+                               (*itp).first= to;
+                       itp++;
+               }
+       }
+
+       {
+               vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
+               while (itp != m_polymaterials.end()) {
+                       if ((*itp).first==from) {
+                               (*itp).first= to;
+
+                               /* also switch internal data */
+                               RAS_IPolyMaterial*mat= (*itp).second;
+                               mat->Replace_IScene(to);
+                       }
+                       itp++;
+               }
+       }
+
+       {
+               vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itp = m_meshobjects.begin();
+               while (itp != m_meshobjects.end()) {
+                       if ((*itp).first==from)
+                               (*itp).first= to;
+                       itp++;
+               }
+       }
+
+       {
+               vector<pair<KX_Scene*,BL_Material*> >::iterator itp = m_materials.begin();
+               while (itp != m_materials.end()) {
+                       if ((*itp).first==from)
+                               (*itp).first= to;
+                       itp++;
+               }
+       }
+       
+       return true;
+}
+
+/* This function merges a mesh from the current scene into another main
+ * it does not convert */
+RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name)
+{
+       ID *me;
+       
+       /* Find a mesh in the current main */
+       for(me = (ID *)m_maggie->mesh.first; me; me= (ID *)me->next)
+               if(strcmp(name, me->name+2)==0)
+                       break;
+       
+       if(me==NULL) {
+               printf("Could not be found \"%s\"\n", name);
+               return NULL;
+       }
+       
+       /* Watch this!, if its used in the original scene can cause big troubles */
+       if(me->us > 0) {
+               printf("Mesh has a user \"%s\"\n", name);
+               me = (ID*)copy_mesh((Mesh*)me);
+               me->us--;
+       }
+       BLI_remlink(&m_maggie->mesh, me); /* even if we made the copy it needs to be removed */
+       BLI_addtail(&maggie->mesh, me);
+
+       
+       /* Must copy the materials this uses else we cant free them */
+       {
+               Mesh *mesh= (Mesh *)me;
+               
+               /* ensure all materials are tagged */
+               for(int i=0; i<mesh->totcol; i++)
+                       if(mesh->mat[i])
+                               mesh->mat[i]->id.flag &= ~LIB_DOIT;
+               
+               for(int i=0; i<mesh->totcol; i++)
+               {
+                       Material *mat_old= mesh->mat[i];
+                       
+                       /* if its tagged its a replaced material */
+                       if(mat_old && (mat_old->id.flag & LIB_DOIT)==0)
+                       {
+                               Material *mat_old= mesh->mat[i];
+                               Material *mat_new= copy_material( mat_old );
+                               
+                               mat_new->id.flag |= LIB_DOIT;
+                               mat_old->id.us--;
+                               
+                               BLI_remlink(&m_maggie->mat, mat_new);
+                               BLI_addtail(&maggie->mat, mat_new);
+                               
+                               mesh->mat[i]= mat_new;
+                               
+                               /* the same material may be used twice */
+                               for(int j=i+1; j<mesh->totcol; j++)
+                               {
+                                       if(mesh->mat[j]==mat_old)
+                                       {
+                                               mesh->mat[j]= mat_new;
+                                               mat_new->id.us++;
+                                               mat_old->id.us--;
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this);
+       kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
+       m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */
+       return meshobj;
+}
index f74944d3552ffce67ba451a032358b1f89816f2b..62d771f1256bff3cddcabf2022dfea7c74b110b7 100644 (file)
@@ -64,6 +64,7 @@ class KX_BlenderSceneConverter : public KX_ISceneConverter
        GEN_Map<CHashedPtr,BL_InterpolatorList*> m_map_blender_to_gameAdtList;
        
        Main*                                   m_maggie;
+       vector<struct Main*>    m_DynamicMaggie;
 
        STR_String                              m_newfilename;
        class KX_KetsjiEngine*  m_ketsjiEngine;
@@ -140,7 +141,39 @@ public:
 
        struct Scene* GetBlenderSceneForName(const STR_String& name);
 
-       struct Main* GetMain() { return m_maggie; };
+//     struct Main* GetMain() { return m_maggie; };
+       struct Main*              GetMainDynamicPath(const char *path);
+       vector<struct Main*> &GetMainDynamic();
+       
+       bool LinkBlendFile(const char *path, char *group, KX_Scene *scene_merge, char **err_str);
+       bool MergeScene(KX_Scene *to, KX_Scene *from);
+       RAS_MeshObject *ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name);
+       bool FreeBlendFile(struct Main *maggie);
+       bool FreeBlendFile(const char *path);
+       void PrintStats() {
+               printf("BGE STATS!\n");
+
+               printf("\nAssets...\n");
+               printf("\t m_worldinfos: %d\n", m_worldinfos.size());
+               printf("\t m_polymaterials: %d\n", m_polymaterials.size());
+               printf("\t m_meshobjects: %d\n", m_meshobjects.size());
+               printf("\t m_materials: %d\n", m_materials.size());
+
+               printf("\nMappings...\n");
+               printf("\t m_map_blender_to_gameobject: %d\n", m_map_blender_to_gameobject.size());
+               printf("\t m_map_mesh_to_gamemesh: %d\n", m_map_mesh_to_gamemesh.size());
+               printf("\t m_map_blender_to_gameactuator: %d\n", m_map_blender_to_gameactuator.size());
+               printf("\t m_map_blender_to_gamecontroller: %d\n", m_map_blender_to_gamecontroller.size());
+               printf("\t m_map_blender_to_gameAdtList: %d\n", m_map_blender_to_gameAdtList.size());
+
+#ifdef WITH_CXX_GUARDEDALLOC
+               MEM_printmemlist_pydict();
+#endif
+//             /printf("\t m_ketsjiEngine->m_scenes: %d\n", m_ketsjiEngine->CurrentScenes()->size());
+       }
+
+
 
 #ifndef DISABLE_PYTHON
        PyObject *GetPyNamespace();
index debefcc45b0ea9da388961c53dcd05471a6ea531..8d3610acc5facb47708026247ee64f390f844e17 100644 (file)
@@ -70,6 +70,11 @@ public:
        virtual void    EndFrame();
        virtual void    RegisterSensor(class SCA_ISensor* sensor);
        int             GetType();
+       //SG_DList &GetSensors() { return m_sensors; }
+
+
+       void                    Replace_LogicManager(SCA_LogicManager* logicmgr) { m_logicmgr= logicmgr; }
+       virtual void    Replace_PhysicsScene(class PHY_IPhysicsEnvironment* env) { } /* only for event managers that use one */
 
 protected:
        EVENT_MANAGER_TYPE              m_mgrtype;
index 11885f988f39b354ec064581e10bbaf62754719d..cebfcf6bdc46301c0d50b5d2c5fe6d2b8332fe12 100644 (file)
@@ -35,6 +35,9 @@
 #include "GEN_Map.h"
 #include "GEN_HashedPtr.h"
 
+class NG_NetworkScene;
+class SCA_IScene;
+
 class SCA_ILogicBrick : public CValue
 {
        Py_Header;
@@ -122,9 +125,14 @@ public:
 
        virtual bool            LessComparedTo(SCA_ILogicBrick* other);
 
+       /* runtime variable, set when Triggering the python controller */
        static class SCA_LogicManager*  m_sCurrentLogicManager;
 
 
+       /* for moving logic bricks between scenes */
+       virtual void            Replace_IScene(SCA_IScene *val) {};
+       virtual void            Replace_NetworkScene(NG_NetworkScene *val) {};
+
 #ifndef DISABLE_PYTHON
        // python methods
        
index 877563e316184ce4017d4ec64eb7744e1a25af5b..3191c99fb2f6aec320da64055b1534ce64c25f80 100644 (file)
@@ -160,6 +160,19 @@ void SCA_ISensor::RegisterToManager()
        m_eventmgr->RegisterSensor(this);
 }
 
+void SCA_ISensor::Replace_EventManager(class SCA_LogicManager* logicmgr)
+{
+       if(m_links) { /* true if we're used currently */
+
+               m_eventmgr->RemoveSensor(this);
+               m_eventmgr= logicmgr->FindEventManager(m_eventmgr->GetType());
+               m_eventmgr->RegisterSensor(this);
+       }
+       else {
+               m_eventmgr= logicmgr->FindEventManager(m_eventmgr->GetType());
+       }
+}
+
 void SCA_ISensor::LinkToController(SCA_IController* controller)
 {
        m_linkedcontrollers.push_back(controller);
index fce5f340be13b7addea3115be0b0979cccb61bd0..e01f5775289b899692d01c5f628ecf80c80a5355 100644 (file)
@@ -133,6 +133,7 @@ public:
 
        virtual void RegisterToManager();
        virtual void UnregisterToManager();
+       void Replace_EventManager(class SCA_LogicManager* logicmgr);
        void ReserveController(int num)
        {
                m_linkedcontrollers.reserve(num);
index d93f2e70e360fb83ba9de807a95412f76716d724..848b7df6658e5102c8dd05b04bfcaf2c5b751422 100644 (file)
@@ -282,6 +282,11 @@ void SCA_LogicManager::RegisterMeshName(const STR_String& meshname,void* mesh)
        m_mapStringToMeshes.insert(mn,mesh);
 }
 
+void SCA_LogicManager::UnregisterMeshName(const STR_String& meshname,void* mesh)
+{
+       STR_HashedString mn = meshname;
+       m_mapStringToMeshes.remove(mn);
+}
 
 
 void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action)
index 402090357cbdff0f89846513daf37fd40d013de0..0c2effc2516f6d48fb2b9a204e64134571103e0e 100644 (file)
@@ -66,6 +66,7 @@ typedef std::map<class SCA_ISensor*,controllerlist > sensormap_t;
 
 #include "SCA_ILogicBrick.h"
 #include "SCA_IActuator.h"
+#include "SCA_EventManager.h"
 
 
 class SCA_LogicManager
@@ -110,6 +111,7 @@ public:
 
        void    AddTriggeredController(SCA_IController* controller, SCA_ISensor* sensor);
        SCA_EventManager*       FindEventManager(int eventmgrtype);
+       vector<class SCA_EventManager*> GetEventManagers() { return m_eventmanagers; }
        
        void    RemoveGameObject(const STR_String& gameobjname);
 
@@ -123,6 +125,9 @@ public:
 
        // for the scripting... needs a FactoryManager later (if we would have time... ;)
        void    RegisterMeshName(const STR_String& meshname,void* mesh);
+       void    UnregisterMeshName(const STR_String& meshname,void* mesh);
+       GEN_Map<STR_HashedString,void*>&        GetMeshMap() { return m_mapStringToMeshes; };
+       
        void    RegisterActionName(const STR_String& actname,void* action);
 
        void*   GetActionByName (const STR_String& actname);
index fa7a674c2503bdc27cc2c9350d5bf6d14983afd5..95283dcce50ee27f6010c0e6c244dd279b2097c1 100644 (file)
@@ -55,6 +55,10 @@ public:
 
        virtual bool Update();
        virtual CValue* GetReplica();
+       virtual void Replace_NetworkScene(NG_NetworkScene *val) 
+       { 
+               m_networkscene= val;
+       };
 
        /* ------------------------------------------------------------ */
        /* Python interface ------------------------------------------- */
index 3a8fe760bb9ccbf5b1d0883400f738debae19f13..90ba5db15ef79746005f31dd332e0e239f52f373 100644 (file)
@@ -66,6 +66,11 @@ public:
        virtual void Init();
        void EndFrame();
        
+       virtual void Replace_NetworkScene(NG_NetworkScene *val)
+       {
+               m_NetworkScene= val;
+       };
+
 #ifndef DISABLE_PYTHON
 
        /* ------------------------------------------------------------- */
index 0946cd320c503cba5bfc6c747f2b23080cc38166..088d17ea741ddacf25c0de44d82124d142eb3361 100644 (file)
@@ -19,6 +19,9 @@
 #include "MEM_guardedalloc.h"
 #endif
 
+#include "SCA_IScene.h" /* only for Replace_IScene */
+#include "KX_Scene.h"
+
 struct MTFace;
 class KX_Scene;
 
@@ -68,6 +71,7 @@ public:
                TCachingInfo& cachingInfo
        )const;
 
+       Material* GetBlenderMaterial() const;
        MTFace* GetMTFace(void) const;
        unsigned int* GetMCol(void) const;
        BL_Texture * getTex (unsigned int idx) { 
@@ -83,6 +87,11 @@ public:
                MT_Scalar ref, MT_Scalar emit, MT_Scalar alpha
        );
        
+       virtual void Replace_IScene(SCA_IScene *val)
+       {
+               mScene= static_cast<KX_Scene *>(val);
+       };
+
 #ifndef DISABLE_PYTHON
        // --------------------------------
        virtual PyObject* py_repr(void) { return PyUnicode_FromString(mMaterial->matname.ReadPtr()); }
@@ -119,7 +128,6 @@ private:
 
        bool UsesLighting(RAS_IRasterizer *rasty) const;
        void GetMaterialRGBAColor(unsigned char *rgba) const;
-       Material* GetBlenderMaterial() const;
        Scene* GetBlenderScene() const;
        void ReleaseMaterial();
 
index bc0f875bca62d873f1f96397ccfc6382ed283b3b..d6e2a623007db8375cd88bf349cd8369650f46e2 100644 (file)
@@ -51,7 +51,7 @@ KX_GameActuator::KX_GameActuator(SCA_IObject *gameobj,
                                                                   int mode,
                                                                   const STR_String& filename,
                                                                   const STR_String& loadinganimationname,
-                                                                  KX_Scene* scene,
+                                                                  SCA_IScene* scene,
                                                                   KX_KetsjiEngine* ketsjiengine)
                                                                   : SCA_IActuator(gameobj, KX_ACT_GAME)
 {
index 37d09a5a9fb39ff15c740aa05b637e1372385fed..4880d476e360bf0e0b34b8dcf26e19db9bea47ed 100644 (file)
@@ -35,6 +35,9 @@
 
 #include "SCA_IActuator.h"
 
+#include "SCA_IScene.h" /* Replace_IScene only */
+#include "KX_Scene.h" /* Replace_IScene only */
+
 class KX_GameActuator : public SCA_IActuator
 {
        Py_Header;
@@ -43,7 +46,7 @@ protected:
        bool                                            m_restart;
        STR_String                                      m_filename;
        STR_String                                      m_loadinganimationname;
-       class KX_Scene*                         m_scene;
+       class SCA_IScene*                       m_scene;
        class KX_KetsjiEngine*          m_ketsjiengine;
 
  public:
@@ -64,7 +67,7 @@ protected:
                                         int mode,
                                         const STR_String& filename,
                                         const STR_String& loadinganimationname,
-                                        KX_Scene* scene,
+                                        SCA_IScene* scene,
                                         KX_KetsjiEngine* ketsjiEngine);
        virtual ~KX_GameActuator();
 
@@ -72,6 +75,11 @@ protected:
 
        virtual bool Update();
        
+       virtual void Replace_IScene(SCA_IScene *val)
+       {
+               m_scene= val;
+       };
+
        /* --------------------------------------------------------------------- */
        /* Python interface ---------------------------------------------------- */
        /* --------------------------------------------------------------------- */
index 9f4fa9a7c02072ed984f4d2da35d9d3eb0cf2d88..6800b2aa871dabe3844f5140328f7b71a0ea9443 100644 (file)
@@ -1606,15 +1606,12 @@ void KX_KetsjiEngine::RemoveScheduledScenes()
        }
 }
 
-
-
-KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
+KX_Scene* KX_KetsjiEngine::CreateScene(Scene *scene)
 {
-       Scene *scene = m_sceneconverter->GetBlenderSceneForName(scenename);
        KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice,
                                                                          m_mousedevice,
                                                                          m_networkdevice,
-                                                                         scenename,
+                                                                         scene->id.name+2,
                                                                          scene);
 
        m_sceneconverter->ConvertScene(tmpscene,
@@ -1624,7 +1621,11 @@ KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
        return tmpscene;
 }
 
-
+KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename)
+{
+       Scene *scene = m_sceneconverter->GetBlenderSceneForName(scenename);
+       return CreateScene(scene);
+}
 
 void KX_KetsjiEngine::AddScheduledScenes()
 {
index 74d683fbad6eb8a27fd4889822867de0398281d5..b815ca0c716903ce76e753d52da26b8298befd95 100644 (file)
@@ -380,6 +380,9 @@ public:
         * @param b Blue component of the override color.
         */
        void GetOverrideFrameColor(float& r, float& g, float& b) const;
+
+       KX_Scene*               CreateScene(const STR_String& scenename);
+       KX_Scene*               CreateScene(Scene *scene);
        
 protected:
        /**
@@ -399,7 +402,6 @@ protected:
        void                    AddScheduledScenes(void);
        void                    ReplaceScheduledScenes(void);
        void                    PostProcessScene(class KX_Scene* scene);
-       KX_Scene*               CreateScene(const STR_String& scenename);
        
        bool                    BeginFrame();
        void                    ClearFrame();
index d4063ef1d164328400ba14dfd7def2eef54647b9..e3f0e2b34f5f83ae362a3d04c3263d49a3c04cce 100644 (file)
@@ -66,6 +66,13 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
                replica->ProcessReplica();
                return replica;
        };
+
+       virtual void Replace_IScene(SCA_IScene *val)
+       {
+               m_kxscene= static_cast<KX_Scene *>(val);
+       };
+
+
        /**
         * @attention Overrides default evaluate. 
         */
index dba12acee7f018475e73f94eea615af03801c5dc..4f7d7f7888da450d0679cc10aaa75daf05728fd4 100644 (file)
@@ -102,6 +102,11 @@ public:
        void DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const;
        virtual bool Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const;
 
+       Material *GetBlenderMaterial() const
+       {
+               return m_material;
+       }
+
        /**
         * Returns the Blender texture face structure that is used for this material.
         * @return The material's texture face.
index 1339200a7405ed7947c69e3550fd3a3bcfebb312..ae4f349847101ab93834861642f51f3aacd56643 100644 (file)
@@ -30,9 +30,6 @@
 
 #include "GL/glew.h"
 
-// directory header for py function getBlendFileList
-#include <stdlib.h>
-
 #ifdef WIN32
 #pragma warning (disable : 4786)
 #endif //WIN32
@@ -50,6 +47,16 @@ extern "C" {
 #endif
 
 #include "KX_PythonInit.h"
+
+// directory header for py function getBlendFileList
+#ifndef WIN32
+  #include <dirent.h>
+  #include <stdlib.h>
+#else
+  #include <io.h>
+  #include "BLI_winstuff.h"
+#endif
+
 //python physics binding
 #include "KX_PyConstraintBinding.h"
 
@@ -82,6 +89,8 @@ extern "C" {
 #include "InputParser.h"
 #include "KX_Scene.h"
 
+#include "NG_NetworkScene.h" //Needed for sendMessage()
+
 #include "BL_Shader.h"
 
 #include "KX_PyMath.h"
@@ -100,12 +109,16 @@ extern "C" {
 #include "BKE_global.h"
 #include "BLI_blenlib.h"
 #include "GPU_material.h"
+#include "MEM_guardedalloc.h"
+
+/* for converting new scenes */
+#include "KX_BlenderSceneConverter.h"
+#include "KX_MeshProxy.h" /* for creating a new library of mesh objects */
+extern "C" {
+       #include "BLO_readfile.h"
+}
+
 
-#ifndef WIN32
-  #include <dirent.h>
-#else
-  #include "BLI_winstuff.h"
-#endif
 #include "NG_NetworkScene.h" //Needed for sendMessage()
 
 static void setSandbox(TPythonSecurityLevel level);
@@ -509,10 +522,16 @@ static PyObject* gPyGetSceneList(PyObject* self)
                KX_Scene* scene = scenes->at(i);
                PyList_SET_ITEM(list, i, scene->GetProxy());
        }
-       
+
        return list;
 }
 
+static PyObject *pyPrintStats(PyObject *,PyObject *,PyObject *)
+{
+       gp_KetsjiScene->GetSceneConverter()->PrintStats();
+       Py_RETURN_NONE;
+}
+
 static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
 {
 #define pprint(x) std::cout << x << std::endl;
@@ -584,6 +603,116 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
        Py_RETURN_NONE;
 }
 
+static PyObject *gLibLoad(PyObject*, PyObject* args)
+{
+       KX_Scene *kx_scene= gp_KetsjiScene;
+       char *path;
+       char *group;
+       char *err_str= NULL;
+       
+       if (!PyArg_ParseTuple(args,"ss:LibLoad",&path, &group))
+               return NULL;
+
+       if(kx_scene->GetSceneConverter()->LinkBlendFile(path, group, kx_scene, &err_str)) {
+               Py_RETURN_TRUE;
+       }
+       
+       if(err_str) {
+               PyErr_SetString(PyExc_ValueError, err_str);
+               return NULL;
+       }
+       
+       Py_RETURN_FALSE;
+}
+
+static PyObject *gLibNew(PyObject*, PyObject* args)
+{
+       KX_Scene *kx_scene= gp_KetsjiScene;
+       char *path;
+       char *group;
+       char *name;
+       PyObject *names;
+       int idcode;
+
+       if (!PyArg_ParseTuple(args,"ssO!:LibNew",&path, &group, &PyList_Type, &names))
+               return NULL;
+       
+       if(kx_scene->GetSceneConverter()->GetMainDynamicPath(path))
+       {
+               PyErr_SetString(PyExc_KeyError, "the name of the path given exists");
+               return NULL;
+       }
+       
+       idcode= BLO_idcode_from_name(group);
+       if(idcode==0) {
+               PyErr_Format(PyExc_ValueError, "invalid group given \"%s\"", group);
+               return NULL;
+       }
+       
+       Main *maggie= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
+       kx_scene->GetSceneConverter()->GetMainDynamic().push_back(maggie);
+       strncpy(maggie->name, path, sizeof(maggie->name)-1);
+       
+       /* Copy the object into main */
+       if(idcode==ID_ME) {
+               PyObject *ret= PyList_New(0);
+               PyObject *item;
+               for(int i= 0; i < PyList_GET_SIZE(names); i++) {
+                       name= _PyUnicode_AsString(PyList_GET_ITEM(names, i));
+                       if(name) {
+                               RAS_MeshObject *meshobj= kx_scene->GetSceneConverter()->ConvertMeshSpecial(kx_scene, maggie, name);
+                               if(meshobj) {
+                                       KX_MeshProxy* meshproxy = new KX_MeshProxy(meshobj);
+                                       item= meshproxy->NewProxy(true);
+                                       PyList_Append(ret, item);
+                                       Py_DECREF(item);
+                               }
+                       }
+                       else {
+                               PyErr_Clear(); /* wasnt a string, ignore for now */
+                       }
+               }
+               
+               return ret;
+       }
+       else {
+               PyErr_Format(PyExc_ValueError, "only \"Mesh\" group currently supported");
+               return NULL;
+       }
+       
+       Py_RETURN_NONE;
+}
+
+static PyObject *gLibFree(PyObject*, PyObject* args)
+{
+       KX_Scene *kx_scene= gp_KetsjiScene;
+       char *path;
+
+       if (!PyArg_ParseTuple(args,"s:LibFree",&path))
+               return NULL;
+
+       if (kx_scene->GetSceneConverter()->FreeBlendFile(path))
+       {
+               Py_RETURN_TRUE;
+       }
+       else {
+               Py_RETURN_FALSE;
+       }
+}
+
+static PyObject *gLibList(PyObject*, PyObject* args)
+{
+       vector<Main*> &dynMaggie = gp_KetsjiScene->GetSceneConverter()->GetMainDynamic();
+       int i= 0;
+       PyObject *list= PyList_New(dynMaggie.size());
+       
+       for (vector<Main*>::iterator it=dynMaggie.begin(); !(it==dynMaggie.end()); it++)
+       {
+               PyList_SET_ITEM(list, i++, PyUnicode_FromString( (*it)->name) );
+       }
+       
+       return list;
+}
 
 static struct PyMethodDef game_methods[] = {
        {"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (const char *)gPyExpandPath_doc},
@@ -616,6 +745,14 @@ static struct PyMethodDef game_methods[] = {
        {"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (const char *)"Gets the estimated average frame rate"},
        {"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (const char *)"Gets a list of blend files in the same directory as the current blend file"},
        {"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"},
+       {"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine stastics"},
+       
+       /* library functions */
+       {"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS, (const char *)""},
+       {"LibNew", (PyCFunction)gLibNew, METH_VARARGS, (const char *)""},
+       {"LibFree", (PyCFunction)gLibFree, METH_VARARGS, (const char *)""},
+       {"LibList", (PyCFunction)gLibList, METH_VARARGS, (const char *)""},
+       
        {NULL, (PyCFunction) NULL, 0, NULL }
 };
 
index 39b447b5657c7314c22a7e85c724347bfc36e207..ea7dd544cb10482dcb6ff3004d3561db9b81e373 100644 (file)
@@ -34,6 +34,8 @@
 
 #include "SCA_ISensor.h"
 #include "MT_Point3.h"
+#include "SCA_IScene.h" /* only for scene replace */
+#include "KX_Scene.h" /* only for scene replace */
 
 struct KX_ClientObjectInfo;
 class KX_RayCast;
@@ -73,6 +75,10 @@ public:
        bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
        bool NeedRayCast(KX_ClientObjectInfo* client);
 
+       virtual void            Replace_IScene(SCA_IScene *val) 
+       {       
+               m_scene= static_cast<KX_Scene *>(val); 
+       }
 
        //Python Interface
        enum RayAxis {
index 4cccc406b584b5874d2e2ea6212035a10c3c1109..53a71e3c6eac411e3e2fd937ff01b42f52d2f29e 100644 (file)
@@ -43,6 +43,8 @@
 
 #include "MT_Vector3.h"
 
+
+
 class SCA_IScene;
 
 class KX_SCA_AddObjectActuator : public SCA_IActuator
@@ -100,6 +102,11 @@ public:
        virtual void 
        ProcessReplica();
 
+       virtual void Replace_IScene(SCA_IScene *val)
+       {
+               m_scene= val;
+       };
+
        virtual bool 
        UnlinkObject(SCA_IObject* clientobj);
 
index 782a24b1ef1efa53ac3ff290f82935b5a45fdbff..b99f40be70714ceddda1a636ceb4e9f9c3786e53 100644 (file)
@@ -59,6 +59,11 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator
        virtual bool 
        Update();
 
+       virtual void Replace_IScene(SCA_IScene *val)
+       {
+               m_scene= val;
+       };
+
        /* --------------------------------------------------------------------- */
        /* Python interface ---------------------------------------------------- */
        /* --------------------------------------------------------------------- */
index 47c823afa9fbe32a9c011eb0621228904897fd3b..5f62c603ac6b0ca1c6c983253afb2c754cc09a69 100644 (file)
@@ -80,6 +80,11 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator
        /* Python interface ---------------------------------------------------- */
        /* --------------------------------------------------------------------- */
 
+       virtual void Replace_IScene(SCA_IScene *val)
+       {
+               m_scene= val;
+       };
+
        static PyObject* pyattr_get_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
        static int pyattr_set_mesh(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
 
index c93ead741822c111cb7dfd244ccb62845a81169f..655c8eedaae664477998f45a25383f371df2e3dd 100644 (file)
@@ -273,6 +273,10 @@ RAS_BucketManager* KX_Scene::GetBucketManager()
 }
 
 
+CListValue* KX_Scene::GetTempObjectList()
+{
+       return m_tempObjectList;
+}
 
 CListValue* KX_Scene::GetObjectList()
 {
@@ -280,7 +284,6 @@ CListValue* KX_Scene::GetObjectList()
 }
 
 
-
 CListValue* KX_Scene::GetRootParentList()
 {
        return m_parentlist;
@@ -1043,7 +1046,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
                        newobj->SetDeformer(NULL);
                }
 
-               if (mesh->IsDeformed())
+               if (mesh->IsDeformed()) /* checks GetMesh() isnt NULL */
                {
                        // we must create a new deformer but which one?
                        KX_GameObject* parentobj = newobj->GetParent();
@@ -1588,10 +1591,10 @@ void KX_Scene::SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter)
 void KX_Scene::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv)
 {
        m_physicsEnvironment = physEnv;
-
-       KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, physEnv);
-       m_logicmgr->RegisterEventManager(touchmgr);
-       return;
+       if(m_physicsEnvironment) {
+               KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, physEnv);
+               m_logicmgr->RegisterEventManager(touchmgr);
+       }
 }
  
 void KX_Scene::setSuspendedTime(double suspendedtime)
@@ -1613,6 +1616,182 @@ double KX_Scene::getSuspendedDelta()
 
 #ifndef DISABLE_PYTHON
 
+
+#include "KX_BulletPhysicsController.h"
+
+static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *to)
+{
+       SCA_LogicManager *logicmgr= to->GetLogicManager();
+
+       brick->Replace_IScene(to);
+       brick->Replace_NetworkScene(to->GetNetworkScene());
+
+       SCA_ISensor *sensor=  dynamic_cast<class SCA_ISensor *>(brick);
+       if(sensor) {
+               sensor->Replace_EventManager(logicmgr);
+       }
+
+       /* near sensors have physics controllers */
+       KX_TouchSensor *touch_sensor = dynamic_cast<class KX_TouchSensor *>(brick);
+       if(touch_sensor) {
+               touch_sensor->GetPhysicsController()->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
+       }
+}
+
+#include "CcdGraphicController.h" // XXX  ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
+#include "CcdPhysicsEnvironment.h" // XXX  ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
+#include "KX_BulletPhysicsController.h"
+
+
+static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene *from)
+{
+       {
+               SCA_ActuatorList& actuators= gameobj->GetActuators();
+               SCA_ActuatorList::iterator ita;
+
+               for (ita = actuators.begin(); !(ita==actuators.end()); ++ita)
+               {
+                       MergeScene_LogicBrick(*ita, to);
+               }
+       }
+
+
+       {
+               SCA_SensorList& sensors= gameobj->GetSensors();
+               SCA_SensorList::iterator its;
+
+               for (its = sensors.begin(); !(its==sensors.end()); ++its)
+               {
+                       MergeScene_LogicBrick(*its, to);
+               }
+       }
+
+       {
+               SCA_ControllerList& controllers= gameobj->GetControllers();
+               SCA_ControllerList::iterator itc;
+
+               for (itc = controllers.begin(); !(itc==controllers.end()); ++itc)
+               {
+                       SCA_IController *cont= *itc;
+                       MergeScene_LogicBrick(cont, to);
+
+                       vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors();
+                       vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
+
+                       for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());++ita) {
+                               MergeScene_LogicBrick(*ita, to);
+                       }
+
+                       for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());++its) {
+                               MergeScene_LogicBrick(*its, to);
+                       }
+               }
+       }
+
+       /* graphics controller */
+       PHY_IGraphicController *ctrl = gameobj->GetGraphicController();
+       if(ctrl) {
+               /* SHOULD update the m_cullingTree */
+               ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
+       }
+
+       /* SG_Node can hold a scene reference */
+       SG_Node *sg= gameobj->GetSGNode();
+       if(sg) {
+               if(sg->GetSGClientInfo() == from) {
+                       sg->SetSGClientInfo(to);
+               }
+
+               SGControllerList::iterator contit;
+               SGControllerList& controllers = sg->GetSGControllerList();
+               for (contit = controllers.begin();contit!=controllers.end();++contit)
+               {
+                       KX_BulletPhysicsController *phys_ctrl= dynamic_cast<KX_BulletPhysicsController *>(*contit);
+                       if (phys_ctrl)
+                               phys_ctrl->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
+               }
+       }
+}
+
+bool KX_Scene::MergeScene(KX_Scene *other)
+{
+       CcdPhysicsEnvironment *env=                     dynamic_cast<CcdPhysicsEnvironment *>(this->GetPhysicsEnvironment());
+       CcdPhysicsEnvironment *env_other=       dynamic_cast<CcdPhysicsEnvironment *>(other->GetPhysicsEnvironment());
+
+       if((env==NULL) != (env_other==NULL)) /* TODO - even when both scenes have NONE physics, the other is loaded with bullet enabled, ??? */
+       {
+               printf("KX_Scene::MergeScene: physics scenes type differ, aborting\n");
+               printf("\tsource %d, terget %d\n", (int)(env!=NULL), (int)(env_other!=NULL));
+               return false;
+       }
+
+       if(GetSceneConverter() != other->GetSceneConverter()) {
+               printf("KX_Scene::MergeScene: converters differ, aborting\n");
+               return false;
+       }
+
+
+       GetBucketManager()->MergeBucketManager(other->GetBucketManager());
+
+       /* move materials across, assume they both use the same scene-converters */
+       GetSceneConverter()->MergeScene(this, other);
+
+       /* active + inactive == all ??? - lets hope so */
+       for (int i = 0; i < other->GetObjectList()->GetCount(); i++)
+       {
+               KX_GameObject* gameobj = (KX_GameObject*)other->GetObjectList()->GetValue(i);
+               MergeScene_GameObject(gameobj, this, other);
+
+               gameobj->UpdateBuckets(false); /* only for active objects */
+       }
+
+       for (int i = 0; i < other->GetInactiveList()->GetCount(); i++)
+       {
+               KX_GameObject* gameobj = (KX_GameObject*)other->GetInactiveList()->GetValue(i);
+               MergeScene_GameObject(gameobj, this, other);
+       }
+
+       GetTempObjectList()->MergeList(other->GetTempObjectList());
+       other->GetTempObjectList()->ReleaseAndRemoveAll();
+
+       GetObjectList()->MergeList(other->GetObjectList());
+       other->GetObjectList()->ReleaseAndRemoveAll();
+
+       GetInactiveList()->MergeList(other->GetInactiveList());
+       other->GetInactiveList()->ReleaseAndRemoveAll();
+
+       GetRootParentList()->MergeList(other->GetRootParentList());
+       other->GetRootParentList()->ReleaseAndRemoveAll();
+
+       GetLightList()->MergeList(other->GetLightList());
+       other->GetLightList()->ReleaseAndRemoveAll();
+
+       if(env) /* bullet scene? - dummy scenes dont need touching */
+               env->MergeEnvironment(env_other);
+
+       /* merge logic */
+       {
+               SCA_LogicManager *logicmgr=                     GetLogicManager();
+               SCA_LogicManager *logicmgr_other=       other->GetLogicManager();
+
+               vector<class SCA_EventManager*>evtmgrs= logicmgr->GetEventManagers();
+               //vector<class SCA_EventManager*>evtmgrs_others= logicmgr_other->GetEventManagers();
+
+               //SCA_EventManager *evtmgr;
+               SCA_EventManager *evtmgr_other;
+
+               for(int i= 0; i < evtmgrs.size(); i++) {
+                       evtmgr_other= logicmgr_other->FindEventManager(evtmgrs[i]->GetType());
+
+                       if(evtmgr_other) /* unlikely but possible one scene has a joystick and not the other */
+                               evtmgr_other->Replace_LogicManager(logicmgr);
+
+                       /* when merging objects sensors are moved across into the new manager, dont need to do this here */
+               }
+       }
+       return true;
+}
+
 //----------------------------------------------------------------------------
 //Python
 
index da72ba2ec983ec7fb146072f4a43a460af2749aa..4b01ab39d95892604553e9218793f0683476c273 100644 (file)
@@ -73,7 +73,6 @@ class KX_Camera;
 class KX_GameObject;
 class KX_LightObject;
 class RAS_BucketManager;
-class RAS_BucketManager;
 class RAS_MaterialBucket;
 class RAS_IPolyMaterial;
 class RAS_IRasterizer;
@@ -83,6 +82,9 @@ class btCollisionShape;
 class KX_BlenderSceneConverter;
 struct KX_ClientObjectInfo;
 
+/* for ID freeing */
+#define IS_TAGGED(_id) ((_id) && (((ID *)_id)->flag & LIB_DOIT))
+
 /**
  * The KX_Scene holds all data for an independent scene. It relates
  * KX_Objects to the specific objects in the modules.
@@ -100,6 +102,7 @@ class KX_Scene : public PyObjectPlus, public SCA_IScene
                CullingInfo(int layer) : m_layer(layer) {}
        };
 
+
 protected:
        RAS_BucketManager*      m_bucketmanager;
        CListValue*                     m_tempObjectList;
@@ -321,6 +324,10 @@ public:
        );
 
                CListValue*                             
+       GetTempObjectList(
+       );
+
+               CListValue*
        GetObjectList(
        );
 
@@ -471,6 +478,7 @@ public:
        KX_Camera* GetpCamera();
        NG_NetworkDeviceInterface* GetNetworkDeviceInterface();
        NG_NetworkScene* GetNetworkScene();
+       KX_BlenderSceneConverter *GetSceneConverter() { return m_sceneConverter; }
 
        /**
         * Replicate the logic bricks associated to this object.
@@ -567,6 +575,15 @@ public:
         * Returns the Blender scene this was made from
         */
        struct Scene *GetBlenderScene() { return m_blenderScene; }
+
+       bool MergeScene(KX_Scene *other);
+
+
+       //void PrintStats(int verbose_level) {
+       //      m_bucketmanager->PrintStats(verbose_level)
+       //}
+
+
 };
 
 typedef std::vector<KX_Scene*> KX_SceneList;
index e11a94798c9ba10e1b37d22ff073317bc6397e70..4afa89269708095752d821e7c3c6350d23d7a1c9 100644 (file)
@@ -34,6 +34,8 @@
 #define __KX_SCENEACTUATOR
 
 #include "SCA_IActuator.h"
+#include "SCA_IScene.h" /* Replace_IScene only */
+#include "KX_Scene.h" /* Replace_IScene only */
 
 class KX_SceneActuator : public SCA_IActuator
 {
@@ -89,6 +91,11 @@ class KX_SceneActuator : public SCA_IActuator
        
 #ifndef DISABLE_PYTHON
 
+       virtual void Replace_IScene(SCA_IScene *val)
+       {
+               m_scene= static_cast<KX_Scene *>(val);
+       };
+
        /* --------------------------------------------------------------------- */
        /* Python interface ---------------------------------------------------- */
        /* --------------------------------------------------------------------- */
index e6414a2e285797a24fe122201159238a30b17c29..c3da11eb1e286a024b1f4810c0d42216443e1aca 100644 (file)
@@ -74,6 +74,7 @@ public:
        virtual void RemoveSensor(SCA_ISensor* sensor);
        SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
        PHY_IPhysicsEnvironment *GetPhysicsEnvironment() { return m_physEnv; }
+       virtual void    Replace_PhysicsScene(PHY_IPhysicsEnvironment* env) { m_physEnv= env; }
 
        
 #ifdef WITH_CXX_GUARDEDALLOC
index ae5b68da8450445cbab05a033b48da1bf6909142..248ce170d713838b6f9b7895061e8f890d20b2ba 100644 (file)
@@ -110,10 +110,12 @@ public:
                if (m_invert) result = !result;
                return result;
        }
-
        
        virtual void EndFrame();
 
+       class PHY_IPhysicsController* GetPhysicsController() { return m_physCtrl; }
+
+
        // todo: put some info for collision maybe
 
 #ifndef DISABLE_PYTHON
index 2dbbb7fa4a02e3f9aa518315d93410f4b02ef755..73ac789edf72f2cc26a581730bf27ad186381890 100644 (file)
@@ -124,6 +124,21 @@ PHY_IGraphicController* CcdGraphicController::GetReplica(class PHY_IMotionState*
        return replica;
 }
 
+void CcdGraphicController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* env)
+{
+       CcdPhysicsEnvironment* phyEnv = static_cast<CcdPhysicsEnvironment*>(env);
+       /* Updates the m_phyEnv's m_cullingTree & m_cullingCache */
+       if(getBroadphaseHandle()) {
+               /* insert into the new physics scene */
+               Activate(false);
+               m_phyEnv= phyEnv;
+               Activate(true);
+       }
+       else {
+               m_phyEnv= phyEnv;
+       }
+}
+
 void CcdGraphicController::Activate(bool active)
 {
        if (active)
index 99885eb99eee5d1a516d330245f2c510b7a1a1f5..07cf6d940cb8b5e9d152c590d5c3e092c620c057 100644 (file)
@@ -47,6 +47,8 @@ public:
        virtual void setBroadphaseHandle(btBroadphaseProxy* handle) { m_handle = handle; }
        virtual btBroadphaseProxy* getBroadphaseHandle() { return m_handle; }
 
+       virtual void SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* env);
+
        ////////////////////////////////////
        // PHY_IGraphicController interface
        ////////////////////////////////////
index b7d0dd2f6e72863e60a721b5fba42018aed08670..69b63affeefb3d2e8783c827568eee00caee0b7f 100644 (file)
@@ -804,6 +804,23 @@ void               CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionsta
 
 }
 
+void   CcdPhysicsController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env)
+{
+       // can safely assume CCD environment
+       CcdPhysicsEnvironment *physicsEnv = static_cast<CcdPhysicsEnvironment*>(env);
+
+       if (m_cci.m_physicsEnv != physicsEnv) 
+       {
+               // since the environment is changing, we must also move the controler to the
+               // new environement. Note that we don't handle sensor explicitely: this
+               // function can be called on sensor but only when they are not registered
+               if (m_cci.m_physicsEnv->removeCcdPhysicsController(this))
+               {
+                       physicsEnv->addCcdPhysicsController(this);
+               }
+               m_cci.m_physicsEnv = physicsEnv;
+       }
+}
 
 void   CcdPhysicsController::SetCenterOfMassTransform(btTransform& xform)
 {
index 69b16ca35bd9ea4ffe38311a777fc125a97159c0..02d723472f687dad9e09efb0fdd9bb5ed15f1cca 100644 (file)
@@ -432,6 +432,7 @@ protected:
 
                // controller replication
                virtual void            PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl);
+               virtual void            SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env);
 
                // kinematic methods
                virtual void            RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local);
index bf28802870adff965a6d7d7680a8f6fa041e2227..22722c0927aa6ec6b9690c79941ab429ffcfeef2 100644 (file)
@@ -420,7 +420,7 @@ void        CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
 
                
 
-void   CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
+bool   CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
 {
        //also remove constraint
        btRigidBody* body = ctrl->GetRigidBody();
@@ -445,13 +445,13 @@ void      CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
                        m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject());
                }
        }
-       m_controllers.erase(ctrl);
-
        if (ctrl->m_registerCount != 0)
                printf("Warning: removing controller with non-zero m_registerCount: %d\n", ctrl->m_registerCount);
 
        //remove it from the triggers
        m_triggerControllers.erase(ctrl);
+
+       return (m_controllers.erase(ctrl) != 0);
 }
 
 void   CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
@@ -1736,10 +1736,19 @@ btDispatcher*   CcdPhysicsEnvironment::getDispatcher()
        return m_dynamicsWorld->getDispatcher();
 }
 
+void CcdPhysicsEnvironment::MergeEnvironment(CcdPhysicsEnvironment *other)
+{
+       std::set<CcdPhysicsController*>::iterator it;
 
+       while (other->m_controllers.begin() != other->m_controllers.end())
+       {
+               it= other->m_controllers.begin();
+               CcdPhysicsController* ctrl= (*it);
 
-
-
+               other->removeCcdPhysicsController(ctrl);
+               this->addCcdPhysicsController(ctrl);
+       }
+}
 
 CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
 {
index e087eac32c5a02be06c9d9dc3b5aa7b707b6671e..21f74e95ed4d6e9d9e051cf7b6daffbf95cdb38e 100644 (file)
@@ -199,7 +199,7 @@ protected:
        
                void    addCcdPhysicsController(CcdPhysicsController* ctrl);
 
-               void    removeCcdPhysicsController(CcdPhysicsController* ctrl);
+               bool    removeCcdPhysicsController(CcdPhysicsController* ctrl);
 
                void    updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
 
@@ -242,13 +242,13 @@ protected:
        
                class btConstraintSolver*       GetConstraintSolver();
 
+               void MergeEnvironment(CcdPhysicsEnvironment *other);
+
        protected:
                
                
 
-               
                std::set<CcdPhysicsController*> m_controllers;
-               
                std::set<CcdPhysicsController*> m_triggerControllers;
 
                PHY_ResponseCallback    m_triggerCallbacks[PHY_NUM_RESPONSE];
index a053a9679b8585af4eb1407947695ebc5f8e759a..e897de255c1778593a967f84953fc9f0681ea937 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "PHY_DynamicTypes.h"
 
+class PHY_IPhysicsEnvironment;
+
 #ifdef WITH_CXX_GUARDEDALLOC
 #include "MEM_guardedalloc.h"
 #endif
@@ -45,8 +47,9 @@ class PHY_IController
        public:
                virtual ~PHY_IController();
                // clientinfo for raycasts for example
-               virtual void*                           getNewClientInfo()=0;
-               virtual void                            setNewClientInfo(void* clientinfo)=0;
+               virtual void*   getNewClientInfo()=0;
+               virtual void    setNewClientInfo(void* clientinfo)=0;
+               virtual void    SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env)=0;
 
        
 #ifdef WITH_CXX_GUARDEDALLOC
index aae971ff42a243fbc1071e04b9e76729b37c4a64..eac3de68d4f0085932edf7efac1d8aacb1b1405c 100644 (file)
@@ -32,7 +32,6 @@
 #include "PHY_IController.h"
 
 
-
 /**
        PHY_IPhysicsController is the abstract simplified Interface to a physical object.
        It contains the IMotionState and IDeformableMesh Interfaces.
@@ -51,7 +50,6 @@ class PHY_IGraphicController : public PHY_IController
 
                virtual PHY_IGraphicController* GetReplica(class PHY_IMotionState* motionstate) {return 0;}
 
-
 #ifdef WITH_CXX_GUARDEDALLOC
        void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, "GE:PHY_IController"); }
        void operator delete( void *mem ) { MEM_freeN(mem); }
index 664e5fddd83c9254f919c9faff265c457b77f26f..b34f8417e4c715be542b163af0625bdc2db9be26 100644 (file)
@@ -32,6 +32,7 @@
 #include "PHY_IController.h"
 
 class PHY_IMotionState;
+class PHY_IPhysicsEnvironment;
 
 /**
        PHY_IPhysicsController is the abstract simplified Interface to a physical object.
index 8b3c4990a7a83052ff6cf2a19073f091ba84669a..f5750b3999817bd628796a8f250a137db142ea68 100644 (file)
@@ -317,3 +317,44 @@ void RAS_BucketManager::ReleaseMaterials(RAS_IPolyMaterial * mat)
        }
 }
 
+/* frees the bucket, only used when freeing scenes */
+void RAS_BucketManager::RemoveMaterial(RAS_IPolyMaterial * mat)
+{
+       BucketList::iterator bit, bitp;
+       list<RAS_MeshSlot>::iterator mit;
+       int i;
+
+
+       for(i=0; i<m_SolidBuckets.size(); i++) {
+               RAS_MaterialBucket *bucket = m_SolidBuckets[i];
+               if (mat == bucket->GetPolyMaterial()) {
+                       m_SolidBuckets.erase(m_SolidBuckets.begin()+i);
+                       delete bucket;
+                       i--;
+               }
+       }
+
+       for(int i=0; i<m_AlphaBuckets.size(); i++) {
+               RAS_MaterialBucket *bucket = m_AlphaBuckets[i];
+               if (mat == bucket->GetPolyMaterial()) {
+                       m_AlphaBuckets.erase(m_AlphaBuckets.begin()+i);
+                       delete bucket;
+                       i--;
+               }
+       }
+}
+
+//#include <stdio.h>
+
+void RAS_BucketManager::MergeBucketManager(RAS_BucketManager *other)
+{
+       /* concatinate lists */
+       // printf("BEFORE %d %d\n", GetSolidBuckets().size(), GetAlphaBuckets().size());
+       GetSolidBuckets().insert( GetSolidBuckets().end(), other->GetSolidBuckets().begin(), other->GetSolidBuckets().end() );
+       other->GetSolidBuckets().clear();
+
+       GetAlphaBuckets().insert( GetAlphaBuckets().end(), other->GetAlphaBuckets().begin(), other->GetAlphaBuckets().end() );
+       other->GetAlphaBuckets().clear();
+       //printf("AFTER %d %d\n", GetSolidBuckets().size(), GetAlphaBuckets().size());
+}
+
index dcac41ab6e9bb62c4e94d83943fd91bd0e06b734..75b5e12a05bc1c5a0122af5d59e56444e17ede33 100644 (file)
@@ -60,6 +60,21 @@ public:
        void ReleaseDisplayLists(RAS_IPolyMaterial * material = NULL);
        void ReleaseMaterials(RAS_IPolyMaterial * material = NULL);
 
+       void RemoveMaterial(RAS_IPolyMaterial * mat); // freeing scenes only
+
+       /* for merging */
+       void MergeBucketManager(RAS_BucketManager *other);
+       BucketList & GetSolidBuckets() {return m_SolidBuckets;};
+       BucketList & GetAlphaBuckets() {return m_AlphaBuckets;};
+
+       /*void PrintStats(int verbose_level) {
+               printf("\nMappings...\n");
+               printf("\t m_SolidBuckets: %d\n", m_SolidBuckets.size());
+               printf("\t\t m_SolidBuckets: %d\n", m_SolidBuckets.size());
+               printf("\t m_AlphaBuckets: %d\n", m_AlphaBuckets.size());
+       }*/
+
+
 private:
        void OrderBuckets(const MT_Transform& cameratrans, BucketList& buckets, vector<sortedmeshslot>& slots, bool alpha);
 
index af909dfa731779e31333305268eab102222170a0..a387d96c3837e450b7491d55849fdfcf7b899e43 100644 (file)
@@ -46,6 +46,7 @@ class RAS_IRasterizer;
 struct MTFace;
 struct Material;
 struct Scene;
+class SCA_IScene;
 
 enum MaterialProps
 {
@@ -164,6 +165,9 @@ public:
        virtual void            GetMaterialRGBAColor(unsigned char *rgba) const;
        virtual bool            UsesLighting(RAS_IRasterizer *rasty) const;
        virtual bool            UsesObjectColor() const;
+
+       virtual void            Replace_IScene(SCA_IScene *val) {}; /* overridden by KX_BlenderMaterial */
+
        /*
         * PreCalculate texture gen
         */
index 0995d5acdd5d69f7dfe9cb88566c4a8bb98b2f12..ffc18e5612f24d0e06f11b5d0b62d1a67d3eb8a6 100644 (file)
@@ -104,6 +104,10 @@ RAS_MeshObject::~RAS_MeshObject()
 
        for(it=m_Polygons.begin(); it!=m_Polygons.end(); it++)
                delete (*it);
+
+       m_sharedvertex_map.clear();
+       m_Polygons.clear();
+       m_materials.clear();
 }
 
 bool RAS_MeshObject::MeshModified()
index 1738423c4f30953def999c3be2284ed6a016cb1a..c9ca8152a7ed308025e88eb8a823a27e029943b7 100644 (file)
@@ -80,7 +80,7 @@ public:
        virtual ~RAS_MeshObject();
 
 
-       bool                            IsDeformed() { return m_bDeformed; }
+       bool                            IsDeformed() { return (m_bDeformed && m_mesh); }
        
        /* materials */
        int                                     NumMaterials();
index 23e6c1e9c99d232d256149ef1c2bac8920a928f4..523be0ef2795bdd6f1f961d1251ca908127ea682 100644 (file)
@@ -241,6 +241,22 @@ public:
                m_SGclientObject = clientObject;
        }
 
+
+       /* needed for scene switching */
+       inline const void* GetSGClientInfo() const
+       {
+               return m_SGclientInfo;
+       }
+       inline void* GetSGClientInfo()
+       {
+               return m_SGclientInfo;
+       }
+       void SetSGClientInfo(void* clientInfo)
+       {
+               m_SGclientInfo = clientInfo;
+       }
+
+
        /** 
         * Set the current simulation time for this node.
         * The implementation of this function runs through