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