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