Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp523
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.h35
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h5
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h8
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp13
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h1
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.h5
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h4
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h5
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h10
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.h12
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp13
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h4
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h7
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h5
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp155
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h6
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h7
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h5
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h5
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp191
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h19
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.h7
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h1
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h4
-rw-r--r--source/gameengine/Physics/Bullet/CcdGraphicController.cpp15
-rw-r--r--source/gameengine/Physics/Bullet/CcdGraphicController.h2
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp17
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h1
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp19
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h6
-rw-r--r--source/gameengine/Physics/common/PHY_IController.h7
-rw-r--r--source/gameengine/Physics/common/PHY_IGraphicController.h2
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.cpp41
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.h15
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h4
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp4
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h2
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.h16
42 files changed, 1164 insertions, 45 deletions
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 8e7560cdcbd..e599b89a2bb 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -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 @@ 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;
+}
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
index f74944d3552..62d771f1256 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.h
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -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();
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
index debefcc45b0..8d3610acc5f 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.h
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -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;
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
index 11885f988f3..cebfcf6bdc4 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.h
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -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
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 877563e3161..3191c99fb2f 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -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);
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index fce5f340be1..e01f5775289 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -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);
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index d93f2e70e36..848b7df6658 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -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)
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.h b/source/gameengine/GameLogic/SCA_LogicManager.h
index 402090357cb..0c2effc2516 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.h
+++ b/source/gameengine/GameLogic/SCA_LogicManager.h
@@ -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);
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
index fa7a674c250..95283dcce50 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
@@ -55,6 +55,10 @@ public:
virtual bool Update();
virtual CValue* GetReplica();
+ virtual void Replace_NetworkScene(NG_NetworkScene *val)
+ {
+ m_networkscene= val;
+ };
/* ------------------------------------------------------------ */
/* Python interface ------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
index 3a8fe760bb9..90ba5db15ef 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
@@ -66,6 +66,11 @@ public:
virtual void Init();
void EndFrame();
+ virtual void Replace_NetworkScene(NG_NetworkScene *val)
+ {
+ m_NetworkScene= val;
+ };
+
#ifndef DISABLE_PYTHON
/* ------------------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 0946cd320c5..088d17ea741 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -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();
diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp
index bc0f875bca6..d6e2a623007 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.cpp
+++ b/source/gameengine/Ketsji/KX_GameActuator.cpp
@@ -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)
{
diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h
index 37d09a5a9fb..4880d476e36 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.h
+++ b/source/gameengine/Ketsji/KX_GameActuator.h
@@ -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 ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 9f4fa9a7c02..6800b2aa871 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -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()
{
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 74d683fbad6..b815ca0c716 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -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();
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index d4063ef1d16..e3f0e2b34f5 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -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.
*/
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index dba12acee7f..4f7d7f7888d 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -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.
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 1339200a740..ae4f3498471 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -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 }
};
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index 39b447b5657..ea7dd544cb1 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -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 {
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index 4cccc406b58..53a71e3c6ea 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -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);
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
index 782a24b1ef1..b99f40be707 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
@@ -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 ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
index 47c823afa9f..5f62c603ac6 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
@@ -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);
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index c93ead74182..655c8eedaae 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -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
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index da72ba2ec98..4b01ab39d95 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -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;
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h
index e11a94798c9..4afa8926970 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.h
+++ b/source/gameengine/Ketsji/KX_SceneActuator.h
@@ -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 ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
index e6414a2e285..c3da11eb1e2 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.h
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -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
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index ae5b68da845..248ce170d71 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -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
diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
index 2dbbb7fa4a0..73ac789edf7 100644
--- a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp
@@ -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)
diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.h b/source/gameengine/Physics/Bullet/CcdGraphicController.h
index 99885eb99ee..07cf6d940cb 100644
--- a/source/gameengine/Physics/Bullet/CcdGraphicController.h
+++ b/source/gameengine/Physics/Bullet/CcdGraphicController.h
@@ -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
////////////////////////////////////
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index b7d0dd2f6e7..69b63affeef 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -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)
{
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 69b16ca35bd..02d723472f6 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -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);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index bf28802870a..22722c0927a 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -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()
{
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index e087eac32c5..21f74e95ed4 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -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];
diff --git a/source/gameengine/Physics/common/PHY_IController.h b/source/gameengine/Physics/common/PHY_IController.h
index a053a9679b8..e897de255c1 100644
--- a/source/gameengine/Physics/common/PHY_IController.h
+++ b/source/gameengine/Physics/common/PHY_IController.h
@@ -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
diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.h b/source/gameengine/Physics/common/PHY_IGraphicController.h
index aae971ff42a..eac3de68d4f 100644
--- a/source/gameengine/Physics/common/PHY_IGraphicController.h
+++ b/source/gameengine/Physics/common/PHY_IGraphicController.h
@@ -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); }
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index 664e5fddd83..b34f8417e4c 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -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.
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
index 8b3c4990a7a..f5750b39998 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -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());
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h
index dcac41ab6e9..75b5e12a05b 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.h
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.h
@@ -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);
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index af909dfa731..a387d96c383 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -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
*/
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 0995d5acdd5..ffc18e5612f 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -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()
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index 1738423c4f3..c9ca8152a7e 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -80,7 +80,7 @@ public:
virtual ~RAS_MeshObject();
- bool IsDeformed() { return m_bDeformed; }
+ bool IsDeformed() { return (m_bDeformed && m_mesh); }
/* materials */
int NumMaterials();
diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h
index 23e6c1e9c99..523be0ef279 100644
--- a/source/gameengine/SceneGraph/SG_IObject.h
+++ b/source/gameengine/SceneGraph/SG_IObject.h
@@ -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