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