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