gameObject -> blenderObject mapping was being created but wasnt needed.
[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 "BKE_ipo.h" // eval_icu
91 #include "DNA_space_types.h"
92 }
93
94
95 KX_BlenderSceneConverter::KX_BlenderSceneConverter(
96                                                         struct Main* maggie,
97                                                         class KX_KetsjiEngine* engine
98                                                         )
99                                                         : m_maggie(maggie),
100                                                         m_ketsjiEngine(engine),
101                                                         m_alwaysUseExpandFraming(false),
102                                                         m_usemat(false),
103                                                         m_useglslmat(false)
104 {
105         m_newfilename = "";
106 }
107
108
109 KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
110 {
111         // clears meshes, and hashmaps from blender to gameengine data
112         int i;
113         // delete sumoshapes
114         
115
116         int numipolists = m_map_blender_to_gameipolist.size();
117         for (i=0; i<numipolists; i++) {
118                 BL_InterpolatorList *ipoList= *m_map_blender_to_gameipolist.at(i);
119
120                 delete (ipoList);
121         }
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
129         vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
130         while (itp != m_polymaterials.end()) {
131                 delete (*itp).second;
132                 itp++;
133         }
134
135         // delete after RAS_IPolyMaterial
136         vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
137         while (itmat != m_materials.end()) {
138                 delete (*itmat).second;
139                 itmat++;
140         }       
141
142
143         vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin();
144         while (itm != m_meshobjects.end()) {
145                 delete (*itm).second;
146                 itm++;
147         }
148         
149 #ifdef USE_SUMO_SOLID
150         KX_ClearSumoSharedShapes();
151 #endif
152
153 #ifdef USE_BULLET
154         KX_ClearBulletSharedShapes();
155 #endif
156
157 }
158
159
160
161 void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
162 {
163         m_newfilename = filename;
164 }
165
166
167
168 bool KX_BlenderSceneConverter::TryAndLoadNewFile()
169 {
170         bool result = false;
171
172         // find the file
173 /*      if ()
174         {
175                 result = true;
176         }
177         // if not, clear the newfilename
178         else
179         {
180                 m_newfilename = "";     
181         }
182 */
183         return result;
184 }
185
186 Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
187 {
188         Scene *sce;
189
190         /**
191          * Find the specified scene by name, or the first
192          * scene if nothing matches (shouldn't happen).
193          */
194
195         for (sce= (Scene*) m_maggie->scene.first; sce; sce= (Scene*) sce->id.next)
196                 if (name == (sce->id.name+2))
197                         return sce;
198
199         return (Scene*)m_maggie->scene.first;
200
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         ///todo: find out if Blender can do this
249         virtual void    draw3dText(const btVector3& location,const char* textString)
250         {
251
252         }
253                 
254 };
255
256 #endif
257
258 void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
259                                                                                         PyObject* dictobj,
260                                                                                         class RAS_IRenderTools* rendertools,
261                                                                                         class RAS_ICanvas* canvas)
262 {
263         //find out which physics engine
264         Scene *blenderscene = destinationscene->GetBlenderScene();
265
266         e_PhysicsEngine physics_engine = UseBullet;
267         bool useDbvtCulling = false;
268         // hook for registration function during conversion.
269         m_currentScene = destinationscene;
270         destinationscene->SetSceneConverter(this);
271         SG_SetActiveStage(SG_STAGE_CONVERTER);
272
273         if (blenderscene)
274         {
275         
276                 if (blenderscene->world)
277                 {
278                         switch (blenderscene->world->physicsEngine)
279                         {
280                         case WOPHY_BULLET:
281                                 {
282                                         physics_engine = UseBullet;
283                                         useDbvtCulling = (blenderscene->world->mode & WO_DBVT_CULLING) != 0;
284                                         break;
285                                 }
286                                 
287                                 case WOPHY_ODE:
288                                 {
289                                         physics_engine = UseODE;
290                                         break;
291                                 }
292                                 case WOPHY_DYNAMO:
293                                 {
294                                         physics_engine = UseDynamo;
295                                         break;
296                                 }
297                                 case WOPHY_SUMO:
298                                 {
299                                         physics_engine = UseSumo; 
300                                         break;
301                                 }
302                                 case WOPHY_NONE:
303                                 {
304                                         physics_engine = UseNone;
305                                 }
306                         }
307                   
308                 }
309         }
310
311         switch (physics_engine)
312         {
313 #ifdef USE_BULLET
314                 case UseBullet:
315                         {
316                                 CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling);
317                                 ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw());
318                                 ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python
319                                 ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python
320
321                                 SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
322                                 int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
323                                 if (visualizePhysics)
324                                         ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints);
325                 
326                                 //todo: get a button in blender ?
327                                 //disable / enable debug drawing (contact points, aabb's etc)   
328                                 //ccdPhysEnv->setDebugMode(1);
329                                 destinationscene->SetPhysicsEnvironment(ccdPhysEnv);
330                                 break;
331                         }
332 #endif
333
334 #ifdef USE_SUMO_SOLID
335                 case UseSumo:
336                         destinationscene ->SetPhysicsEnvironment(new SumoPhysicsEnvironment());
337                         break;
338 #endif
339 #ifdef USE_ODE
340
341                 case UseODE:
342                         destinationscene ->SetPhysicsEnvironment(new ODEPhysicsEnvironment());
343                         break;
344 #endif //USE_ODE
345         
346                 case UseDynamo:
347                 {
348                 }
349                 
350                 default:
351                 case UseNone:
352                         physics_engine = UseNone;
353                         destinationscene ->SetPhysicsEnvironment(new DummyPhysicsEnvironment());
354                         break;
355         }
356
357         BL_ConvertBlenderObjects(m_maggie,
358                 destinationscene,
359                 m_ketsjiEngine,
360                 physics_engine,
361                 dictobj,
362                 rendertools,
363                 canvas,
364                 this,
365                 m_alwaysUseExpandFraming
366                 );
367
368         //These lookup are not needed during game
369         m_map_blender_to_gameactuator.clear();
370         m_map_blender_to_gamecontroller.clear();
371         m_map_blender_to_gameobject.clear();
372
373         //Clearing this lookup table has the effect of disabling the cache of meshes
374         //between scenes, even if they are shared in the blend file.
375         //This cache mecanism is buggy so I leave it disable and the memory leak
376         //that would result from this is fixed in RemoveScene()
377         m_map_mesh_to_gamemesh.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         /* only maintained while converting, freed during game runtime */
492         m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
493 }
494
495 void KX_BlenderSceneConverter::UnregisterGameObject(
496                                                                         KX_GameObject *gameobject) 
497 {
498 #if 0
499         struct Object *bobp= gameobject->GetBlenderObject();
500         if (bobp) {
501                 CHashedPtr bptr(bobp);
502                 KX_GameObject **gobp= m_map_blender_to_gameobject[bptr];
503                 if (gobp && *gobp == gameobject)
504                 {
505                         // also maintain m_map_blender_to_gameobject if the gameobject
506                         // being removed is matching the blender object
507                         m_map_blender_to_gameobject.remove(bptr);
508                 }
509         }
510 #endif
511 }
512
513 KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
514                                                                         struct Object *for_blenderobject) 
515 {
516         KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
517         
518         return obp?*obp:NULL;
519 }
520
521 void KX_BlenderSceneConverter::RegisterGameMesh(
522                                                                         RAS_MeshObject *gamemesh,
523                                                                         struct Mesh *for_blendermesh)
524 {
525         m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
526         m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh));
527 }
528
529
530
531 RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
532                                                                         struct Mesh *for_blendermesh/*,
533                                                                         unsigned int onlayer*/)
534 {
535         RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
536         
537         if (meshp/* && onlayer==(*meshp)->GetLightLayer()*/) {
538                 return *meshp;
539         } else {
540                 return NULL;
541         }
542 }
543
544         
545
546
547         
548
549 void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
550 {
551         m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
552 }
553
554
555
556 void KX_BlenderSceneConverter::RegisterInterpolatorList(
557                                                                         BL_InterpolatorList *ipoList,
558                                                                         struct Ipo *for_ipo)
559 {
560         m_map_blender_to_gameipolist.insert(CHashedPtr(for_ipo), ipoList);
561 }
562
563
564
565 BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
566                                                                         struct Ipo *for_ipo)
567 {
568         BL_InterpolatorList **listp = m_map_blender_to_gameipolist[CHashedPtr(for_ipo)];
569                 
570         return listp?*listp:NULL;
571 }
572
573
574
575 void KX_BlenderSceneConverter::RegisterGameActuator(
576                                                                         SCA_IActuator *act,
577                                                                         struct bActuator *for_actuator)
578 {
579         m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
580 }
581
582
583
584 SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
585                                                                         struct bActuator *for_actuator)
586 {
587         SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
588         
589         return actp?*actp:NULL;
590 }
591
592
593
594 void KX_BlenderSceneConverter::RegisterGameController(
595                                                                         SCA_IController *cont,
596                                                                         struct bController *for_controller)
597 {
598         m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
599 }
600
601
602
603 SCA_IController *KX_BlenderSceneConverter::FindGameController(
604                                                                         struct bController *for_controller)
605 {
606         SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
607         
608         return contp?*contp:NULL;
609 }
610
611
612
613 void KX_BlenderSceneConverter::RegisterWorldInfo(
614                                                                         KX_WorldInfo *worldinfo)
615 {
616         m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
617 }
618
619 /*
620  * When deleting an IPO curve from Python, check if the IPO is being
621  * edited and if so clear the pointer to the old curve.
622  */
623 void KX_BlenderSceneConverter::localDel_ipoCurve ( IpoCurve * icu)
624 {
625         if (!G.sipo)
626                 return;
627
628         int i;
629         EditIpo *ei= (EditIpo *)G.sipo->editipo;
630         if (!ei) return;
631
632         for(i=0; i<G.sipo->totipo; i++, ei++) {
633                 if ( ei->icu == icu ) {
634                         ei->flag &= ~(IPO_SELECT | IPO_EDIT);
635                         ei->icu= 0;
636                         return;
637                 }
638         }
639 }
640
641 //quick hack
642 extern "C"
643 {
644         Ipo *add_ipo( char *name, int idcode );
645         char *getIpoCurveName( IpoCurve * icu );
646         struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int, short);
647         void testhandles_ipocurve(struct IpoCurve *icu);
648         void insert_vert_icu(struct IpoCurve *, float, float, short);
649         float eval_icu(struct IpoCurve *icu, float ipotime);
650         //void Mat3ToEul(float tmat[][3], float *eul);
651         void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot);
652 }
653
654 IpoCurve* findIpoCurve(IpoCurve* first, const char* searchName)
655 {
656         IpoCurve* icu1;
657         for( icu1 = first; icu1; icu1 = icu1->next ) 
658         {
659                 char* curveName = getIpoCurveName( icu1 );
660                 if( !strcmp( curveName, searchName) )
661                 {
662                         return icu1;
663                 }
664         }
665         return 0;
666 }
667
668 // this is not longer necesary //rcruiz
669 /*Ipo* KX_BlenderSceneConverter::findIpoForName(char* objName)
670 {
671         Ipo* ipo_iter = (Ipo*)m_maggie->ipo.first;
672
673         while( ipo_iter )
674         {
675                 if( strcmp( objName, ipo_iter->id.name + 2 ) == 0 ) 
676                 {
677                         return ipo_iter;
678                 }
679                 ipo_iter = (Ipo*)ipo_iter->id.next;
680         }
681         return 0;
682 }
683 */
684
685 void    KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
686 {
687
688         KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
689         int numScenes = scenes->size();
690         int i;
691         for (i=0;i<numScenes;i++)
692         {
693                 KX_Scene* scene = scenes->at(i);
694                 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
695                 CListValue* parentList = scene->GetRootParentList();
696                 int numObjects = parentList->GetCount();
697                 int g;
698                 for (g=0;g<numObjects;g++)
699                 {
700                         KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
701                         if (gameObj->IsDynamic())
702                         {
703                                 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
704                                 
705                                 Object* blenderObject = gameObj->GetBlenderObject();
706                                 if (blenderObject)
707                                 {
708                                         //erase existing ipo's
709                                         Ipo* ipo = blenderObject->ipo;//findIpoForName(blenderObject->id.name+2);
710                                         if (ipo)
711                                         {       //clear the curve data
712                                                 if (clearIpo){//rcruiz
713                                                         IpoCurve *icu1;
714                                                                                                                 
715                                                         int numCurves = 0;
716                                                         for( icu1 = (IpoCurve*)ipo->curve.first; icu1;  ) {
717                                                         
718                                                                 IpoCurve* tmpicu = icu1;
719                                                                 
720                                                                 /*int i;
721                                                                 BezTriple *bezt;
722                                                                 for( bezt = tmpicu->bezt, i = 0;        i < tmpicu->totvert; i++, bezt++){
723                                                                         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]);
724                                                                 }*/
725                                                                 
726                                                                 icu1 = icu1->next;
727                                                                 numCurves++;
728                         
729                                                                 BLI_remlink( &( blenderObject->ipo->curve ), tmpicu );
730                                                                 if( tmpicu->bezt )
731                                                                         MEM_freeN( tmpicu->bezt );
732                                                                 MEM_freeN( tmpicu );
733                                                                 localDel_ipoCurve( tmpicu );
734                                                         }
735                                                 }
736                                         } else
737                                         {       ipo = add_ipo(blenderObject->id.name+2, ID_OB);
738                                                 blenderObject->ipo = ipo;
739
740                                         }
741                                 
742                                         
743
744                                         
745
746                                 }
747                         }
748
749                 }
750                 
751         
752         }
753
754
755
756 }
757
758 void    KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo(){
759         
760         if (addInitFromFrame){          
761                 KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
762                 int numScenes = scenes->size();
763                 if (numScenes>=0){
764                         KX_Scene* scene = scenes->at(0);
765                         CListValue* parentList = scene->GetRootParentList();
766                         for (int ix=0;ix<parentList->GetCount();ix++){
767                                 KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix);
768                                 if (!gameobj->IsDynamic()){
769                                         Object* blenderobject = gameobj->GetBlenderObject();
770                                         if (!blenderobject)
771                                                 continue;
772                                         if (blenderobject->type==OB_ARMATURE)
773                                                 continue;
774                                         float eu[3];
775                                         Mat4ToEul(blenderobject->obmat,eu);                                     
776                                         MT_Point3 pos = MT_Point3(
777                                                 blenderobject->obmat[3][0],
778                                                 blenderobject->obmat[3][1],
779                                                 blenderobject->obmat[3][2]
780                                         );
781                                         MT_Vector3 eulxyz = MT_Vector3(
782                                                 eu[0],
783                                                 eu[1],
784                                                 eu[2]
785                                         );
786                                         MT_Vector3 scale = MT_Vector3(
787                                                 blenderobject->size[0],
788                                                 blenderobject->size[1],
789                                                 blenderobject->size[2]
790                                         );
791                                         gameobj->NodeSetLocalPosition(pos);
792                                         gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
793                                         gameobj->NodeSetLocalScale(scale);
794                                         gameobj->NodeUpdateGS(0);
795                                 }
796                         }
797                 }
798         }
799 }
800
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 = gameObj->GetBlenderObject();
824                                 if (blenderObject && blenderObject->ipo)
825                                 {
826                                         const MT_Point3& position = gameObj->NodeGetWorldPosition();
827                                         //const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
828                                         const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
829                                         
830                                         float eulerAngles[3];   
831                                         float eulerAnglesOld[3] = {0.0f, 0.0f, 0.0f};                                           
832                                         float tmat[3][3];
833                                         
834                                         Ipo* ipo = blenderObject->ipo;
835
836                                         //create the curves, if not existing, set linear if new
837
838                                         IpoCurve *icu_lx = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
839                                         if (!icu_lx) {
840                                                 icu_lx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1);
841                                                 if(icu_lx) icu_lx->ipo = IPO_LIN;
842                                         }
843                                         IpoCurve *icu_ly = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
844                                         if (!icu_ly) {
845                                                 icu_ly = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1);
846                                                 if(icu_ly) icu_ly->ipo = IPO_LIN;
847                                         }
848                                         IpoCurve *icu_lz = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
849                                         if (!icu_lz) {
850                                                 icu_lz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1);
851                                                 if(icu_lz) icu_lz->ipo = IPO_LIN;
852                                         }
853                                         IpoCurve *icu_rx = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
854                                         if (!icu_rx) {
855                                                 icu_rx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1);
856                                                 if(icu_rx) icu_rx->ipo = IPO_LIN;
857                                         }
858                                         IpoCurve *icu_ry = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
859                                         if (!icu_ry) {
860                                                 icu_ry = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1);
861                                                 if(icu_ry) icu_ry->ipo = IPO_LIN;
862                                         }
863                                         IpoCurve *icu_rz = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
864                                         if (!icu_rz) {
865                                                 icu_rz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1);
866                                                 if(icu_rz) icu_rz->ipo = IPO_LIN;
867                                         }
868                                         
869                                         if(icu_rx) eulerAnglesOld[0]= eval_icu( icu_rx, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
870                                         if(icu_ry) eulerAnglesOld[1]= eval_icu( icu_ry, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
871                                         if(icu_rz) eulerAnglesOld[2]= eval_icu( icu_rz, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
872                                         
873                                         // orn.getValue((float *)tmat); // uses the wrong ordering, cant use this
874                                         for (int r=0;r<3;r++)
875                                                 for (int c=0;c<3;c++)
876                                                         tmat[r][c] = orn[c][r];
877                                         
878                                         // Mat3ToEul(tmat, eulerAngles); // better to use Mat3ToCompatibleEul
879                                         Mat3ToCompatibleEul(tmat, eulerAngles, eulerAnglesOld);
880                                         
881                                         //eval_icu
882                                         for(int x = 0; x < 3; x++)
883                                                 eulerAngles[x] *= (float) ((180 / 3.14159265f) / 10.0);
884                                         
885                                         //fill the curves with data
886                                         if (icu_lx) insert_vert_icu(icu_lx, frameNumber, position.x(), 1);
887                                         if (icu_ly) insert_vert_icu(icu_ly, frameNumber, position.y(), 1);
888                                         if (icu_lz) insert_vert_icu(icu_lz, frameNumber, position.z(), 1);
889                                         if (icu_rx) insert_vert_icu(icu_rx, frameNumber, eulerAngles[0], 1);
890                                         if (icu_ry) insert_vert_icu(icu_ry, frameNumber, eulerAngles[1], 1);
891                                         if (icu_rz) insert_vert_icu(icu_rz, frameNumber, eulerAngles[2], 1);
892                                         
893                                         // Handles are corrected at the end, testhandles_ipocurve isnt needed yet
894                                 }
895                         }
896                 }
897         }
898 }
899
900
901 void    KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
902 {
903
904         KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
905         int numScenes = scenes->size();
906         int i;
907         for (i=0;i<numScenes;i++)
908         {
909                 KX_Scene* scene = scenes->at(i);
910                 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
911                 CListValue* parentList = scene->GetRootParentList();
912                 int numObjects = parentList->GetCount();
913                 int g;
914                 for (g=0;g<numObjects;g++)
915                 {
916                         KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
917                         if (gameObj->IsDynamic())
918                         {
919                                 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
920                                 
921                                 Object* blenderObject = gameObj->GetBlenderObject();
922                                 if (blenderObject && blenderObject->ipo)
923                                 {
924                                         Ipo* ipo = blenderObject->ipo;
925                                         
926                                         //create the curves, if not existing
927                                         //testhandles_ipocurve checks for NULL
928                                         testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocX"));
929                                         testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocY"));
930                                         testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ"));
931                                         testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotX"));
932                                         testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotY"));
933                                         testhandles_ipocurve(findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ"));
934                                 }
935                         }
936
937                 }
938                 
939         
940         }
941
942
943
944 }