diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2009-11-16 02:58:56 +0300 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2009-11-16 02:58:56 +0300 |
commit | b45ab480e07931406785c8fc877e7cee849c8998 (patch) | |
tree | 88dbf52d49d1a3c26a5f4683517cfd3d7d7adcbf /source/gameengine/Ketsji | |
parent | 349fa813eaf413cd2f472e545e7ce2cb6b087b1c (diff) |
BGE: dynamic loading patch commited. API and demo files available here: https://projects.blender.org/tracker/?func=detail&aid=19492&group_id=9&atid=127
Diffstat (limited to 'source/gameengine/Ketsji')
19 files changed, 434 insertions, 28 deletions
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 |