|
Blender
V2.59
|
00001 /* 00002 * $Id: KX_BlenderSceneConverter.cpp 39044 2011-08-05 05:26:19Z campbellbarton $ 00003 * ***** BEGIN GPL LICENSE BLOCK ***** 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00020 * All rights reserved. 00021 * 00022 * The Original Code is: all of this file. 00023 * 00024 * Contributor(s): none yet. 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #if defined(WIN32) && !defined(FREE_WINDOWS) 00035 #pragma warning (disable:4786) // suppress stl-MSVC debug info warning 00036 #endif 00037 00038 #include "KX_Scene.h" 00039 #include "KX_GameObject.h" 00040 #include "KX_BlenderSceneConverter.h" 00041 #include "KX_IpoConvert.h" 00042 #include "RAS_MeshObject.h" 00043 #include "KX_PhysicsEngineEnums.h" 00044 #include "PHY_IPhysicsEnvironment.h" 00045 #include "KX_KetsjiEngine.h" 00046 #include "KX_IPhysicsController.h" 00047 #include "BL_Material.h" 00048 #include "BL_ActionActuator.h" 00049 #include "KX_BlenderMaterial.h" 00050 #include "KX_PolygonMaterial.h" 00051 00052 00053 #include "BL_System.h" 00054 00055 #include "DummyPhysicsEnvironment.h" 00056 00057 #include "KX_ConvertPhysicsObject.h" 00058 00059 #ifdef USE_BULLET 00060 #include "CcdPhysicsEnvironment.h" 00061 #endif 00062 00063 #include "KX_BlenderSceneConverter.h" 00064 #include "KX_BlenderScalarInterpolator.h" 00065 #include "BL_BlenderDataConversion.h" 00066 #include "BlenderWorldInfo.h" 00067 #include "KX_Scene.h" 00068 00069 /* This little block needed for linking to Blender... */ 00070 #ifdef WIN32 00071 #include "BLI_winstuff.h" 00072 #endif 00073 00074 /* This list includes only data type definitions */ 00075 #include "DNA_scene_types.h" 00076 #include "DNA_world_types.h" 00077 #include "BKE_main.h" 00078 00079 #include "BLI_math.h" 00080 00081 extern "C" 00082 { 00083 #include "DNA_object_types.h" 00084 #include "DNA_curve_types.h" 00085 #include "DNA_mesh_types.h" 00086 #include "DNA_material_types.h" 00087 #include "BLI_blenlib.h" 00088 #include "MEM_guardedalloc.h" 00089 #include "BKE_global.h" 00090 #include "BKE_animsys.h" 00091 #include "BKE_library.h" 00092 #include "BKE_material.h" // copy_material 00093 #include "BKE_mesh.h" // copy_mesh 00094 #include "DNA_space_types.h" 00095 #include "DNA_anim_types.h" 00096 #include "RNA_define.h" 00097 #include "../../blender/editors/include/ED_keyframing.h" 00098 } 00099 00100 /* Only for dynamic loading and merging */ 00101 #include "RAS_BucketManager.h" // XXX cant stay 00102 #include "KX_BlenderSceneConverter.h" 00103 #include "BL_BlenderDataConversion.h" 00104 #include "KX_MeshProxy.h" 00105 #include "RAS_MeshObject.h" 00106 extern "C" { 00107 #include "BKE_context.h" 00108 #include "BLO_readfile.h" 00109 #include "BKE_idcode.h" 00110 #include "BKE_report.h" 00111 #include "DNA_space_types.h" 00112 #include "DNA_windowmanager_types.h" /* report api */ 00113 #include "../../blender/blenlib/BLI_linklist.h" 00114 } 00115 00116 KX_BlenderSceneConverter::KX_BlenderSceneConverter( 00117 struct Main* maggie, 00118 class KX_KetsjiEngine* engine 00119 ) 00120 : m_maggie(maggie), 00121 /*m_maggie_dyn(NULL),*/ 00122 m_ketsjiEngine(engine), 00123 m_alwaysUseExpandFraming(false), 00124 m_usemat(false), 00125 m_useglslmat(false) 00126 { 00127 tag_main(maggie, 0); /* avoid re-tagging later on */ 00128 m_newfilename = ""; 00129 } 00130 00131 00132 KX_BlenderSceneConverter::~KX_BlenderSceneConverter() 00133 { 00134 // clears meshes, and hashmaps from blender to gameengine data 00135 int i; 00136 // delete sumoshapes 00137 00138 00139 int numAdtLists = m_map_blender_to_gameAdtList.size(); 00140 for (i=0; i<numAdtLists; i++) { 00141 BL_InterpolatorList *adtList= *m_map_blender_to_gameAdtList.at(i); 00142 00143 delete (adtList); 00144 } 00145 00146 vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itw = m_worldinfos.begin(); 00147 while (itw != m_worldinfos.end()) { 00148 delete (*itw).second; 00149 itw++; 00150 } 00151 00152 vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin(); 00153 while (itp != m_polymaterials.end()) { 00154 delete (*itp).second; 00155 itp++; 00156 } 00157 00158 // delete after RAS_IPolyMaterial 00159 vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin(); 00160 while (itmat != m_materials.end()) { 00161 delete (*itmat).second; 00162 itmat++; 00163 } 00164 00165 00166 vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin(); 00167 while (itm != m_meshobjects.end()) { 00168 delete (*itm).second; 00169 itm++; 00170 } 00171 00172 #ifdef USE_BULLET 00173 KX_ClearBulletSharedShapes(); 00174 #endif 00175 00176 /* free any data that was dynamically loaded */ 00177 for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) { 00178 Main *main= *it; 00179 free_main(main); 00180 } 00181 00182 m_DynamicMaggie.clear(); 00183 } 00184 00185 void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename) 00186 { 00187 m_newfilename = filename; 00188 } 00189 00190 00191 00192 bool KX_BlenderSceneConverter::TryAndLoadNewFile() 00193 { 00194 bool result = false; 00195 00196 // find the file 00197 /* if () 00198 { 00199 result = true; 00200 } 00201 // if not, clear the newfilename 00202 else 00203 { 00204 m_newfilename = ""; 00205 } 00206 */ 00207 return result; 00208 } 00209 00210 Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name) 00211 { 00212 Scene *sce; 00213 00218 if((sce= (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2))) 00219 return sce; 00220 00221 for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) { 00222 Main *main= *it; 00223 00224 if((sce= (Scene *)BLI_findstring(&main->scene, name.ReadPtr(), offsetof(ID, name) + 2))) 00225 return sce; 00226 } 00227 00228 return (Scene*)m_maggie->scene.first; 00229 00230 } 00231 #include "KX_PythonInit.h" 00232 00233 #ifdef USE_BULLET 00234 00235 #include "LinearMath/btIDebugDraw.h" 00236 00237 00238 struct BlenderDebugDraw : public btIDebugDraw 00239 { 00240 BlenderDebugDraw () : 00241 m_debugMode(0) 00242 { 00243 } 00244 00245 int m_debugMode; 00246 00247 virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) 00248 { 00249 if (m_debugMode >0) 00250 { 00251 MT_Vector3 kxfrom(from[0],from[1],from[2]); 00252 MT_Vector3 kxto(to[0],to[1],to[2]); 00253 MT_Vector3 kxcolor(color[0],color[1],color[2]); 00254 00255 KX_RasterizerDrawDebugLine(kxfrom,kxto,kxcolor); 00256 } 00257 } 00258 00259 virtual void reportErrorWarning(const char* warningString) 00260 { 00261 00262 } 00263 00264 virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color) 00265 { 00266 //not yet 00267 } 00268 00269 virtual void setDebugMode(int debugMode) 00270 { 00271 m_debugMode = debugMode; 00272 } 00273 virtual int getDebugMode() const 00274 { 00275 return m_debugMode; 00276 } 00278 virtual void draw3dText(const btVector3& location,const char* textString) 00279 { 00280 00281 } 00282 00283 }; 00284 00285 #endif 00286 00287 void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene, 00288 class RAS_IRenderTools* rendertools, 00289 class RAS_ICanvas* canvas) 00290 { 00291 //find out which physics engine 00292 Scene *blenderscene = destinationscene->GetBlenderScene(); 00293 00294 e_PhysicsEngine physics_engine = UseBullet; 00295 bool useDbvtCulling = false; 00296 // hook for registration function during conversion. 00297 m_currentScene = destinationscene; 00298 destinationscene->SetSceneConverter(this); 00299 SG_SetActiveStage(SG_STAGE_CONVERTER); 00300 00301 if (blenderscene) 00302 { 00303 00304 switch (blenderscene->gm.physicsEngine) 00305 { 00306 case WOPHY_BULLET: 00307 { 00308 physics_engine = UseBullet; 00309 useDbvtCulling = (blenderscene->gm.mode & WO_DBVT_CULLING) != 0; 00310 break; 00311 } 00312 00313 case WOPHY_ODE: 00314 { 00315 physics_engine = UseODE; 00316 break; 00317 } 00318 case WOPHY_DYNAMO: 00319 { 00320 physics_engine = UseDynamo; 00321 break; 00322 } 00323 case WOPHY_SUMO: 00324 { 00325 physics_engine = UseSumo; 00326 break; 00327 } 00328 case WOPHY_NONE: 00329 { 00330 physics_engine = UseNone; 00331 } 00332 } 00333 } 00334 00335 switch (physics_engine) 00336 { 00337 #ifdef USE_BULLET 00338 case UseBullet: 00339 { 00340 CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling); 00341 ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw()); 00342 ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python 00343 ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python 00344 00345 SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/ 00346 int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0); 00347 if (visualizePhysics) 00348 ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints); 00349 00350 //todo: get a button in blender ? 00351 //disable / enable debug drawing (contact points, aabb's etc) 00352 //ccdPhysEnv->setDebugMode(1); 00353 destinationscene->SetPhysicsEnvironment(ccdPhysEnv); 00354 break; 00355 } 00356 #endif 00357 case UseDynamo: 00358 { 00359 } 00360 00361 default: 00362 case UseNone: 00363 physics_engine = UseNone; 00364 destinationscene ->SetPhysicsEnvironment(new DummyPhysicsEnvironment()); 00365 break; 00366 } 00367 00368 BL_ConvertBlenderObjects(m_maggie, 00369 destinationscene, 00370 m_ketsjiEngine, 00371 physics_engine, 00372 rendertools, 00373 canvas, 00374 this, 00375 m_alwaysUseExpandFraming 00376 ); 00377 00378 //These lookup are not needed during game 00379 m_map_blender_to_gameactuator.clear(); 00380 m_map_blender_to_gamecontroller.clear(); 00381 m_map_blender_to_gameobject.clear(); 00382 00383 //Clearing this lookup table has the effect of disabling the cache of meshes 00384 //between scenes, even if they are shared in the blend file. 00385 //This cache mecanism is buggy so I leave it disable and the memory leak 00386 //that would result from this is fixed in RemoveScene() 00387 m_map_mesh_to_gamemesh.clear(); 00388 } 00389 00390 // This function removes all entities stored in the converter for that scene 00391 // It should be used instead of direct delete scene 00392 // Note that there was some provision for sharing entities (meshes...) between 00393 // scenes but that is now disabled so all scene will have their own copy 00394 // and we can delete them here. If the sharing is reactivated, change this code too.. 00395 // (see KX_BlenderSceneConverter::ConvertScene) 00396 void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene) 00397 { 00398 int i, size; 00399 // delete the scene first as it will stop the use of entities 00400 delete scene; 00401 // delete the entities of this scene 00402 vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; 00403 size = m_worldinfos.size(); 00404 for (i=0, worldit=m_worldinfos.begin(); i<size; ) { 00405 if ((*worldit).first == scene) { 00406 delete (*worldit).second; 00407 *worldit = m_worldinfos.back(); 00408 m_worldinfos.pop_back(); 00409 size--; 00410 } else { 00411 i++; 00412 worldit++; 00413 } 00414 } 00415 00416 vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit; 00417 size = m_polymaterials.size(); 00418 for (i=0, polymit=m_polymaterials.begin(); i<size; ) { 00419 if ((*polymit).first == scene) { 00420 delete (*polymit).second; 00421 *polymit = m_polymaterials.back(); 00422 m_polymaterials.pop_back(); 00423 size--; 00424 } else { 00425 i++; 00426 polymit++; 00427 } 00428 } 00429 00430 vector<pair<KX_Scene*,BL_Material*> >::iterator matit; 00431 size = m_materials.size(); 00432 for (i=0, matit=m_materials.begin(); i<size; ) { 00433 if ((*matit).first == scene) { 00434 delete (*matit).second; 00435 *matit = m_materials.back(); 00436 m_materials.pop_back(); 00437 size--; 00438 } else { 00439 i++; 00440 matit++; 00441 } 00442 } 00443 00444 vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit; 00445 size = m_meshobjects.size(); 00446 for (i=0, meshit=m_meshobjects.begin(); i<size; ) { 00447 if ((*meshit).first == scene) { 00448 delete (*meshit).second; 00449 *meshit = m_meshobjects.back(); 00450 m_meshobjects.pop_back(); 00451 size--; 00452 } else { 00453 i++; 00454 meshit++; 00455 } 00456 } 00457 } 00458 00459 // use blender materials 00460 void KX_BlenderSceneConverter::SetMaterials(bool val) 00461 { 00462 m_usemat = val; 00463 m_useglslmat = false; 00464 } 00465 00466 void KX_BlenderSceneConverter::SetGLSLMaterials(bool val) 00467 { 00468 m_usemat = val; 00469 m_useglslmat = val; 00470 } 00471 00472 bool KX_BlenderSceneConverter::GetMaterials() 00473 { 00474 return m_usemat; 00475 } 00476 00477 bool KX_BlenderSceneConverter::GetGLSLMaterials() 00478 { 00479 return m_useglslmat; 00480 } 00481 00482 void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat) 00483 { 00484 m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat)); 00485 } 00486 00487 00488 00489 void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming( 00490 bool to_what) 00491 { 00492 m_alwaysUseExpandFraming= to_what; 00493 } 00494 00495 00496 00497 void KX_BlenderSceneConverter::RegisterGameObject( 00498 KX_GameObject *gameobject, 00499 struct Object *for_blenderobject) 00500 { 00501 /* only maintained while converting, freed during game runtime */ 00502 m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject); 00503 } 00504 00505 /* only need to run this during conversion since 00506 * m_map_blender_to_gameobject is freed after conversion */ 00507 void KX_BlenderSceneConverter::UnregisterGameObject( 00508 KX_GameObject *gameobject) 00509 { 00510 struct Object *bobp= gameobject->GetBlenderObject(); 00511 if (bobp) { 00512 CHashedPtr bptr(bobp); 00513 KX_GameObject **gobp= m_map_blender_to_gameobject[bptr]; 00514 if (gobp && *gobp == gameobject) 00515 { 00516 // also maintain m_map_blender_to_gameobject if the gameobject 00517 // being removed is matching the blender object 00518 m_map_blender_to_gameobject.remove(bptr); 00519 } 00520 } 00521 } 00522 00523 KX_GameObject *KX_BlenderSceneConverter::FindGameObject( 00524 struct Object *for_blenderobject) 00525 { 00526 KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)]; 00527 00528 return obp?*obp:NULL; 00529 } 00530 00531 void KX_BlenderSceneConverter::RegisterGameMesh( 00532 RAS_MeshObject *gamemesh, 00533 struct Mesh *for_blendermesh) 00534 { 00535 if(for_blendermesh) { /* dynamically loaded meshes we dont want to keep lookups for */ 00536 m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh); 00537 } 00538 m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh)); 00539 } 00540 00541 00542 00543 RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh( 00544 struct Mesh *for_blendermesh/*, 00545 unsigned int onlayer*/) 00546 { 00547 RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)]; 00548 00549 if (meshp/* && onlayer==(*meshp)->GetLightLayer()*/) { 00550 return *meshp; 00551 } else { 00552 return NULL; 00553 } 00554 } 00555 00556 00557 00558 00559 00560 00561 void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat) 00562 { 00563 m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat)); 00564 } 00565 00566 00567 00568 void KX_BlenderSceneConverter::RegisterInterpolatorList( 00569 BL_InterpolatorList *adtList, 00570 struct AnimData *for_adt) 00571 { 00572 m_map_blender_to_gameAdtList.insert(CHashedPtr(for_adt), adtList); 00573 } 00574 00575 00576 00577 BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList( 00578 struct AnimData *for_adt) 00579 { 00580 BL_InterpolatorList **listp = m_map_blender_to_gameAdtList[CHashedPtr(for_adt)]; 00581 00582 return listp?*listp:NULL; 00583 } 00584 00585 00586 00587 void KX_BlenderSceneConverter::RegisterGameActuator( 00588 SCA_IActuator *act, 00589 struct bActuator *for_actuator) 00590 { 00591 m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act); 00592 } 00593 00594 00595 00596 SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator( 00597 struct bActuator *for_actuator) 00598 { 00599 SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)]; 00600 00601 return actp?*actp:NULL; 00602 } 00603 00604 00605 00606 void KX_BlenderSceneConverter::RegisterGameController( 00607 SCA_IController *cont, 00608 struct bController *for_controller) 00609 { 00610 m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont); 00611 } 00612 00613 00614 00615 SCA_IController *KX_BlenderSceneConverter::FindGameController( 00616 struct bController *for_controller) 00617 { 00618 SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)]; 00619 00620 return contp?*contp:NULL; 00621 } 00622 00623 00624 00625 void KX_BlenderSceneConverter::RegisterWorldInfo( 00626 KX_WorldInfo *worldinfo) 00627 { 00628 m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo)); 00629 } 00630 00631 void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) 00632 { 00633 00634 KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); 00635 int numScenes = scenes->size(); 00636 int i; 00637 for (i=0;i<numScenes;i++) 00638 { 00639 KX_Scene* scene = scenes->at(i); 00640 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment(); 00641 CListValue* parentList = scene->GetRootParentList(); 00642 int numObjects = parentList->GetCount(); 00643 int g; 00644 for (g=0;g<numObjects;g++) 00645 { 00646 KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g); 00647 if (gameObj->IsDynamic()) 00648 { 00649 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); 00650 00651 Object* blenderObject = gameObj->GetBlenderObject(); 00652 if (blenderObject) 00653 { 00654 #if 0 00655 //erase existing ipo's 00656 Ipo* ipo = blenderObject->ipo;//findIpoForName(blenderObject->id.name+2); 00657 if (ipo) 00658 { //clear the curve data 00659 if (clearIpo){//rcruiz 00660 IpoCurve *icu1; 00661 00662 int numCurves = 0; 00663 for( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) { 00664 00665 IpoCurve* tmpicu = icu1; 00666 00667 /*int i; 00668 BezTriple *bezt; 00669 for( bezt = tmpicu->bezt, i = 0; i < tmpicu->totvert; i++, bezt++){ 00670 printf("(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",bezt->vec[0][0],bezt->vec[0][1],bezt->vec[0][2],bezt->vec[1][0],bezt->vec[1][1],bezt->vec[1][2],bezt->vec[2][0],bezt->vec[2][1],bezt->vec[2][2]); 00671 }*/ 00672 00673 icu1 = icu1->next; 00674 numCurves++; 00675 00676 BLI_remlink( &( blenderObject->ipo->curve ), tmpicu ); 00677 if( tmpicu->bezt ) 00678 MEM_freeN( tmpicu->bezt ); 00679 MEM_freeN( tmpicu ); 00680 localDel_ipoCurve( tmpicu ); 00681 } 00682 } 00683 } else 00684 { ipo = NULL; // XXX add_ipo(blenderObject->id.name+2, ID_OB); 00685 blenderObject->ipo = ipo; 00686 00687 } 00688 #endif 00689 } 00690 } 00691 00692 } 00693 00694 00695 } 00696 00697 00698 00699 } 00700 00701 void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo(){ 00702 00703 if (addInitFromFrame){ 00704 KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); 00705 int numScenes = scenes->size(); 00706 if (numScenes>=0){ 00707 KX_Scene* scene = scenes->at(0); 00708 CListValue* parentList = scene->GetRootParentList(); 00709 for (int ix=0;ix<parentList->GetCount();ix++){ 00710 KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix); 00711 if (!gameobj->IsDynamic()){ 00712 Object* blenderobject = gameobj->GetBlenderObject(); 00713 if (!blenderobject) 00714 continue; 00715 if (blenderobject->type==OB_ARMATURE) 00716 continue; 00717 float eu[3]; 00718 mat4_to_eul(eu,blenderobject->obmat); 00719 MT_Point3 pos = MT_Point3( 00720 blenderobject->obmat[3][0], 00721 blenderobject->obmat[3][1], 00722 blenderobject->obmat[3][2] 00723 ); 00724 MT_Vector3 eulxyz = MT_Vector3( 00725 eu[0], 00726 eu[1], 00727 eu[2] 00728 ); 00729 MT_Vector3 scale = MT_Vector3( 00730 blenderobject->size[0], 00731 blenderobject->size[1], 00732 blenderobject->size[2] 00733 ); 00734 gameobj->NodeSetLocalPosition(pos); 00735 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); 00736 gameobj->NodeSetLocalScale(scale); 00737 gameobj->NodeUpdateGS(0); 00738 } 00739 } 00740 } 00741 } 00742 } 00743 00744 00746 void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber) 00747 { 00748 00749 KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); 00750 int numScenes = scenes->size(); 00751 int i; 00752 for (i=0;i<numScenes;i++) 00753 { 00754 KX_Scene* scene = scenes->at(i); 00755 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment(); 00756 CListValue* parentList = scene->GetObjectList(); 00757 int numObjects = parentList->GetCount(); 00758 int g; 00759 for (g=0;g<numObjects;g++) 00760 { 00761 KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g); 00762 Object* blenderObject = gameObj->GetBlenderObject(); 00763 if (blenderObject && blenderObject->parent==NULL && gameObj->GetPhysicsController() != NULL) 00764 { 00765 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); 00766 00767 if(blenderObject->adt==NULL) 00768 BKE_id_add_animdata(&blenderObject->id); 00769 00770 if (blenderObject->adt) 00771 { 00772 const MT_Point3& position = gameObj->NodeGetWorldPosition(); 00773 //const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); 00774 const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation(); 00775 00776 position.getValue(blenderObject->loc); 00777 00778 float tmat[3][3]; 00779 for (int r=0;r<3;r++) 00780 for (int c=0;c<3;c++) 00781 tmat[r][c] = (float)orn[c][r]; 00782 00783 mat3_to_compatible_eul(blenderObject->rot, blenderObject->rot, tmat); 00784 00785 insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "location", -1, (float)frameNumber, INSERTKEY_FAST); 00786 insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "rotation_euler", -1, (float)frameNumber, INSERTKEY_FAST); 00787 00788 #if 0 00789 const MT_Point3& position = gameObj->NodeGetWorldPosition(); 00790 //const MT_Vector3& scale = gameObj->NodeGetWorldScaling(); 00791 const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation(); 00792 00793 float eulerAngles[3]; 00794 float eulerAnglesOld[3] = {0.0f, 0.0f, 0.0f}; 00795 float tmat[3][3]; 00796 00797 // XXX animato 00798 Ipo* ipo = blenderObject->ipo; 00799 00800 //create the curves, if not existing, set linear if new 00801 00802 IpoCurve *icu_lx = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"); 00803 if (!icu_lx) { 00804 icu_lx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1); 00805 if(icu_lx) icu_lx->ipo = IPO_LIN; 00806 } 00807 IpoCurve *icu_ly = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"); 00808 if (!icu_ly) { 00809 icu_ly = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1); 00810 if(icu_ly) icu_ly->ipo = IPO_LIN; 00811 } 00812 IpoCurve *icu_lz = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"); 00813 if (!icu_lz) { 00814 icu_lz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1); 00815 if(icu_lz) icu_lz->ipo = IPO_LIN; 00816 } 00817 IpoCurve *icu_rx = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"); 00818 if (!icu_rx) { 00819 icu_rx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1); 00820 if(icu_rx) icu_rx->ipo = IPO_LIN; 00821 } 00822 IpoCurve *icu_ry = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"); 00823 if (!icu_ry) { 00824 icu_ry = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1); 00825 if(icu_ry) icu_ry->ipo = IPO_LIN; 00826 } 00827 IpoCurve *icu_rz = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"); 00828 if (!icu_rz) { 00829 icu_rz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1); 00830 if(icu_rz) icu_rz->ipo = IPO_LIN; 00831 } 00832 00833 if(icu_rx) eulerAnglesOld[0]= eval_icu( icu_rx, frameNumber - 1 ) / ((180 / 3.14159265f) / 10); 00834 if(icu_ry) eulerAnglesOld[1]= eval_icu( icu_ry, frameNumber - 1 ) / ((180 / 3.14159265f) / 10); 00835 if(icu_rz) eulerAnglesOld[2]= eval_icu( icu_rz, frameNumber - 1 ) / ((180 / 3.14159265f) / 10); 00836 00837 // orn.getValue((float *)tmat); // uses the wrong ordering, cant use this 00838 for (int r=0;r<3;r++) 00839 for (int c=0;c<3;c++) 00840 tmat[r][c] = orn[c][r]; 00841 00842 // mat3_to_eul( eulerAngles,tmat); // better to use Mat3ToCompatibleEul 00843 mat3_to_compatible_eul( eulerAngles, eulerAnglesOld,tmat); 00844 00845 //eval_icu 00846 for(int x = 0; x < 3; x++) 00847 eulerAngles[x] *= (float) ((180 / 3.14159265f) / 10.0); 00848 00849 //fill the curves with data 00850 if (icu_lx) insert_vert_icu(icu_lx, frameNumber, position.x(), 1); 00851 if (icu_ly) insert_vert_icu(icu_ly, frameNumber, position.y(), 1); 00852 if (icu_lz) insert_vert_icu(icu_lz, frameNumber, position.z(), 1); 00853 if (icu_rx) insert_vert_icu(icu_rx, frameNumber, eulerAngles[0], 1); 00854 if (icu_ry) insert_vert_icu(icu_ry, frameNumber, eulerAngles[1], 1); 00855 if (icu_rz) insert_vert_icu(icu_rz, frameNumber, eulerAngles[2], 1); 00856 00857 // Handles are corrected at the end, testhandles_ipocurve isnt needed yet 00858 #endif 00859 } 00860 } 00861 } 00862 } 00863 } 00864 00865 00866 void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo() 00867 { 00868 00869 KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); 00870 int numScenes = scenes->size(); 00871 int i; 00872 for (i=0;i<numScenes;i++) 00873 { 00874 KX_Scene* scene = scenes->at(i); 00875 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment(); 00876 CListValue* parentList = scene->GetRootParentList(); 00877 int numObjects = parentList->GetCount(); 00878 int g; 00879 for (g=0;g<numObjects;g++) 00880 { 00881 KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g); 00882 if (gameObj->IsDynamic()) 00883 { 00884 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController(); 00885 00886 Object* blenderObject = gameObj->GetBlenderObject(); 00887 if (blenderObject && blenderObject->ipo) 00888 { 00889 // XXX animato 00890 #if 0 00891 Ipo* ipo = blenderObject->ipo; 00892 00893 //create the curves, if not existing 00894 //testhandles_ipocurve checks for NULL 00895 testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocX")); 00896 testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocY")); 00897 testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ")); 00898 testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotX")); 00899 testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotY")); 00900 testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ")); 00901 #endif 00902 } 00903 } 00904 00905 } 00906 00907 00908 } 00909 00910 00911 00912 } 00913 00914 #ifdef WITH_PYTHON 00915 PyObject *KX_BlenderSceneConverter::GetPyNamespace() 00916 { 00917 return m_ketsjiEngine->GetPyNamespace(); 00918 } 00919 #endif 00920 00921 vector<Main*> &KX_BlenderSceneConverter::GetMainDynamic() 00922 { 00923 return m_DynamicMaggie; 00924 } 00925 00926 Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path) 00927 { 00928 for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) 00929 if(BLI_path_cmp((*it)->name, path) == 0) 00930 return *it; 00931 00932 return NULL; 00933 } 00934 00935 bool KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) 00936 { 00937 BlendHandle *bpy_openlib = BLO_blendhandle_from_memory(data, length); 00938 00939 // Error checking is done in LinkBlendFile 00940 return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options); 00941 } 00942 00943 bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) 00944 { 00945 BlendHandle *bpy_openlib = BLO_blendhandle_from_file((char *)path, NULL); 00946 00947 // Error checking is done in LinkBlendFile 00948 return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options); 00949 } 00950 00951 bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options) 00952 { 00953 Main *main_newlib; /* stored as a dynamic 'main' until we free it */ 00954 Main *main_tmp= NULL; /* created only for linking, then freed */ 00955 LinkNode *names = NULL; 00956 int idcode= BKE_idcode_from_name(group); 00957 short flag= 0; /* dont need any special options */ 00958 ReportList reports; 00959 static char err_local[255]; 00960 00961 /* only scene and mesh supported right now */ 00962 if(idcode!=ID_SCE && idcode!=ID_ME &&idcode!=ID_AC) { 00963 snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group); 00964 *err_str= err_local; 00965 BLO_blendhandle_close(bpy_openlib); 00966 return false; 00967 } 00968 00969 if(GetMainDynamicPath(path)) { 00970 snprintf(err_local, sizeof(err_local), "blend file already open \"%s\"\n", path); 00971 *err_str= err_local; 00972 BLO_blendhandle_close(bpy_openlib); 00973 return false; 00974 } 00975 00976 if(bpy_openlib==NULL) { 00977 snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path); 00978 *err_str= err_local; 00979 return false; 00980 } 00981 00982 main_newlib= (Main *)MEM_callocN( sizeof(Main), "BgeMain"); 00983 BKE_reports_init(&reports, RPT_STORE); 00984 00985 /* here appending/linking starts */ 00986 main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); 00987 00988 int totnames_dummy; 00989 names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode, &totnames_dummy); 00990 00991 int i=0; 00992 LinkNode *n= names; 00993 while(n) { 00994 BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, idcode); 00995 n= (LinkNode *)n->next; 00996 i++; 00997 } 00998 BLI_linklist_free(names, free); /* free linklist *and* each node's data */ 00999 01000 BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag); 01001 01002 /* now do another round of linking for Scenes so all actions are properly loaded */ 01003 if (idcode==ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) { 01004 main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path); 01005 01006 int totnames_dummy; 01007 names = BLO_blendhandle_get_datablock_names( bpy_openlib, ID_AC, &totnames_dummy); 01008 01009 int i=0; 01010 LinkNode *n= names; 01011 while(n) { 01012 BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, ID_AC); 01013 n= (LinkNode *)n->next; 01014 i++; 01015 } 01016 BLI_linklist_free(names, free); /* free linklist *and* each node's data */ 01017 01018 BLO_library_append_end(NULL, main_tmp, &bpy_openlib, ID_AC, flag); 01019 } 01020 01021 BLO_blendhandle_close(bpy_openlib); 01022 01023 BKE_reports_clear(&reports); 01024 /* done linking */ 01025 01026 /* needed for lookups*/ 01027 GetMainDynamic().push_back(main_newlib); 01028 strncpy(main_newlib->name, path, sizeof(main_newlib->name)); 01029 01030 01031 if(idcode==ID_ME) { 01032 /* Convert all new meshes into BGE meshes */ 01033 ID* mesh; 01034 01035 for(mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) { 01036 if (options & LIB_LOAD_VERBOSE) 01037 printf("MeshName: %s\n", mesh->name+2); 01038 RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this); 01039 scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); 01040 } 01041 } 01042 else if(idcode==ID_AC) { 01043 /* Convert all actions */ 01044 ID *action; 01045 01046 for(action= (ID *)main_newlib->action.first; action; action= (ID *)action->next) { 01047 if (options & LIB_LOAD_VERBOSE) 01048 printf("ActionName: %s\n", action->name+2); 01049 scene_merge->GetLogicManager()->RegisterActionName(action->name+2, action); 01050 } 01051 } 01052 else if(idcode==ID_SCE) { 01053 /* Merge all new linked in scene into the existing one */ 01054 ID *scene; 01055 for(scene= (ID *)main_newlib->scene.first; scene; scene= (ID *)scene->next ) { 01056 if (options & LIB_LOAD_VERBOSE) 01057 printf("SceneName: %s\n", scene->name+2); 01058 01059 /* merge into the base scene */ 01060 KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene); 01061 scene_merge->MergeScene(other); 01062 01063 // RemoveScene(other); // Dont run this, it frees the entire scene converter data, just delete the scene 01064 delete other; 01065 } 01066 01067 /* Now handle all the actions */ 01068 if (options & LIB_LOAD_LOAD_ACTIONS) { 01069 ID *action; 01070 01071 for(action= (ID *)main_newlib->action.first; action; action= (ID *)action->next) { 01072 if (options & LIB_LOAD_VERBOSE) 01073 printf("ActionName: %s\n", action->name+2); 01074 scene_merge->GetLogicManager()->RegisterActionName(action->name+2, action); 01075 } 01076 } 01077 } 01078 01079 return true; 01080 } 01081 01082 /* Note m_map_*** are all ok and dont need to be freed 01083 * most are temp and NewRemoveObject frees m_map_gameobject_to_blender */ 01084 bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie) 01085 { 01086 int maggie_index; 01087 int i=0; 01088 01089 if(maggie==NULL) 01090 return false; 01091 01092 /* tag all false except the one we remove */ 01093 for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) { 01094 Main *main= *it; 01095 if(main != maggie) { 01096 tag_main(main, 0); 01097 } 01098 else { 01099 maggie_index= i; 01100 } 01101 i++; 01102 } 01103 01104 m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index); 01105 tag_main(maggie, 1); 01106 01107 01108 /* free all tagged objects */ 01109 KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); 01110 int numScenes = scenes->size(); 01111 01112 01113 for (int scene_idx=0;scene_idx<numScenes;scene_idx++) 01114 { 01115 KX_Scene* scene = scenes->at(scene_idx); 01116 if(IS_TAGGED(scene->GetBlenderScene())) { 01117 RemoveScene(scene); // XXX - not tested yet 01118 scene_idx--; 01119 numScenes--; 01120 } 01121 else { 01122 01123 /* incase the mesh might be refered to later */ 01124 { 01125 CTR_Map<STR_HashedString,void*> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap(); 01126 01127 for(int i=0; i<mapStringToMeshes.size(); i++) 01128 { 01129 RAS_MeshObject *meshobj= (RAS_MeshObject *) *mapStringToMeshes.at(i); 01130 if(meshobj && IS_TAGGED(meshobj->GetMesh())) 01131 { 01132 STR_HashedString mn = meshobj->GetName(); 01133 mapStringToMeshes.remove(mn); 01134 m_map_mesh_to_gamemesh.remove(CHashedPtr(meshobj->GetMesh())); 01135 i--; 01136 } 01137 } 01138 } 01139 01140 /* Now unregister actions */ 01141 { 01142 CTR_Map<STR_HashedString,void*> &mapStringToActions = scene->GetLogicManager()->GetActionMap(); 01143 01144 for(int i=0; i<mapStringToActions.size(); i++) 01145 { 01146 ID *action= (ID*) *mapStringToActions.at(i); 01147 01148 if(IS_TAGGED(action)) 01149 { 01150 STR_HashedString an = action->name+2; 01151 mapStringToActions.remove(an); 01152 i--; 01153 } 01154 } 01155 } 01156 01157 //scene->FreeTagged(); /* removed tagged objects and meshes*/ 01158 CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL}; 01159 01160 for(int ob_ls_idx=0; obj_lists[ob_ls_idx]; ob_ls_idx++) 01161 { 01162 CListValue *obs= obj_lists[ob_ls_idx]; 01163 RAS_MeshObject* mesh; 01164 01165 for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++) 01166 { 01167 KX_GameObject* gameobj = (KX_GameObject*)obs->GetValue(ob_idx); 01168 if(IS_TAGGED(gameobj->GetBlenderObject())) { 01169 01170 int size_before = obs->GetCount(); 01171 01172 /* Eventually calls RemoveNodeDestructObject 01173 * frees m_map_gameobject_to_blender from UnregisterGameObject */ 01174 scene->RemoveObject(gameobj); 01175 01176 if(size_before != obs->GetCount()) 01177 ob_idx--; 01178 else { 01179 printf("ERROR COULD NOT REMOVE \"%s\"\n", gameobj->GetName().ReadPtr()); 01180 } 01181 } 01182 else { 01183 /* free the mesh, we could be referecing a linked one! */ 01184 int mesh_index= gameobj->GetMeshCount(); 01185 while(mesh_index--) { 01186 mesh= gameobj->GetMesh(mesh_index); 01187 if(IS_TAGGED(mesh->GetMesh())) { 01188 gameobj->RemoveMeshes(); /* XXX - slack, should only remove meshes that are library items but mostly objects only have 1 mesh */ 01189 break; 01190 } 01191 } 01192 01193 /* make sure action actuators are not referencing tagged actions */ 01194 for (unsigned int act_idx=0; act_idx<gameobj->GetActuators().size(); act_idx++) 01195 { 01196 if (gameobj->GetActuators()[act_idx]->IsType(SCA_IActuator::KX_ACT_ACTION)) 01197 { 01198 BL_ActionActuator *act = (BL_ActionActuator*)gameobj->GetActuators()[act_idx]; 01199 if(IS_TAGGED(act->GetAction())) 01200 act->SetAction(NULL); 01201 } 01202 } 01203 } 01204 } 01205 } 01206 } 01207 } 01208 01209 01210 int size; 01211 01212 // delete the entities of this scene 01213 /* TODO - */ 01214 /* 01215 vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; 01216 size = m_worldinfos.size(); 01217 for (i=0, worldit=m_worldinfos.begin(); i<size; ) { 01218 if ((*worldit).second) { 01219 delete (*worldit).second; 01220 *worldit = m_worldinfos.back(); 01221 m_worldinfos.pop_back(); 01222 size--; 01223 } else { 01224 i++; 01225 worldit++; 01226 } 01227 }*/ 01228 01229 01230 /* Worlds dont reference original blender data so we need to make a set from them */ 01231 typedef std::set<KX_WorldInfo*> KX_WorldInfoSet; 01232 KX_WorldInfoSet worldset; 01233 for (int scene_idx=0;scene_idx<numScenes;scene_idx++) 01234 { 01235 KX_Scene* scene = scenes->at(scene_idx); 01236 if(scene->GetWorldInfo()) 01237 worldset.insert( scene->GetWorldInfo() ); 01238 } 01239 01240 vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; 01241 size = m_worldinfos.size(); 01242 for (i=0, worldit=m_worldinfos.begin(); i<size; ) { 01243 if ((*worldit).second && (worldset.count((*worldit).second)) == 0) { 01244 delete (*worldit).second; 01245 *worldit = m_worldinfos.back(); 01246 m_worldinfos.pop_back(); 01247 size--; 01248 } else { 01249 i++; 01250 worldit++; 01251 } 01252 } 01253 worldset.clear(); 01254 /* done freeing the worlds */ 01255 01256 01257 01258 01259 vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit; 01260 size = m_polymaterials.size(); 01261 01262 01263 01264 for (i=0, polymit=m_polymaterials.begin(); i<size; ) { 01265 RAS_IPolyMaterial *mat= (*polymit).second; 01266 Material *bmat= NULL; 01267 01268 /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */ 01269 if(mat->GetFlag() & RAS_BLENDERMAT) { 01270 KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat); 01271 bmat= bl_mat->GetBlenderMaterial(); 01272 01273 } else { 01274 KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat); 01275 bmat= kx_mat->GetBlenderMaterial(); 01276 } 01277 01278 if (IS_TAGGED(bmat)) { 01279 /* only remove from bucket */ 01280 ((*polymit).first)->GetBucketManager()->RemoveMaterial(mat); 01281 } 01282 01283 i++; 01284 polymit++; 01285 } 01286 01287 01288 01289 for (i=0, polymit=m_polymaterials.begin(); i<size; ) { 01290 RAS_IPolyMaterial *mat= (*polymit).second; 01291 Material *bmat= NULL; 01292 01293 /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */ 01294 if(mat->GetFlag() & RAS_BLENDERMAT) { 01295 KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat); 01296 bmat= bl_mat->GetBlenderMaterial(); 01297 01298 } else { 01299 KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat); 01300 bmat= kx_mat->GetBlenderMaterial(); 01301 } 01302 01303 if(bmat) { 01304 //printf("FOUND MAT '%s' !!! ", ((ID*)bmat)->name+2); 01305 } 01306 else { 01307 //printf("LOST MAT !!!"); 01308 } 01309 01310 if (IS_TAGGED(bmat)) { 01311 01312 delete (*polymit).second; 01313 *polymit = m_polymaterials.back(); 01314 m_polymaterials.pop_back(); 01315 size--; 01316 //printf("tagged !\n"); 01317 } else { 01318 i++; 01319 polymit++; 01320 //printf("(un)tagged !\n"); 01321 } 01322 } 01323 01324 vector<pair<KX_Scene*,BL_Material*> >::iterator matit; 01325 size = m_materials.size(); 01326 for (i=0, matit=m_materials.begin(); i<size; ) { 01327 BL_Material *mat= (*matit).second; 01328 if (IS_TAGGED(mat->material)) { 01329 delete (*matit).second; 01330 *matit = m_materials.back(); 01331 m_materials.pop_back(); 01332 size--; 01333 } else { 01334 i++; 01335 matit++; 01336 } 01337 } 01338 01339 vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit; 01340 size = m_meshobjects.size(); 01341 for (i=0, meshit=m_meshobjects.begin(); i<size; ) { 01342 RAS_MeshObject *me= (*meshit).second; 01343 if (IS_TAGGED(me->GetMesh())) { 01344 delete (*meshit).second; 01345 *meshit = m_meshobjects.back(); 01346 m_meshobjects.pop_back(); 01347 size--; 01348 } else { 01349 i++; 01350 meshit++; 01351 } 01352 } 01353 01354 free_main(maggie); 01355 01356 return true; 01357 } 01358 01359 bool KX_BlenderSceneConverter::FreeBlendFile(const char *path) 01360 { 01361 return FreeBlendFile(GetMainDynamicPath(path)); 01362 } 01363 01364 bool KX_BlenderSceneConverter::MergeScene(KX_Scene *to, KX_Scene *from) 01365 { 01366 01367 { 01368 vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itp = m_worldinfos.begin(); 01369 while (itp != m_worldinfos.end()) { 01370 if ((*itp).first==from) 01371 (*itp).first= to; 01372 itp++; 01373 } 01374 } 01375 01376 { 01377 vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin(); 01378 while (itp != m_polymaterials.end()) { 01379 if ((*itp).first==from) { 01380 (*itp).first= to; 01381 01382 /* also switch internal data */ 01383 RAS_IPolyMaterial*mat= (*itp).second; 01384 mat->Replace_IScene(to); 01385 } 01386 itp++; 01387 } 01388 } 01389 01390 { 01391 vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itp = m_meshobjects.begin(); 01392 while (itp != m_meshobjects.end()) { 01393 if ((*itp).first==from) 01394 (*itp).first= to; 01395 itp++; 01396 } 01397 } 01398 01399 { 01400 vector<pair<KX_Scene*,BL_Material*> >::iterator itp = m_materials.begin(); 01401 while (itp != m_materials.end()) { 01402 if ((*itp).first==from) 01403 (*itp).first= to; 01404 itp++; 01405 } 01406 } 01407 01408 return true; 01409 } 01410 01411 /* This function merges a mesh from the current scene into another main 01412 * it does not convert */ 01413 RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name) 01414 { 01415 /* Find a mesh in the current main */ 01416 ID *me= static_cast<ID *>(BLI_findstring(&m_maggie->mesh, name, offsetof(ID, name) + 2)); 01417 01418 if(me==NULL) { 01419 printf("Could not be found \"%s\"\n", name); 01420 return NULL; 01421 } 01422 01423 /* Watch this!, if its used in the original scene can cause big troubles */ 01424 if(me->us > 0) { 01425 printf("Mesh has a user \"%s\"\n", name); 01426 me = (ID*)copy_mesh((Mesh*)me); 01427 me->us--; 01428 } 01429 BLI_remlink(&m_maggie->mesh, me); /* even if we made the copy it needs to be removed */ 01430 BLI_addtail(&maggie->mesh, me); 01431 01432 01433 /* Must copy the materials this uses else we cant free them */ 01434 { 01435 Mesh *mesh= (Mesh *)me; 01436 01437 /* ensure all materials are tagged */ 01438 for(int i=0; i<mesh->totcol; i++) 01439 if(mesh->mat[i]) 01440 mesh->mat[i]->id.flag &= ~LIB_DOIT; 01441 01442 for(int i=0; i<mesh->totcol; i++) 01443 { 01444 Material *mat_old= mesh->mat[i]; 01445 01446 /* if its tagged its a replaced material */ 01447 if(mat_old && (mat_old->id.flag & LIB_DOIT)==0) 01448 { 01449 Material *mat_old= mesh->mat[i]; 01450 Material *mat_new= copy_material( mat_old ); 01451 01452 mat_new->id.flag |= LIB_DOIT; 01453 mat_old->id.us--; 01454 01455 BLI_remlink(&m_maggie->mat, mat_new); 01456 BLI_addtail(&maggie->mat, mat_new); 01457 01458 mesh->mat[i]= mat_new; 01459 01460 /* the same material may be used twice */ 01461 for(int j=i+1; j<mesh->totcol; j++) 01462 { 01463 if(mesh->mat[j]==mat_old) 01464 { 01465 mesh->mat[j]= mat_new; 01466 mat_new->id.us++; 01467 mat_old->id.us--; 01468 } 01469 } 01470 } 01471 } 01472 } 01473 01474 RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this); 01475 kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); 01476 m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */ 01477 return meshobj; 01478 }