svn merge -r 21041:21301 https://svn.blender.org/svnroot/bf-blender/branches/blender2...
[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 #include "KX_ConvertPhysicsObject.h"
48
49 #ifdef USE_BULLET
50 #include "CcdPhysicsEnvironment.h"
51 #endif
52
53 #include "KX_BlenderSceneConverter.h"
54 #include "KX_BlenderScalarInterpolator.h"
55 #include "BL_BlenderDataConversion.h"
56 #include "BlenderWorldInfo.h"
57 #include "KX_Scene.h"
58
59 /* This little block needed for linking to Blender... */
60 #ifdef WIN32
61 #include "BLI_winstuff.h"
62 #endif
63
64 /* This list includes only data type definitions */
65 #include "DNA_scene_types.h"
66 #include "DNA_world_types.h"
67 #include "BKE_main.h"
68
69 #include "BLI_arithb.h"
70
71 extern "C"
72 {
73 #include "DNA_object_types.h"
74 #include "DNA_curve_types.h"
75 #include "BLI_blenlib.h"
76 #include "MEM_guardedalloc.h"
77 //XXX #include "BSE_editipo.h"
78 //XXX #include "BSE_editipo_types.h"
79 #include "DNA_ipo_types.h"
80 #include "BKE_global.h"
81 #include "BKE_ipo.h" // eval_icu
82 #include "DNA_space_types.h"
83 }
84
85
86 KX_BlenderSceneConverter::KX_BlenderSceneConverter(
87                                                         struct Main* maggie,
88                                                         class KX_KetsjiEngine* engine
89                                                         )
90                                                         : m_maggie(maggie),
91                                                         m_ketsjiEngine(engine),
92                                                         m_alwaysUseExpandFraming(false),
93                                                         m_usemat(false),
94                                                         m_useglslmat(false)
95 {
96         m_newfilename = "";
97 }
98
99
100 KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
101 {
102         // clears meshes, and hashmaps from blender to gameengine data
103         int i;
104         // delete sumoshapes
105         
106
107         int numAdtLists = m_map_blender_to_gameAdtList.size();
108         for (i=0; i<numAdtLists; i++) {
109                 BL_InterpolatorList *adtList= *m_map_blender_to_gameAdtList.at(i);
110
111                 delete (adtList);
112         }
113
114         vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itw = m_worldinfos.begin();
115         while (itw != m_worldinfos.end()) {
116                 delete (*itw).second;
117                 itw++;
118         }
119
120         vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
121         while (itp != m_polymaterials.end()) {
122                 delete (*itp).second;
123                 itp++;
124         }
125
126         // delete after RAS_IPolyMaterial
127         vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
128         while (itmat != m_materials.end()) {
129                 delete (*itmat).second;
130                 itmat++;
131         }       
132
133
134         vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin();
135         while (itm != m_meshobjects.end()) {
136                 delete (*itm).second;
137                 itm++;
138         }
139
140 #ifdef USE_BULLET
141         KX_ClearBulletSharedShapes();
142 #endif
143
144 }
145
146
147
148 void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
149 {
150         m_newfilename = filename;
151 }
152
153
154
155 bool KX_BlenderSceneConverter::TryAndLoadNewFile()
156 {
157         bool result = false;
158
159         // find the file
160 /*      if ()
161         {
162                 result = true;
163         }
164         // if not, clear the newfilename
165         else
166         {
167                 m_newfilename = "";     
168         }
169 */
170         return result;
171 }
172
173 Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
174 {
175         Scene *sce;
176
177         /**
178          * Find the specified scene by name, or the first
179          * scene if nothing matches (shouldn't happen).
180          */
181
182         for (sce= (Scene*) m_maggie->scene.first; sce; sce= (Scene*) sce->id.next)
183                 if (name == (sce->id.name+2))
184                         return sce;
185
186         return (Scene*)m_maggie->scene.first;
187
188 }
189 #include "KX_PythonInit.h"
190
191 #ifdef USE_BULLET
192
193 #include "LinearMath/btIDebugDraw.h"
194
195
196 struct  BlenderDebugDraw : public btIDebugDraw
197 {
198         BlenderDebugDraw () :
199                 m_debugMode(0) 
200         {
201         }
202         
203         int m_debugMode;
204
205         virtual void    drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
206         {
207                 if (m_debugMode >0)
208                 {
209                         MT_Vector3 kxfrom(from[0],from[1],from[2]);
210                         MT_Vector3 kxto(to[0],to[1],to[2]);
211                         MT_Vector3 kxcolor(color[0],color[1],color[2]);
212
213                         KX_RasterizerDrawDebugLine(kxfrom,kxto,kxcolor);
214                 }
215         }
216         
217         virtual void    reportErrorWarning(const char* warningString)
218         {
219
220         }
221
222         virtual void    drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)
223         {
224                 //not yet
225         }
226
227         virtual void    setDebugMode(int debugMode)
228         {
229                 m_debugMode = debugMode;
230         }
231         virtual int             getDebugMode() const
232         {
233                 return m_debugMode;
234         }
235         ///todo: find out if Blender can do this
236         virtual void    draw3dText(const btVector3& location,const char* textString)
237         {
238
239         }
240                 
241 };
242
243 #endif
244
245 void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
246                                                                                         class KX_Scene* destinationscene,
247                                                                                         PyObject* dictobj,
248                                                                                         class SCA_IInputDevice* keyinputdev,
249                                                                                         class RAS_IRenderTools* rendertools,
250                                                                                         class RAS_ICanvas* canvas)
251 {
252         //find out which physics engine
253         Scene *blenderscene = GetBlenderSceneForName(scenename);
254
255         e_PhysicsEngine physics_engine = UseBullet;
256         bool useDbvtCulling = false;
257         // hook for registration function during conversion.
258         m_currentScene = destinationscene;
259         destinationscene->SetSceneConverter(this);
260         SG_SetActiveStage(SG_STAGE_CONVERTER);
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                                         useDbvtCulling = (blenderscene->world->mode & WO_DBVT_CULLING) != 0;
273                                         break;
274                                 }
275                                 
276                                 case WOPHY_ODE:
277                                 {
278                                         physics_engine = UseODE;
279                                         break;
280                                 }
281                                 case WOPHY_DYNAMO:
282                                 {
283                                         physics_engine = UseDynamo;
284                                         break;
285                                 }
286                                 case WOPHY_SUMO:
287                                 {
288                                         physics_engine = UseSumo; 
289                                         break;
290                                 }
291                                 case WOPHY_NONE:
292                                 {
293                                         physics_engine = UseNone;
294                                 }
295                         }
296                   
297                 }
298         }
299
300         switch (physics_engine)
301         {
302 #ifdef USE_BULLET
303                 case UseBullet:
304                         {
305                                 CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling);
306                                 ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw());
307                                 ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python
308                                 ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python
309
310                                 SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
311                                 int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
312                                 if (visualizePhysics)
313                                         ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints);
314                 
315                                 //todo: get a button in blender ?
316                                 //disable / enable debug drawing (contact points, aabb's etc)   
317                                 //ccdPhysEnv->setDebugMode(1);
318                                 destinationscene->SetPhysicsEnvironment(ccdPhysEnv);
319                                 break;
320                         }
321 #endif  
322                 case UseDynamo:
323                 {
324                 }
325                 
326                 default:
327                 case UseNone:
328                         physics_engine = UseNone;
329                         destinationscene ->SetPhysicsEnvironment(new DummyPhysicsEnvironment());
330                         break;
331         }
332
333         BL_ConvertBlenderObjects(m_maggie,
334                 scenename,
335                 destinationscene,
336                 m_ketsjiEngine,
337                 physics_engine,
338                 dictobj,
339                 keyinputdev,
340                 rendertools,
341                 canvas,
342                 this,
343                 m_alwaysUseExpandFraming
344                 );
345
346         //These lookup are not needed during game
347         m_map_blender_to_gameactuator.clear();
348         m_map_blender_to_gamecontroller.clear();
349         m_map_blender_to_gameobject.clear();
350
351         //Clearing this lookup table has the effect of disabling the cache of meshes
352         //between scenes, even if they are shared in the blend file.
353         //This cache mecanism is buggy so I leave it disable and the memory leak
354         //that would result from this is fixed in RemoveScene()
355         m_map_mesh_to_gamemesh.clear();
356         //Don't clear this lookup, it is needed for the baking physics into ipo animation
357         //To avoid it's infinite grows, object will be unregister when they are deleted 
358         //see KX_Scene::NewRemoveObject
359         //m_map_gameobject_to_blender.clear();
360 }
361
362 // This function removes all entities stored in the converter for that scene
363 // It should be used instead of direct delete scene
364 // Note that there was some provision for sharing entities (meshes...) between
365 // scenes but that is now disabled so all scene will have their own copy
366 // and we can delete them here. If the sharing is reactivated, change this code too..
367 // (see KX_BlenderSceneConverter::ConvertScene)
368 void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
369 {
370         int i, size;
371         // delete the scene first as it will stop the use of entities
372         delete scene;
373         // delete the entities of this scene
374         vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
375         size = m_worldinfos.size();
376         for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
377                 if ((*worldit).first == scene) {
378                         delete (*worldit).second;
379                         *worldit = m_worldinfos.back();
380                         m_worldinfos.pop_back();
381                         size--;
382                 } else {
383                         i++;
384                         worldit++;
385                 }
386         }
387
388         vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit;
389         size = m_polymaterials.size();
390         for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
391                 if ((*polymit).first == scene) {
392                         delete (*polymit).second;
393                         *polymit = m_polymaterials.back();
394                         m_polymaterials.pop_back();
395                         size--;
396                 } else {
397                         i++;
398                         polymit++;
399                 }
400         }
401
402         vector<pair<KX_Scene*,BL_Material*> >::iterator matit;
403         size = m_materials.size();
404         for (i=0, matit=m_materials.begin(); i<size; ) {
405                 if ((*matit).first == scene) {
406                         delete (*matit).second;
407                         *matit = m_materials.back();
408                         m_materials.pop_back();
409                         size--;
410                 } else {
411                         i++;
412                         matit++;
413                 }
414         }
415
416         vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
417         size = m_meshobjects.size();
418         for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
419                 if ((*meshit).first == scene) {
420                         delete (*meshit).second;
421                         *meshit = m_meshobjects.back();
422                         m_meshobjects.pop_back();
423                         size--;
424                 } else {
425                         i++;
426                         meshit++;
427                 }
428         }
429 }
430
431 // use blender materials
432 void KX_BlenderSceneConverter::SetMaterials(bool val)
433 {
434         m_usemat = val;
435         m_useglslmat = false;
436 }
437
438 void KX_BlenderSceneConverter::SetGLSLMaterials(bool val)
439 {
440         m_usemat = val;
441         m_useglslmat = val;
442 }
443
444 bool KX_BlenderSceneConverter::GetMaterials()
445 {
446         return m_usemat;
447 }
448
449 bool KX_BlenderSceneConverter::GetGLSLMaterials()
450 {
451         return m_useglslmat;
452 }
453
454 void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
455 {
456         m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
457 }
458
459
460
461 void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(
462         bool to_what)
463 {
464         m_alwaysUseExpandFraming= to_what;
465 }
466
467         
468
469 void KX_BlenderSceneConverter::RegisterGameObject(
470                                                                         KX_GameObject *gameobject, 
471                                                                         struct Object *for_blenderobject) 
472 {
473         m_map_gameobject_to_blender.insert(CHashedPtr(gameobject),for_blenderobject);
474         m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
475 }
476
477 void KX_BlenderSceneConverter::UnregisterGameObject(
478                                                                         KX_GameObject *gameobject) 
479 {
480         CHashedPtr gptr(gameobject);
481         struct Object **bobp= m_map_gameobject_to_blender[gptr];
482         if (bobp) {
483                 CHashedPtr bptr(*bobp);
484                 KX_GameObject **gobp= m_map_blender_to_gameobject[bptr];
485                 if (gobp && *gobp == gameobject)
486                         // also maintain m_map_blender_to_gameobject if the gameobject
487                         // being removed is matching the blender object
488                         m_map_blender_to_gameobject.remove(bptr);
489                 m_map_gameobject_to_blender.remove(gptr);
490         }
491 }
492
493
494 KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
495                                                                         struct Object *for_blenderobject) 
496 {
497         KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
498         
499         return obp?*obp:NULL;
500 }
501
502
503
504 struct Object *KX_BlenderSceneConverter::FindBlenderObject(
505                                                                         KX_GameObject *for_gameobject) 
506 {
507         struct Object **obp= m_map_gameobject_to_blender[CHashedPtr(for_gameobject)];
508         
509         return obp?*obp:NULL;
510 }
511
512         
513
514 void KX_BlenderSceneConverter::RegisterGameMesh(
515                                                                         RAS_MeshObject *gamemesh,
516                                                                         struct Mesh *for_blendermesh)
517 {
518         m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
519         m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh));
520 }
521
522
523
524 RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
525                                                                         struct Mesh *for_blendermesh/*,
526                                                                         unsigned int onlayer*/)
527 {
528         RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
529         
530         if (meshp/* && onlayer==(*meshp)->GetLightLayer()*/) {
531                 return *meshp;
532         } else {
533                 return NULL;
534         }
535 }
536
537         
538
539
540         
541
542 void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
543 {
544         m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
545 }
546
547
548
549 void KX_BlenderSceneConverter::RegisterInterpolatorList(
550                                                                         BL_InterpolatorList *adtList,
551                                                                         struct AnimData *for_adt)
552 {
553         m_map_blender_to_gameAdtList.insert(CHashedPtr(for_adt), adtList);
554 }
555
556
557
558 BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
559                                                                         struct AnimData *for_adt)
560 {
561         BL_InterpolatorList **listp = m_map_blender_to_gameAdtList[CHashedPtr(for_adt)];
562                 
563         return listp?*listp:NULL;
564 }
565
566
567
568 void KX_BlenderSceneConverter::RegisterGameActuator(
569                                                                         SCA_IActuator *act,
570                                                                         struct bActuator *for_actuator)
571 {
572         m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
573 }
574
575
576
577 SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
578                                                                         struct bActuator *for_actuator)
579 {
580         SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
581         
582         return actp?*actp:NULL;
583 }
584
585
586
587 void KX_BlenderSceneConverter::RegisterGameController(
588                                                                         SCA_IController *cont,
589                                                                         struct bController *for_controller)
590 {
591         m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
592 }
593
594
595
596 SCA_IController *KX_BlenderSceneConverter::FindGameController(
597                                                                         struct bController *for_controller)
598 {
599         SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
600         
601         return contp?*contp:NULL;
602 }
603
604
605
606 void KX_BlenderSceneConverter::RegisterWorldInfo(
607                                                                         KX_WorldInfo *worldinfo)
608 {
609         m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
610 }
611
612 /*
613  * When deleting an IPO curve from Python, check if the IPO is being
614  * edited and if so clear the pointer to the old curve.
615  */
616 void KX_BlenderSceneConverter::localDel_ipoCurve ( IpoCurve * icu )
617 {
618 #if 0 //XXX
619         if (!G.sipo)
620                 return;
621
622         int i;
623         EditIpo *ei= (EditIpo *)G.sipo->editipo;
624         if (!ei) return;
625
626         for(i=0; i<G.sipo->totipo; i++, ei++) {
627                 if ( ei->icu == icu ) {
628                         ei->flag &= ~(IPO_SELECT | IPO_EDIT);
629                         ei->icu= 0;
630                         return;
631                 }
632         }
633 #endif
634 }
635
636 //quick hack
637 extern "C"
638 {
639         Ipo *add_ipo( char *name, int idcode );
640         //XXX char *getIpoCurveName( IpoCurve * icu );
641         //XXX struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int);
642         //XXX void testhandles_ipocurve(struct IpoCurve *icu);
643         void insert_vert_icu(struct IpoCurve *, float, float, short);
644         float eval_icu(struct IpoCurve *icu, float ipotime);
645         //void Mat3ToEul(float tmat[][3], float *eul);
646         void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot);
647 }
648
649 IpoCurve* findIpoCurve(IpoCurve* first, const char* searchName)
650 {
651         IpoCurve* icu1;
652         for( icu1 = first; icu1; icu1 = icu1->next ) 
653         {
654                 /*XXX char* curveName = getIpoCurveName( icu1 );
655                 if( !strcmp( curveName, searchName) )
656                 {
657                         return icu1;
658                 }*/
659         }
660         return 0;
661 }
662
663 // this is not longer necesary //rcruiz
664 /*Ipo* KX_BlenderSceneConverter::findIpoForName(char* objName)
665 {
666         Ipo* ipo_iter = (Ipo*)m_maggie->ipo.first;
667
668         while( ipo_iter )
669         {
670                 if( strcmp( objName, ipo_iter->id.name + 2 ) == 0 ) 
671                 {
672                         return ipo_iter;
673                 }
674                 ipo_iter = (Ipo*)ipo_iter->id.next;
675         }
676         return 0;
677 }
678 */
679
680 void    KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
681 {
682
683         KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
684         int numScenes = scenes->size();
685         int i;
686         for (i=0;i<numScenes;i++)
687         {
688                 KX_Scene* scene = scenes->at(i);
689                 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
690                 CListValue* parentList = scene->GetRootParentList();
691                 int numObjects = parentList->GetCount();
692                 int g;
693                 for (g=0;g<numObjects;g++)
694                 {
695                         KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
696                         if (gameObj->IsDynamic())
697                         {
698                                 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
699                                 
700                                 Object* blenderObject = FindBlenderObject(gameObj);
701                                 if (blenderObject)
702                                 {
703                                         //erase existing ipo's
704                                         Ipo* ipo = blenderObject->ipo;//findIpoForName(blenderObject->id.name+2);
705                                         if (ipo)
706                                         {       //clear the curve data
707                                                 if (clearIpo){//rcruiz
708                                                         IpoCurve *icu1;
709                                                                                                                 
710                                                         int numCurves = 0;
711                                                         for( icu1 = (IpoCurve*)ipo->curve.first; icu1;  ) {
712                                                         
713                                                                 IpoCurve* tmpicu = icu1;
714                                                                 
715                                                                 /*int i;
716                                                                 BezTriple *bezt;
717                                                                 for( bezt = tmpicu->bezt, i = 0;        i < tmpicu->totvert; i++, bezt++){
718                                                                         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]);
719                                                                 }*/
720                                                                 
721                                                                 icu1 = icu1->next;
722                                                                 numCurves++;
723                         
724                                                                 BLI_remlink( &( blenderObject->ipo->curve ), tmpicu );
725                                                                 if( tmpicu->bezt )
726                                                                         MEM_freeN( tmpicu->bezt );
727                                                                 MEM_freeN( tmpicu );
728                                                                 localDel_ipoCurve( tmpicu );
729                                                         }
730                                                 }
731                                         } else
732                                         {       ipo = NULL; // XXX add_ipo(blenderObject->id.name+2, ID_OB);
733                                                 blenderObject->ipo = ipo;
734
735                                         }
736                                 
737                                         
738
739                                         
740
741                                 }
742                         }
743
744                 }
745                 
746         
747         }
748
749
750
751 }
752
753 void    KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo(){
754         
755         if (addInitFromFrame){          
756                 KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
757                 int numScenes = scenes->size();
758                 if (numScenes>=0){
759                         KX_Scene* scene = scenes->at(0);
760                         CListValue* parentList = scene->GetRootParentList();
761                         for (int ix=0;ix<parentList->GetCount();ix++){
762                                 KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix);
763                                 if (!gameobj->IsDynamic()){
764                                         Object* blenderobject = FindBlenderObject(gameobj);
765                                         if (!blenderobject)
766                                                 continue;
767                                         if (blenderobject->type==OB_ARMATURE)
768                                                 continue;
769                                         float eu[3];
770                                         Mat4ToEul(blenderobject->obmat,eu);                                     
771                                         MT_Point3 pos = MT_Point3(
772                                                 blenderobject->obmat[3][0],
773                                                 blenderobject->obmat[3][1],
774                                                 blenderobject->obmat[3][2]
775                                         );
776                                         MT_Vector3 eulxyz = MT_Vector3(
777                                                 eu[0],
778                                                 eu[1],
779                                                 eu[2]
780                                         );
781                                         MT_Vector3 scale = MT_Vector3(
782                                                 blenderobject->size[0],
783                                                 blenderobject->size[1],
784                                                 blenderobject->size[2]
785                                         );
786                                         gameobj->NodeSetLocalPosition(pos);
787                                         gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
788                                         gameobj->NodeSetLocalScale(scale);
789                                         gameobj->NodeUpdateGS(0);
790                                 }
791                         }
792                 }
793         }
794 }
795
796
797         ///this generates ipo curves for position, rotation, allowing to use game physics in animation
798 void    KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
799 {
800
801         KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
802         int numScenes = scenes->size();
803         int i;
804         for (i=0;i<numScenes;i++)
805         {
806                 KX_Scene* scene = scenes->at(i);
807                 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
808                 CListValue* parentList = scene->GetRootParentList();
809                 int numObjects = parentList->GetCount();
810                 int g;
811                 for (g=0;g<numObjects;g++)
812                 {
813                         KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
814                         if (gameObj->IsDynamic())
815                         {
816                                 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
817                                 
818                                 Object* blenderObject = FindBlenderObject(gameObj);
819                                 if (blenderObject && blenderObject->ipo)
820                                 {
821                                         const MT_Point3& position = gameObj->NodeGetWorldPosition();
822                                         //const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
823                                         const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
824                                         
825                                         float eulerAngles[3];   
826                                         float eulerAnglesOld[3] = {0.0f, 0.0f, 0.0f};                                           
827                                         float tmat[3][3];
828                                         
829                                         // XXX animato
830 #if 0
831                                         Ipo* ipo = blenderObject->ipo;
832
833                                         //create the curves, if not existing, set linear if new
834
835                                         IpoCurve *icu_lx = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
836                                         if (!icu_lx) {
837                                                 icu_lx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_X, 1);
838                                                 if(icu_lx) icu_lx->ipo = IPO_LIN;
839                                         }
840                                         IpoCurve *icu_ly = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
841                                         if (!icu_ly) {
842                                                 icu_ly = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Y, 1);
843                                                 if(icu_ly) icu_ly->ipo = IPO_LIN;
844                                         }
845                                         IpoCurve *icu_lz = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
846                                         if (!icu_lz) {
847                                                 icu_lz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_LOC_Z, 1);
848                                                 if(icu_lz) icu_lz->ipo = IPO_LIN;
849                                         }
850                                         IpoCurve *icu_rx = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
851                                         if (!icu_rx) {
852                                                 icu_rx = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_X, 1);
853                                                 if(icu_rx) icu_rx->ipo = IPO_LIN;
854                                         }
855                                         IpoCurve *icu_ry = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
856                                         if (!icu_ry) {
857                                                 icu_ry = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Y, 1);
858                                                 if(icu_ry) icu_ry->ipo = IPO_LIN;
859                                         }
860                                         IpoCurve *icu_rz = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
861                                         if (!icu_rz) {
862                                                 icu_rz = verify_ipocurve(&blenderObject->id, ipo->blocktype, NULL, NULL, NULL, OB_ROT_Z, 1);
863                                                 if(icu_rz) icu_rz->ipo = IPO_LIN;
864                                         }
865                                         
866                                         if(icu_rx) eulerAnglesOld[0]= eval_icu( icu_rx, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
867                                         if(icu_ry) eulerAnglesOld[1]= eval_icu( icu_ry, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
868                                         if(icu_rz) eulerAnglesOld[2]= eval_icu( icu_rz, frameNumber - 1 ) / ((180 / 3.14159265f) / 10);
869                                         
870                                         // orn.getValue((float *)tmat); // uses the wrong ordering, cant use this
871                                         for (int r=0;r<3;r++)
872                                                 for (int c=0;c<3;c++)
873                                                         tmat[r][c] = orn[c][r];
874                                         
875                                         // Mat3ToEul(tmat, eulerAngles); // better to use Mat3ToCompatibleEul
876                                         Mat3ToCompatibleEul(tmat, eulerAngles, eulerAnglesOld);
877                                         
878                                         //eval_icu
879                                         for(int x = 0; x < 3; x++)
880                                                 eulerAngles[x] *= (float) ((180 / 3.14159265f) / 10.0);
881                                         
882                                         //fill the curves with data
883                                         if (icu_lx) insert_vert_icu(icu_lx, frameNumber, position.x(), 1);
884                                         if (icu_ly) insert_vert_icu(icu_ly, frameNumber, position.y(), 1);
885                                         if (icu_lz) insert_vert_icu(icu_lz, frameNumber, position.z(), 1);
886                                         if (icu_rx) insert_vert_icu(icu_rx, frameNumber, eulerAngles[0], 1);
887                                         if (icu_ry) insert_vert_icu(icu_ry, frameNumber, eulerAngles[1], 1);
888                                         if (icu_rz) insert_vert_icu(icu_rz, frameNumber, eulerAngles[2], 1);
889                                         
890                                         // Handles are corrected at the end, testhandles_ipocurve isnt needed yet
891 #endif
892                                 }
893                         }
894                 }
895         }
896 }
897
898
899 void    KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
900 {
901
902         KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
903         int numScenes = scenes->size();
904         int i;
905         for (i=0;i<numScenes;i++)
906         {
907                 KX_Scene* scene = scenes->at(i);
908                 //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
909                 CListValue* parentList = scene->GetRootParentList();
910                 int numObjects = parentList->GetCount();
911                 int g;
912                 for (g=0;g<numObjects;g++)
913                 {
914                         KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
915                         if (gameObj->IsDynamic())
916                         {
917                                 //KX_IPhysicsController* physCtrl = gameObj->GetPhysicsController();
918                                 
919                                 Object* blenderObject = FindBlenderObject(gameObj);
920                                 if (blenderObject && blenderObject->ipo)
921                                 {
922                                         // XXX animato
923 #if 0
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 #endif
935                                 }
936                         }
937
938                 }
939                 
940         
941         }
942
943
944
945 }