f2d9d46bf9488a2926fc2a09032365136ade28e6
[blender.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
50 // Expressions
51 #include "ListValue.h"
52 #include "IntValue.h"
53 // Collision & Fuzzics LTD
54
55 #include "PHY_Pro.h"
56
57
58 #include "KX_Scene.h"
59 #include "KX_GameObject.h"
60 #include "RAS_FramingManager.h"
61 #include "RAS_MeshObject.h"
62
63 #include "KX_ConvertActuators.h"
64 #include "KX_ConvertControllers.h"
65 #include "KX_ConvertSensors.h"
66
67 #include "SCA_LogicManager.h"
68 #include "SCA_EventManager.h"
69 #include "SCA_TimeEventManager.h"
70 #include "KX_Light.h"
71 #include "KX_Camera.h"
72 #include "KX_EmptyObject.h"
73 #include "MT_Point3.h"
74 #include "MT_Transform.h"
75 #include "MT_MinMax.h"
76 #include "SCA_IInputDevice.h"
77 #include "RAS_TexMatrix.h"
78 #include "RAS_ICanvas.h"
79 #include "RAS_MaterialBucket.h"
80 //#include "KX_BlenderPolyMaterial.h"
81 #include "RAS_Polygon.h"
82 #include "RAS_TexVert.h"
83 #include "RAS_BucketManager.h"
84 #include "RAS_IRenderTools.h"
85
86 #include "DNA_action_types.h"
87 #include "BKE_main.h"
88 #include "BL_SkinMeshObject.h"
89 #include "BL_SkinDeformer.h"
90 #include "BL_MeshDeformer.h"
91 //#include "BL_ArmatureController.h"
92
93 #include "BlenderWorldInfo.h"
94
95 #include "KX_KetsjiEngine.h"
96 #include "KX_BlenderSceneConverter.h"
97
98 #include"SND_Scene.h"
99 #include "SND_SoundListener.h"
100
101 /* This little block needed for linking to Blender... */
102 #ifdef WIN32
103 #include "BLI_winstuff.h"
104 #endif
105
106 /* This list includes only data type definitions */
107 #include "DNA_object_types.h"
108 #include "DNA_material_types.h"
109 #include "DNA_image_types.h"
110 #include "DNA_lamp_types.h"
111 #include "DNA_group_types.h"
112 #include "DNA_scene_types.h"
113 #include "DNA_camera_types.h"
114 #include "DNA_property_types.h"
115 #include "DNA_text_types.h"
116 #include "DNA_sensor_types.h"
117 #include "DNA_controller_types.h"
118 #include "DNA_actuator_types.h"
119 #include "DNA_mesh_types.h"
120 #include "DNA_meshdata_types.h"
121 #include "DNA_view3d_types.h"
122 #include "DNA_world_types.h"
123 #include "DNA_sound_types.h"
124 #include "DNA_key_types.h"
125
126
127 #include "MEM_guardedalloc.h"
128 #include "BKE_utildefines.h"
129 #include "BKE_key.h"
130 #include "BKE_mesh.h"
131 #include "MT_Point3.h"
132
133
134 #include "BKE_material.h" /* give_current_material */
135 /* end of blender include block */
136
137 #include "KX_BlenderInputDevice.h"
138 #include "KX_ConvertProperties.h"
139 #include "KX_HashedPtr.h"
140
141
142 #include "KX_ScalarInterpolator.h"
143
144 #include "KX_IpoConvert.h"
145 #include "SYS_System.h"
146
147 #include "SG_Node.h"
148 #include "SG_BBox.h"
149 #include "SG_Tree.h"
150
151 // defines USE_ODE to choose physics engine
152 #include "KX_ConvertPhysicsObject.h"
153
154
155 // This file defines relationships between parents and children
156 // in the game engine.
157
158 #include "KX_SG_NodeRelationships.h"
159
160 #include "BL_ArmatureObject.h"
161 #include "BL_DeformableGameObject.h"
162
163 static int default_face_mode = TF_DYNAMIC;
164
165 static unsigned int KX_rgbaint2uint_new(unsigned int icol)
166 {
167         union
168         {
169                 unsigned int integer;
170                 unsigned char cp[4];
171         } out_colour, in_colour;
172         
173         in_colour.integer = icol;
174         out_colour.cp[0] = in_colour.cp[3]; // red
175         out_colour.cp[1] = in_colour.cp[2]; // green
176         out_colour.cp[2] = in_colour.cp[1]; // blue
177         out_colour.cp[3] = in_colour.cp[0]; // alpha
178         
179         return out_colour.integer;
180 }
181
182 /* Now the real converting starts... */
183 static unsigned int KX_Mcol2uint_new(MCol col)
184 {
185         /* color has to be converted without endian sensitivity. So no shifting! */
186         union
187         {
188                 MCol col;
189                 unsigned int integer;
190                 unsigned char cp[4];
191         } out_colour, in_colour;
192
193         in_colour.col = col;
194         out_colour.cp[0] = in_colour.cp[3]; // red
195         out_colour.cp[1] = in_colour.cp[2]; // green
196         out_colour.cp[2] = in_colour.cp[1]; // blue
197         out_colour.cp[3] = in_colour.cp[0]; // alpha
198         
199         return out_colour.integer;
200 }
201
202 static void SetDefaultFaceType(Scene* scene)
203 {
204         default_face_mode = TF_DYNAMIC;
205         Base *base = static_cast<Base*>(scene->base.first);
206         while(base)
207         {
208                 if (base->object->type == OB_LAMP)
209                 {
210                         default_face_mode = TF_DYNAMIC|TF_LIGHT;
211                         return;
212                 }
213                 base = base->next;
214         }
215 }
216
217 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter)
218 {
219         RAS_MeshObject *meshobj;
220         bool    skinMesh = false;
221         
222         int lightlayer = blenderobj->lay;
223         
224         // Determine if we need to make a skinned mesh
225         if (mesh->dvert){
226                 meshobj = new BL_SkinMeshObject(lightlayer);
227                 skinMesh = true;
228         }
229         else {
230                 meshobj = new RAS_MeshObject(lightlayer);
231         }
232         
233         meshobj->SetName(mesh->id.name);
234         
235         MFace* mface = static_cast<MFace*>(mesh->mface);
236         TFace* tface = static_cast<TFace*>(mesh->tface);
237         assert(mface);
238         MCol* mmcol = mesh->mcol;
239         
240         meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
241         
242         for (int f=0;f<mesh->totface;f++,mface++)
243         {
244                 
245                 bool collider = true;
246                 
247                 // only add valid polygons
248                 if (mface->v3)
249                 {
250                         MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
251                         // rgb3 is set from the adjoint face in a square
252                         unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
253                         MT_Vector3      no0(mesh->mvert[mface->v1].no[0], mesh->mvert[mface->v1].no[1], mesh->mvert[mface->v1].no[2]),
254                                         no1(mesh->mvert[mface->v2].no[0], mesh->mvert[mface->v2].no[1], mesh->mvert[mface->v2].no[2]),
255                                         no2(mesh->mvert[mface->v3].no[0], mesh->mvert[mface->v3].no[1], mesh->mvert[mface->v3].no[2]),
256                                         no3(0.0, 0.0, 0.0);
257                         MT_Point3       pt0(mesh->mvert[mface->v1].co),
258                                         pt1(mesh->mvert[mface->v2].co),
259                                         pt2(mesh->mvert[mface->v3].co),
260                                         pt3(0.0, 0.0, 0.0);
261                         
262                         no0 /= 32767.0;
263                         no1 /= 32767.0;
264                         no2 /= 32767.0;
265                         if (mface->v4)
266                         {
267                                 pt3 = MT_Point3(mesh->mvert[mface->v4].co);
268                                 no3 = MT_Vector3(mesh->mvert[mface->v4].no[0], mesh->mvert[mface->v4].no[1], mesh->mvert[mface->v4].no[2]);
269                                 no3 /= 32767.0;
270                         }
271         
272                         if(!(mface->flag & ME_SMOOTH))
273                         {
274                                 MT_Vector3 norm = ((pt1-pt0).cross(pt2-pt0)).safe_normalized();
275                                 norm[0] = ((int) (10*norm[0]))/10.0;
276                                 norm[1] = ((int) (10*norm[1]))/10.0;
277                                 norm[2] = ((int) (10*norm[2]))/10.0;
278                                 no0=no1=no2=no3= norm;
279         
280                         }
281                 
282                         {
283                                 Image* bima = ((mesh->tface && tface) ? (Image*) tface->tpage : NULL);
284         
285                                 STR_String imastr = 
286                                         ((mesh->tface && tface) ? 
287                                         (bima? (bima)->id.name : "" ) : "" );
288                 
289                                 char transp=0;
290                                 short mode=0, tile=0;
291                                 int     tilexrep=4,tileyrep = 4;
292                                 
293                                 if (bima)
294                                 {
295                                         tilexrep = bima->xrep;
296                                         tileyrep = bima->yrep;
297                         
298                                 }
299         
300                                 Material* ma = give_current_material(blenderobj, 1 /* mface->mat_nr */);
301                                 const char* matnameptr = (ma ? ma->id.name : "");
302                                 
303                                 bool polyvisible = true;
304                                 if (mesh->tface && tface)
305                                 {
306                                         // Use texface colors if available
307                                         //TF_DYNAMIC means the polygon is a collision face
308                                         collider = (tface->mode & TF_DYNAMIC != 0);
309                                         transp = tface->transp;
310                                         tile = tface->tile;
311                                         mode = tface->mode;
312                                         
313                                         polyvisible = !((tface->flag & TF_HIDE)||(tface->mode & TF_INVISIBLE));
314                                         
315                                         uv0 = MT_Point2(tface->uv[0]);
316                                         uv1 = MT_Point2(tface->uv[1]);
317                                         uv2 = MT_Point2(tface->uv[2]);
318                                         rgb0 = KX_rgbaint2uint_new(tface->col[0]);
319                                         rgb1 = KX_rgbaint2uint_new(tface->col[1]);
320                                         rgb2 = KX_rgbaint2uint_new(tface->col[2]);
321         
322                                         if (mface->v4)
323                                         {
324                                                 uv3 = MT_Point2(tface->uv[3]);
325                                                 rgb3 = KX_rgbaint2uint_new(tface->col[3]);
326                                         } 
327                                 } 
328                                 else
329                                 {
330                                         //
331                                         if (mmcol)
332                                         {
333                                                 // Use vertex colours
334                                                 rgb0 = KX_Mcol2uint_new(mmcol[0]);
335                                                 rgb1 = KX_Mcol2uint_new(mmcol[1]);
336                                                 rgb2 = KX_Mcol2uint_new(mmcol[2]);
337                                                 
338                                                 
339                                                 if (mface->v4)
340                                                 {
341                                                         rgb3 = KX_Mcol2uint_new(mmcol[3]);
342                                                         
343                                                 }
344                                         
345                                                 mmcol += 4;
346                                         }
347                                         else
348                                         {
349                                                 // If there are no vertex colors OR texfaces,
350                                                 // Initialize face to white and set COLLSION true and everything else FALSE
351                                                 unsigned int colour = 0xFFFFFFFFL;
352                                                 mode = default_face_mode;       
353                                                 transp = TF_SOLID;
354                                                 tile = 0;
355                                                 if (ma)
356                                                 {
357                                                         // If we have a material, take the default colour from the material.
358                                                         union
359                                                         {
360                                                                 unsigned char cp[4];
361                                                                 unsigned int integer;
362                                                         } col_converter;
363                                                         
364                                                         col_converter.cp[3] = (unsigned char) (ma->r*255.0);
365                                                         col_converter.cp[2] = (unsigned char) (ma->g*255.0);
366                                                         col_converter.cp[1] = (unsigned char) (ma->b*255.0);
367                                                         col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
368                                                         
369                                                         colour = col_converter.integer;
370                                                 }
371                                                 
372                                                 rgb0 = KX_rgbaint2uint_new(colour);
373                                                 rgb1 = KX_rgbaint2uint_new(colour);
374                                                 rgb2 = KX_rgbaint2uint_new(colour);     
375                                                 
376                                                 if (mface->v4)
377                                                         rgb3 = KX_rgbaint2uint_new(colour);
378                                         }
379                                 }
380                                         
381                                 
382                                 bool istriangle = (mface->v4==0);
383                                 bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false;
384                                 
385                                 RAS_IPolyMaterial* polymat = rendertools->CreateBlenderPolyMaterial(imastr, false, matnameptr,
386                                         tile, tilexrep, tileyrep, 
387                                         mode, transp, zsort, lightlayer, istriangle, blenderobj, tface);
388         
389                                 if (ma)
390                                 {
391                                         polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
392                                         polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
393                                         polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
394
395                                 } else
396                                 {
397                                         polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
398                                         polymat->m_shininess = 35.0;
399                                 }
400
401                         
402                                 // this is needed to free up memory afterwards
403                                 converter->RegisterPolyMaterial(polymat);
404         
405                                 RAS_MaterialBucket* bucket = scene->FindBucket(polymat);
406                                                          
407                                 int nverts = mface->v4?4:3;
408                                 int vtxarray = meshobj->FindVertexArray(nverts,polymat);
409                                 RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
410                                 if (skinMesh) {
411                                         int d1, d2, d3, d4;
412                                         bool flat;
413
414                                         /* If the face is set to solid, all fnors are the same */
415                                         if (mface->flag & ME_SMOOTH)
416                                                 flat = false;
417                                         else
418                                                 flat = true;
419                                         
420                                         d1=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v1, &mesh->dvert[mface->v1], polymat);
421                                         d2=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v2, &mesh->dvert[mface->v2], polymat);
422                                         d3=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v3, &mesh->dvert[mface->v3], polymat);
423                                         if (nverts==4)
424                                                 d4=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v4, &mesh->dvert[mface->v4], polymat);
425                                         poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,d1,flat, polymat));
426                                         poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,d2,flat, polymat));
427                                         poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,d3,flat, polymat));
428                                         if (nverts==4)
429                                                 poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,d4, flat,polymat));
430                                 }
431                                 else
432                                 {
433                                         poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,polymat,mface->v1));
434                                         poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,polymat,mface->v2));
435                                         poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,polymat,mface->v3));
436                                         if (nverts==4)
437                                                 poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,polymat,mface->v4));
438                                 }
439                                 meshobj->AddPolygon(poly);
440                                 if (poly->IsCollider())
441                                 {
442                                         RAS_TriangleIndex idx;
443                                         idx.m_index[0] = mface->v1;
444                                         idx.m_index[1] = mface->v2;
445                                         idx.m_index[2] = mface->v3;
446                                         idx.m_collider = collider;
447                                         meshobj->m_triangle_indices.push_back(idx);
448                                         if (nverts==4)
449                                         {
450                                         idx.m_index[0] = mface->v1;
451                                         idx.m_index[1] = mface->v3;
452                                         idx.m_index[2] = mface->v4;
453                                         idx.m_collider = collider;
454                                         meshobj->m_triangle_indices.push_back(idx);
455                                         }
456                                 }
457                                 
458                                 poly->SetVisibleWireframeEdges(mface->edcode);
459                                 poly->SetCollider(collider);
460                         }
461                 }
462                 if (tface) 
463                         tface++;
464         }
465         meshobj->UpdateMaterialList();
466         
467         return meshobj;
468 }
469
470 static PHY_MaterialProps g_materialProps = {
471         1.0,    // restitution
472         2.0,    // friction 
473         0.0,    // fh spring constant
474         0.0,    // fh damping
475         0.0,    // fh distance
476         false   // sliding material?
477 };
478
479         
480         
481 static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject,
482                                                                                                   KX_Scene *kxscene)
483 {
484         PHY_MaterialProps *materialProps = new PHY_MaterialProps;
485         
486         assert(materialProps);
487                 
488         Material* blendermat = give_current_material(blenderobject, 0);
489                 
490         if (blendermat)
491         {
492                 assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f);
493         
494                 materialProps->m_restitution = blendermat->reflect;
495                 materialProps->m_friction = blendermat->friction;
496                 materialProps->m_fh_spring = blendermat->fh;
497                 materialProps->m_fh_damping = blendermat->xyfrict;
498                 materialProps->m_fh_distance = blendermat->fhdist;
499                 materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
500         }
501         else {
502                 *materialProps = g_materialProps;
503         }
504         
505         return materialProps;
506 }
507
508 static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject,
509                                                                                                  KX_Scene *kxscene)
510 {
511         PHY_ShapeProps *shapeProps = new PHY_ShapeProps;
512         
513         assert(shapeProps);
514                 
515         shapeProps->m_mass = blenderobject->mass;
516         
517 //  This needs to be fixed in blender. For now, we use:
518         
519 // in Blender, inertia stands for the size value which is equivalent to
520 // the sphere radius
521         shapeProps->m_inertia = blenderobject->formfactor;
522         
523         assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
524         assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
525         
526         shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
527         shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
528         
529         shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0]; 
530         shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
531         shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2];
532         shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0);
533         
534         shapeProps->m_do_fh     = (blenderobject->gameflag & OB_DO_FH) != 0; 
535         shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
536         
537         return shapeProps;
538 }
539
540         
541         
542         
543                 
544 //////////////////////////////////////////////////////////
545         
546
547
548 static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
549 {
550         MVert *mvert;
551         BoundBox *bb;
552         MT_Point3 min, max;
553         float mloc[3], msize[3];
554         int a;
555         
556         if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
557         bb= me->bb;
558         
559         INIT_MINMAX(min, max);
560
561         if (!loc) loc= mloc;
562         if (!size) size= msize;
563         
564         mvert= me->mvert;
565         for(a=0; a<me->totvert; a++, mvert++) {
566                 DO_MINMAX(mvert->co, min, max);
567         }
568                 
569         if(me->totvert) {
570                 loc[0]= (min[0]+max[0])/2.0;
571                 loc[1]= (min[1]+max[1])/2.0;
572                 loc[2]= (min[2]+max[2])/2.0;
573                 
574                 size[0]= (max[0]-min[0])/2.0;
575                 size[1]= (max[1]-min[1])/2.0;
576                 size[2]= (max[2]-min[2])/2.0;
577         }
578         else {
579                 loc[0]= loc[1]= loc[2]= 0.0;
580                 size[0]= size[1]= size[2]= 0.0;
581         }
582                 
583         bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
584         bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
585                 
586         bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
587         bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
588
589         bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
590         bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
591
592         float radius = 0;
593         for (a=0, mvert = me->mvert; a < me->totvert; a++, mvert++)
594         {
595                 float vert_radius = MT_Vector3(mvert->co).length2();
596                 if (vert_radius > radius)
597                         radius = vert_radius;
598         } 
599         return sqrt(radius);
600 }
601                 
602
603
604
605 static void my_tex_space_mesh(Mesh *me)
606                 {
607         KeyBlock *kb;
608         float *fp, loc[3], size[3], min[3], max[3];
609         int a;
610
611         my_boundbox_mesh(me, loc, size);
612         
613         if(me->texflag & AUTOSPACE) {
614                 if(me->key) {
615                         kb= me->key->refkey;
616                         if (kb) {
617         
618                                 INIT_MINMAX(min, max);
619                 
620                                 fp= (float *)kb->data;
621                                 for(a=0; a<kb->totelem; a++, fp+=3) {   
622                                         DO_MINMAX(fp, min, max);
623                                 }
624                                 if(kb->totelem) {
625                                         loc[0]= (min[0]+max[0])/2.0; loc[1]= (min[1]+max[1])/2.0; loc[2]= (min[2]+max[2])/2.0;
626                                         size[0]= (max[0]-min[0])/2.0; size[1]= (max[1]-min[1])/2.0; size[2]= (max[2]-min[2])/2.0;
627         } 
628         else {
629                                         loc[0]= loc[1]= loc[2]= 0.0;
630                                         size[0]= size[1]= size[2]= 0.0;
631                                 }
632                                 
633                         }
634                                 }
635         
636                 VECCOPY(me->loc, loc);
637                 VECCOPY(me->size, size);
638                 me->rot[0]= me->rot[1]= me->rot[2]= 0.0;
639         
640                 if(me->size[0]==0.0) me->size[0]= 1.0;
641                 else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001;
642                 else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001;
643         
644                 if(me->size[1]==0.0) me->size[1]= 1.0;
645                 else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001;
646                 else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001;
647                                                 
648                 if(me->size[2]==0.0) me->size[2]= 1.0;
649                 else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001;
650                 else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001;
651         }
652         
653 }
654
655 static void my_get_local_bounds(Object *ob, float *centre, float *size)
656 {
657         BoundBox *bb= NULL;
658         /* uses boundbox, function used by Ketsji */
659         switch (ob->type)
660         {
661                 case OB_MESH:
662                         bb= ( (Mesh *)ob->data )->bb;
663                         if(bb==0) 
664                         {
665                                 my_tex_space_mesh((struct Mesh *)ob->data);
666                                 bb= ( (Mesh *)ob->data )->bb;
667                         }
668                         break;
669                 case OB_CURVE:
670                 case OB_SURF:
671                 case OB_FONT:
672                         centre[0]= centre[1]= centre[2]= 0.0;
673                         size[0]  = size[1]=size[2]=0.0;
674                         break;
675                 case OB_MBALL:
676                         bb= ob->bb;
677                         break;
678         }
679         
680         if(bb==NULL) 
681         {
682                 centre[0]= centre[1]= centre[2]= 0.0;
683                 size[0] = size[1]=size[2]=1.0;
684         }
685         else 
686         {
687                 size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
688                 size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
689                 size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
690                                         
691                 centre[0]= 0.5*(bb->vec[0][0] + bb->vec[4][0]);
692                 centre[1]= 0.5*(bb->vec[0][1] + bb->vec[2][1]);
693                 centre[2]= 0.5*(bb->vec[0][2] + bb->vec[1][2]);
694         }
695 }
696         
697
698
699
700 //////////////////////////////////////////////////////
701
702
703
704
705
706 void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
707                                                  struct Object* blenderobject,
708                                                  RAS_MeshObject* meshobj,
709                                                  KX_Scene* kxscene,
710                                                  int activeLayerBitInfo,
711                                                  e_PhysicsEngine        physics_engine,
712                                                  KX_BlenderSceneConverter *converter
713                                                  )
714                                         
715 {
716         SYS_SystemHandle syshandle = SYS_GetSystem();
717         //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
718         //bool bRigidBody = (userigidbody == 0);
719
720         PHY_ShapeProps* shapeprops =
721                         CreateShapePropsFromBlenderObject(blenderobject, 
722                         kxscene);
723
724         
725         PHY_MaterialProps* smmaterial = 
726                 CreateMaterialFromBlenderObject(blenderobject, kxscene);
727                                         
728         KX_ObjectProperties objprop;
729         if ((objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0))
730         {
731                 objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
732                 objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
733                 objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
734         } else {
735                 objprop.m_dyna = false;
736                 objprop.m_angular_rigidbody = false;
737                 objprop.m_ghost = false;
738         }
739         //mmm, for now, taks this for the size of the dynamicobject
740         // Blender uses inertia for radius of dynamic object
741         objprop.m_radius = blenderobject->inertia;
742         objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
743         objprop.m_dynamic_parent=NULL;
744         objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
745         objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
746         
747         KX_BoxBounds bb;
748         my_get_local_bounds(blenderobject,objprop.m_boundobject.box.m_center,bb.m_extends);
749         if (blenderobject->gameflag & OB_BOUNDS)
750         {
751                 switch (blenderobject->boundtype)
752                 {
753                         case OB_BOUND_BOX:
754                                 objprop.m_boundclass = KX_BOUNDBOX;
755                                 //mmm, has to be divided by 2 to be proper extends
756                                 objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_extends[0];
757                                 objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1];
758                                 objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2];
759                                 break;
760                         case OB_BOUND_POLYT:
761                                 if (blenderobject->type == OB_MESH)
762                                 {
763                                         objprop.m_boundclass = KX_BOUNDPOLYTOPE;
764                                         break;
765                                 }
766                                 // Object is not a mesh... fall through OB_BOUND_POLYH to 
767                                 // OB_BOUND_SPHERE
768                         case OB_BOUND_POLYH:
769                                 if (blenderobject->type == OB_MESH)
770                                 {
771                                         objprop.m_boundclass = KX_BOUNDMESH;
772                                         break;
773                                 }
774                                 // Object is not a mesh... can't use polyheder. 
775                                 // Fall through and become a sphere.
776                         case OB_BOUND_SPHERE:
777                         {
778                                 objprop.m_boundclass = KX_BOUNDSPHERE;
779                                 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2]));
780                                 break;
781                         }
782                         case OB_BOUND_CYLINDER:
783                         {
784                                 objprop.m_boundclass = KX_BOUNDCYLINDER;
785                                 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
786                                 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
787                                 break;
788                         }
789                         case OB_BOUND_CONE:
790                         {
791                                 objprop.m_boundclass = KX_BOUNDCONE;
792                                 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
793                                 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
794                                 break;
795                         }
796                 }
797         }
798
799         // get Root Parent of blenderobject
800         struct Object* parent= blenderobject->parent;
801         while(parent && parent->parent) {
802                 parent= parent->parent;
803         }
804
805         if (parent && (parent->gameflag & OB_DYNAMIC)) {
806                 
807                 KX_GameObject *parentgameobject = converter->FindGameObject(parent);
808                 objprop.m_dynamic_parent = parentgameobject;
809
810         }
811
812         objprop.m_concave = (blenderobject->boundtype & 4) != 0;
813         
814         switch (physics_engine)
815         {
816 #ifdef USE_SUMO_SOLID
817                 case UseSumo:
818                         KX_ConvertSumoObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
819                         break;
820 #endif
821                         
822 #ifdef USE_ODE
823                 case UseODE:
824                         KX_ConvertODEEngineObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
825                         break;
826 #endif //USE_ODE
827
828                 case UseDynamo:
829                         //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops,    smmaterial,     &objprop);
830                         break;
831                         
832                 case UseNone:
833                 default:
834                         break;
835         }
836
837 }
838
839
840
841
842
843 static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
844         RAS_LightObject lightobj;
845         KX_LightObject *gamelight;
846         
847         lightobj.m_att1 = la->att1;
848         lightobj.m_att2 = (la->mode & LA_QUAD)?la->att2:0.0;
849         lightobj.m_red = la->r;
850         lightobj.m_green = la->g;
851         lightobj.m_blue = la->b;
852         lightobj.m_distance = la->dist;
853         lightobj.m_energy = la->energy;
854         lightobj.m_layer = layerflag;
855         lightobj.m_spotblend = la->spotblend;
856         lightobj.m_spotsize = la->spotsize;
857         
858         lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
859         lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
860         
861         if (la->mode & LA_NEG)
862         {
863                 lightobj.m_red = -lightobj.m_red;
864                 lightobj.m_green = -lightobj.m_green;
865                 lightobj.m_blue = -lightobj.m_blue;
866         }
867                 
868         if (la->type==LA_SUN) {
869                 lightobj.m_type = RAS_LightObject::LIGHT_SUN;
870         } else if (la->type==LA_SPOT) {
871                 lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
872         } else {
873                 lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
874         }
875         
876         gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj);
877         BL_ConvertLampIpos(la, gamelight, converter);
878         
879         return gamelight;
880 }
881
882 static KX_Camera *gamecamera_from_bcamera(Camera *ca, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
883         RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP);
884         KX_Camera *gamecamera;
885         
886         gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
887         gamecamera->SetName(ca->id.name + 2);
888         
889         BL_ConvertCameraIpos(ca, gamecamera, converter);
890         
891         return gamecamera;
892 }
893
894 static KX_GameObject *gameobject_from_blenderobject(
895                                                                 Object *ob, 
896                                                                 KX_Scene *kxscene, 
897                                                                 RAS_IRenderTools *rendertools, 
898                                                                 KX_BlenderSceneConverter *converter,
899                                                                 Scene *blenderscene) 
900 {
901         KX_GameObject *gameobj = NULL;
902         
903         switch(ob->type)
904         {
905         case OB_LAMP:
906         {
907                 KX_LightObject* gamelight= gamelight_from_blamp(static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
908                 gameobj = gamelight;
909                 
910                 gamelight->AddRef();
911                 kxscene->GetLightList()->Add(gamelight);
912                 
913                 break;
914         }
915         
916         case OB_CAMERA:
917         {
918                 KX_Camera* gamecamera = gamecamera_from_bcamera(static_cast<Camera*>(ob->data), kxscene, converter);
919                 gameobj = gamecamera;
920                 
921                 gamecamera->AddRef();
922                 kxscene->AddCamera(gamecamera);
923                 
924                 break;
925         }
926         
927         case OB_MESH:
928         {
929                 Mesh* mesh = static_cast<Mesh*>(ob->data);
930                 RAS_MeshObject* meshobj = converter->FindGameMesh(mesh, ob->lay);
931                 float centre[3], extents[3];
932                 float radius = my_boundbox_mesh((Mesh*) ob->data, centre, extents);
933                 
934                 if (!meshobj) {
935                         meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter);
936                         converter->RegisterGameMesh(meshobj, mesh);
937                 }
938                 
939                 // needed for python scripting
940                 kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
941         
942                 gameobj = new BL_DeformableGameObject(kxscene,KX_Scene::m_callbacks);
943         
944                 // set transformation
945                 gameobj->AddMesh(meshobj);
946         
947                 // for all objects: check whether they want to
948                 // respond to updates
949                 bool ignoreActivityCulling =  
950                         ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
951                 gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
952         
953                 //      If this is a skin object, make Skin Controller
954                 if (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && ((Mesh*)ob->data)->dvert){
955                         BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj);                          
956                         ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
957                 }
958                 else if (((Mesh*)ob->data)->dvert){
959                         BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj);
960                         ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
961                 }
962                 
963                 MT_Point3 min = MT_Point3(centre) - MT_Vector3(extents);
964                 MT_Point3 max = MT_Point3(centre) + MT_Vector3(extents);
965                 SG_BBox bbox = SG_BBox(min, max);
966                 gameobj->GetSGNode()->SetBBox(bbox);
967                 gameobj->GetSGNode()->SetRadius(radius);
968         
969                 break;
970         }
971         
972         case OB_ARMATURE:
973         {
974                 gameobj = new BL_ArmatureObject (kxscene, KX_Scene::m_callbacks,
975                         (bArmature*)ob->data,
976                         ob->pose);
977         
978                 /* Get the current pose from the armature object and apply it as the rest pose */
979                 break;
980         }
981         
982         case OB_EMPTY:
983         {
984                 gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks);
985                 // set transformation
986                 break;
987         }
988         }
989         
990         return gameobj;
991 }
992
993 struct parentChildLink {
994         struct Object* m_blenderchild;
995         SG_Node* m_gamechildnode;
996 };
997
998         /**
999          * Find the specified scene by name, or the first
1000          * scene if nothing matches (shouldn't happen).
1001          */
1002 static struct Scene *GetSceneForName(struct Main *maggie, const STR_String& scenename) {
1003         Scene *sce;
1004
1005         for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
1006                 if (scenename == (sce->id.name+2))
1007                         return sce;
1008
1009         return (Scene*) maggie->scene.first;
1010 }
1011
1012 // convert blender objects into ketsji gameobjects
1013 void BL_ConvertBlenderObjects(struct Main* maggie,
1014                                                           const STR_String& scenename,
1015                                                           KX_Scene* kxscene,
1016                                                           KX_KetsjiEngine* ketsjiEngine,
1017                                                           e_PhysicsEngine       physics_engine,
1018                                                           PyObject* pythondictionary,
1019                                                           SCA_IInputDevice* keydev,
1020                                                           RAS_IRenderTools* rendertools,
1021                                                           RAS_ICanvas* canvas,
1022                                                           KX_BlenderSceneConverter* converter,
1023                                                           bool alwaysUseExpandFraming
1024                                                           )
1025 {       
1026         Scene *blenderscene = GetSceneForName(maggie, scenename);
1027
1028         // Get the frame settings of the canvas.
1029         // Get the aspect ratio of the canvas as designed by the user.
1030
1031         RAS_FrameSettings::RAS_FrameType frame_type;
1032         int aspect_width;
1033         int aspect_height;
1034         
1035         if (alwaysUseExpandFraming) {
1036                 frame_type = RAS_FrameSettings::e_frame_extend;
1037                 aspect_width = canvas->GetWidth();
1038                 aspect_height = canvas->GetHeight();
1039         } else {
1040                 if (blenderscene->framing.type == SCE_GAMEFRAMING_BARS) {
1041                         frame_type = RAS_FrameSettings::e_frame_bars;
1042                 } else if (blenderscene->framing.type == SCE_GAMEFRAMING_EXTEND) {
1043                         frame_type = RAS_FrameSettings::e_frame_extend;
1044                 } else {
1045                         frame_type = RAS_FrameSettings::e_frame_scale;
1046                 }
1047                 
1048                 aspect_width = blenderscene->r.xsch;
1049                 aspect_height = blenderscene->r.ysch;
1050         }
1051         
1052         RAS_FrameSettings frame_settings(
1053                 frame_type,
1054                 blenderscene->framing.col[0],
1055                 blenderscene->framing.col[1],
1056                 blenderscene->framing.col[2],
1057                 aspect_width,
1058                 aspect_height
1059         );
1060         kxscene->SetFramingType(frame_settings);
1061
1062         kxscene->SetGravity(MT_Vector3(0,0,(blenderscene->world != NULL) ? -blenderscene->world->gravity : -9.8));
1063         
1064         /* set activity culling parameters */
1065         if (blenderscene->world) {
1066                 kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
1067                 kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
1068         } else {
1069                 kxscene->SetActivityCulling(false);
1070         }
1071         
1072         int activeLayerBitInfo = blenderscene->lay;
1073         
1074         // templist to find Root Parents (object with no parents)
1075         CListValue* templist = new CListValue();
1076         CListValue*     sumolist = new CListValue();
1077         
1078         vector<parentChildLink> vec_parent_child;
1079         
1080         CListValue* objectlist = kxscene->GetObjectList();
1081         CListValue* parentlist = kxscene->GetRootParentList();
1082         
1083         SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
1084         SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
1085         
1086         CListValue* logicbrick_conversionlist = new CListValue();
1087         
1088         SG_TreeFactory tf;
1089         
1090         // Convert actions to actionmap
1091         bAction *curAct;
1092         for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
1093         {
1094                 logicmgr->RegisterActionName(curAct->id.name, curAct);
1095         }
1096         
1097         SetDefaultFaceType(blenderscene);
1098         
1099         Base *base = static_cast<Base*>(blenderscene->base.first);
1100         while(base)
1101         {
1102                 Object* blenderobject = base->object;
1103                 KX_GameObject* gameobj = gameobject_from_blenderobject(
1104                                                                                 base->object, 
1105                                                                                 kxscene, 
1106                                                                                 rendertools, 
1107                                                                                 converter,
1108                                                                                 blenderscene);
1109                                                                                         
1110                 if (gameobj)
1111                 {
1112                         MT_Point3 pos = MT_Point3(
1113                                 blenderobject->loc[0]+blenderobject->dloc[0],
1114                                 blenderobject->loc[1]+blenderobject->dloc[1],
1115                                 blenderobject->loc[2]+blenderobject->dloc[2]
1116                         );
1117                         MT_Vector3 eulxyz = MT_Vector3(
1118                                 blenderobject->rot[0],
1119                                 blenderobject->rot[1],
1120                                 blenderobject->rot[2]
1121                         );
1122                         MT_Vector3 scale = MT_Vector3(
1123                                 blenderobject->size[0],
1124                                 blenderobject->size[1],
1125                                 blenderobject->size[2]
1126                         );
1127                         
1128                         gameobj->NodeSetLocalPosition(pos);
1129                         gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
1130                         gameobj->NodeSetLocalScale(scale);
1131                         gameobj->NodeUpdateGS(0,true);
1132                         
1133                         BL_ConvertIpos(blenderobject,gameobj,converter);
1134         
1135                         bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
1136         
1137                         sumolist->Add(gameobj->AddRef());
1138                         
1139                         BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
1140                         
1141         
1142                         gameobj->SetName(blenderobject->id.name);
1143         
1144                         // templist to find Root Parents (object with no parents)
1145                         templist->Add(gameobj->AddRef());
1146                         
1147                         // update children/parent hierarchy
1148                         if (blenderobject->parent != 0)
1149                         {
1150                                 // blender has an additional 'parentinverse' offset in each object
1151                                 SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
1152                         
1153                                 // define a normal parent relationship for this node.
1154                                 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
1155                                 parentinversenode->SetParentRelation(parent_relation);
1156         
1157                                 parentChildLink pclink;
1158                                 pclink.m_blenderchild = blenderobject;
1159                                 pclink.m_gamechildnode = parentinversenode;
1160                                 vec_parent_child.push_back(pclink);
1161         
1162                                 float* fl = (float*) blenderobject->parentinv;
1163                                 MT_Transform parinvtrans(fl);
1164                                 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
1165                                 parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
1166                                 parentinversenode->AddChild(gameobj->GetSGNode());
1167                         }
1168                         
1169                         // needed for python scripting
1170                         logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
1171         
1172                         converter->RegisterGameObject(gameobj, blenderobject);  
1173                         
1174                         // this was put in rapidly, needs to be looked at more closely
1175                         // only draw/use objects in active 'blender' layers
1176         
1177                         logicbrick_conversionlist->Add(gameobj->AddRef());
1178                         
1179                         if (isInActiveLayer)
1180                         {
1181                                 objectlist->Add(gameobj->AddRef());
1182                                 tf.Add(gameobj->GetSGNode());
1183                                 
1184                                 gameobj->NodeUpdateGS(0,true);
1185                                 gameobj->Bucketize();
1186                                 
1187                         }
1188                         
1189                 }
1190                         
1191                 base = base->next;
1192         }
1193
1194         if (blenderscene->camera) {
1195                 KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
1196                 
1197                 kxscene->SetActiveCamera(gamecamera);
1198         }
1199
1200         //      Set up armatures
1201         for (base = static_cast<Base*>(blenderscene->base.first); base; base=base->next){
1202                 if (base->object->type==OB_MESH){
1203                         Mesh *me = (Mesh*)base->object->data;
1204         
1205                         if (me->dvert){
1206                                 KX_GameObject *obj = converter->FindGameObject(base->object);
1207         
1208                                 if (base->object->parent && base->object->parent->type==OB_ARMATURE && base->object->partype==PARSKEL){
1209                                         KX_GameObject *par = converter->FindGameObject(base->object->parent);
1210                                         if (par)
1211                                                 ((BL_SkinDeformer*)(((BL_DeformableGameObject*)obj)->m_pDeformer))->SetArmature((BL_ArmatureObject*) par);
1212                                 }
1213                         }
1214                 }
1215         }
1216         
1217         // create hierarchy information
1218         int i;
1219         vector<parentChildLink>::iterator pcit;
1220         
1221         for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
1222         {
1223         
1224                 struct Object* blenderchild = pcit->m_blenderchild;
1225                 if (blenderchild->partype == PARVERT1)
1226                 {
1227                         // creat a new vertex parent relationship for this node.
1228                         KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
1229                         pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
1230                 } else 
1231                 if (blenderchild->partype == PARSLOW) 
1232                 {
1233                         // creat a new slow parent relationship for this node.
1234                         KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
1235                         pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
1236                 }       
1237         
1238                 struct Object* blenderparent = blenderchild->parent;
1239                 KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
1240                 if (parentobj)
1241                 {
1242                         parentobj->     GetSGNode()->AddChild(pcit->m_gamechildnode);
1243                 }
1244         }
1245         vec_parent_child.clear();
1246         
1247         // find 'root' parents (object that has not parents in SceneGraph)
1248         for (i=0;i<templist->GetCount();++i)
1249         {
1250                 KX_GameObject* gameobj = (KX_GameObject*) templist->GetValue(i);
1251                 if (gameobj->GetSGNode()->GetSGParent() == 0)
1252                 {
1253                         parentlist->Add(gameobj->AddRef());
1254                         gameobj->NodeUpdateGS(0,true);
1255                 }
1256         }
1257         
1258         // create physics information
1259         for (i=0;i<sumolist->GetCount();i++)
1260         {
1261                 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
1262                 struct Object* blenderobject = converter->FindBlenderObject(gameobj);
1263                 int nummeshes = gameobj->GetMeshCount();
1264                 RAS_MeshObject* meshobj = 0;
1265
1266                 if (nummeshes > 0)
1267                 {
1268                         meshobj = gameobj->GetMesh(0);
1269                 }
1270
1271                 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter);
1272
1273         }
1274         
1275         templist->Release();
1276         sumolist->Release();    
1277
1278
1279         int executePriority=0; /* incremented by converter routines */
1280         
1281         // convert global sound stuff
1282
1283         /* XXX, glob is the very very wrong place for this
1284          * to be, re-enable once the listener has been moved into
1285          * the scene. */
1286 #if 0
1287         SND_Scene* soundscene = kxscene->GetSoundScene();
1288         SND_SoundListener* listener = soundscene->GetListener();
1289         if (listener && glob->listener)
1290         {
1291                 listener->SetDopplerFactor(glob->listener->dopplerfactor);
1292                 listener->SetDopplerVelocity(glob->listener->dopplervelocity);
1293                 listener->SetGain(glob->listener->gain);
1294         }
1295 #endif
1296
1297         // convert world
1298         KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene->world);
1299         converter->RegisterWorldInfo(worldinfo);
1300         kxscene->SetWorldInfo(worldinfo);
1301         
1302         // convert logic bricks, sensors, controllers and actuators
1303         for (i=0;i<logicbrick_conversionlist->GetCount();i++)
1304         {
1305                 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
1306                 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
1307                 bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
1308                 BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, activeLayerBitInfo,isInActiveLayer,rendertools,converter);
1309         }
1310         for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
1311         {
1312                 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
1313                 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
1314                 bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
1315                 BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,activeLayerBitInfo,isInActiveLayer,converter);
1316         }
1317         for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
1318         {
1319                 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
1320                 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
1321                 bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
1322                 BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter);
1323         }
1324         logicbrick_conversionlist->Release();
1325         
1326         // Calculate the scene btree -
1327         // too slow - commented out.
1328         //kxscene->SetNodeTree(tf.MakeTree());
1329 }
1330