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