PageRenderTime 86ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/blender-2.63a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp

#
C++ | 1464 lines | 1051 code | 264 blank | 149 comment | 192 complexity | bc7dbdfd38a0d535b17d475891708648 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-3.0, BSD-2-Clause, Apache-2.0, AGPL-1.0
  1. /*
  2. * ***** BEGIN GPL LICENSE BLOCK *****
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software Foundation,
  16. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. *
  18. * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  19. * All rights reserved.
  20. *
  21. * The Original Code is: all of this file.
  22. *
  23. * Contributor(s): none yet.
  24. *
  25. * ***** END GPL LICENSE BLOCK *****
  26. */
  27. /** \file gameengine/Converter/KX_BlenderSceneConverter.cpp
  28. * \ingroup bgeconv
  29. */
  30. #if defined(WIN32) && !defined(FREE_WINDOWS)
  31. #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
  32. #endif
  33. #include "KX_Scene.h"
  34. #include "KX_GameObject.h"
  35. #include "KX_BlenderSceneConverter.h"
  36. #include "KX_IpoConvert.h"
  37. #include "RAS_MeshObject.h"
  38. #include "KX_PhysicsEngineEnums.h"
  39. #include "PHY_IPhysicsEnvironment.h"
  40. #include "KX_KetsjiEngine.h"
  41. #include "KX_IPhysicsController.h"
  42. #include "BL_Material.h"
  43. #include "BL_ActionActuator.h"
  44. #include "KX_BlenderMaterial.h"
  45. #include "KX_PolygonMaterial.h"
  46. #include "BL_System.h"
  47. #include "DummyPhysicsEnvironment.h"
  48. #include "KX_ConvertPhysicsObject.h"
  49. #ifdef USE_BULLET
  50. #include "CcdPhysicsEnvironment.h"
  51. #endif
  52. #include "KX_BlenderSceneConverter.h"
  53. #include "KX_BlenderScalarInterpolator.h"
  54. #include "BL_BlenderDataConversion.h"
  55. #include "BlenderWorldInfo.h"
  56. #include "KX_Scene.h"
  57. /* This little block needed for linking to Blender... */
  58. #ifdef WIN32
  59. #include "BLI_winstuff.h"
  60. #endif
  61. /* This list includes only data type definitions */
  62. #include "DNA_scene_types.h"
  63. #include "DNA_world_types.h"
  64. #include "BKE_main.h"
  65. #include "BLI_math.h"
  66. extern "C"
  67. {
  68. #include "DNA_object_types.h"
  69. #include "DNA_curve_types.h"
  70. #include "DNA_mesh_types.h"
  71. #include "DNA_material_types.h"
  72. #include "BLI_blenlib.h"
  73. #include "MEM_guardedalloc.h"
  74. #include "BKE_global.h"
  75. #include "BKE_animsys.h"
  76. #include "BKE_library.h"
  77. #include "BKE_material.h" // copy_material
  78. #include "BKE_mesh.h" // copy_mesh
  79. #include "DNA_space_types.h"
  80. #include "DNA_anim_types.h"
  81. #include "RNA_define.h"
  82. #include "../../blender/editors/include/ED_keyframing.h"
  83. }
  84. /* Only for dynamic loading and merging */
  85. #include "RAS_BucketManager.h" // XXX cant stay
  86. #include "KX_BlenderSceneConverter.h"
  87. #include "BL_BlenderDataConversion.h"
  88. #include "KX_MeshProxy.h"
  89. #include "RAS_MeshObject.h"
  90. extern "C" {
  91. #include "BKE_context.h"
  92. #include "BLO_readfile.h"
  93. #include "BKE_idcode.h"
  94. #include "BKE_report.h"
  95. #include "DNA_space_types.h"
  96. #include "DNA_windowmanager_types.h" /* report api */
  97. #include "../../blender/blenlib/BLI_linklist.h"
  98. }
  99. KX_BlenderSceneConverter::KX_BlenderSceneConverter(
  100. struct Main* maggie,
  101. class KX_KetsjiEngine* engine
  102. )
  103. : m_maggie(maggie),
  104. /*m_maggie_dyn(NULL),*/
  105. m_ketsjiEngine(engine),
  106. m_alwaysUseExpandFraming(false),
  107. m_usemat(false),
  108. m_useglslmat(false)
  109. {
  110. tag_main(maggie, 0); /* avoid re-tagging later on */
  111. m_newfilename = "";
  112. }
  113. KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
  114. {
  115. // clears meshes, and hashmaps from blender to gameengine data
  116. int i;
  117. // delete sumoshapes
  118. int numAdtLists = m_map_blender_to_gameAdtList.size();
  119. for (i=0; i<numAdtLists; i++) {
  120. BL_InterpolatorList *adtList= *m_map_blender_to_gameAdtList.at(i);
  121. delete (adtList);
  122. }
  123. vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itw = m_worldinfos.begin();
  124. while (itw != m_worldinfos.end()) {
  125. delete (*itw).second;
  126. itw++;
  127. }
  128. vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
  129. while (itp != m_polymaterials.end()) {
  130. delete (*itp).second;
  131. itp++;
  132. }
  133. // delete after RAS_IPolyMaterial
  134. vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
  135. while (itmat != m_materials.end()) {
  136. delete (*itmat).second;
  137. itmat++;
  138. }
  139. vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin();
  140. while (itm != m_meshobjects.end()) {
  141. delete (*itm).second;
  142. itm++;
  143. }
  144. #ifdef USE_BULLET
  145. KX_ClearBulletSharedShapes();
  146. #endif
  147. /* free any data that was dynamically loaded */
  148. for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
  149. Main *main= *it;
  150. free_main(main);
  151. }
  152. m_DynamicMaggie.clear();
  153. }
  154. void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
  155. {
  156. m_newfilename = filename;
  157. }
  158. bool KX_BlenderSceneConverter::TryAndLoadNewFile()
  159. {
  160. bool result = false;
  161. // find the file
  162. /* if ()
  163. {
  164. result = true;
  165. }
  166. // if not, clear the newfilename
  167. else
  168. {
  169. m_newfilename = "";
  170. }
  171. */
  172. return result;
  173. }
  174. Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
  175. {
  176. Scene *sce;
  177. /**
  178. * Find the specified scene by name, or the first
  179. * scene if nothing matches (shouldn't happen).
  180. */
  181. if ((sce= (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
  182. return sce;
  183. for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
  184. Main *main= *it;
  185. if ((sce= (Scene *)BLI_findstring(&main->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
  186. return sce;
  187. }
  188. return (Scene*)m_maggie->scene.first;
  189. }
  190. #include "KX_PythonInit.h"
  191. #ifdef USE_BULLET
  192. #include "LinearMath/btIDebugDraw.h"
  193. struct BlenderDebugDraw : public btIDebugDraw
  194. {
  195. BlenderDebugDraw () :
  196. m_debugMode(0)
  197. {
  198. }
  199. int m_debugMode;
  200. virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
  201. {
  202. if (m_debugMode >0)
  203. {
  204. MT_Vector3 kxfrom(from[0],from[1],from[2]);
  205. MT_Vector3 kxto(to[0],to[1],to[2]);
  206. MT_Vector3 kxcolor(color[0],color[1],color[2]);
  207. KX_RasterizerDrawDebugLine(kxfrom,kxto,kxcolor);
  208. }
  209. }
  210. virtual void reportErrorWarning(const char* warningString)
  211. {
  212. }
  213. virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)
  214. {
  215. //not yet
  216. }
  217. virtual void setDebugMode(int debugMode)
  218. {
  219. m_debugMode = debugMode;
  220. }
  221. virtual int getDebugMode() const
  222. {
  223. return m_debugMode;
  224. }
  225. ///todo: find out if Blender can do this
  226. virtual void draw3dText(const btVector3& location,const char* textString)
  227. {
  228. }
  229. };
  230. #endif
  231. void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
  232. class RAS_IRenderTools* rendertools,
  233. class RAS_ICanvas* canvas)
  234. {
  235. //find out which physics engine
  236. Scene *blenderscene = destinationscene->GetBlenderScene();
  237. e_PhysicsEngine physics_engine = UseBullet;
  238. bool useDbvtCulling = false;
  239. // hook for registration function during conversion.
  240. m_currentScene = destinationscene;
  241. destinationscene->SetSceneConverter(this);
  242. SG_SetActiveStage(SG_STAGE_CONVERTER);
  243. if (blenderscene)
  244. {
  245. switch (blenderscene->gm.physicsEngine)
  246. {
  247. case WOPHY_BULLET:
  248. {
  249. physics_engine = UseBullet;
  250. useDbvtCulling = (blenderscene->gm.mode & WO_DBVT_CULLING) != 0;
  251. break;
  252. }
  253. default:
  254. case WOPHY_NONE:
  255. {
  256. physics_engine = UseNone;
  257. break;
  258. }
  259. }
  260. }
  261. switch (physics_engine)
  262. {
  263. #ifdef USE_BULLET
  264. case UseBullet:
  265. {
  266. CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling);
  267. ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw());
  268. ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python
  269. ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python
  270. SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
  271. int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
  272. if (visualizePhysics)
  273. ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints);
  274. //todo: get a button in blender ?
  275. //disable / enable debug drawing (contact points, aabb's etc)
  276. //ccdPhysEnv->setDebugMode(1);
  277. destinationscene->SetPhysicsEnvironment(ccdPhysEnv);
  278. break;
  279. }
  280. #endif
  281. default:
  282. case UseNone:
  283. physics_engine = UseNone;
  284. destinationscene ->SetPhysicsEnvironment(new DummyPhysicsEnvironment());
  285. break;
  286. }
  287. BL_ConvertBlenderObjects(m_maggie,
  288. destinationscene,
  289. m_ketsjiEngine,
  290. physics_engine,
  291. rendertools,
  292. canvas,
  293. this,
  294. m_alwaysUseExpandFraming
  295. );
  296. //These lookup are not needed during game
  297. m_map_blender_to_gameactuator.clear();
  298. m_map_blender_to_gamecontroller.clear();
  299. m_map_blender_to_gameobject.clear();
  300. //Clearing this lookup table has the effect of disabling the cache of meshes
  301. //between scenes, even if they are shared in the blend file.
  302. //This cache mecanism is buggy so I leave it disable and the memory leak
  303. //that would result from this is fixed in RemoveScene()
  304. m_map_mesh_to_gamemesh.clear();
  305. #ifndef USE_BULLET
  306. /* quiet compiler warning */
  307. (void)useDbvtCulling;
  308. #endif
  309. }
  310. // This function removes all entities stored in the converter for that scene
  311. // It should be used instead of direct delete scene
  312. // Note that there was some provision for sharing entities (meshes...) between
  313. // scenes but that is now disabled so all scene will have their own copy
  314. // and we can delete them here. If the sharing is reactivated, change this code too..
  315. // (see KX_BlenderSceneConverter::ConvertScene)
  316. void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
  317. {
  318. int i, size;
  319. // delete the scene first as it will stop the use of entities
  320. delete scene;
  321. // delete the entities of this scene
  322. vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
  323. size = m_worldinfos.size();
  324. for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
  325. if ((*worldit).first == scene) {
  326. delete (*worldit).second;
  327. *worldit = m_worldinfos.back();
  328. m_worldinfos.pop_back();
  329. size--;
  330. } else {
  331. i++;
  332. worldit++;
  333. }
  334. }
  335. vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit;
  336. size = m_polymaterials.size();
  337. for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
  338. if ((*polymit).first == scene) {
  339. delete (*polymit).second;
  340. *polymit = m_polymaterials.back();
  341. m_polymaterials.pop_back();
  342. size--;
  343. } else {
  344. i++;
  345. polymit++;
  346. }
  347. }
  348. vector<pair<KX_Scene*,BL_Material*> >::iterator matit;
  349. size = m_materials.size();
  350. for (i=0, matit=m_materials.begin(); i<size; ) {
  351. if ((*matit).first == scene) {
  352. delete (*matit).second;
  353. *matit = m_materials.back();
  354. m_materials.pop_back();
  355. size--;
  356. } else {
  357. i++;
  358. matit++;
  359. }
  360. }
  361. vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
  362. size = m_meshobjects.size();
  363. for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
  364. if ((*meshit).first == scene) {
  365. delete (*meshit).second;
  366. *meshit = m_meshobjects.back();
  367. m_meshobjects.pop_back();
  368. size--;
  369. } else {
  370. i++;
  371. meshit++;
  372. }
  373. }
  374. }
  375. // use blender materials
  376. void KX_BlenderSceneConverter::SetMaterials(bool val)
  377. {
  378. m_usemat = val;
  379. m_useglslmat = false;
  380. }
  381. void KX_BlenderSceneConverter::SetGLSLMaterials(bool val)
  382. {
  383. m_usemat = val;
  384. m_useglslmat = val;
  385. }
  386. bool KX_BlenderSceneConverter::GetMaterials()
  387. {
  388. return m_usemat;
  389. }
  390. bool KX_BlenderSceneConverter::GetGLSLMaterials()
  391. {
  392. return m_useglslmat;
  393. }
  394. void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
  395. {
  396. m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
  397. }
  398. void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(
  399. bool to_what)
  400. {
  401. m_alwaysUseExpandFraming= to_what;
  402. }
  403. void KX_BlenderSceneConverter::RegisterGameObject(
  404. KX_GameObject *gameobject,
  405. struct Object *for_blenderobject)
  406. {
  407. /* only maintained while converting, freed during game runtime */
  408. m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
  409. }
  410. /* only need to run this during conversion since
  411. * m_map_blender_to_gameobject is freed after conversion */
  412. void KX_BlenderSceneConverter::UnregisterGameObject(
  413. KX_GameObject *gameobject)
  414. {
  415. struct Object *bobp= gameobject->GetBlenderObject();
  416. if (bobp) {
  417. CHashedPtr bptr(bobp);
  418. KX_GameObject **gobp= m_map_blender_to_gameobject[bptr];
  419. if (gobp && *gobp == gameobject)
  420. {
  421. // also maintain m_map_blender_to_gameobject if the gameobject
  422. // being removed is matching the blender object
  423. m_map_blender_to_gameobject.remove(bptr);
  424. }
  425. }
  426. }
  427. KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
  428. struct Object *for_blenderobject)
  429. {
  430. KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
  431. return obp?*obp:NULL;
  432. }
  433. void KX_BlenderSceneConverter::RegisterGameMesh(
  434. RAS_MeshObject *gamemesh,
  435. struct Mesh *for_blendermesh)
  436. {
  437. if (for_blendermesh) { /* dynamically loaded meshes we don't want to keep lookups for */
  438. m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
  439. }
  440. m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh));
  441. }
  442. RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
  443. struct Mesh *for_blendermesh/*,
  444. unsigned int onlayer*/)
  445. {
  446. RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
  447. if (meshp/* && onlayer==(*meshp)->GetLightLayer()*/) {
  448. return *meshp;
  449. } else {
  450. return NULL;
  451. }
  452. }
  453. void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
  454. {
  455. m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
  456. }
  457. void KX_BlenderSceneConverter::RegisterInterpolatorList(
  458. BL_InterpolatorList *actList,
  459. struct bAction *for_act)
  460. {
  461. m_map_blender_to_gameAdtList.insert(CHashedPtr(for_act), actList);
  462. }
  463. BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
  464. struct bAction *for_act)
  465. {
  466. BL_InterpolatorList **listp = m_map_blender_to_gameAdtList[CHashedPtr(for_act)];
  467. return listp?*listp:NULL;
  468. }
  469. void KX_BlenderSceneConverter::RegisterGameActuator(
  470. SCA_IActuator *act,
  471. struct bActuator *for_actuator)
  472. {
  473. m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
  474. }
  475. SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
  476. struct bActuator *for_actuator)
  477. {
  478. SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
  479. return actp?*actp:NULL;
  480. }
  481. void KX_BlenderSceneConverter::RegisterGameController(
  482. SCA_IController *cont,
  483. struct bController *for_controller)
  484. {
  485. m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
  486. }
  487. SCA_IController *KX_BlenderSceneConverter::FindGameController(
  488. struct bController *for_controller)
  489. {
  490. SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
  491. return contp?*contp:NULL;
  492. }
  493. void KX_BlenderSceneConverter::RegisterWorldInfo(
  494. KX_WorldInfo *worldinfo)
  495. {
  496. m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
  497. }
  498. void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
  499. {
  500. KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
  501. int numScenes = scenes->size();
  502. int i;
  503. for (i=0;i<numScenes;i++)
  504. {
  505. KX_Scene* scene = scenes->at(i);
  506. //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
  507. CListValue* parentList = scene->GetRootParentList();
  508. int numObjects = parentList->GetCount();
  509. int g;
  510. for (g=0;g<numObjects;g++)
  511. {
  512. KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
  513. if (gameObj->IsDynamic())
  514. {
  515. //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
  516. Object* blenderObject = gameObj->GetBlenderObject();
  517. if (blenderObject)
  518. {
  519. #if 0
  520. //erase existing ipo's
  521. Ipo* ipo = blenderObject->ipo;//findIpoForName(blenderObject->id.name+2);
  522. if (ipo)
  523. { //clear the curve data
  524. if (clearIpo) {//rcruiz
  525. IpoCurve *icu1;
  526. int numCurves = 0;
  527. for ( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) {
  528. IpoCurve* tmpicu = icu1;
  529. /*int i;
  530. BezTriple *bezt;
  531. for ( bezt = tmpicu->bezt, i = 0; i < tmpicu->totvert; i++, bezt++) {
  532. 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]);
  533. }*/
  534. icu1 = icu1->next;
  535. numCurves++;
  536. BLI_remlink( &( blenderObject->ipo->curve ), tmpicu );
  537. if ( tmpicu->bezt )
  538. MEM_freeN( tmpicu->bezt );
  539. MEM_freeN( tmpicu );
  540. localDel_ipoCurve( tmpicu );
  541. }
  542. }
  543. } else
  544. { ipo = NULL; // XXX add_ipo(blenderObject->id.name+2, ID_OB);
  545. blenderObject->ipo = ipo;
  546. }
  547. #endif
  548. }
  549. }
  550. }
  551. }
  552. }
  553. void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo()
  554. {
  555. if (addInitFromFrame) {
  556. KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
  557. int numScenes = scenes->size();
  558. if (numScenes>=0) {
  559. KX_Scene* scene = scenes->at(0);
  560. CListValue* parentList = scene->GetRootParentList();
  561. for (int ix=0;ix<parentList->GetCount();ix++) {
  562. KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix);
  563. if (!gameobj->IsDynamic()) {
  564. Object* blenderobject = gameobj->GetBlenderObject();
  565. if (!blenderobject)
  566. continue;
  567. if (blenderobject->type==OB_ARMATURE)
  568. continue;
  569. float eu[3];
  570. mat4_to_eul(eu,blenderobject->obmat);
  571. MT_Point3 pos = MT_Point3(
  572. blenderobject->obmat[3][0],
  573. blenderobject->obmat[3][1],
  574. blenderobject->obmat[3][2]
  575. );
  576. MT_Vector3 eulxyz = MT_Vector3(
  577. eu[0],
  578. eu[1],
  579. eu[2]
  580. );
  581. MT_Vector3 scale = MT_Vector3(
  582. blenderobject->size[0],
  583. blenderobject->size[1],
  584. blenderobject->size[2]
  585. );
  586. gameobj->NodeSetLocalPosition(pos);
  587. gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
  588. gameobj->NodeSetLocalScale(scale);
  589. gameobj->NodeUpdateGS(0);
  590. }
  591. }
  592. }
  593. }
  594. }
  595. ///this generates ipo curves for position, rotation, allowing to use game physics in animation
  596. void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
  597. {
  598. KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
  599. int numScenes = scenes->size();
  600. int i;
  601. for (i=0;i<numScenes;i++)
  602. {
  603. KX_Scene* scene = scenes->at(i);
  604. //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
  605. CListValue* parentList = scene->GetObjectList();
  606. int numObjects = parentList->GetCount();
  607. int g;
  608. for (g=0;g<numObjects;g++)
  609. {
  610. KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
  611. Object* blenderObject = gameObj->GetBlenderObject();
  612. if (blenderObject && blenderObject->parent==NULL && gameObj->IsDynamic())
  613. {
  614. //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
  615. if (blenderObject->adt==NULL)
  616. BKE_id_add_animdata(&blenderObject->id);
  617. if (blenderObject->adt)
  618. {
  619. const MT_Point3& position = gameObj->NodeGetWorldPosition();
  620. //const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
  621. const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
  622. position.getValue(blenderObject->loc);
  623. float tmat[3][3];
  624. for (int r=0;r<3;r++)
  625. for (int c=0;c<3;c++)
  626. tmat[r][c] = (float)orn[c][r];
  627. mat3_to_compatible_eul(blenderObject->rot, blenderObject->rot, tmat);
  628. insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "location", -1, (float)frameNumber, INSERTKEY_FAST);
  629. insert_keyframe(NULL, &blenderObject->id, NULL, NULL, "rotation_euler", -1, (float)frameNumber, INSERTKEY_FAST);
  630. #if 0
  631. const MT_Point3& position = gameObj->NodeGetWorldPosition();
  632. //const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
  633. const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
  634. float eulerAngles[3];
  635. float eulerAnglesOld[3] = {0.0f, 0.0f, 0.0f};
  636. float tmat[3][3];
  637. // XXX animato
  638. Ipo* ipo = blenderObject->ipo;
  639. //create the curves, if not existing, set linear if new
  640. IpoCurve *icu_lx = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
  641. if (!icu_lx) {
  642. icu_lx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1);
  643. if (icu_lx) icu_lx->ipo = IPO_LIN;
  644. }
  645. IpoCurve *icu_ly = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
  646. if (!icu_ly) {
  647. icu_ly = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1);
  648. if (icu_ly) icu_ly->ipo = IPO_LIN;
  649. }
  650. IpoCurve *icu_lz = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
  651. if (!icu_lz) {
  652. icu_lz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1);
  653. if (icu_lz) icu_lz->ipo = IPO_LIN;
  654. }
  655. IpoCurve *icu_rx = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
  656. if (!icu_rx) {
  657. icu_rx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1);
  658. if (icu_rx) icu_rx->ipo = IPO_LIN;
  659. }
  660. IpoCurve *icu_ry = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
  661. if (!icu_ry) {
  662. icu_ry = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1);
  663. if (icu_ry) icu_ry->ipo = IPO_LIN;
  664. }
  665. IpoCurve *icu_rz = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
  666. if (!icu_rz) {
  667. icu_rz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1);
  668. if (icu_rz) icu_rz->ipo = IPO_LIN;
  669. }
  670. if (icu_rx) eulerAnglesOld[0]= eval_icu( icu_rx, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
  671. if (icu_ry) eulerAnglesOld[1]= eval_icu( icu_ry, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
  672. if (icu_rz) eulerAnglesOld[2]= eval_icu( icu_rz, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
  673. // orn.getValue((float *)tmat); // uses the wrong ordering, cant use this
  674. for (int r=0;r<3;r++)
  675. for (int c=0;c<3;c++)
  676. tmat[r][c] = orn[c][r];
  677. // mat3_to_eul( eulerAngles,tmat); // better to use Mat3ToCompatibleEul
  678. mat3_to_compatible_eul( eulerAngles, eulerAnglesOld,tmat);
  679. //eval_icu
  680. for (int x = 0; x < 3; x++)
  681. eulerAngles[x] *= (float) ((180 / 3.14159265f) / 10.0);
  682. //fill the curves with data
  683. if (icu_lx) insert_vert_icu(icu_lx, frameNumber, position.x(), 1);
  684. if (icu_ly) insert_vert_icu(icu_ly, frameNumber, position.y(), 1);
  685. if (icu_lz) insert_vert_icu(icu_lz, frameNumber, position.z(), 1);
  686. if (icu_rx) insert_vert_icu(icu_rx, frameNumber, eulerAngles[0], 1);
  687. if (icu_ry) insert_vert_icu(icu_ry, frameNumber, eulerAngles[1], 1);
  688. if (icu_rz) insert_vert_icu(icu_rz, frameNumber, eulerAngles[2], 1);
  689. // Handles are corrected at the end, testhandles_ipocurve isn't needed yet
  690. #endif
  691. }
  692. }
  693. }
  694. }
  695. }
  696. void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
  697. {
  698. KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
  699. int numScenes = scenes->size();
  700. int i;
  701. for (i=0;i<numScenes;i++)
  702. {
  703. KX_Scene* scene = scenes->at(i);
  704. //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
  705. CListValue* parentList = scene->GetRootParentList();
  706. int numObjects = parentList->GetCount();
  707. int g;
  708. for (g=0;g<numObjects;g++)
  709. {
  710. KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
  711. if (gameObj->IsDynamic())
  712. {
  713. //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
  714. #if 0
  715. Object* blenderObject = gameObj->GetBlenderObject();
  716. if (blenderObject && blenderObject->ipo)
  717. {
  718. // XXX animato
  719. Ipo* ipo = blenderObject->ipo;
  720. //create the curves, if not existing
  721. //testhandles_ipocurve checks for NULL
  722. testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"));
  723. testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"));
  724. testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"));
  725. testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"));
  726. testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"));
  727. testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"));
  728. }
  729. #endif
  730. }
  731. }
  732. }
  733. }
  734. #ifdef WITH_PYTHON
  735. PyObject *KX_BlenderSceneConverter::GetPyNamespace()
  736. {
  737. return m_ketsjiEngine->GetPyNamespace();
  738. }
  739. #endif
  740. vector<Main*> &KX_BlenderSceneConverter::GetMainDynamic()
  741. {
  742. return m_DynamicMaggie;
  743. }
  744. Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path)
  745. {
  746. for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++)
  747. if (BLI_path_cmp((*it)->name, path) == 0)
  748. return *it;
  749. return NULL;
  750. }
  751. bool KX_BlenderSceneConverter::LinkBlendFileMemory(void *data, int length, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
  752. {
  753. BlendHandle *bpy_openlib = BLO_blendhandle_from_memory(data, length);
  754. // Error checking is done in LinkBlendFile
  755. return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options);
  756. }
  757. bool KX_BlenderSceneConverter::LinkBlendFilePath(const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
  758. {
  759. BlendHandle *bpy_openlib = BLO_blendhandle_from_file((char *)path, NULL);
  760. // Error checking is done in LinkBlendFile
  761. return LinkBlendFile(bpy_openlib, path, group, scene_merge, err_str, options);
  762. }
  763. bool KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
  764. {
  765. Main *main_newlib; /* stored as a dynamic 'main' until we free it */
  766. Main *main_tmp= NULL; /* created only for linking, then freed */
  767. LinkNode *names = NULL;
  768. int idcode= BKE_idcode_from_name(group);
  769. short flag= 0; /* don't need any special options */
  770. ReportList reports;
  771. static char err_local[255];
  772. /* only scene and mesh supported right now */
  773. if (idcode!=ID_SCE && idcode!=ID_ME &&idcode!=ID_AC) {
  774. snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group);
  775. *err_str= err_local;
  776. BLO_blendhandle_close(bpy_openlib);
  777. return false;
  778. }
  779. if (GetMainDynamicPath(path)) {
  780. snprintf(err_local, sizeof(err_local), "blend file already open \"%s\"\n", path);
  781. *err_str= err_local;
  782. BLO_blendhandle_close(bpy_openlib);
  783. return false;
  784. }
  785. if (bpy_openlib==NULL) {
  786. snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path);
  787. *err_str= err_local;
  788. return false;
  789. }
  790. main_newlib= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
  791. BKE_reports_init(&reports, RPT_STORE);
  792. /* here appending/linking starts */
  793. main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path);
  794. int totnames_dummy;
  795. names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode, &totnames_dummy);
  796. int i=0;
  797. LinkNode *n= names;
  798. while(n) {
  799. BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, idcode);
  800. n= (LinkNode *)n->next;
  801. i++;
  802. }
  803. BLI_linklist_free(names, free); /* free linklist *and* each node's data */
  804. BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag);
  805. /* now do another round of linking for Scenes so all actions are properly loaded */
  806. if (idcode==ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) {
  807. main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path);
  808. int totnames_dummy;
  809. names = BLO_blendhandle_get_datablock_names( bpy_openlib, ID_AC, &totnames_dummy);
  810. int i=0;
  811. LinkNode *n= names;
  812. while(n) {
  813. BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, ID_AC);
  814. n= (LinkNode *)n->next;
  815. i++;
  816. }
  817. BLI_linklist_free(names, free); /* free linklist *and* each node's data */
  818. BLO_library_append_end(NULL, main_tmp, &bpy_openlib, ID_AC, flag);
  819. }
  820. BLO_blendhandle_close(bpy_openlib);
  821. BKE_reports_clear(&reports);
  822. /* done linking */
  823. /* needed for lookups*/
  824. GetMainDynamic().push_back(main_newlib);
  825. strncpy(main_newlib->name, path, sizeof(main_newlib->name));
  826. if (idcode==ID_ME) {
  827. /* Convert all new meshes into BGE meshes */
  828. ID* mesh;
  829. for (mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) {
  830. if (options & LIB_LOAD_VERBOSE)
  831. printf("MeshName: %s\n", mesh->name+2);
  832. RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this);
  833. scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
  834. }
  835. }
  836. else if (idcode==ID_AC) {
  837. /* Convert all actions */
  838. ID *action;
  839. for (action= (ID *)main_newlib->action.first; action; action= (ID *)action->next) {
  840. if (options & LIB_LOAD_VERBOSE)
  841. printf("ActionName: %s\n", action->name+2);
  842. scene_merge->GetLogicManager()->RegisterActionName(action->name+2, action);
  843. }
  844. }
  845. else if (idcode==ID_SCE) {
  846. /* Merge all new linked in scene into the existing one */
  847. ID *scene;
  848. for (scene= (ID *)main_newlib->scene.first; scene; scene= (ID *)scene->next ) {
  849. if (options & LIB_LOAD_VERBOSE)
  850. printf("SceneName: %s\n", scene->name+2);
  851. /* merge into the base scene */
  852. KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene);
  853. scene_merge->MergeScene(other);
  854. // RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene
  855. delete other;
  856. }
  857. /* Now handle all the actions */
  858. if (options & LIB_LOAD_LOAD_ACTIONS) {
  859. ID *action;
  860. for (action= (ID *)main_newlib->action.first; action; action= (ID *)action->next) {
  861. if (options & LIB_LOAD_VERBOSE)
  862. printf("ActionName: %s\n", action->name+2);
  863. scene_merge->GetLogicManager()->RegisterActionName(action->name+2, action);
  864. }
  865. }
  866. }
  867. return true;
  868. }
  869. /* Note m_map_*** are all ok and don't need to be freed
  870. * most are temp and NewRemoveObject frees m_map_gameobject_to_blender */
  871. bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
  872. {
  873. int maggie_index= -1;
  874. int i=0;
  875. if (maggie==NULL)
  876. return false;
  877. /* tag all false except the one we remove */
  878. for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
  879. Main *main= *it;
  880. if (main != maggie) {
  881. tag_main(main, 0);
  882. }
  883. else {
  884. maggie_index= i;
  885. }
  886. i++;
  887. }
  888. /* should never happen but just to be safe */
  889. if (maggie_index == -1)
  890. return false;
  891. m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index);
  892. tag_main(maggie, 1);
  893. /* free all tagged objects */
  894. KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
  895. int numScenes = scenes->size();
  896. for (int scene_idx=0;scene_idx<numScenes;scene_idx++)
  897. {
  898. KX_Scene* scene = scenes->at(scene_idx);
  899. if (IS_TAGGED(scene->GetBlenderScene())) {
  900. RemoveScene(scene); // XXX - not tested yet
  901. scene_idx--;
  902. numScenes--;
  903. }
  904. else {
  905. /* in case the mesh might be refered to later */
  906. {
  907. CTR_Map<STR_HashedString,void*> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap();
  908. for (int i=0; i<mapStringToMeshes.size(); i++)
  909. {
  910. RAS_MeshObject *meshobj= (RAS_MeshObject *) *mapStringToMeshes.at(i);
  911. if (meshobj && IS_TAGGED(meshobj->GetMesh()))
  912. {
  913. STR_HashedString mn = meshobj->GetName();
  914. mapStringToMeshes.remove(mn);
  915. m_map_mesh_to_gamemesh.remove(CHashedPtr(meshobj->GetMesh()));
  916. i--;
  917. }
  918. }
  919. }
  920. /* Now unregister actions */
  921. {
  922. CTR_Map<STR_HashedString,void*> &mapStringToActions = scene->GetLogicManager()->GetActionMap();
  923. for (int i=0; i<mapStringToActions.size(); i++)
  924. {
  925. ID *action= (ID*) *mapStringToActions.at(i);
  926. if (IS_TAGGED(action))
  927. {
  928. STR_HashedString an = action->name+2;
  929. mapStringToActions.remove(an);
  930. i--;
  931. }
  932. }
  933. }
  934. //scene->FreeTagged(); /* removed tagged objects and meshes*/
  935. CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL};
  936. for (int ob_ls_idx=0; obj_lists[ob_ls_idx]; ob_ls_idx++)
  937. {
  938. CListValue *obs= obj_lists[ob_ls_idx];
  939. RAS_MeshObject* mesh;
  940. for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++)
  941. {
  942. KX_GameObject* gameobj = (KX_GameObject*)obs->GetValue(ob_idx);
  943. if (IS_TAGGED(gameobj->GetBlenderObject())) {
  944. int size_before = obs->GetCount();
  945. /* Eventually calls RemoveNodeDestructObject
  946. * frees m_map_gameobject_to_blender from UnregisterGameObject */
  947. scene->RemoveObject(gameobj);
  948. if (size_before != obs->GetCount())
  949. ob_idx--;
  950. else {
  951. printf("ERROR COULD NOT REMOVE \"%s\"\n", gameobj->GetName().ReadPtr());
  952. }
  953. }
  954. else {
  955. /* free the mesh, we could be referecing a linked one! */
  956. int mesh_index= gameobj->GetMeshCount();
  957. while(mesh_index--) {
  958. mesh= gameobj->GetMesh(mesh_index);
  959. if (IS_TAGGED(mesh->GetMesh())) {
  960. gameobj->RemoveMeshes(); /* XXX - slack, should only remove meshes that are library items but mostly objects only have 1 mesh */
  961. break;
  962. }
  963. }
  964. /* make sure action actuators are not referencing tagged actions */
  965. for (unsigned int act_idx=0; act_idx<gameobj->GetActuators().size(); act_idx++)
  966. {
  967. if (gameobj->GetActuators()[act_idx]->IsType(SCA_IActuator::KX_ACT_ACTION))
  968. {
  969. BL_ActionActuator *act = (BL_ActionActuator*)gameobj->GetActuators()[act_idx];
  970. if (IS_TAGGED(act->GetAction()))
  971. act->SetAction(NULL);
  972. }
  973. }
  974. }
  975. }
  976. }
  977. }
  978. }
  979. int size;
  980. // delete the entities of this scene
  981. /* TODO - */
  982. #if 0
  983. vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
  984. size = m_worldinfos.size();
  985. for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
  986. if ((*worldit).second) {
  987. delete (*worldit).second;
  988. *worldit = m_worldinfos.back();
  989. m_worldinfos.pop_back();
  990. size--;
  991. } else {
  992. i++;
  993. worldit++;
  994. }
  995. }
  996. #endif
  997. /* Worlds don't reference original blender data so we need to make a set from them */
  998. typedef std::set<KX_WorldInfo*> KX_WorldInfoSet;
  999. KX_WorldInfoSet worldset;
  1000. for (int scene_idx=0;scene_idx<numScenes;scene_idx++)
  1001. {
  1002. KX_Scene* scene = scenes->at(scene_idx);
  1003. if (scene->GetWorldInfo())
  1004. worldset.insert( scene->GetWorldInfo() );
  1005. }
  1006. vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
  1007. size = m_worldinfos.size();
  1008. for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
  1009. if ((*worldit).second && (worldset.count((*worldit).second)) == 0) {
  1010. delete (*worldit).second;
  1011. *worldit = m_worldinfos.back();
  1012. m_worldinfos.pop_back();
  1013. size--;
  1014. } else {
  1015. i++;
  1016. worldit++;
  1017. }
  1018. }
  1019. worldset.clear();
  1020. /* done freeing the worlds */
  1021. vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit;
  1022. size = m_polymaterials.size();
  1023. for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
  1024. RAS_IPolyMaterial *mat= (*polymit).second;
  1025. Material *bmat= NULL;
  1026. /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */
  1027. if (mat->GetFlag() & RAS_BLENDERMAT) {
  1028. KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat);
  1029. bmat= bl_mat->GetBlenderMaterial();
  1030. } else {
  1031. KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat);
  1032. bmat= kx_mat->GetBlenderMaterial();
  1033. }
  1034. if (IS_TAGGED(bmat)) {
  1035. /* only remove from bucket */
  1036. ((*polymit).first)->GetBucketManager()->RemoveMaterial(mat);
  1037. }
  1038. i++;
  1039. polymit++;
  1040. }
  1041. for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
  1042. RAS_IPolyMaterial *mat= (*polymit).second;
  1043. Material *bmat= NULL;
  1044. /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */
  1045. if (mat->GetFlag() & RAS_BLENDERMAT) {
  1046. KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat);
  1047. bmat= bl_mat->GetBlenderMaterial();
  1048. } else {
  1049. KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat);
  1050. bmat= kx_mat->GetBlenderMaterial();
  1051. }
  1052. if (bmat) {
  1053. //printf("FOUND MAT '%s' !!! ", ((ID*)bmat)->name+2);
  1054. }
  1055. else {
  1056. //printf("LOST MAT !!!");
  1057. }
  1058. if (IS_TAGGED(bmat)) {
  1059. delete (*polymit).second;
  1060. *polymit = m_polymaterials.back();
  1061. m_polymaterials.pop_back();
  1062. size--;
  1063. //printf("tagged !\n");
  1064. } else {
  1065. i++;
  1066. polymit++;
  1067. //printf("(un)tagged !\n");
  1068. }
  1069. }
  1070. vector<pair<KX_Scene*,BL_Material*> >::iterator matit;
  1071. size = m_materials.size();
  1072. for (i=0, matit=m_materials.begin(); i<size; ) {
  1073. BL_Material *mat= (*matit).second;
  1074. if (IS_TAGGED(mat->material)) {
  1075. delete (*matit).second;
  1076. *matit = m_materials.back();
  1077. m_materials.pop_back();
  1078. size--;
  1079. } else {
  1080. i++;
  1081. matit++;
  1082. }
  1083. }
  1084. vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
  1085. size = m_meshobjects.size();
  1086. for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
  1087. RAS_MeshObject *me= (*meshit).second;
  1088. if (IS_TAGGED(me->GetMesh())) {
  1089. delete (*meshit).second;
  1090. *meshit = m_meshobjects.back();
  1091. m_meshobjects.pop_back();
  1092. size--;
  1093. } else {
  1094. i++;
  1095. meshit++;
  1096. }
  1097. }
  1098. free_main(maggie);
  1099. return true;
  1100. }
  1101. bool KX_BlenderSceneConverter::FreeBlendFile(const char *path)
  1102. {
  1103. return FreeBlendFile(GetMainDynamicPath(path));
  1104. }
  1105. bool KX_BlenderSceneConverter::MergeScene(KX_Scene *to, KX_Scene *from)
  1106. {
  1107. {
  1108. vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itp = m_worldinfos.begin();
  1109. while (itp != m_worldinfos.end()) {
  1110. if ((*itp).first==from)
  1111. (*itp).first= to;
  1112. itp++;
  1113. }
  1114. }
  1115. {
  1116. vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
  1117. while (itp != m_polymaterials.end()) {
  1118. if ((*itp).first==from) {
  1119. (*itp).first= to;
  1120. /* also switch internal data */
  1121. RAS_IPolyMaterial*mat= (*itp).second;
  1122. mat->Replace_IScene(to);
  1123. }
  1124. itp++;
  1125. }
  1126. }
  1127. {
  1128. vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itp = m_meshobjects.begin();
  1129. while (itp != m_meshobjects.end()) {
  1130. if ((*itp).first==from)
  1131. (*itp).first= to;
  1132. itp++;
  1133. }
  1134. }
  1135. {
  1136. vector<pair<KX_Scene*,BL_Material*> >::iterator itp = m_materials.begin();
  1137. while (itp != m_materials.end()) {
  1138. if ((*itp).first==from)
  1139. (*itp).first= to;
  1140. itp++;
  1141. }
  1142. }
  1143. return true;
  1144. }
  1145. /* This function merges a mesh from the current scene into another main
  1146. * it does not convert */
  1147. RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name)
  1148. {
  1149. /* Find a mesh in the current main */
  1150. ID *me= static_cast<ID *>(BLI_findstring(&m_maggie->mesh, name, offsetof(ID, name) + 2));
  1151. if (me==NULL) {
  1152. printf("Could not be found \"%s\"\n", name);
  1153. return NULL;
  1154. }
  1155. /* Watch this!, if its used in the original scene can cause big troubles */
  1156. if (me->us > 0) {
  1157. printf("Mesh has a user \"%s\"\n", name);
  1158. me = (ID*)copy_mesh((Mesh*)me);
  1159. me->us--;
  1160. }
  1161. BLI_remlink(&m_maggie->mesh, me); /* even if we made the copy it needs to be removed */
  1162. BLI_addtail(&maggie->mesh, me);
  1163. /* Must copy the materials this uses else we cant free them */
  1164. {
  1165. Mesh *mesh= (Mesh *)me;
  1166. /* ensure all materials are tagged */
  1167. for (int i=0; i<mesh->totcol; i++)
  1168. if (mesh->mat[i])
  1169. mesh->mat[i]->id.flag &= ~LIB_DOIT;
  1170. for (int i=0; i<mesh->totcol; i++)
  1171. {
  1172. Material *mat_old= mesh->mat[i];
  1173. /* if its tagged its a replaced material */
  1174. if (mat_old && (mat_old->id.flag & LIB_DOIT)==0)
  1175. {
  1176. Material *mat_old= mesh->mat[i];
  1177. Material *mat_new= copy_material( mat_old );
  1178. mat_new->id.flag |= LIB_DOIT;
  1179. mat_old->id.us--;
  1180. BLI_remlink(&m_maggie->mat, mat_new);
  1181. BLI_addtail(&maggie->mat, mat_new);
  1182. mesh->mat[i]= mat_new;
  1183. /* the same material may be used twice */
  1184. for (int j=i+1; j<mesh->totcol; j++)
  1185. {
  1186. if (mesh->mat[j]==mat_old)
  1187. {
  1188. mesh->mat[j]= mat_new;
  1189. mat_new->id.us++;
  1190. mat_old->id.us--;
  1191. }
  1192. }
  1193. }
  1194. }
  1195. }
  1196. RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this);
  1197. kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
  1198. m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */
  1199. return meshobj;
  1200. }