diff options
Diffstat (limited to 'source/gameengine/Converter/KX_BlenderSceneConverter.cpp')
-rw-r--r-- | source/gameengine/Converter/KX_BlenderSceneConverter.cpp | 196 |
1 files changed, 153 insertions, 43 deletions
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 067fce3eefe..3fcb4765c67 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -100,7 +100,8 @@ KX_BlenderSceneConverter::KX_BlenderSceneConverter( m_sipo(sipo), m_ketsjiEngine(engine), m_alwaysUseExpandFraming(false), - m_usemat(false) + m_usemat(false), + m_useglslmat(false) { m_newfilename = ""; } @@ -120,29 +121,29 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (ipoList); } - vector<KX_WorldInfo*>::iterator itw = m_worldinfos.begin(); + vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itw = m_worldinfos.begin(); while (itw != m_worldinfos.end()) { - delete (*itw); + delete (*itw).second; itw++; } - vector<RAS_IPolyMaterial*>::iterator itp = m_polymaterials.begin(); + vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin(); while (itp != m_polymaterials.end()) { - delete (*itp); + delete (*itp).second; itp++; } // delete after RAS_IPolyMaterial - vector<BL_Material *>::iterator itmat = m_materials.begin(); + vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin(); while (itmat != m_materials.end()) { - delete (*itmat); + delete (*itmat).second; itmat++; } - vector<RAS_MeshObject*>::iterator itm = m_meshobjects.begin(); + vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin(); while (itm != m_meshobjects.end()) { - delete (*itm); + delete (*itm).second; itm++; } @@ -183,20 +184,21 @@ bool KX_BlenderSceneConverter::TryAndLoadNewFile() return result; } - +Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name) +{ + Scene *sce; /** * Find the specified scene by name, or the first * scene if nothing matches (shouldn't happen). */ -static struct Scene *GetSceneForName2(struct Main *maggie, const STR_String& scenename) { - Scene *sce; - for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next) - if (scenename == (sce->id.name+2)) + for (sce= (Scene*) m_maggie->scene.first; sce; sce= (Scene*) sce->id.next) + if (name == (sce->id.name+2)) return sce; - return (Scene*) maggie->scene.first; + return (Scene*)m_maggie->scene.first; + } #include "KX_PythonInit.h" @@ -244,6 +246,11 @@ struct BlenderDebugDraw : public btIDebugDraw { return m_debugMode; } + ///todo: find out if Blender can do this + virtual void draw3dText(const btVector3& location,const char* textString) + { + + } }; @@ -257,9 +264,12 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, class RAS_ICanvas* canvas) { //find out which physics engine - Scene *blenderscene = GetSceneForName2(m_maggie, scenename); + Scene *blenderscene = GetBlenderSceneForName(scenename); e_PhysicsEngine physics_engine = UseBullet; + // hook for registration function during conversion. + m_currentScene = destinationscene; + destinationscene->SetSceneConverter(this); if (blenderscene) { @@ -357,21 +367,102 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename, m_alwaysUseExpandFraming ); + //These lookup are not needed during game m_map_blender_to_gameactuator.clear(); m_map_blender_to_gamecontroller.clear(); - m_map_blender_to_gameobject.clear(); - m_map_mesh_to_gamemesh.clear(); - //don't clear it yet, it is needed for the baking physics into ipo animation + //Clearing this lookup table has the effect of disabling the cache of meshes + //between scenes, even if they are shared in the blend file. + //This cache mecanism is buggy so I leave it disable and the memory leak + //that would result from this is fixed in RemoveScene() + m_map_mesh_to_gamemesh.clear(); + //Don't clear this lookup, it is needed for the baking physics into ipo animation + //To avoid it's infinite grows, object will be unregister when they are deleted + //see KX_Scene::NewRemoveObject //m_map_gameobject_to_blender.clear(); } +// This function removes all entities stored in the converter for that scene +// It should be used instead of direct delete scene +// Note that there was some provision for sharing entities (meshes...) between +// scenes but that is now disabled so all scene will have their own copy +// and we can delete them here. If the sharing is reactivated, change this code too.. +// (see KX_BlenderSceneConverter::ConvertScene) +void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene) +{ + int i, size; + // delete the scene first as it will stop the use of entities + delete scene; + // delete the entities of this scene + vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; + size = m_worldinfos.size(); + for (i=0, worldit=m_worldinfos.begin(); i<size; ) { + if ((*worldit).first == scene) { + delete (*worldit).second; + *worldit = m_worldinfos.back(); + m_worldinfos.pop_back(); + size--; + } else { + i++; + worldit++; + } + } + + vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit; + size = m_polymaterials.size(); + for (i=0, polymit=m_polymaterials.begin(); i<size; ) { + if ((*polymit).first == scene) { + delete (*polymit).second; + *polymit = m_polymaterials.back(); + m_polymaterials.pop_back(); + size--; + } else { + i++; + polymit++; + } + } + + vector<pair<KX_Scene*,BL_Material*> >::iterator matit; + size = m_materials.size(); + for (i=0, matit=m_materials.begin(); i<size; ) { + if ((*matit).first == scene) { + 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; ) { + if ((*meshit).first == scene) { + delete (*meshit).second; + *meshit = m_meshobjects.back(); + m_meshobjects.pop_back(); + size--; + } else { + i++; + meshit++; + } + } +} // use blender materials void KX_BlenderSceneConverter::SetMaterials(bool val) { m_usemat = val; + m_useglslmat = false; +} + +void KX_BlenderSceneConverter::SetGLSLMaterials(bool val) +{ + m_usemat = val; + m_useglslmat = val; } bool KX_BlenderSceneConverter::GetMaterials() @@ -379,10 +470,14 @@ bool KX_BlenderSceneConverter::GetMaterials() return m_usemat; } +bool KX_BlenderSceneConverter::GetGLSLMaterials() +{ + return m_useglslmat; +} void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat) { - m_materials.push_back(mat); + m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat)); } @@ -403,6 +498,21 @@ void KX_BlenderSceneConverter::RegisterGameObject( m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject); } +void KX_BlenderSceneConverter::UnregisterGameObject( + KX_GameObject *gameobject) +{ + CHashedPtr gptr(gameobject); + struct Object **bobp= m_map_gameobject_to_blender[gptr]; + if (bobp) { + CHashedPtr bptr(*bobp); + KX_GameObject **gobp= m_map_blender_to_gameobject[bptr]; + if (gobp && *gobp == gameobject) + // also maintain m_map_blender_to_gameobject if the gameobject + // being removed is matching the blender object + m_map_blender_to_gameobject.remove(bptr); + m_map_gameobject_to_blender.remove(gptr); + } +} KX_GameObject *KX_BlenderSceneConverter::FindGameObject( @@ -430,7 +540,7 @@ void KX_BlenderSceneConverter::RegisterGameMesh( struct Mesh *for_blendermesh) { m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh); - m_meshobjects.push_back(gamemesh); + m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh)); } @@ -455,7 +565,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh( void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat) { - m_polymaterials.push_back(polymat); + m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat)); } @@ -520,7 +630,7 @@ SCA_IController *KX_BlenderSceneConverter::FindGameController( void KX_BlenderSceneConverter::RegisterWorldInfo( KX_WorldInfo *worldinfo) { - m_worldinfos.push_back(worldinfo); + m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo)); } /* @@ -552,13 +662,13 @@ extern "C" { Ipo *add_ipo( char *name, int idcode ); char *getIpoCurveName( IpoCurve * icu ); - struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int); + struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int, short); void testhandles_ipocurve(struct IpoCurve *icu); + void insert_vert_icu(struct IpoCurve *, float, float, short); void Mat3ToEul(float tmat[][3], float *eul); - } -IpoCurve* findIpoCurve(IpoCurve* first,char* searchName) +IpoCurve* findIpoCurve(IpoCurve* first, const char* searchName) { IpoCurve* icu1; for( icu1 = first; icu1; icu1 = icu1->next ) @@ -726,7 +836,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g); if (gameObj->IsDynamic()) { - KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); + //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); Object* blenderObject = FindBlenderObject(gameObj); if (blenderObject) @@ -754,7 +864,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) - const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); + //const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); const MT_Point3& position = gameObj->NodeGetWorldPosition(); Ipo* ipo = blenderObject->ipo; @@ -765,27 +875,27 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) IpoCurve *icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1); @@ -882,7 +992,7 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo() KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g); if (gameObj->IsDynamic()) { - KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); + //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); Object* blenderObject = FindBlenderObject(gameObj); if (blenderObject) @@ -910,8 +1020,8 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo() - const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); - const MT_Point3& position = gameObj->NodeGetWorldPosition(); + //const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); + //const MT_Point3& position = gameObj->NodeGetWorldPosition(); Ipo* ipo = blenderObject->ipo; if (ipo) @@ -921,27 +1031,27 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo() IpoCurve *icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1); icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); if (!icu1) - icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z); + icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1); |