Merged 15170:15635 from trunk (no conflicts or even merges)
[blender.git] / source / gameengine / Converter / KX_BlenderSceneConverter.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #ifdef WIN32
30         #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
31 #endif
32
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 "SYS_System.h"
44
45 #include "DummyPhysicsEnvironment.h"
46
47 //to decide to use sumo/ode or dummy physics - defines USE_ODE
48 #include "KX_ConvertPhysicsObject.h"
49
50 #ifdef USE_BULLET
51 #include "CcdPhysicsEnvironment.h"
52 #endif
53
54 #ifdef USE_ODE
55 #include "OdePhysicsEnvironment.h"
56 #endif //USE_ODE
57
58 #ifdef USE_SUMO_SOLID
59 #include "SumoPhysicsEnvironment.h"
60 #endif
61
62 #include "KX_BlenderSceneConverter.h"
63 #include "KX_BlenderScalarInterpolator.h"
64 #include "BL_BlenderDataConversion.h"
65 #include "BlenderWorldInfo.h"
66 #include "KX_Scene.h"
67
68 /* This little block needed for linking to Blender... */
69 #ifdef WIN32
70 #include "BLI_winstuff.h"
71 #endif
72
73 /* This list includes only data type definitions */
74 #include "DNA_scene_types.h"
75 #include "DNA_world_types.h"
76 #include "BKE_main.h"
77
78 #include "BLI_arithb.h"
79
80 extern "C"
81 {
82 #include "DNA_object_types.h"
83 #include "DNA_curve_types.h"
84 #include "BLI_blenlib.h"
85 #include "MEM_guardedalloc.h"
86 #include "BSE_editipo.h"
87 #include "BSE_editipo_types.h"
88 #include "DNA_ipo_types.h"
89 #include "BKE_global.h"
90 #include "DNA_space_types.h"
91 }
92
93
94 KX_BlenderSceneConverter::KX_BlenderSceneConverter(
95                                                         struct Main* maggie,
96                                                         struct SpaceIpo*        sipo,
97                                                         class KX_KetsjiEngine* engine
98                                                         )
99                                                         : m_maggie(maggie),
100                                                         m_sipo(sipo),
101                                                         m_ketsjiEngine(engine),
102                                                         m_alwaysUseExpandFraming(false),
103                                                         m_usemat(false),
104                                                         m_useglslmat(false)
105 {
106         m_newfilename = "";
107 }
108
109
110 KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
111 {
112         // clears meshes, and hashmaps from blender to gameengine data
113         int i;
114         // delete sumoshapes
115         
116
117         int numipolists = m_map_blender_to_gameipolist.size();
118         for (i=0; i<numipolists; i++) {
119                 BL_InterpolatorList *ipoList= *m_map_blender_to_gameipolist.at(i);
120
121                 delete (ipoList);
122         }
123
124         vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itw = m_worldinfos.begin();
125         while (itw != m_worldinfos.end()) {
126                 delete (*itw).second;
127                 itw++;
128         }
129
130         vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
131         while (itp != m_polymaterials.end()) {
132                 delete (*itp).second;
133                 itp++;
134         }
135
136         // delete after RAS_IPolyMaterial
137         vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
138         while (itmat != m_materials.end()) {
139                 delete (*itmat).second;
140                 itmat++;
141         }       
142
143
144         vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin();
145         while (itm != m_meshobjects.end()) {
146                 delete (*itm).second;
147                 itm++;
148         }
149         
150 #ifdef USE_SUMO_SOLID
151         KX_ClearSumoSharedShapes();
152 #endif
153
154 #ifdef USE_BULLET
155         KX_ClearBulletSharedShapes();
156 #endif
157
158 }
159
160
161
162 void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
163 {
164         m_newfilename = filename;
165 }
166
167
168
169 bool KX_BlenderSceneConverter::TryAndLoadNewFile()
170 {
171         bool result = false;
172
173         // find the file
174 /*      if ()
175         {
176                 result = true;
177         }
178         // if not, clear the newfilename
179         else
180         {
181                 m_newfilename = "";     
182         }
183 */
184         return result;
185 }
186
187
188
189         /**
190          * Find the specified scene by name, or the first
191          * scene if nothing matches (shouldn't happen).
192          */
193 static struct Scene *GetSceneForName2(struct Main *maggie, const STR_String& scenename) {
194         Scene *sce;
195
196         for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
197                 if (scenename == (sce->id.name+2))
198                         return sce;
199
200         return (Scene*) maggie->scene.first;
201 }
202 #include "KX_PythonInit.h"
203
204 #ifdef USE_BULLET
205
206 #include "LinearMath/btIDebugDraw.h"
207
208
209 struct  BlenderDebugDraw : public btIDebugDraw
210 {
211         BlenderDebugDraw () :
212                 m_debugMode(0) 
213         {
214         }
215         
216         int m_debugMode;
217
218         virtual void    drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
219         {
220                 if (m_debugMode >0)
221                 {
222                         MT_Vector3 kxfrom(from[0],from[1],from[2]);
223                         MT_Vector3 kxto(to[0],to[1],to[2]);
224                         MT_Vector3 kxcolor(color[0],color[1],color[2]);
225
226                         KX_RasterizerDrawDebugLine(kxfrom,kxto,kxcolor);
227                 }
228         }
229         
230         virtual void    reportErrorWarning(const char* warningString)
231         {
232
233         }
234
235         virtual void    drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)
236         {
237                 //not yet
238         }
239
240         virtual void    setDebugMode(int debugMode)
241         {
242                 m_debugMode = debugMode;
243         }
244         virtual int             getDebugMode() const
245         {
246                 return m_debugMode;
247         }
248                 
249 };
250
251 #endif
252
253 void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
254                                                                                         class KX_Scene* destinationscene,
255                                                                                         PyObject* dictobj,
256                                                                                         class SCA_IInputDevice* keyinputdev,
257                                                                                         class RAS_IRenderTools* rendertools,
258                                                                                         class RAS_ICanvas* canvas)
259 {
260         //find out which physics engine
261         Scene *blenderscene = GetSceneForName2(m_maggie, scenename);
262
263         e_PhysicsEngine physics_engine = UseBullet;
264         // hook for registration function during conversion.
265         m_currentScene = destinationscene;
266         destinationscene->SetSceneConverter(this);
267
268         if (blenderscene)
269         {
270         
271                 if (blenderscene->world)
272                 {
273                         switch (blenderscene->world->physicsEngine)
274                         {
275                         case WOPHY_BULLET:
276                                 {
277                                         physics_engine = UseBullet;
278                                         break;
279                                 }
280                                 
281                                 case WOPHY_ODE:
282                                 {
283                                         physics_engine = UseODE;
284                                         break;
285                                 }
286                                 case WOPHY_DYNAMO:
287                                 {
288                                         physics_engine = UseDynamo;
289                                         break;
290                                 }
291                                 case WOPHY_SUMO:
292                                 {
293                                         physics_engine = UseSumo; 
294                                         break;
295                                 }
296                                 case WOPHY_NONE:
297                                 {
298                                         physics_engine = UseNone;
299                                 }
300                         }
301                   
302                 }
303         }
304
305         switch (physics_engine)
306         {
307 #ifdef USE_BULLET
308                 case UseBullet:
309                         {
310                                 CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment();
311                                 ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw());
312                                 ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python
313                                 ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python
314
315                                 SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
316                                 int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
317                                 if (visualizePhysics)
318                                         ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText);
319                 
320                                 //todo: get a button in blender ?
321                                 //disable / enable debug drawing (contact points, aabb's etc)   
322                                 //ccdPhysEnv->setDebugMode(1);
323                                 destinationscene->SetPhysicsEnvironment(ccdPhysEnv);
324                                 break;
325                         }
326 #endif
327
328 #ifdef USE_SUMO_SOLID
329                 case UseSumo:
330                         destinationscene ->SetPhysicsEnvironment(new SumoPhysicsEnvironment());
331                         break;
332 #endif
333 #ifdef USE_ODE
334
335                 case UseODE:
336                         destinationscene ->SetPhysicsEnvironment(new ODEPhysicsEnvironment());
337                         break;
338 #endif //USE_ODE
339         
340                 case UseDynamo:
341                 {
342                 }
343                 
344                 default:
345                 case UseNone:
346                         physics_engine = UseNone;
347                         destinationscene ->SetPhysicsEnvironment(new DummyPhysicsEnvironment());
348                         break;
349         }
350
351         BL_ConvertBlenderObjects(m_maggie,
352                 scenename,
353                 destinationscene,
354                 m_ketsjiEngine,
355                 physics_engine,
356                 dictobj,
357                 keyinputdev,
358                 rendertools,
359                 canvas,
360                 this,
361                 m_alwaysUseExpandFraming
362                 );
363
364         //These lookup are not needed during game
365         m_map_blender_to_gameactuator.clear();
366         m_map_blender_to_gamecontroller.clear();
367         m_map_blender_to_gameobject.clear();
368
369         //Clearing this lookup table has the effect of disabling the cache of meshes
370         //between scenes, even if they are shared in the blend file.
371         //This cache mecanism is buggy so I leave it disable and the memory leak
372         //that would result from this is fixed in RemoveScene()
373         m_map_mesh_to_gamemesh.clear();
374         //Don't clear this lookup, it is needed for the baking physics into ipo animation
375         //To avoid it's infinite grows, object will be unregister when they are deleted 
376         //see KX_Scene::NewRemoveObject
377         //m_map_gameobject_to_blender.clear();
378 }
379
380 // This function removes all entities stored in the converter for that scene
381 // It should be used instead of direct delete scene
382 // Note that there was some provision for sharing entities (meshes...) between
383 // scenes but that is now disabled so all scene will have their own copy
384 // and we can delete them here. If the sharing is reactivated, change this code too..
385 // (see KX_BlenderSceneConverter::ConvertScene)
386 void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
387 {
388         int i, size;
389         // delete the scene first as it will stop the use of entities
390         delete scene;
391         // delete the entities of this scene
392         vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
393         size = m_worldinfos.size();
394         for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
395                 if ((*worldit).first == scene) {
396                         delete (*worldit).second;
397                         *worldit = m_worldinfos.back();
398                         m_worldinfos.pop_back();
399                         size--;
400                 } else {
401                         i++;
402                         worldit++;
403                 }
404         }
405
406         vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit;
407         size = m_polymaterials.size();
408         for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
409                 if ((*polymit).first == scene) {
410                         delete (*polymit).second;
411                         *polymit = m_polymaterials.back();
412                         m_polymaterials.pop_back();
413                         size--;
414                 } else {
415                         i++;
416                         polymit++;
417                 }
418         }
419
420         vector<pair<KX_Scene*,BL_Material*> >::iterator matit;
421         size = m_materials.size();
422         for (i=0, matit=m_materials.begin(); i<size; ) {
423                 if ((*matit).first == scene) {
424                         delete (*matit).second;
425                         *matit = m_materials.back();
426                         m_materials.pop_back();
427                         size--;
428                 } else {
429                         i++;
430                         matit++;
431                 }
432         }
433
434         vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
435         size = m_meshobjects.size();
436         for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
437                 if ((*meshit).first == scene) {
438                         delete (*meshit).second;
439                         *meshit = m_meshobjects.back();
440                         m_meshobjects.pop_back();
441                         size--;
442                 } else {
443                         i++;
444                         meshit++;
445                 }
446         }
447 }
448
449 // use blender materials
450 void KX_BlenderSceneConverter::SetMaterials(bool val)
451 {
452         m_usemat = val;
453         m_useglslmat = false;
454 }
455
456 void KX_BlenderSceneConverter::SetGLSLMaterials(bool val)
457 {
458         m_usemat = val;
459         m_useglslmat = val;
460 }
461
462 bool KX_BlenderSceneConverter::GetMaterials()
463 {
464         return m_usemat;
465 }
466
467 bool KX_BlenderSceneConverter::GetGLSLMaterials()
468 {
469         return m_useglslmat;
470 }
471
472 void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
473 {
474         m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
475 }
476
477
478
479 void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(
480         bool to_what)
481 {
482         m_alwaysUseExpandFraming= to_what;
483 }
484
485         
486
487 void KX_BlenderSceneConverter::RegisterGameObject(
488                                                                         KX_GameObject *gameobject, 
489                                                                         struct Object *for_blenderobject) 
490 {
491         m_map_gameobject_to_blender.insert(CHashedPtr(gameobject),for_blenderobject);
492         m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
493 }
494
495 void KX_BlenderSceneConverter::UnregisterGameObject(
496                                                                         KX_GameObject *gameobject) 
497 {
498         m_map_gameobject_to_blender.remove(CHashedPtr(gameobject));
499 }
500
501
502 KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
503                                                                         struct Object *for_blenderobject) 
504 {
505         KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
506         
507         return obp?*obp:NULL;
508 }
509
510
511
512 struct Object *KX_BlenderSceneConverter::FindBlenderObject(
513                                                                         KX_GameObject *for_gameobject) 
514 {
515         struct Object **obp= m_map_gameobject_to_blender[CHashedPtr(for_gameobject)];
516         
517         return obp?*obp:NULL;
518 }
519
520         
521
522 void KX_BlenderSceneConverter::RegisterGameMesh(
523                                                                         RAS_MeshObject *gamemesh,
524                                                                         struct Mesh *for_blendermesh)
525 {
526         m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
527         m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh));
528 }
529
530
531
532 RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
533                                                                         struct Mesh *for_blendermesh,
534                                                                         unsigned int onlayer)
535 {
536         RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
537         
538         if (meshp && onlayer==(*meshp)->GetLightLayer()) {
539                 return *meshp;
540         } else {
541                 return NULL;
542         }
543 }
544
545         
546
547
548         
549
550 void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
551 {
552         m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
553 }
554
555
556
557 void KX_BlenderSceneConverter::RegisterInterpolatorList(
558                                                                         BL_InterpolatorList *ipoList,
559                                                                         struct Ipo *for_ipo)
560 {
561         m_map_blender_to_gameipolist.insert(CHashedPtr(for_ipo), ipoList);
562 }
563
564
565
566 BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
567                                                                         struct Ipo *for_ipo)
568 {
569         BL_InterpolatorList **listp = m_map_blender_to_gameipolist[CHashedPtr(for_ipo)];
570                 
571         return listp?*listp:NULL;
572 }
573
574
575
576 void KX_BlenderSceneConverter::RegisterGameActuator(
577                                                                         SCA_IActuator *act,
578                                                                         struct bActuator *for_actuator)
579 {
580         m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
581 }
582
583
584
585 SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
586                                                                         struct bActuator *for_actuator)
587 {
588         SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
589         
590         return actp?*actp:NULL;
591 }
592
593
594
595 void KX_BlenderSceneConverter::RegisterGameController(
596                                                                         SCA_IController *cont,
597                                                                         struct bController *for_controller)
598 {
599         m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
600 }
601
602
603
604 SCA_IController *KX_BlenderSceneConverter::FindGameController(
605                                                                         struct bController *for_controller)
606 {
607         SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
608         
609         return contp?*contp:NULL;
610 }
611
612
613
614 void KX_BlenderSceneConverter::RegisterWorldInfo(
615                                                                         KX_WorldInfo *worldinfo)
616 {
617         m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
618 }
619
620 /*
621  * When deleting an IPO curve from Python, check if the IPO is being
622  * edited and if so clear the pointer to the old curve.
623  */
624 void KX_BlenderSceneConverter::localDel_ipoCurve ( IpoCurve * icu ,struct SpaceIpo*     sipo)
625 {
626         if (!sipo)
627                 return;
628
629         int i;
630         EditIpo *ei= (EditIpo *)sipo->editipo;
631         if (!ei) return;
632
633         for(i=0; i<G.sipo->totipo; i++, ei++) {
634                 if ( ei->icu == icu ) {
635                         ei->flag &= ~(IPO_SELECT | IPO_EDIT);
636                         ei->icu= 0;
637                         return;
638                 }
639         }
640 }
641
642 //quick hack
643 extern "C"
644 {
645         Ipo *add_ipo( char *name, int idcode );
646         char *getIpoCurveName( IpoCurve * icu );
647         struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int);
648         void testhandles_ipocurve(struct IpoCurve *icu);
649         void Mat3ToEul(float tmat[][3], float *eul);
650
651 }
652
653 IpoCurve* findIpoCurve(IpoCurve* first,char* searchName)
654 {
655         IpoCurve* icu1;
656         for( icu1 = first; icu1; icu1 = icu1->next ) 
657         {
658                 char* curveName = getIpoCurveName( icu1 );
659                 if( !strcmp( curveName, searchName) )
660                 {
661                         return icu1;
662                 }
663         }
664         return 0;
665 }
666
667 // this is not longer necesary //rcruiz
668 /*Ipo* KX_BlenderSceneConverter::findIpoForName(char* objName)
669 {
670         Ipo* ipo_iter = (Ipo*)m_maggie->ipo.first;
671
672         while( ipo_iter )
673         {
674                 if( strcmp( objName, ipo_iter->id.name + 2 ) == 0 ) 
675                 {
676                         return ipo_iter;
677                 }
678                 ipo_iter = (Ipo*)ipo_iter->id.next;
679         }
680         return 0;
681 }
682 */
683
684 void    KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
685 {
686
687         KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
688         int numScenes = scenes->size();
689         int i;
690         for (i=0;i<numScenes;i++)
691         {
692                 KX_Scene* scene = scenes->at(i);
693                 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
694                 CListValue* parentList = scene->GetRootParentList();
695                 int numObjects = parentList->GetCount();
696                 int g;
697                 for (g=0;g<numObjects;g++)
698                 {
699                         KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
700                         if (gameObj->IsDynamic())
701                         {
702                                 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
703                                 
704                                 Object* blenderObject = FindBlenderObject(gameObj);
705                                 if (blenderObject)
706                                 {
707                                         //erase existing ipo's
708                                         Ipo* ipo = blenderObject->ipo;//findIpoForName(blenderObject->id.name+2);
709                                         if (ipo)
710                                         {       //clear the curve data
711                                                 if (clearIpo){//rcruiz
712                                                         IpoCurve *icu1;
713                                                                                                                 
714                                                         int numCurves = 0;
715                                                         for( icu1 = (IpoCurve*)ipo->curve.first; icu1;  ) {
716                                                         
717                                                                 IpoCurve* tmpicu = icu1;
718                                                                 
719                                                                 /*int i;
720                                                                 BezTriple *bezt;
721                                                                 for( bezt = tmpicu->bezt, i = 0;        i < tmpicu->totvert; i++, bezt++){
722                                                                         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]);
723                                                                 }*/
724                                                                 
725                                                                 icu1 = icu1->next;
726                                                                 numCurves++;
727                         
728                                                                 BLI_remlink( &( blenderObject->ipo->curve ), tmpicu );
729                                                                 if( tmpicu->bezt )
730                                                                         MEM_freeN( tmpicu->bezt );
731                                                                 MEM_freeN( tmpicu );
732                                                                 localDel_ipoCurve( tmpicu ,m_sipo);
733                                                         }
734                                                 }
735                                         } else
736                                         {       ipo = add_ipo(blenderObject->id.name+2, ID_OB);
737                                                 blenderObject->ipo = ipo;
738
739                                         }
740                                 
741                                         
742
743                                         
744
745                                 }
746                         }
747
748                 }
749                 
750         
751         }
752
753
754
755 }
756
757 void    KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo(){
758         
759         if (addInitFromFrame){          
760                 KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
761                 int numScenes = scenes->size();
762                 if (numScenes>=0){
763                         KX_Scene* scene = scenes->at(0);
764                         CListValue* parentList = scene->GetRootParentList();
765                         for (int ix=0;ix<parentList->GetCount();ix++){
766                                 KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix);
767                                 if (!gameobj->IsDynamic()){
768                                         Object* blenderobject = FindBlenderObject(gameobj);
769                                         if (!blenderobject)
770                                                 continue;
771                                         if (blenderobject->type==OB_ARMATURE)
772                                                 continue;
773                                         float eu[3];
774                                         Mat4ToEul(blenderobject->obmat,eu);                                     
775                                         MT_Point3 pos = MT_Point3(
776                                                 blenderobject->obmat[3][0],
777                                                 blenderobject->obmat[3][1],
778                                                 blenderobject->obmat[3][2]
779                                         );
780                                         MT_Vector3 eulxyz = MT_Vector3(
781                                                 eu[0],
782                                                 eu[1],
783                                                 eu[2]
784                                         );
785                                         MT_Vector3 scale = MT_Vector3(
786                                                 blenderobject->size[0],
787                                                 blenderobject->size[1],
788                                                 blenderobject->size[2]
789                                         );
790                                         gameobj->NodeSetLocalPosition(pos);
791                                         gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
792                                         gameobj->NodeSetLocalScale(scale);
793                                         gameobj->NodeUpdateGS(0,true);
794                                 }
795                         }
796                 }
797         }
798 }
799
800 #define TEST_HANDLES_GAME2IPO 0
801
802         ///this generates ipo curves for position, rotation, allowing to use game physics in animation
803 void    KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
804 {
805
806         KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
807         int numScenes = scenes->size();
808         int i;
809         for (i=0;i<numScenes;i++)
810         {
811                 KX_Scene* scene = scenes->at(i);
812                 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
813                 CListValue* parentList = scene->GetRootParentList();
814                 int numObjects = parentList->GetCount();
815                 int g;
816                 for (g=0;g<numObjects;g++)
817                 {
818                         KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
819                         if (gameObj->IsDynamic())
820                         {
821                                 KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
822                                 
823                                 Object* blenderObject = FindBlenderObject(gameObj);
824                                 if (blenderObject)
825                                 {
826
827                                         const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
828                                         float eulerAngles[3];   
829                                         float tmat[3][3];
830                                         for (int r=0;r<3;r++)
831                                         {
832                                                 for (int c=0;c<3;c++)
833                                                 {
834                                                         tmat[r][c] = orn[c][r];
835                                                 }
836                                         }
837                                         Mat3ToEul(tmat, eulerAngles);
838                                         
839                                         for(int x = 0; x < 3; x++) {
840                                                 eulerAngles[x] *= (float) (180 / 3.14159265f);
841                                         }
842
843                                         eulerAngles[0]/=10.f;
844                                         eulerAngles[1]/=10.f;
845                                         eulerAngles[2]/=10.f;
846
847
848
849                                         const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
850                                         const MT_Point3& position = gameObj->NodeGetWorldPosition();
851                                         
852                                         Ipo* ipo = blenderObject->ipo;
853                                         if (ipo)
854                                         {
855
856                                                 //create the curves, if not existing
857
858                                         IpoCurve *icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
859                                         if (!icu1)
860                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X);
861                                         
862                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
863                                         if (!icu1)
864                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y);
865                                         
866                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
867                                         if (!icu1)
868                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z);
869
870                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
871                                         if (!icu1)
872                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X);
873
874                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
875                                         if (!icu1)
876                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y);
877
878                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
879                                         if (!icu1)
880                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z);
881
882
883
884                                         //fill the curves with data
885
886                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
887                                                 if (icu1)
888                                                 {
889                                                         float curVal = position.x();
890                                                         insert_vert_icu(icu1, frameNumber, curVal, 0);
891 #ifdef TEST_HANDLES_GAME2IPO
892                                                         testhandles_ipocurve(icu1);
893 #endif
894                                                 }
895                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
896                                                 if (icu1)
897                                                 {
898                                                         float curVal = position.y();
899                                                         insert_vert_icu(icu1, frameNumber, curVal, 0);
900 #ifdef TEST_HANDLES_GAME2IPO
901
902                                                         testhandles_ipocurve(icu1);
903 #endif
904                                                 }
905                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
906                                                 if (icu1)
907                                                 {
908                                                         float curVal = position.z();
909                                                         insert_vert_icu(icu1, frameNumber, curVal, 0);
910 #ifdef TEST_HANDLES_GAME2IPO
911                                                         testhandles_ipocurve(icu1);
912 #endif
913                                                 }
914                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
915                                                 if (icu1)
916                                                 {
917                                                         float curVal = eulerAngles[0];
918                                                         insert_vert_icu(icu1, frameNumber, curVal, 0);
919 #ifdef TEST_HANDLES_GAME2IPO
920
921                                                         testhandles_ipocurve(icu1);
922 #endif
923                                                 }
924                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
925                                                 if (icu1)
926                                                 {
927                                                         float curVal = eulerAngles[1];
928                                                         insert_vert_icu(icu1, frameNumber, curVal, 0);
929 #ifdef TEST_HANDLES_GAME2IPO
930
931                                                         testhandles_ipocurve(icu1);
932 #endif
933                                                 }
934                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
935                                                 if (icu1)
936                                                 {
937                                                         float curVal = eulerAngles[2];
938                                                         insert_vert_icu(icu1, frameNumber, curVal, 0);
939 #ifdef TEST_HANDLES_GAME2IPO
940                                                         
941                                                         testhandles_ipocurve(icu1);
942 #endif
943
944                                                 }
945
946                                         }
947                                 }
948                         }
949
950                 }
951                 
952         
953         }       
954         
955
956 }
957
958
959 void    KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
960 {
961
962         KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
963         int numScenes = scenes->size();
964         int i;
965         for (i=0;i<numScenes;i++)
966         {
967                 KX_Scene* scene = scenes->at(i);
968                 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
969                 CListValue* parentList = scene->GetRootParentList();
970                 int numObjects = parentList->GetCount();
971                 int g;
972                 for (g=0;g<numObjects;g++)
973                 {
974                         KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
975                         if (gameObj->IsDynamic())
976                         {
977                                 KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
978                                 
979                                 Object* blenderObject = FindBlenderObject(gameObj);
980                                 if (blenderObject)
981                                 {
982
983                                         const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
984                                         float eulerAngles[3];   
985                                         float tmat[3][3];
986                                         for (int r=0;r<3;r++)
987                                         {
988                                                 for (int c=0;c<3;c++)
989                                                 {
990                                                         tmat[r][c] = orn[c][r];
991                                                 }
992                                         }
993                                         Mat3ToEul(tmat, eulerAngles);
994                                         
995                                         for(int x = 0; x < 3; x++) {
996                                                 eulerAngles[x] *= (float) (180 / 3.14159265f);
997                                         }
998
999                                         eulerAngles[0]/=10.f;
1000                                         eulerAngles[1]/=10.f;
1001                                         eulerAngles[2]/=10.f;
1002
1003
1004
1005                                         const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
1006                                         const MT_Point3& position = gameObj->NodeGetWorldPosition();
1007                                         
1008                                         Ipo* ipo = blenderObject->ipo;
1009                                         if (ipo)
1010                                         {
1011
1012                                                 //create the curves, if not existing
1013
1014                                         IpoCurve *icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
1015                                         if (!icu1)
1016                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X);
1017                                         
1018                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
1019                                         if (!icu1)
1020                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y);
1021                                         
1022                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
1023                                         if (!icu1)
1024                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z);
1025
1026                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
1027                                         if (!icu1)
1028                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X);
1029
1030                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
1031                                         if (!icu1)
1032                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y);
1033
1034                                         icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
1035                                         if (!icu1)
1036                                                 icu1 = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z);
1037
1038
1039
1040                                         //fill the curves with data
1041
1042                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
1043                                                 if (icu1)
1044                                                 {
1045                                                         testhandles_ipocurve(icu1);
1046                                                 }
1047                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
1048                                                 if (icu1)
1049                                                 {
1050                                                         testhandles_ipocurve(icu1);
1051                                                 }
1052                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
1053                                                 if (icu1)
1054                                                 {
1055                                                         testhandles_ipocurve(icu1);
1056                                                 }
1057                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
1058                                                 if (icu1)
1059                                                 {
1060                                                         testhandles_ipocurve(icu1);
1061                                                 }
1062                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
1063                                                 if (icu1)
1064                                                 {
1065                                                         testhandles_ipocurve(icu1);
1066                                                 }
1067                                                 icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
1068                                                 if (icu1)
1069                                                 {
1070                                                         testhandles_ipocurve(icu1);
1071                                                 }
1072
1073                                         }
1074                                 }
1075                         }
1076
1077                 }
1078                 
1079         
1080         }
1081
1082
1083
1084 }