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