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