BGE real-time soft bodies, step 2 / 3: create a btSoftBody. Next step is hooking...
[blender-staging.git] / source / gameengine / Converter / BL_BlenderDataConversion.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Convert blender data to ketsji
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #ifdef WIN32
36 #pragma warning (disable : 4786)
37 #endif
38
39 #include <math.h>
40
41 #include "BL_BlenderDataConversion.h"
42 #include "KX_BlenderGL.h"
43 #include "KX_BlenderScalarInterpolator.h"
44
45 #include "RAS_IPolygonMaterial.h"
46 #include "KX_PolygonMaterial.h"
47
48 // Expressions
49 #include "ListValue.h"
50 #include "IntValue.h"
51 // Collision & Fuzzics LTD
52
53 #include "PHY_Pro.h"
54
55
56 #include "KX_Scene.h"
57 #include "KX_GameObject.h"
58 #include "RAS_FramingManager.h"
59 #include "RAS_MeshObject.h"
60
61 #include "KX_ConvertActuators.h"
62 #include "KX_ConvertControllers.h"
63 #include "KX_ConvertSensors.h"
64
65 #include "SCA_LogicManager.h"
66 #include "SCA_EventManager.h"
67 #include "SCA_TimeEventManager.h"
68 #include "KX_Light.h"
69 #include "KX_Camera.h"
70 #include "KX_EmptyObject.h"
71 #include "MT_Point3.h"
72 #include "MT_Transform.h"
73 #include "MT_MinMax.h"
74 #include "SCA_IInputDevice.h"
75 #include "RAS_TexMatrix.h"
76 #include "RAS_ICanvas.h"
77 #include "RAS_MaterialBucket.h"
78 //#include "KX_BlenderPolyMaterial.h"
79 #include "RAS_Polygon.h"
80 #include "RAS_TexVert.h"
81 #include "RAS_BucketManager.h"
82 #include "RAS_IRenderTools.h"
83 #include "BL_Material.h"
84 #include "KX_BlenderMaterial.h"
85 #include "BL_Texture.h"
86
87 #include "DNA_action_types.h"
88 #include "BKE_main.h"
89 #include "BKE_global.h"
90 #include "BKE_object.h"
91 #include "BKE_scene.h"
92 #include "BL_SkinMeshObject.h"
93 #include "BL_ShapeDeformer.h"
94 #include "BL_SkinDeformer.h"
95 #include "BL_MeshDeformer.h"
96 //#include "BL_ArmatureController.h"
97
98 #include "BlenderWorldInfo.h"
99
100 #include "KX_KetsjiEngine.h"
101 #include "KX_BlenderSceneConverter.h"
102
103 #include"SND_Scene.h"
104 #include "SND_SoundListener.h"
105
106 /* This little block needed for linking to Blender... */
107 #ifdef WIN32
108 #include "BLI_winstuff.h"
109 #endif
110
111 /* This list includes only data type definitions */
112 #include "DNA_object_types.h"
113 #include "DNA_material_types.h"
114 #include "DNA_texture_types.h"
115 #include "DNA_image_types.h"
116 #include "DNA_lamp_types.h"
117 #include "DNA_group_types.h"
118 #include "DNA_scene_types.h"
119 #include "DNA_camera_types.h"
120 #include "DNA_property_types.h"
121 #include "DNA_text_types.h"
122 #include "DNA_sensor_types.h"
123 #include "DNA_controller_types.h"
124 #include "DNA_actuator_types.h"
125 #include "DNA_mesh_types.h"
126 #include "DNA_meshdata_types.h"
127 #include "DNA_view3d_types.h"
128 #include "DNA_world_types.h"
129 #include "DNA_sound_types.h"
130 #include "DNA_key_types.h"
131 #include "DNA_armature_types.h"
132
133 #include "MEM_guardedalloc.h"
134 #include "BKE_utildefines.h"
135 #include "BKE_key.h"
136 #include "BKE_mesh.h"
137 #include "MT_Point3.h"
138
139 #include "BLI_arithb.h"
140
141 extern "C" {
142 #include "BKE_customdata.h"
143 #include "BKE_cdderivedmesh.h"
144 #include "BKE_DerivedMesh.h"
145 }
146
147 #include "BKE_material.h" /* give_current_material */
148 /* end of blender include block */
149
150 #include "KX_BlenderInputDevice.h"
151 #include "KX_ConvertProperties.h"
152 #include "KX_HashedPtr.h"
153
154
155 #include "KX_ScalarInterpolator.h"
156
157 #include "KX_IpoConvert.h"
158 #include "SYS_System.h"
159
160 #include "SG_Node.h"
161 #include "SG_BBox.h"
162 #include "SG_Tree.h"
163
164 // defines USE_ODE to choose physics engine
165 #include "KX_ConvertPhysicsObject.h"
166
167
168 // This file defines relationships between parents and children
169 // in the game engine.
170
171 #include "KX_SG_NodeRelationships.h"
172 #include "KX_SG_BoneParentNodeRelationship.h"
173
174 #include "BL_ArmatureObject.h"
175 #include "BL_DeformableGameObject.h"
176
177 #ifdef __cplusplus
178 extern "C" {
179 #endif
180 #include "BSE_headerbuttons.h"
181 void update_for_newframe();
182 //void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
183 //#include "BKE_ipo.h"
184 //void do_all_data_ipos(void);
185 #ifdef __cplusplus
186 }
187 #endif
188
189 static int default_face_mode = TF_DYNAMIC;
190
191 static unsigned int KX_rgbaint2uint_new(unsigned int icol)
192 {
193         union
194         {
195                 unsigned int integer;
196                 unsigned char cp[4];
197         } out_color, in_color;
198         
199         in_color.integer = icol;
200         out_color.cp[0] = in_color.cp[3]; // red
201         out_color.cp[1] = in_color.cp[2]; // green
202         out_color.cp[2] = in_color.cp[1]; // blue
203         out_color.cp[3] = in_color.cp[0]; // alpha
204         
205         return out_color.integer;
206 }
207
208 /* Now the real converting starts... */
209 static unsigned int KX_Mcol2uint_new(MCol col)
210 {
211         /* color has to be converted without endian sensitivity. So no shifting! */
212         union
213         {
214                 MCol col;
215                 unsigned int integer;
216                 unsigned char cp[4];
217         } out_color, in_color;
218
219         in_color.col = col;
220         out_color.cp[0] = in_color.cp[3]; // red
221         out_color.cp[1] = in_color.cp[2]; // green
222         out_color.cp[2] = in_color.cp[1]; // blue
223         out_color.cp[3] = in_color.cp[0]; // alpha
224         
225         return out_color.integer;
226 }
227
228 static void SetDefaultFaceType(Scene* scene)
229 {
230         default_face_mode = TF_DYNAMIC;
231         Scene *sce;
232         Base *base;
233
234         for(SETLOOPER(scene,base))
235         {
236                 if (base->object->type == OB_LAMP)
237                 {
238                         default_face_mode = TF_DYNAMIC|TF_LIGHT;
239                         return;
240                 }
241         }
242 }
243
244
245 // --
246 static void GetRGB(short type,
247         MFace* mface,
248         MCol* mmcol,
249         Material *mat,
250         unsigned int &c0, 
251         unsigned int &c1, 
252         unsigned int &c2, 
253         unsigned int &c3)
254 {
255         unsigned int color = 0xFFFFFFFFL;
256         switch(type)
257         {
258                 case 0: // vertex colors
259                 {
260                         if(mmcol) {
261                                 c0 = KX_Mcol2uint_new(mmcol[0]);
262                                 c1 = KX_Mcol2uint_new(mmcol[1]);
263                                 c2 = KX_Mcol2uint_new(mmcol[2]);
264                                 if (mface->v4)
265                                         c3 = KX_Mcol2uint_new(mmcol[3]);
266                         }else // backup white
267                         {
268                                 c0 = KX_rgbaint2uint_new(color);
269                                 c1 = KX_rgbaint2uint_new(color);
270                                 c2 = KX_rgbaint2uint_new(color);        
271                                 if (mface->v4)
272                                         c3 = KX_rgbaint2uint_new( color );
273                         }
274                 } break;
275                 
276         
277                 case 1: // material rgba
278                 {
279                         if (mat) {
280                                 union {
281                                         unsigned char cp[4];
282                                         unsigned int integer;
283                                 } col_converter;
284                                 col_converter.cp[3] = (unsigned char) (mat->r*255.0);
285                                 col_converter.cp[2] = (unsigned char) (mat->g*255.0);
286                                 col_converter.cp[1] = (unsigned char) (mat->b*255.0);
287                                 col_converter.cp[0] = (unsigned char) (mat->alpha*255.0);
288                                 color = col_converter.integer;
289                         }
290                         c0 = KX_rgbaint2uint_new(color);
291                         c1 = KX_rgbaint2uint_new(color);
292                         c2 = KX_rgbaint2uint_new(color);        
293                         if (mface->v4)
294                                 c3 = KX_rgbaint2uint_new(color);
295                 } break;
296                 
297                 default: // white
298                 {
299                         c0 = KX_rgbaint2uint_new(color);
300                         c1 = KX_rgbaint2uint_new(color);
301                         c2 = KX_rgbaint2uint_new(color);        
302                         if (mface->v4)
303                                 c3 = KX_rgbaint2uint_new(color);
304                 } break;
305         }
306 }
307
308 typedef struct MTF_localLayer
309 {
310         MTFace *face;
311         const char *name;
312 }MTF_localLayer;
313
314 // ------------------------------------
315 BL_Material* ConvertMaterial(
316         Material *mat, 
317         MTFace* tface,  
318         const char *tfaceName,
319         MFace* mface, 
320         MCol* mmcol, 
321         int lightlayer, 
322         Object* blenderobj,
323         MTF_localLayer *layers,
324         bool glslmat)
325 {
326         //this needs some type of manager
327         BL_Material *material = new BL_Material();
328
329         int numchan =   -1, texalpha = 0;
330         bool validmat   = (mat!=0);
331         bool validface  = (tface!=0);
332         
333         short type = 0;
334         if( validmat )
335                 type = 1; // material color 
336         
337         material->IdMode = DEFAULT_BLENDER;
338         material->glslmat = (validmat)? glslmat: false;
339
340         // --------------------------------
341         if(validmat) {
342
343                 // use vertex colors by explicitly setting
344                 if(mat->mode &MA_VERTEXCOLP || glslmat)
345                         type = 0;
346
347                 // use lighting?
348                 material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
349                 MTex *mttmp = 0;
350                 numchan = getNumTexChannels(mat);
351                 int valid_index = 0;
352                 
353                 // use the face texture if
354                 // 1) it is set in the buttons
355                 // 2) we have a face texture and a material but no valid texture in slot 1
356                 bool facetex = false;
357                 if(validface && mat->mode &MA_FACETEXTURE) 
358                         facetex = true;
359                 if(validface && !mat->mtex[0])
360                         facetex = true;
361                 if(validface && mat->mtex[0]) {
362                         MTex *tmp = mat->mtex[0];
363                         if(!tmp->tex || tmp->tex && !tmp->tex->ima )
364                                 facetex = true;
365                 }
366                 numchan = numchan>MAXTEX?MAXTEX:numchan;
367         
368                 // foreach MTex
369                 for(int i=0; i<numchan; i++) {
370                         // use face tex
371
372                         if(i==0 && facetex ) {
373                                 Image*tmp = (Image*)(tface->tpage);
374
375                                 if(tmp) {
376                                         material->img[i] = tmp;
377                                         material->texname[i] = material->img[i]->id.name;
378                                         material->flag[i] |= ( tface->transp  &TF_ALPHA )?USEALPHA:0;
379                                         material->flag[i] |= ( tface->transp  &TF_ADD   )?CALCALPHA:0;
380                                         material->flag[i] |= MIPMAP;
381
382                                         if(material->img[i]->flag & IMA_REFLECT)
383                                                 material->mapping[i].mapping |= USEREFL;
384                                         else
385                                         {
386                                                 mttmp = getImageFromMaterial( mat, i );
387                                                 if(mttmp && mttmp->texco &TEXCO_UV)
388                                                 {
389                                                         STR_String uvName = mttmp->uvname;
390
391                                                         if (!uvName.IsEmpty())
392                                                                 material->mapping[i].uvCoName = mttmp->uvname;
393                                                         else
394                                                                 material->mapping[i].uvCoName = "";
395                                                 }
396                                                 material->mapping[i].mapping |= USEUV;
397                                         }
398
399                                         if(material->ras_mode & USE_LIGHT)
400                                                 material->ras_mode &= ~USE_LIGHT;
401                                         if(tface->mode & TF_LIGHT)
402                                                 material->ras_mode |= USE_LIGHT;
403
404                                         valid_index++;
405                                 }
406                                 else {
407                                         material->img[i] = 0;
408                                         material->texname[i] = "";
409                                 }
410                                 continue;
411                         }
412
413                         mttmp = getImageFromMaterial( mat, i );
414                         if( mttmp ) {
415                                 if( mttmp->tex ) {
416                                         if( mttmp->tex->type == TEX_IMAGE ) {
417                                                 material->mtexname[i] = mttmp->tex->id.name;
418                                                 material->img[i] = mttmp->tex->ima;
419                                                 if( material->img[i] ) {
420
421                                                         material->texname[i] = material->img[i]->id.name;
422                                                         material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
423                                                         // -----------------------
424                                                         if( mttmp->tex->imaflag &TEX_USEALPHA ) {
425                                                                 material->flag[i]       |= USEALPHA;
426                                                         }
427                                                         // -----------------------
428                                                         else if( mttmp->tex->imaflag &TEX_CALCALPHA ) {
429                                                                 material->flag[i]       |= CALCALPHA;
430                                                         }
431                                                         else if(mttmp->tex->flag &TEX_NEGALPHA) {
432                                                                 material->flag[i]       |= USENEGALPHA;
433                                                         }
434
435                                                         material->color_blend[i] = mttmp->colfac;
436                                                         material->flag[i] |= ( mttmp->mapto  & MAP_ALPHA                )?TEXALPHA:0;
437                                                         material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE    )?TEXNEG:0;
438
439                                                         if(!glslmat && (material->flag[i] & TEXALPHA))
440                                                                 texalpha = 1;
441                                                 }
442                                         }
443                                         else if(mttmp->tex->type == TEX_ENVMAP) {
444                                                 if( mttmp->tex->env->stype == ENV_LOAD ) {
445                                         
446                                                         material->mtexname[i]     = mttmp->tex->id.name;
447                                                         EnvMap *env = mttmp->tex->env;
448                                                         env->ima = mttmp->tex->ima;
449                                                         material->cubemap[i] = env;
450
451                                                         if (material->cubemap[i])
452                                                         {
453                                                                 if (!material->cubemap[i]->cube[0])
454                                                                         BL_Texture::SplitEnvMap(material->cubemap[i]);
455
456                                                                 material->texname[i]= material->cubemap[i]->ima->id.name;
457                                                                 material->mapping[i].mapping |= USEENV;
458                                                         }
459                                                 }
460                                         }
461                                         material->flag[i] |= (mat->ipo!=0)?HASIPO:0;
462                                         /// --------------------------------
463                                         // mapping methods
464                                         material->mapping[i].mapping |= ( mttmp->texco  & TEXCO_REFL    )?USEREFL:0;
465                                         
466                                         if(mttmp->texco & TEXCO_OBJECT) {
467                                                 material->mapping[i].mapping |= USEOBJ;
468                                                 if(mttmp->object)
469                                                         material->mapping[i].objconame = mttmp->object->id.name;
470                                         }
471                                         else if(mttmp->texco &TEXCO_REFL)
472                                                 material->mapping[i].mapping |= USEREFL;
473                                         else if(mttmp->texco &(TEXCO_ORCO|TEXCO_GLOB))
474                                                 material->mapping[i].mapping |= USEORCO;
475                                         else if(mttmp->texco &TEXCO_UV)
476                                         {
477                                                 STR_String uvName = mttmp->uvname;
478
479                                                 if (!uvName.IsEmpty())
480                                                         material->mapping[i].uvCoName = mttmp->uvname;
481                                                 else
482                                                         material->mapping[i].uvCoName = "";
483                                                 material->mapping[i].mapping |= USEUV;
484                                         }
485                                         else if(mttmp->texco &TEXCO_NORM)
486                                                 material->mapping[i].mapping |= USENORM;
487                                         else if(mttmp->texco &TEXCO_TANGENT)
488                                                 material->mapping[i].mapping |= USETANG;
489                                         else
490                                                 material->mapping[i].mapping |= DISABLE;
491                                         
492                                         material->mapping[i].scale[0] = mttmp->size[0];
493                                         material->mapping[i].scale[1] = mttmp->size[1];
494                                         material->mapping[i].scale[2] = mttmp->size[2];
495                                         material->mapping[i].offsets[0] = mttmp->ofs[0];
496                                         material->mapping[i].offsets[1] = mttmp->ofs[1];
497                                         material->mapping[i].offsets[2] = mttmp->ofs[2];
498
499                                         material->mapping[i].projplane[0] = mttmp->projx;
500                                         material->mapping[i].projplane[1] = mttmp->projy;
501                                         material->mapping[i].projplane[2] = mttmp->projz;
502                                         /// --------------------------------
503                                         
504                                         switch( mttmp->blendtype ) {
505                                         case MTEX_BLEND:
506                                                 material->blend_mode[i] = BLEND_MIX;
507                                                 break;
508                                         case MTEX_MUL:
509                                                 material->blend_mode[i] = BLEND_MUL;
510                                                 break;
511                                         case MTEX_ADD:
512                                                 material->blend_mode[i] = BLEND_ADD;
513                                                 break;
514                                         case MTEX_SUB:
515                                                 material->blend_mode[i] = BLEND_SUB;
516                                                 break;
517                                         case MTEX_SCREEN:
518                                                 material->blend_mode[i] = BLEND_SCR;
519                                                 break;
520                                         }
521                                         valid_index++;
522                                 }
523                         }
524                 }
525
526                 // above one tex the switches here
527                 // are not used
528                 switch(valid_index) {
529                 case 0:
530                         material->IdMode = DEFAULT_BLENDER;
531                         break;
532                 case 1:
533                         material->IdMode = ONETEX;
534                         break;
535                 default:
536                         material->IdMode = GREATERTHAN2;
537                         break;
538                 }
539                 material->SetUsers(mat->id.us);
540
541                 material->num_enabled = valid_index;
542
543                 material->speccolor[0]  = mat->specr;
544                 material->speccolor[1]  = mat->specg;
545                 material->speccolor[2]  = mat->specb;
546                 material->hard                  = (float)mat->har/4.0f;
547                 material->matcolor[0]   = mat->r;
548                 material->matcolor[1]   = mat->g;
549                 material->matcolor[2]   = mat->b;
550                 material->matcolor[3]   = mat->alpha;
551                 material->alpha                 = mat->alpha;
552                 material->emit                  = mat->emit;
553                 material->spec_f                = mat->spec;
554                 material->ref                   = mat->ref;
555                 material->amb                   = mat->amb;
556
557                 material->ras_mode |= (mat->mode & MA_WIRE)? WIRE: 0;
558         }
559         else {
560                 int valid = 0;
561
562                 // check for tface tex to fallback on
563                 if( validface ){
564
565                         // no light bugfix
566                         if(tface->mode) material->ras_mode |= USE_LIGHT;
567
568                         material->img[0] = (Image*)(tface->tpage);
569                         // ------------------------
570                         if(material->img[0]) {
571                                 material->texname[0] = material->img[0]->id.name;
572                                 material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
573                                 material->flag[0] |= ( tface->transp  &TF_ALPHA )?USEALPHA:0;
574                                 material->flag[0] |= ( tface->transp  &TF_ADD   )?CALCALPHA:0;
575                                 valid++;
576                         }
577                 }
578                 material->SetUsers(-1);
579                 material->num_enabled   = valid;
580                 material->IdMode                = TEXFACE;
581                 material->speccolor[0]  = 1.f;
582                 material->speccolor[1]  = 1.f;
583                 material->speccolor[2]  = 1.f;
584                 material->hard                  = 35.f;
585                 material->matcolor[0]   = 0.5f;
586                 material->matcolor[1]   = 0.5f;
587                 material->matcolor[2]   = 0.5f;
588                 material->spec_f                = 0.5f;
589                 material->ref                   = 0.8f;
590         }
591         MT_Point2 uv[4];
592         MT_Point2 uv2[4];
593         const char *uvName = "", *uv2Name = "";
594
595         uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f);
596         uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f);
597
598         if( validface ) {
599
600                 material->ras_mode |= !( 
601                         (mface->flag & ME_HIDE) ||
602                         (tface->mode & TF_INVISIBLE)
603                         )?POLY_VIS:0;
604
605                 material->transp = tface->transp;
606                 material->tile  = tface->tile;
607                 material->mode  = tface->mode;
608                         
609                 uv[0]   = MT_Point2(tface->uv[0]);
610                 uv[1]   = MT_Point2(tface->uv[1]);
611                 uv[2]   = MT_Point2(tface->uv[2]);
612
613                 if (mface->v4) 
614                         uv[3]   = MT_Point2(tface->uv[3]);
615
616                 uvName = tfaceName;
617         } 
618         else {
619                 // nothing at all
620                 material->ras_mode |= (POLY_VIS| (validmat?0:USE_LIGHT));
621                 material->mode          = default_face_mode;    
622                 material->transp        = TF_SOLID;
623                 material->tile          = 0;
624         }
625
626         // with ztransp enabled, enforce alpha blending mode
627         if(validmat && (mat->mode & MA_ZTRA) && (material->transp == TF_SOLID))
628                 material->transp = TF_ALPHA;
629
630         // always zsort alpha + add
631         if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) && (material->transp != TF_CLIP)) {
632                 material->ras_mode |= ALPHA;
633                 material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
634         }
635
636         // collider or not?
637         material->ras_mode |= (material->mode & TF_DYNAMIC)? COLLIDER: 0;
638
639         // these flags are irrelevant at this point, remove so they
640         // don't hurt material bucketing 
641         material->mode &= ~(TF_DYNAMIC|TF_ALPHASORT|TF_TEX);
642
643         // get uv sets
644         if(validmat) 
645         {
646                 bool isFirstSet = true;
647
648                 // only two sets implemented, but any of the eight 
649                 // sets can make up the two layers
650                 for (int vind = 0; vind<material->num_enabled; vind++)
651                 {
652                         BL_Mapping &map = material->mapping[vind];
653
654                         if (map.uvCoName.IsEmpty())
655                                 isFirstSet = false;
656                         else
657                         {
658                                 for (int lay=0; lay<MAX_MTFACE; lay++)
659                                 {
660                                         MTF_localLayer& layer = layers[lay];
661                                         if (layer.face == 0) break;
662
663                                         if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
664                                         {
665                                                 MT_Point2 uvSet[4];
666
667                                                 uvSet[0]        = MT_Point2(layer.face->uv[0]);
668                                                 uvSet[1]        = MT_Point2(layer.face->uv[1]);
669                                                 uvSet[2]        = MT_Point2(layer.face->uv[2]);
670
671                                                 if (mface->v4) 
672                                                         uvSet[3]        = MT_Point2(layer.face->uv[3]);
673                                                 else
674                                                         uvSet[3]        = MT_Point2(0.0f, 0.0f);
675
676                                                 if (isFirstSet)
677                                                 {
678                                                         uv[0] = uvSet[0]; uv[1] = uvSet[1];
679                                                         uv[2] = uvSet[2]; uv[3] = uvSet[3];
680                                                         isFirstSet = false;
681                                                         uvName = layer.name;
682                                                 }
683                                                 else if(strcmp(layer.name, uvName) != 0)
684                                                 {
685                                                         uv2[0] = uvSet[0]; uv2[1] = uvSet[1];
686                                                         uv2[2] = uvSet[2]; uv2[3] = uvSet[3];
687                                                         map.mapping |= USECUSTOMUV;
688                                                         uv2Name = layer.name;
689                                                 }
690                                         }
691                                 }
692                         }
693                 }
694         }
695
696         unsigned int rgb[4];
697         GetRGB(type,mface,mmcol,mat,rgb[0],rgb[1],rgb[2], rgb[3]);
698
699         // swap the material color, so MCol on TF_BMFONT works
700         if (validmat && type==1 && (tface && tface->mode & TF_BMFONT))
701         {
702                 rgb[0] = KX_rgbaint2uint_new(rgb[0]);
703                 rgb[1] = KX_rgbaint2uint_new(rgb[1]);
704                 rgb[2] = KX_rgbaint2uint_new(rgb[2]);
705                 rgb[3] = KX_rgbaint2uint_new(rgb[3]);
706         }
707
708         material->SetConversionRGB(rgb);
709         material->SetConversionUV(uvName, uv);
710         material->SetConversionUV2(uv2Name, uv2);
711
712         if(validmat)
713                 material->matname       =(mat->id.name);
714
715         material->tface         = tface;
716         material->material      = mat;
717         return material;
718 }
719
720
721 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter)
722 {
723         RAS_MeshObject *meshobj;
724         bool skinMesh = false;
725         int lightlayer = blenderobj->lay;
726
727         // Get DerivedMesh data
728         DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj);
729
730         MVert *mvert = dm->getVertArray(dm);
731         int totvert = dm->getNumVerts(dm);
732
733         MFace *mface = dm->getFaceArray(dm);
734         MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE));
735         MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL));
736         float (*tangent)[3] = NULL;
737         int totface = dm->getNumFaces(dm);
738         const char *tfaceName = "";
739
740         if(tface) {
741                 DM_add_tangent_layer(dm);
742                 tangent = (float(*)[3])dm->getFaceDataArray(dm, CD_TANGENT);
743         }
744
745         // Determine if we need to make a skinned mesh
746         if (mesh->dvert || mesh->key) {
747                 meshobj = new BL_SkinMeshObject(mesh, lightlayer);
748                 skinMesh = true;
749         }
750         else
751                 meshobj = new RAS_MeshObject(mesh, lightlayer);
752
753         // Extract avaiable layers
754         MTF_localLayer *layers =  new MTF_localLayer[MAX_MTFACE];
755         for (int lay=0; lay<MAX_MTFACE; lay++) {
756                 layers[lay].face = 0;
757                 layers[lay].name = "";
758         }
759
760         int validLayers = 0;
761         for (int i=0; i<dm->faceData.totlayer; i++)
762         {
763                 if (dm->faceData.layers[i].type == CD_MTFACE)
764                 {
765                         assert(validLayers <= 8);
766
767                         layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data);
768                         layers[validLayers].name = dm->faceData.layers[i].name;
769                         if(tface == layers[validLayers].face)
770                                 tfaceName = layers[validLayers].name;
771                         validLayers++;
772                 }
773         }
774
775         meshobj->SetName(mesh->id.name);
776         meshobj->m_sharedvertex_map.resize(totvert);
777
778         for (int f=0;f<totface;f++,mface++)
779         {
780                 Material* ma = 0;
781                 bool collider = true;
782                 MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
783                 MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
784                 unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
785
786                 MT_Point3 pt0, pt1, pt2, pt3;
787                 MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0);
788                 MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
789
790                 /* get coordinates, normals and tangents */
791                 pt0 = MT_Point3(mvert[mface->v1].co);
792                 pt1 = MT_Point3(mvert[mface->v2].co);
793                 pt2 = MT_Point3(mvert[mface->v3].co);
794                 pt3 = (mface->v4)? MT_Point3(mvert[mface->v4].co): MT_Point3(0.0, 0.0, 0.0);
795
796                 if(mface->flag & ME_SMOOTH) {
797                         float n0[3], n1[3], n2[3], n3[3];
798
799                         NormalShortToFloat(n0, mvert[mface->v1].no);
800                         NormalShortToFloat(n1, mvert[mface->v2].no);
801                         NormalShortToFloat(n2, mvert[mface->v3].no);
802                         no0 = n0;
803                         no1 = n1;
804                         no2 = n2;
805
806                         if(mface->v4) {
807                                 NormalShortToFloat(n3, mvert[mface->v4].no);
808                                 no3 = n3;
809                         }
810                 }
811                 else {
812                         float fno[3];
813
814                         if(mface->v4)
815                                 CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
816                                         mvert[mface->v3].co, mvert[mface->v4].co, fno);
817                         else
818                                 CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
819                                         mvert[mface->v3].co, fno);
820
821                         no0 = no1 = no2 = no3 = MT_Vector3(fno);
822                 }
823
824                 if(tangent) {
825                         tan0 = tangent[f*4 + 0];
826                         tan1 = tangent[f*4 + 1];
827                         tan2 = tangent[f*4 + 2];
828
829                         if (mface->v4)
830                                 tan3 = tangent[f*4 + 3];
831                 }
832
833                 /* get material */
834                 ma = give_current_material(blenderobj, mface->mat_nr+1);
835         
836                 {
837                         bool visible = true;
838                         RAS_IPolyMaterial* polymat = NULL;
839                         BL_Material *bl_mat = NULL;
840
841                         if(converter->GetMaterials()) {
842                                 /* do Blender Multitexture and Blender GLSL materials */
843                                 unsigned int rgb[4];
844                                 MT_Point2 uv[4];
845
846                                 /* first is the BL_Material */
847                                 bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol,
848                                         lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
849
850                                 bl_mat->material_index =  (int)mface->mat_nr;
851
852                                 visible = ((bl_mat->ras_mode & POLY_VIS)!=0);
853                                 collider = ((bl_mat->ras_mode & COLLIDER)!=0);
854
855                                 /* vertex colors and uv's were stored in bl_mat temporarily */
856                                 bl_mat->GetConversionRGB(rgb);
857                                 rgb0 = rgb[0]; rgb1 = rgb[1];
858                                 rgb2 = rgb[2]; rgb3 = rgb[3];
859
860                                 bl_mat->GetConversionUV(uv);
861                                 uv0 = uv[0]; uv1 = uv[1];
862                                 uv2 = uv[2]; uv3 = uv[3];
863
864                                 bl_mat->GetConversionUV2(uv);
865                                 uv20 = uv[0]; uv21 = uv[1];
866                                 uv22 = uv[2]; uv23 = uv[3];
867                                 
868                                 /* then the KX_BlenderMaterial */
869                                 polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer);
870                         }
871                         else {
872                                 /* do Texture Face materials */
873                                 Image* bima = (tface)? (Image*)tface->tpage: NULL;
874                                 STR_String imastr =  (tface)? (bima? (bima)->id.name : "" ) : "";
875                 
876                                 char transp=0;
877                                 short mode=0, tile=0;
878                                 int     tilexrep=4,tileyrep = 4;
879                                 
880                                 if (bima) {
881                                         tilexrep = bima->xrep;
882                                         tileyrep = bima->yrep;
883                                 }
884
885                                 /* get tface properties if available */
886                                 if(tface) {
887                                         /* TF_DYNAMIC means the polygon is a collision face */
888                                         collider = ((tface->mode & TF_DYNAMIC) != 0);
889                                         transp = tface->transp;
890                                         tile = tface->tile;
891                                         mode = tface->mode;
892                                         
893                                         visible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
894                                         
895                                         uv0 = MT_Point2(tface->uv[0]);
896                                         uv1 = MT_Point2(tface->uv[1]);
897                                         uv2 = MT_Point2(tface->uv[2]);
898         
899                                         if (mface->v4)
900                                                 uv3 = MT_Point2(tface->uv[3]);
901                                 } 
902                                 else {
903                                         /* no texfaces, set COLLSION true and everything else FALSE */
904                                         mode = default_face_mode;       
905                                         transp = TF_SOLID;
906                                         tile = 0;
907                                 }
908
909                                 /* get vertex colors */
910                                 if (mcol) {
911                                         /* we have vertex colors */
912                                         rgb0 = KX_Mcol2uint_new(mcol[0]);
913                                         rgb1 = KX_Mcol2uint_new(mcol[1]);
914                                         rgb2 = KX_Mcol2uint_new(mcol[2]);
915                                         
916                                         if (mface->v4)
917                                                 rgb3 = KX_Mcol2uint_new(mcol[3]);
918                                 }
919                                 else {
920                                         /* no vertex colors, take from material, otherwise white */
921                                         unsigned int color = 0xFFFFFFFFL;
922
923                                         if (ma)
924                                         {
925                                                 union
926                                                 {
927                                                         unsigned char cp[4];
928                                                         unsigned int integer;
929                                                 } col_converter;
930                                                 
931                                                 col_converter.cp[3] = (unsigned char) (ma->r*255.0);
932                                                 col_converter.cp[2] = (unsigned char) (ma->g*255.0);
933                                                 col_converter.cp[1] = (unsigned char) (ma->b*255.0);
934                                                 col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
935                                                 
936                                                 color = col_converter.integer;
937                                         }
938
939                                         rgb0 = KX_rgbaint2uint_new(color);
940                                         rgb1 = KX_rgbaint2uint_new(color);
941                                         rgb2 = KX_rgbaint2uint_new(color);      
942                                         
943                                         if (mface->v4)
944                                                 rgb3 = KX_rgbaint2uint_new(color);
945                                 }
946                                 
947                                 // only zsort alpha + add
948                                 bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
949                                 bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
950
951                                 polymat = new KX_PolygonMaterial(imastr, ma,
952                                         tile, tilexrep, tileyrep, 
953                                         mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol);
954         
955                                 if (ma) {
956                                         polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
957                                         polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
958                                         polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
959                                 }
960                                 else {
961                                         polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
962                                         polymat->m_shininess = 35.0;
963                                 }
964                         }
965
966                         /* mark face as flat, so vertices are split */
967                         bool flat = (mface->flag & ME_SMOOTH) == 0;
968
969                         // see if a bucket was reused or a new one was created
970                         // this way only one KX_BlenderMaterial object has to exist per bucket
971                         bool bucketCreated; 
972                         RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
973                         if (bucketCreated) {
974                                 // this is needed to free up memory afterwards
975                                 converter->RegisterPolyMaterial(polymat);
976                                 if(converter->GetMaterials()) {
977                                         converter->RegisterBlenderMaterial(bl_mat);
978                                 }
979                         } else {
980                                 // delete the material objects since they are no longer needed
981                                 // from now on, use the polygon material from the material bucket
982                                 delete polymat;
983                                 if(converter->GetMaterials()) {
984                                         delete bl_mat;
985                                 }
986                                 polymat = bucket->GetPolyMaterial();
987                         }
988                                                  
989                         int nverts = (mface->v4)? 4: 3;
990                         RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts);
991
992                         poly->SetVisible(visible);
993                         poly->SetCollider(collider);
994                         //poly->SetEdgeCode(mface->edcode);
995
996                         meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
997                         meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
998                         meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
999
1000                         if (nverts==4)
1001                                 meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
1002                 }
1003
1004                 if (tface) 
1005                         tface++;
1006                 if (mcol)
1007                         mcol+=4;
1008
1009                 for (int lay=0; lay<MAX_MTFACE; lay++)
1010                 {
1011                         MTF_localLayer &layer = layers[lay];
1012                         if (layer.face == 0) break;
1013
1014                         layer.face++;
1015                 }
1016         }
1017         meshobj->m_sharedvertex_map.clear();
1018
1019         // pre calculate texture generation
1020         for(list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
1021                 mit != meshobj->GetLastMaterial(); ++ mit) {
1022                 mit->m_bucket->GetPolyMaterial()->OnConstruction();
1023         }
1024
1025         if (layers)
1026                 delete []layers;
1027         
1028         dm->release(dm);
1029
1030         return meshobj;
1031 }
1032
1033         
1034         
1035 static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject,
1036                                                                                                   KX_Scene *kxscene)
1037 {
1038         PHY_MaterialProps *materialProps = new PHY_MaterialProps;
1039         
1040         MT_assert(materialProps && "Create physics material properties failed");
1041                 
1042         Material* blendermat = give_current_material(blenderobject, 0);
1043                 
1044         if (blendermat)
1045         {
1046                 MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f);
1047         
1048                 materialProps->m_restitution = blendermat->reflect;
1049                 materialProps->m_friction = blendermat->friction;
1050                 materialProps->m_fh_spring = blendermat->fh;
1051                 materialProps->m_fh_damping = blendermat->xyfrict;
1052                 materialProps->m_fh_distance = blendermat->fhdist;
1053                 materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
1054         }
1055         else {
1056                 //give some defaults
1057                 materialProps->m_restitution = 0.f;
1058                 materialProps->m_friction = 0.5;
1059                 materialProps->m_fh_spring = 0.f;
1060                 materialProps->m_fh_damping = 0.f;
1061                 materialProps->m_fh_distance = 0.f;
1062                 materialProps->m_fh_normal = false;
1063
1064         }
1065         
1066         return materialProps;
1067 }
1068
1069 static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject,
1070                                                                                                  KX_Scene *kxscene)
1071 {
1072         PHY_ShapeProps *shapeProps = new PHY_ShapeProps;
1073         
1074         MT_assert(shapeProps);
1075                 
1076         shapeProps->m_mass = blenderobject->mass;
1077         
1078 //  This needs to be fixed in blender. For now, we use:
1079         
1080 // in Blender, inertia stands for the size value which is equivalent to
1081 // the sphere radius
1082         shapeProps->m_inertia = blenderobject->formfactor;
1083         
1084         MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
1085         MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
1086         
1087         shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
1088         shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
1089         
1090         shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0]; 
1091         shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
1092         shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2];
1093         shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0);
1094         
1095         shapeProps->m_do_fh     = (blenderobject->gameflag & OB_DO_FH) != 0; 
1096         shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
1097         
1098         return shapeProps;
1099 }
1100
1101         
1102         
1103         
1104                 
1105 //////////////////////////////////////////////////////////
1106         
1107
1108
1109 static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
1110 {
1111         MVert *mvert;
1112         BoundBox *bb;
1113         MT_Point3 min, max;
1114         float mloc[3], msize[3];
1115         int a;
1116         
1117         if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
1118         bb= me->bb;
1119         
1120         INIT_MINMAX(min, max);
1121
1122         if (!loc) loc= mloc;
1123         if (!size) size= msize;
1124         
1125         mvert= me->mvert;
1126         for(a=0; a<me->totvert; a++, mvert++) {
1127                 DO_MINMAX(mvert->co, min, max);
1128         }
1129                 
1130         if(me->totvert) {
1131                 loc[0]= (min[0]+max[0])/2.0;
1132                 loc[1]= (min[1]+max[1])/2.0;
1133                 loc[2]= (min[2]+max[2])/2.0;
1134                 
1135                 size[0]= (max[0]-min[0])/2.0;
1136                 size[1]= (max[1]-min[1])/2.0;
1137                 size[2]= (max[2]-min[2])/2.0;
1138         }
1139         else {
1140                 loc[0]= loc[1]= loc[2]= 0.0;
1141                 size[0]= size[1]= size[2]= 0.0;
1142         }
1143                 
1144         bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
1145         bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
1146                 
1147         bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
1148         bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
1149
1150         bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
1151         bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
1152
1153         float radius = 0;
1154         for (a=0, mvert = me->mvert; a < me->totvert; a++, mvert++)
1155         {
1156                 float vert_radius = MT_Vector3(mvert->co).length2();
1157                 if (vert_radius > radius)
1158                         radius = vert_radius;
1159         } 
1160         return sqrt(radius);
1161 }
1162                 
1163
1164
1165
1166 static void my_tex_space_mesh(Mesh *me)
1167                 {
1168         KeyBlock *kb;
1169         float *fp, loc[3], size[3], min[3], max[3];
1170         int a;
1171
1172         my_boundbox_mesh(me, loc, size);
1173         
1174         if(me->texflag & AUTOSPACE) {
1175                 if(me->key) {
1176                         kb= me->key->refkey;
1177                         if (kb) {
1178         
1179                                 INIT_MINMAX(min, max);
1180                 
1181                                 fp= (float *)kb->data;
1182                                 for(a=0; a<kb->totelem; a++, fp+=3) {   
1183                                         DO_MINMAX(fp, min, max);
1184                                 }
1185                                 if(kb->totelem) {
1186                                         loc[0]= (min[0]+max[0])/2.0; loc[1]= (min[1]+max[1])/2.0; loc[2]= (min[2]+max[2])/2.0;
1187                                         size[0]= (max[0]-min[0])/2.0; size[1]= (max[1]-min[1])/2.0; size[2]= (max[2]-min[2])/2.0;
1188         } 
1189         else {
1190                                         loc[0]= loc[1]= loc[2]= 0.0;
1191                                         size[0]= size[1]= size[2]= 0.0;
1192                                 }
1193                                 
1194                         }
1195                                 }
1196         
1197                 VECCOPY(me->loc, loc);
1198                 VECCOPY(me->size, size);
1199                 me->rot[0]= me->rot[1]= me->rot[2]= 0.0;
1200         
1201                 if(me->size[0]==0.0) me->size[0]= 1.0;
1202                 else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001;
1203                 else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001;
1204         
1205                 if(me->size[1]==0.0) me->size[1]= 1.0;
1206                 else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001;
1207                 else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001;
1208                                                 
1209                 if(me->size[2]==0.0) me->size[2]= 1.0;
1210                 else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001;
1211                 else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001;
1212         }
1213         
1214 }
1215
1216 static void my_get_local_bounds(Object *ob, float *center, float *size)
1217 {
1218         BoundBox *bb= NULL;
1219         /* uses boundbox, function used by Ketsji */
1220         switch (ob->type)
1221         {
1222                 case OB_MESH:
1223                         bb= ( (Mesh *)ob->data )->bb;
1224                         if(bb==0) 
1225                         {
1226                                 my_tex_space_mesh((struct Mesh *)ob->data);
1227                                 bb= ( (Mesh *)ob->data )->bb;
1228                         }
1229                         break;
1230                 case OB_CURVE:
1231                 case OB_SURF:
1232                 case OB_FONT:
1233                         center[0]= center[1]= center[2]= 0.0;
1234                         size[0]  = size[1]=size[2]=0.0;
1235                         break;
1236                 case OB_MBALL:
1237                         bb= ob->bb;
1238                         break;
1239         }
1240         
1241         if(bb==NULL) 
1242         {
1243                 center[0]= center[1]= center[2]= 0.0;
1244                 size[0] = size[1]=size[2]=1.0;
1245         }
1246         else 
1247         {
1248                 size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
1249                 size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
1250                 size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
1251                                         
1252                 center[0]= 0.5*(bb->vec[0][0] + bb->vec[4][0]);
1253                 center[1]= 0.5*(bb->vec[0][1] + bb->vec[2][1]);
1254                 center[2]= 0.5*(bb->vec[0][2] + bb->vec[1][2]);
1255         }
1256 }
1257         
1258
1259
1260
1261 //////////////////////////////////////////////////////
1262
1263
1264
1265
1266
1267 void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
1268                                                  struct Object* blenderobject,
1269                                                  RAS_MeshObject* meshobj,
1270                                                  KX_Scene* kxscene,
1271                                                  int activeLayerBitInfo,
1272                                                  e_PhysicsEngine        physics_engine,
1273                                                  KX_BlenderSceneConverter *converter,
1274                                                  bool processCompoundChildren
1275                                                  )
1276                                         
1277 {
1278         //SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
1279         //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
1280         //bool bRigidBody = (userigidbody == 0);
1281
1282         // object has physics representation?
1283         if (!(blenderobject->gameflag & OB_COLLISION))
1284                 return;
1285
1286         // get Root Parent of blenderobject
1287         struct Object* parent= blenderobject->parent;
1288         while(parent && parent->parent) {
1289                 parent= parent->parent;
1290         }
1291
1292         bool isCompoundChild = false;
1293
1294         if (parent && (parent->gameflag & OB_DYNAMIC)) {
1295                 
1296                 if ((parent->gameflag & OB_CHILD) != 0)
1297                 {
1298                         isCompoundChild = true;
1299                 } 
1300         }
1301         if (processCompoundChildren != isCompoundChild)
1302                 return;
1303
1304
1305         PHY_ShapeProps* shapeprops =
1306                         CreateShapePropsFromBlenderObject(blenderobject, 
1307                         kxscene);
1308
1309         
1310         PHY_MaterialProps* smmaterial = 
1311                 CreateMaterialFromBlenderObject(blenderobject, kxscene);
1312                                         
1313         KX_ObjectProperties objprop;
1314
1315         objprop.m_isCompoundChild = isCompoundChild;
1316         objprop.m_hasCompoundChildren = (blenderobject->gameflag & OB_CHILD) != 0;
1317         objprop.m_margin = blenderobject->margin;
1318         // ACTOR is now a separate feature
1319         objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
1320         objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
1321         objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
1322         objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
1323         objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
1324         objprop.m_disableSleeping = (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0;//abuse the OB_COLLISION_RESPONSE flag
1325         //mmm, for now, taks this for the size of the dynamicobject
1326         // Blender uses inertia for radius of dynamic object
1327         objprop.m_radius = blenderobject->inertia;
1328         objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
1329         objprop.m_dynamic_parent=NULL;
1330         objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
1331         objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
1332         KX_BoxBounds bb;
1333         my_get_local_bounds(blenderobject,objprop.m_boundobject.box.m_center,bb.m_extends);
1334         if (blenderobject->gameflag & OB_BOUNDS)
1335         {
1336                 switch (blenderobject->boundtype)
1337                 {
1338                         case OB_BOUND_BOX:
1339                                 objprop.m_boundclass = KX_BOUNDBOX;
1340                                 //mmm, has to be divided by 2 to be proper extends
1341                                 objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_extends[0];
1342                                 objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1];
1343                                 objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2];
1344                                 break;
1345                         case OB_BOUND_POLYT:
1346                                 if (blenderobject->type == OB_MESH)
1347                                 {
1348                                         objprop.m_boundclass = KX_BOUNDPOLYTOPE;
1349                                         break;
1350                                 }
1351                                 // Object is not a mesh... fall through OB_BOUND_POLYH to 
1352                                 // OB_BOUND_SPHERE
1353                         case OB_BOUND_POLYH:
1354                                 if (blenderobject->type == OB_MESH)
1355                                 {
1356                                         objprop.m_boundclass = KX_BOUNDMESH;
1357                                         break;
1358                                 }
1359                                 // Object is not a mesh... can't use polyheder. 
1360                                 // Fall through and become a sphere.
1361                         case OB_BOUND_SPHERE:
1362                         {
1363                                 objprop.m_boundclass = KX_BOUNDSPHERE;
1364                                 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2]));
1365                                 break;
1366                         }
1367                         case OB_BOUND_CYLINDER:
1368                         {
1369                                 objprop.m_boundclass = KX_BOUNDCYLINDER;
1370                                 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1371                                 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
1372                                 break;
1373                         }
1374                         case OB_BOUND_CONE:
1375                         {
1376                                 objprop.m_boundclass = KX_BOUNDCONE;
1377                                 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1378                                 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
1379                                 break;
1380                         }
1381                 }
1382         }
1383
1384         
1385         if (parent && (parent->gameflag & OB_DYNAMIC)) {
1386                 
1387                 KX_GameObject *parentgameobject = converter->FindGameObject(parent);
1388                 objprop.m_dynamic_parent = parentgameobject;
1389                 //cannot be dynamic:
1390                 objprop.m_dyna = false;
1391                 shapeprops->m_mass = 0.f;
1392         }
1393
1394         
1395         objprop.m_concave = (blenderobject->boundtype & 4) != 0;
1396         
1397         switch (physics_engine)
1398         {
1399 #ifdef USE_BULLET
1400                 case UseBullet:
1401                         KX_ConvertBulletObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
1402                         break;
1403
1404 #endif
1405 #ifdef USE_SUMO_SOLID
1406                 case UseSumo:
1407                         KX_ConvertSumoObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
1408                         break;
1409 #endif
1410                         
1411 #ifdef USE_ODE
1412                 case UseODE:
1413                         KX_ConvertODEEngineObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
1414                         break;
1415 #endif //USE_ODE
1416
1417                 case UseDynamo:
1418                         //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops,    smmaterial,     &objprop);
1419                         break;
1420                         
1421                 case UseNone:
1422                 default:
1423                         break;
1424         }
1425         delete shapeprops;
1426         delete smmaterial;
1427 }
1428
1429
1430
1431
1432
1433 static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
1434         RAS_LightObject lightobj;
1435         KX_LightObject *gamelight;
1436         
1437         lightobj.m_att1 = la->att1;
1438         lightobj.m_att2 = (la->mode & LA_QUAD)?la->att2:0.0;
1439         lightobj.m_red = la->r;
1440         lightobj.m_green = la->g;
1441         lightobj.m_blue = la->b;
1442         lightobj.m_distance = la->dist;
1443         lightobj.m_energy = la->energy;
1444         lightobj.m_layer = layerflag;
1445         lightobj.m_spotblend = la->spotblend;
1446         lightobj.m_spotsize = la->spotsize;
1447         
1448         lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
1449         lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
1450         
1451         if (la->mode & LA_NEG)
1452         {
1453                 lightobj.m_red = -lightobj.m_red;
1454                 lightobj.m_green = -lightobj.m_green;
1455                 lightobj.m_blue = -lightobj.m_blue;
1456         }
1457                 
1458         if (la->type==LA_SUN) {
1459                 lightobj.m_type = RAS_LightObject::LIGHT_SUN;
1460         } else if (la->type==LA_SPOT) {
1461                 lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
1462         } else {
1463                 lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
1464         }
1465
1466         gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools,
1467                 lightobj, converter->GetGLSLMaterials());
1468
1469         BL_ConvertLampIpos(la, gamelight, converter);
1470         
1471         return gamelight;
1472 }
1473
1474 static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
1475         Camera* ca = static_cast<Camera*>(ob->data);
1476         RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob));
1477         KX_Camera *gamecamera;
1478         
1479         gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
1480         gamecamera->SetName(ca->id.name + 2);
1481         
1482         BL_ConvertCameraIpos(ca, gamecamera, converter);
1483         
1484         return gamecamera;
1485 }
1486
1487 static KX_GameObject *gameobject_from_blenderobject(
1488                                                                 Object *ob, 
1489                                                                 KX_Scene *kxscene, 
1490                                                                 RAS_IRenderTools *rendertools, 
1491                                                                 KX_BlenderSceneConverter *converter,
1492                                                                 Scene *blenderscene) 
1493 {
1494         KX_GameObject *gameobj = NULL;
1495         
1496         switch(ob->type)
1497         {
1498         case OB_LAMP:
1499         {
1500                 KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
1501                 gameobj = gamelight;
1502                 
1503                 gamelight->AddRef();
1504                 kxscene->GetLightList()->Add(gamelight);
1505
1506                 break;
1507         }
1508         
1509         case OB_CAMERA:
1510         {
1511                 KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, converter);
1512                 gameobj = gamecamera;
1513                 
1514                 //don't add a reference: the camera list in kxscene->m_cameras is not released at the end
1515                 //gamecamera->AddRef();
1516                 kxscene->AddCamera(gamecamera);
1517                 
1518                 break;
1519         }
1520         
1521         case OB_MESH:
1522         {
1523                 Mesh* mesh = static_cast<Mesh*>(ob->data);
1524                 RAS_MeshObject* meshobj = converter->FindGameMesh(mesh, ob->lay);
1525                 float center[3], extents[3];
1526                 float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents);
1527                 
1528                 if (!meshobj) {
1529                         meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter);
1530                         converter->RegisterGameMesh(meshobj, mesh);
1531                 }
1532                 
1533                 // needed for python scripting
1534                 kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
1535         
1536                 gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_callbacks);
1537         
1538                 // set transformation
1539                 gameobj->AddMesh(meshobj);
1540         
1541                 // for all objects: check whether they want to
1542                 // respond to updates
1543                 bool ignoreActivityCulling =  
1544                         ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
1545                 gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
1546         
1547                 // two options exists for deform: shape keys and armature
1548                 // only support relative shape key
1549                 bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE;
1550                 bool bHasDvert = mesh->dvert != NULL && ob->defbase.first;
1551                 bool bHasArmature = (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && bHasDvert);
1552
1553                 if (bHasShapeKey) {
1554                         // not that we can have shape keys without dvert! 
1555                         BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, 
1556                                                                                                                         ob, (BL_SkinMeshObject*)meshobj);
1557                         ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
1558                         if (bHasArmature)
1559                                 dcont->LoadShapeDrivers(ob->parent);
1560                 } else if (bHasArmature) {
1561                         BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
1562                                                                                                                         ob, (BL_SkinMeshObject*)meshobj);
1563                         ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
1564                 } else if (bHasDvert) {
1565                         // this case correspond to a mesh that can potentially deform but not with the
1566                         // object to which it is attached for the moment. A skin mesh was created in
1567                         // BL_ConvertMesh() so must create a deformer too!
1568                         BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
1569                                                                                                                   ob, (BL_SkinMeshObject*)meshobj);
1570                         ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
1571                 }
1572                 
1573                 MT_Point3 min = MT_Point3(center) - MT_Vector3(extents);
1574                 MT_Point3 max = MT_Point3(center) + MT_Vector3(extents);
1575                 SG_BBox bbox = SG_BBox(min, max);
1576                 gameobj->GetSGNode()->SetBBox(bbox);
1577                 gameobj->GetSGNode()->SetRadius(radius);
1578         
1579                 break;
1580         }
1581         
1582         case OB_ARMATURE:
1583         {
1584                 gameobj = new BL_ArmatureObject(
1585                         kxscene,
1586                         KX_Scene::m_callbacks,
1587                         ob // handle
1588                 );
1589                 /* Get the current pose from the armature object and apply it as the rest pose */
1590                 break;
1591         }
1592         
1593         case OB_EMPTY:
1594         {
1595                 gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks);
1596                 // set transformation
1597                 break;
1598         }
1599         }
1600         if (gameobj) 
1601         {
1602                 gameobj->SetPhysicsEnvironment(kxscene->GetPhysicsEnvironment());
1603                 gameobj->SetLayer(ob->lay);
1604                 gameobj->SetBlenderObject(ob);
1605                 /* set the visibility state based on the objects render option in the outliner */
1606                 if(ob->restrictflag & OB_RESTRICT_RENDER) gameobj->SetVisible(0, 0);
1607         }
1608         return gameobj;
1609 }
1610
1611 struct parentChildLink {
1612         struct Object* m_blenderchild;
1613         SG_Node* m_gamechildnode;
1614 };
1615
1616 #include "DNA_constraint_types.h"
1617 #include "BIF_editconstraint.h"
1618
1619 bPoseChannel *get_active_posechannel2 (Object *ob)
1620 {
1621         bArmature *arm= (bArmature*)ob->data;
1622         bPoseChannel *pchan;
1623         
1624         /* find active */
1625         for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1626                 if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer))
1627                         return pchan;
1628         }
1629         
1630         return NULL;
1631 }
1632
1633 ListBase *get_active_constraints2(Object *ob)
1634 {
1635         if (!ob)
1636                 return NULL;
1637
1638         if (ob->flag & OB_POSEMODE) {
1639                 bPoseChannel *pchan;
1640
1641                 pchan = get_active_posechannel2(ob);
1642                 if (pchan)
1643                         return &pchan->constraints;
1644         }
1645         else 
1646                 return &ob->constraints;
1647
1648         return NULL;
1649 }
1650
1651
1652 void RBJconstraints(Object *ob)//not used
1653 {
1654         ListBase *conlist;
1655         bConstraint *curcon;
1656
1657         conlist = get_active_constraints2(ob);
1658
1659         if (conlist) {
1660                 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) {
1661
1662                         printf("%i\n",curcon->type);
1663                 }
1664
1665
1666         }
1667 }
1668
1669 #include "PHY_IPhysicsEnvironment.h"
1670 #include "KX_IPhysicsController.h"
1671 #include "PHY_DynamicTypes.h"
1672
1673 KX_IPhysicsController* getPhId(CListValue* sumolist,STR_String busc){//not used
1674
1675     for (int j=0;j<sumolist->GetCount();j++)
1676         {
1677             KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j);
1678             if (gameobje->GetName()==busc)
1679             return gameobje->GetPhysicsController();
1680         }
1681
1682         return 0;
1683
1684 }
1685
1686 KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){
1687
1688     for (int j=0;j<sumolist->GetCount();j++)
1689         {
1690             KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j);
1691             if (gameobje->GetName()==busc)
1692             return gameobje;
1693         }
1694         
1695         return 0;
1696
1697 }
1698
1699 // convert blender objects into ketsji gameobjects
1700 void BL_ConvertBlenderObjects(struct Main* maggie,
1701                                                           const STR_String& scenename,
1702                                                           KX_Scene* kxscene,
1703                                                           KX_KetsjiEngine* ketsjiEngine,
1704                                                           e_PhysicsEngine       physics_engine,
1705                                                           PyObject* pythondictionary,
1706                                                           SCA_IInputDevice* keydev,
1707                                                           RAS_IRenderTools* rendertools,
1708                                                           RAS_ICanvas* canvas,
1709                                                           KX_BlenderSceneConverter* converter,
1710                                                           bool alwaysUseExpandFraming
1711                                                           )
1712 {       
1713
1714         Scene *blenderscene = converter->GetBlenderSceneForName(scenename);
1715         // for SETLOOPER
1716         Scene *sce;
1717         Base *base;
1718
1719         // Get the frame settings of the canvas.
1720         // Get the aspect ratio of the canvas as designed by the user.
1721
1722         RAS_FrameSettings::RAS_FrameType frame_type;
1723         int aspect_width;
1724         int aspect_height;
1725         vector<MT_Vector3> inivel,iniang;
1726         set<Group*> grouplist;  // list of groups to be converted
1727         set<Object*> allblobj;  // all objects converted
1728         set<Object*> groupobj;  // objects from groups (never in active layer)
1729
1730         if (alwaysUseExpandFraming) {
1731                 frame_type = RAS_FrameSettings::e_frame_extend;
1732                 aspect_width = canvas->GetWidth();
1733                 aspect_height = canvas->GetHeight();
1734         } else {
1735                 if (blenderscene->framing.type == SCE_GAMEFRAMING_BARS) {
1736                         frame_type = RAS_FrameSettings::e_frame_bars;
1737                 } else if (blenderscene->framing.type == SCE_GAMEFRAMING_EXTEND) {
1738                         frame_type = RAS_FrameSettings::e_frame_extend;
1739                 } else {
1740                         frame_type = RAS_FrameSettings::e_frame_scale;
1741                 }
1742                 
1743                 aspect_width = blenderscene->r.xsch;
1744                 aspect_height = blenderscene->r.ysch;
1745         }
1746         
1747         RAS_FrameSettings frame_settings(
1748                 frame_type,
1749                 blenderscene->framing.col[0],
1750                 blenderscene->framing.col[1],
1751                 blenderscene->framing.col[2],
1752                 aspect_width,
1753                 aspect_height
1754         );
1755         kxscene->SetFramingType(frame_settings);
1756
1757         kxscene->SetGravity(MT_Vector3(0,0,(blenderscene->world != NULL) ? -blenderscene->world->gravity : -9.8));
1758         
1759         /* set activity culling parameters */
1760         if (blenderscene->world) {
1761                 kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
1762                 kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
1763         } else {
1764                 kxscene->SetActivityCulling(false);
1765         }
1766         
1767         int activeLayerBitInfo = blenderscene->lay;
1768         
1769         // templist to find Root Parents (object with no parents)
1770         CListValue* templist = new CListValue();
1771         CListValue*     sumolist = new CListValue();
1772         
1773         vector<parentChildLink> vec_parent_child;
1774         
1775         CListValue* objectlist = kxscene->GetObjectList();
1776         CListValue* inactivelist = kxscene->GetInactiveList();
1777         CListValue* parentlist = kxscene->GetRootParentList();
1778         
1779         SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
1780         SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
1781         
1782         CListValue* logicbrick_conversionlist = new CListValue();
1783         
1784         //SG_TreeFactory tf;
1785         
1786         // Convert actions to actionmap
1787         bAction *curAct;
1788         for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
1789         {
1790                 logicmgr->RegisterActionName(curAct->id.name, curAct);
1791         }
1792
1793         SetDefaultFaceType(blenderscene);
1794         // Let's support scene set.
1795         // Beware of name conflict in linked data, it will not crash but will create confusion
1796         // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have
1797         // no conflicting name for Object, Object data and Action.
1798         for (SETLOOPER(blenderscene, base))
1799         {
1800                 Object* blenderobject = base->object;
1801                 allblobj.insert(blenderobject);
1802
1803                 KX_GameObject* gameobj = gameobject_from_blenderobject(
1804                                                                                 base->object, 
1805                                                                                 kxscene, 
1806                                                                                 rendertools, 
1807                                                                                 converter,
1808                                                                                 blenderscene);
1809                                                                                 
1810                 bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
1811                 bool addobj=true;
1812                 
1813                 if (converter->addInitFromFrame)
1814                         if (!isInActiveLayer)
1815                                 addobj=false;
1816
1817                 if (gameobj&&addobj)
1818                 {
1819                         MT_Point3 posPrev;                      
1820                         MT_Matrix3x3 angor;                     
1821                         if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra;
1822                         
1823                         MT_Point3 pos = MT_Point3(
1824                                 blenderobject->loc[0]+blenderobject->dloc[0],
1825                                 blenderobject->loc[1]+blenderobject->dloc[1],
1826                                 blenderobject->loc[2]+blenderobject->dloc[2]
1827                         );
1828                         MT_Vector3 eulxyz = MT_Vector3(
1829                                 blenderobject->rot[0],
1830                                 blenderobject->rot[1],
1831                                 blenderobject->rot[2]
1832                         );
1833                         MT_Vector3 scale = MT_Vector3(
1834                                 blenderobject->size[0],
1835                                 blenderobject->size[1],
1836                                 blenderobject->size[2]
1837                         );
1838                         if (converter->addInitFromFrame){//rcruiz
1839                                 float eulxyzPrev[3];
1840                                 blenderscene->r.cfra=blenderscene->r.sfra-1;
1841                                 update_for_newframe();
1842                                 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
1843                                                                                         blenderobject->loc[1]+blenderobject->dloc[1],
1844                                                                                         blenderobject->loc[2]+blenderobject->dloc[2]
1845                                                                         );
1846                                 eulxyzPrev[0]=blenderobject->rot[0];
1847                                 eulxyzPrev[1]=blenderobject->rot[1];
1848                                 eulxyzPrev[2]=blenderobject->rot[2];
1849
1850                                 double fps = (double) blenderscene->r.frs_sec/
1851                                         (double) blenderscene->r.frs_sec_base;
1852
1853                                 tmp.scale(fps, fps, fps);
1854                                 inivel.push_back(tmp);
1855                                 tmp=eulxyz-eulxyzPrev;
1856                                 tmp.scale(fps, fps, fps);
1857                                 iniang.push_back(tmp);
1858                                 blenderscene->r.cfra=blenderscene->r.sfra;
1859                                 update_for_newframe();
1860                         }               
1861                                                 
1862                         gameobj->NodeSetLocalPosition(pos);
1863                         gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
1864                         gameobj->NodeSetLocalScale(scale);
1865                         gameobj->NodeUpdateGS(0,true);
1866                         
1867                         BL_ConvertIpos(blenderobject,gameobj,converter);
1868                         BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
1869                         
1870                         sumolist->Add(gameobj->AddRef());
1871                         
1872                         BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
1873                         
1874         
1875                         gameobj->SetName(blenderobject->id.name);
1876         
1877                         // templist to find Root Parents (object with no parents)
1878                         templist->Add(gameobj->AddRef());
1879                         
1880                         // update children/parent hierarchy
1881                         if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
1882                         {
1883                                 // blender has an additional 'parentinverse' offset in each object
1884                                 SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
1885                         
1886                                 // define a normal parent relationship for this node.
1887                                 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
1888                                 parentinversenode->SetParentRelation(parent_relation);
1889         
1890                                 parentChildLink pclink;
1891                                 pclink.m_blenderchild = blenderobject;
1892                                 pclink.m_gamechildnode = parentinversenode;
1893                                 vec_parent_child.push_back(pclink);
1894
1895                                 float* fl = (float*) blenderobject->parentinv;
1896                                 MT_Transform parinvtrans(fl);
1897                                 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
1898                                 // problem here: the parent inverse transform combines scaling and rotation 
1899                                 // in the basis but the scenegraph needs separate rotation and scaling.
1900                                 // This is not important for OpenGL (it uses 4x4 matrix) but it is important
1901                                 // for the physic engine that needs a separate scaling
1902                                 //parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
1903
1904                                 // Extract the rotation and the scaling from the basis
1905                                 MT_Matrix3x3 ori(parinvtrans.getBasis());
1906                                 MT_Vector3 x(ori.getColumn(0));
1907                                 MT_Vector3 y(ori.getColumn(1));
1908                                 MT_Vector3 z(ori.getColumn(2));
1909                                 MT_Vector3 scale(x.length(), y.length(), z.length());
1910                                 if (!MT_fuzzyZero(scale[0]))
1911                                         x /= scale[0];
1912                                 if (!MT_fuzzyZero(scale[1]))
1913                                         y /= scale[1];
1914                                 if (!MT_fuzzyZero(scale[2]))
1915                                         z /= scale[2];
1916                                 ori.setColumn(0, x);                                                            
1917                                 ori.setColumn(1, y);                                                            
1918                                 ori.setColumn(2, z);                                                            
1919                                 parentinversenode->SetLocalOrientation(ori);
1920                                 parentinversenode->SetLocalScale(scale);
1921                                 
1922                                 parentinversenode->AddChild(gameobj->GetSGNode());
1923                         }
1924                         
1925                         // needed for python scripting
1926                         logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
1927
1928                         // needed for group duplication
1929                         logicmgr->RegisterGameObj(blenderobject, gameobj);
1930                         for (int i = 0; i < gameobj->GetMeshCount(); i++)
1931                                 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
1932         
1933                         converter->RegisterGameObject(gameobj, blenderobject);  
1934                         // this was put in rapidly, needs to be looked at more closely
1935                         // only draw/use objects in active 'blender' layers
1936         
1937                         logicbrick_conversionlist->Add(gameobj->AddRef());
1938                         
1939                         if (converter->addInitFromFrame){
1940                                 posPrev=gameobj->NodeGetWorldPosition();
1941                                 angor=gameobj->NodeGetWorldOrientation();
1942                         }
1943                         if (isInActiveLayer)
1944                         {
1945                                 objectlist->Add(gameobj->AddRef());
1946                                 //tf.Add(gameobj->GetSGNode());
1947                                 
1948                                 gameobj->NodeUpdateGS(0,true);
1949                                 gameobj->AddMeshUser();
1950                 
1951                         }
1952                         else
1953                         {
1954                                 //we must store this object otherwise it will be deleted 
1955                                 //at the end of this function if it is not a root object
1956                                 inactivelist->Add(gameobj->AddRef());
1957                         }
1958                         if (gameobj->IsDupliGroup())
1959                                 grouplist.insert(blenderobject->dup_group);
1960                         if (converter->addInitFromFrame){
1961                                 gameobj->NodeSetLocalPosition(posPrev);
1962                                 gameobj->NodeSetLocalOrientation(angor);
1963                         }
1964                                                 
1965                 }
1966                 /* Note about memory leak issues:
1967                    When a CValue derived class is created, m_refcount is initialized to 1
1968                    so the class must be released after being used to make sure that it won't 
1969                    hang in memory. If the object needs to be stored for a long time, 
1970                    use AddRef() so that this Release() does not free the object.
1971                    Make sure that for any AddRef() there is a Release()!!!! 
1972                    Do the same for any object derived from CValue, CExpression and NG_NetworkMessage
1973                  */
1974                 if (gameobj)
1975                         gameobj->Release();
1976
1977         }
1978
1979         if (!grouplist.empty())
1980         {
1981                 // now convert the group referenced by dupli group object
1982                 // keep track of all groups already converted
1983                 set<Group*> allgrouplist = grouplist;
1984                 set<Group*> tempglist;
1985                 // recurse
1986                 while (!grouplist.empty())
1987                 {
1988                         set<Group*>::iterator git;
1989                         tempglist.clear();
1990                         tempglist.swap(grouplist);
1991                         for (git=tempglist.begin(); git!=tempglist.end(); git++)
1992                         {
1993                                 Group* group = *git;
1994                                 GroupObject* go;
1995                                 for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next) 
1996                                 {
1997                                         Object* blenderobject = go->ob;
1998                                         if (converter->FindGameObject(blenderobject) == NULL)
1999                                         {
2000                                                 allblobj.insert(blenderobject);
2001                                                 groupobj.insert(blenderobject);
2002                                                 KX_GameObject* gameobj = gameobject_from_blenderobject(
2003                                                                                                                 blenderobject, 
2004                                                                                                                 kxscene, 
2005                                                                                                                 rendertools, 
2006                                                                                                                 converter,
2007                                                                                                                 blenderscene);
2008                                                                                 
2009                                                 // this code is copied from above except that
2010                                                 // object from groups are never in active layer
2011                                                 bool isInActiveLayer = false;
2012                                                 bool addobj=true;
2013                                                 
2014                                                 if (converter->addInitFromFrame)
2015                                                         if (!isInActiveLayer)
2016                                                                 addobj=false;
2017                                                                                                                 
2018                                                 if (gameobj&&addobj)
2019                                                 {
2020                                                         MT_Point3 posPrev;                      
2021                                                         MT_Matrix3x3 angor;                     
2022                                                         if (converter->addInitFromFrame) 
2023                                                                 blenderscene->r.cfra=blenderscene->r.sfra;
2024                                                         
2025                                                         MT_Point3 pos = MT_Point3(
2026                                                                 blenderobject->loc[0]+blenderobject->dloc[0],
2027                                                                 blenderobject->loc[1]+blenderobject->dloc[1],
2028                                                                 blenderobject->loc[2]+blenderobject->dloc[2]
2029                                                         );
2030                                                         MT_Vector3 eulxyz = MT_Vector3(
2031                                                                 blenderobject->rot[0],
2032                                                                 blenderobject->rot[1],
2033                                                                 blenderobject->rot[2]
2034                                                         );
2035                                                         MT_Vector3 scale = MT_Vector3(
2036                                                                 blenderobject->size[0],
2037                                                                 blenderobject->size[1],
2038                                                                 blenderobject->size[2]
2039                                                         );
2040                                                         if (converter->addInitFromFrame){//rcruiz
2041                                                                 float eulxyzPrev[3];
2042                                                                 blenderscene->r.cfra=blenderscene->r.sfra-1;
2043                                                                 update_for_newframe();
2044                                                                 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
2045                                                                                                                         blenderobject->loc[1]+blenderobject->dloc[1],
2046                                                                                                                         blenderobject->loc[2]+blenderobject->dloc[2]
2047                                                                                                         );
2048                                                                 eulxyzPrev[0]=blenderobject->rot[0];
2049                                                                 eulxyzPrev[1]=blenderobject->rot[1];
2050                                                                 eulxyzPrev[2]=blenderobject->rot[2];
2051
2052                                                                 double fps = (double) blenderscene->r.frs_sec/
2053                                                                         (double) blenderscene->r.frs_sec_base;
2054
2055                                                                 tmp.scale(fps, fps, fps);
2056                                                                 inivel.push_back(tmp);
2057                                                                 tmp=eulxyz-eulxyzPrev;
2058                                                                 tmp.scale(fps, fps, fps);
2059                                                                 iniang.push_back(tmp);
2060                                                                 blenderscene->r.cfra=blenderscene->r.sfra;
2061                                                                 update_for_newframe();
2062                                                         }               
2063                                                                                 
2064                                                         gameobj->NodeSetLocalPosition(pos);
2065                                                         gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
2066                                                         gameobj->NodeSetLocalScale(scale);
2067                                                         gameobj->NodeUpdateGS(0,true);
2068                                                         
2069                                                         BL_ConvertIpos(blenderobject,gameobj,converter);
2070                                                         BL_ConvertMaterialIpos(blenderobject,gameobj, converter);       
2071                                         
2072                                                         sumolist->Add(gameobj->AddRef());
2073                                                         
2074                                                         BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
2075                                                         
2076                                         
2077                                                         gameobj->SetName(blenderobject->id.name);
2078                                         
2079                                                         // templist to find Root Parents (object with no parents)
2080                                                         templist->Add(gameobj->AddRef());
2081                                                         
2082                                                         // update children/parent hierarchy
2083                                                         if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
2084                                                         {
2085                                                                 // blender has an additional 'parentinverse' offset in each object
2086                                                                 SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
2087                                                         
2088                                                                 // define a normal parent relationship for this node.
2089                                                                 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
2090                                                                 parentinversenode->SetParentRelation(parent_relation);
2091                                         
2092                                                                 parentChildLink pclink;
2093                                                                 pclink.m_blenderchild = blenderobject;
2094                                                                 pclink.m_gamechildnode = parentinversenode;
2095                                                                 vec_parent_child.push_back(pclink);
2096
2097                                                                 float* fl = (float*) blenderobject->parentinv;
2098                                                                 MT_Transform parinvtrans(fl);
2099                                                                 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
2100
2101                                                                 // Extract the rotation and the scaling from the basis
2102                                                                 MT_Matrix3x3 ori(parinvtrans.getBasis());
2103                                                                 MT_Vector3 x(ori.getColumn(0));
2104                                                                 MT_Vector3 y(ori.getColumn(1));
2105                                                                 MT_Vector3 z(ori.getColumn(2));
2106                                                                 MT_Vector3 scale(x.length(), y.length(), z.length());
2107                                                                 if (!MT_fuzzyZero(scale[0]))
2108                                                                         x /= scale[0];
2109                                                                 if (!MT_fuzzyZero(scale[1]))
2110                                                                         y /= scale[1];
2111                                                                 if (!MT_fuzzyZero(scale[2]))
2112                                                                         z /= scale[2];
2113                                                                 ori.setColumn(0, x);                                                            
2114                                                                 ori.setColumn(1, y);                                                            
2115                                                                 ori.setColumn(2, z);                                                            
2116                                                                 parentinversenode->SetLocalOrientation(ori);
2117                                                                 parentinversenode->SetLocalScale(scale);
2118                                                                 
2119                                                                 parentinversenode->AddChild(gameobj->GetSGNode());
2120                                                         }
2121                                                         
2122                                                         // needed for python scripting
2123                                                         logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
2124
2125                                                         // needed for group duplication
2126                                                         logicmgr->RegisterGameObj(blenderobject, gameobj);
2127                                                         for (int i = 0; i < gameobj->GetMeshCount(); i++)
2128                                                                 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
2129                                         
2130                                                         converter->RegisterGameObject(gameobj, blenderobject);  
2131                                                         // this was put in rapidly, needs to be looked at more closely
2132                                                         // only draw/use objects in active 'blender' layers
2133                                         
2134                                                         logicbrick_conversionlist->Add(gameobj->AddRef());
2135                                                         
2136                                                         if (converter->addInitFromFrame){
2137                                                                 posPrev=gameobj->NodeGetWorldPosition();
2138                                                                 angor=gameobj->NodeGetWorldOrientation();
2139                                                         }
2140                                                         if (isInActiveLayer)
2141                                                         {
2142                                                                 objectlist->Add(gameobj->AddRef());
2143                                                                 //tf.Add(gameobj->GetSGNode());
2144                                                                 
2145                                                                 gameobj->NodeUpdateGS(0,true);
2146                                                                 gameobj->AddMeshUser();
2147                                                         }
2148                                                         else
2149                                                         {
2150                                                                 //we must store this object otherwise it will be deleted 
2151                                                                 //at the end of this function if it is not a root object
2152                                                                 inactivelist->Add(gameobj->AddRef());
2153
2154                                                         }
2155                                                         if (gameobj->IsDupliGroup())
2156                                                         {
2157                                                                 // check that the group is not already converted
2158                                                                 if (allgrouplist.insert(blenderobject->dup_group).second)
2159                                                                         grouplist.insert(blenderobject->dup_group);
2160                                                         }
2161                                                         if (converter->addInitFromFrame){
2162                                                                 gameobj->NodeSetLocalPosition(posPrev);
2163                                                                 gameobj->NodeSetLocalOrientation(angor);
2164                                                         }
2165                                                                                 
2166                                                 }
2167                                                 if (gameobj)
2168                                                         gameobj->Release();
2169                                         }
2170                                 }
2171                         }
2172                 }
2173         }
2174
2175         // non-camera objects not supported as camera currently
2176         if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) {
2177                 KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
2178                 
2179                 if(gamecamera)
2180                         kxscene->SetActiveCamera(gamecamera);
2181         }
2182
2183         //      Set up armatures
2184         set<Object*>::iterator oit;
2185         for(oit=allblobj.begin(); oit!=allblobj.end(); oit++)
2186         {
2187                 Object* blenderobj = *oit;
2188                 if (blenderobj->type==OB_MESH) {
2189                         Mesh *me = (Mesh*)blenderobj->data;
2190         
2191                         if (me->dvert){
2192                                 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)converter->FindGameObject(blenderobj);
2193         
2194                                 if (obj && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE && blenderobj->partype==PARSKEL){
2195                                         KX_GameObject *par = converter->FindGameObject(blenderobj->parent);
2196                                         if (par && obj->m_pDeformer)
2197                                                 ((BL_SkinDeformer*)obj->m_pDeformer)->SetArmature((BL_ArmatureObject*) par);
2198                                 }
2199                         }
2200                 }
2201         }
2202         
2203         // create hierarchy information
2204         int i;
2205         vector<parentChildLink>::iterator pcit;
2206         
2207         for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
2208         {
2209         
2210                 struct Object* blenderchild = pcit->m_blenderchild;
2211                 struct Object* blenderparent = blenderchild->parent;
2212                 KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
2213                 KX_GameObject* childobj = converter->FindGameObject(blenderchild);
2214
2215                 assert(childobj);
2216
2217                 if (!parentobj || objectlist->SearchValue(childobj) != objectlist->SearchValue(parentobj))
2218                 {
2219                         // special case: the parent and child object are not in the same layer. 
2220                         // This weird situation is used in Apricot for test purposes.
2221                         // Resolve it by not converting the child
2222                         childobj->GetSGNode()->DisconnectFromParent();
2223                         delete pcit->m_gamechildnode;
2224                         // Now destroy the child object but also all its descendent that may already be linked
2225                         // Remove the child reference in the local list!
2226                         // Note: there may be descendents already if the children of the child were processed
2227                         //       by this loop before the child. In that case, we must remove the children also
2228                         CListValue* childrenlist = (CListValue*)childobj->PyGetChildrenRecursive(childobj);
2229                         childrenlist->Add(childobj->AddRef());
2230                         for ( i=0;i<childrenlist->GetCount();i++)
2231                         {
2232                                 KX_GameObject* obj = static_cast<KX_GameObject*>(childrenlist->GetValue(i));
2233                                 if (templist->RemoveValue(obj))
2234                                         obj->Release();
2235                                 if (sumolist->RemoveValue(obj))
2236                                         obj->Release();
2237                                 if (logicbrick_conversionlist->RemoveValue(obj))
2238                                         obj->Release();
2239                         }
2240                         childrenlist->Release();
2241                         // now destroy recursively
2242                         kxscene->RemoveObject(childobj);
2243                         continue;
2244                 }
2245
2246                 switch (blenderchild->partype)
2247                 {
2248                         case PARVERT1:
2249                         {
2250                                 // creat a new vertex parent relationship for this node.
2251                                 KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
2252                                 pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
2253                                 break;
2254                         }
2255                         case PARSLOW:
2256                         {
2257                                 // creat a new slow parent relationship for this node.
2258                                 KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
2259                                 pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
2260                                 break;
2261                         }       
2262                         case PARBONE:
2263                         {
2264                                 // parent this to a bone
2265                                 Bone *parent_bone = get_named_bone(get_armature(blenderchild->parent), blenderchild->parsubstr);
2266
2267                                 if(parent_bone) {
2268                                         KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone);
2269                                         pcit->m_gamechildnode->SetParentRelation(bone_parent_relation);
2270                                 }
2271                         
2272                                 break;
2273                         }
2274                         case PARSKEL: // skinned - ignore
2275                                 break;
2276                         case PAROBJECT:
2277                         case PARCURVE:
2278                         case PARKEY:
2279                         case PARVERT3:
2280                         default:
2281                                 // unhandled
2282                                 break;
2283                 }
2284         
2285                 parentobj->     GetSGNode()->AddChild(pcit->m_gamechildnode);
2286         }
2287         vec_parent_child.clear();
2288         
2289         // find 'root' parents (object that has not parents in SceneGraph)
2290         for (i=0;i<templist->GetCount();++i)
2291         {
2292                 KX_GameObject* gameobj = (KX_GameObject*) templist->GetValue(i);
2293                 if (gameobj->GetSGNode()->GetSGParent() == 0)
2294                 {
2295                         parentlist->Add(gameobj->AddRef());
2296                         gameobj->NodeUpdateGS(0,true);
2297                 }
2298         }
2299         
2300         bool processCompoundChildren = false;
2301
2302         // create physics information
2303         for (i=0;i<sumolist->GetCount();i++)
2304         {
2305                 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2306                 struct Object* blenderobject = converter->FindBlenderObject(gameobj);
2307                 int nummeshes = gameobj->GetMeshCount();
2308                 RAS_MeshObject* meshobj = 0;
2309                 if (nummeshes > 0)
2310                 {
2311                         meshobj = gameobj->GetMesh(0);
2312                 }
2313                 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
2314                 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
2315         }
2316
2317         processCompoundChildren = true;
2318         // create physics information
2319         for (i=0;i<sumolist->GetCount();i++)
2320         {
2321                 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2322                 struct Object* blenderobject = converter->FindBlenderObject(gameobj);
2323                 int nummeshes = gameobj->GetMeshCount();
2324                 RAS_MeshObject* meshobj = 0;
2325                 if (nummeshes > 0)
2326                 {
2327                         meshobj = gameobj->GetMesh(0);
2328                 }
2329                 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
2330                 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
2331         }
2332         
2333         
2334         //set ini linearVel and int angularVel //rcruiz
2335         if (converter->addInitFromFrame)
2336                 for (i=0;i<sumolist->GetCount();i++)
2337                 {
2338                         KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2339                         if (gameobj->IsDynamic()){
2340                                 gameobj->setLinearVelocity(inivel[i],false);
2341                                 gameobj->setAngularVelocity(iniang[i],false);
2342                         }
2343                 
2344                 
2345                 }       
2346
2347                 // create physics joints
2348         for (i=0;i<sumolist->GetCount();i++)
2349         {
2350                 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2351                 struct Object* blenderobject = converter->FindBlenderObject(gameobj);
2352                 ListBase *conlist;
2353                 bConstraint *curcon;
2354                 conlist = get_active_constraints2(blenderobject);
2355
2356                 if (conlist) {
2357                         for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) {
2358                                 if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT){
2359
2360                                         bRigidBodyJointConstraint *dat=(bRigidBodyJointConstraint *)curcon->data;
2361
2362                                         if (!dat->child){
2363
2364                                                 PHY_IPhysicsController* physctr2 = 0;
2365
2366                                                 if (dat->tar)
2367                                                 {
2368                                                         KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist);
2369                                                         if (gotar && gotar->GetPhysicsController())
2370                                                                 physctr2 = (PHY_IPhysicsController*) gotar->GetPhysicsController()->GetUserData();
2371                                                 }
2372
2373                                                 if (gameobj->GetPhysicsController())
2374                                                 {
2375                                                         float radsPerDeg = 6.283185307179586232f / 360.f;
2376
2377                                                         PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) gameobj->GetPhysicsController()->GetUserData();
2378                                                         //we need to pass a full constraint frame, not just axis
2379                                     
2380                                                         //localConstraintFrameBasis
2381                                                         MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*dat->axX,radsPerDeg*dat->axY,radsPerDeg*dat->axZ));
2382                                                         MT_Vector3 axis0 = localCFrame.getColumn(0);
2383                                                         MT_Vector3 axis1 = localCFrame.getColumn(1);
2384                                                         MT_Vector3 axis2 = localCFrame.getColumn(2);
2385                                                                 
2386                                                         int constraintId = kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,
2387                                                                 (float)dat->pivY,(float)dat->pivZ,
2388                                                                 (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
2389                                                                 (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
2390                                                                 (float)axis2.x(),(float)axis2.y(),(float)axis2.z());
2391                                                         if (constraintId)
2392                                                         {
2393                                                                 //if it is a generic 6DOF constraint, set all the limits accordingly
2394                                                                 if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT)
2395                                                                 {
2396                                                                         int dof;
2397                                                                         int dofbit=1;
2398                                                                         for (dof=0;dof<6;dof++)
2399                                                                         {
2400                                                                                 if (dat->flag & dofbit)
2401                                                                                 {
2402                                                                                         kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
2403                                                                                 } else
2404                                                                                 {
2405                                                                                         //minLimit > maxLimit means free(disabled limit) for this degree of freedom
2406                                                                                         kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1);
2407                                                                                 }
2408                                                                                 dofbit<<=1;
2409                                                                         }
2410                                                                 }
2411                                                         }
2412                                                 }
2413                                         }
2414                                 }
2415                         }
2416                 }
2417         }
2418
2419         templist->Release();
2420         sumolist->Release();    
2421
2422         int executePriority=0; /* incremented by converter routines */
2423         
2424         // convert global sound stuff
2425
2426         /* XXX, glob is the very very wrong place for this
2427          * to be, re-enable once the listener has been moved into
2428          * the scene. */
2429 #if 1
2430         SND_Scene* soundscene = kxscene->GetSoundScene();
2431         SND_SoundListener* listener = soundscene->GetListener();
2432         if (listener && G.listener)
2433         {
2434                 listener->SetDopplerFactor(G.listener->dopplerfactor);
2435                 listener->SetDopplerVelocity(G.listener->dopplervelocity);
2436                 listener->SetGain(G.listener->gain);
2437         }
2438 #endif
2439
2440         // convert world
2441         KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene->world);
2442         converter->RegisterWorldInfo(worldinfo);
2443         kxscene->SetWorldInfo(worldinfo);
2444
2445 #define CONVERT_LOGIC
2446 #ifdef CONVERT_LOGIC
2447         // convert logic bricks, sensors, controllers and actuators
2448         for (i=0;i<logicbrick_conversionlist->GetCount();i++)
2449         {
2450                 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
2451                 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
2452                 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
2453                 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
2454                 BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, layerMask,isInActiveLayer,rendertools,converter);
2455         }
2456         for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
2457         {
2458                 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
2459                 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
2460                 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
2461                 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
2462                 BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,layerMask,isInActiveLayer,converter);
2463         }
2464         for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
2465         {
2466                 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
2467                 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
2468                 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
2469                 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
2470                 BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter);
2471                 // set the init state to all objects
2472                 gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
2473         }
2474         // apply the initial state to controllers, only on the active objects as this registers the sensors
2475         for ( i=0;i<objectlist->GetCount();i++)
2476         {
2477                 KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i));
2478                 gameobj->ResetState();
2479         }
2480
2481 #endif //CONVERT_LOGIC
2482
2483         logicbrick_conversionlist->Release();
2484         
2485         // Calculate the scene btree -
2486         // too slow - commented out.
2487         //kxscene->SetNodeTree(tf.MakeTree());
2488
2489         // instantiate dupli group, we will loop trough the object
2490         // that are in active layers. Note that duplicating group
2491         // has the effect of adding objects at the end of objectlist.
2492         // Only loop through the first part of the list.
2493         int objcount = objectlist->GetCount();
2494         for (i=0;i<objcount;i++)
2495         {
2496                 KX_GameObject* gameobj = (KX_GameObject*) objectlist->GetValue(i);
2497                 if (gameobj->IsDupliGroup())
2498                 {
2499                         kxscene->DupliGroupRecurse(gameobj, 0);
2500                 }
2501         }
2502
2503         KX_Camera *activecam = kxscene->GetActiveCamera();
2504         MT_Scalar distance = (activecam)? activecam->GetCameraFar() - activecam->GetCameraNear(): 100.0f;
2505         RAS_BucketManager *bucketmanager = kxscene->GetBucketManager();
2506         bucketmanager->OptimizeBuckets(distance);
2507 }
2508