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