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