4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
28 * Convert blender data to ketsji
36 #pragma warning (disable : 4786)
41 #include "BL_BlenderDataConversion.h"
42 #include "KX_BlenderGL.h"
43 #include "KX_BlenderScalarInterpolator.h"
45 #include "RAS_IPolygonMaterial.h"
46 #include "KX_PolygonMaterial.h"
49 #include "ListValue.h"
51 // Collision & Fuzzics LTD
57 #include "KX_GameObject.h"
58 #include "RAS_FramingManager.h"
59 #include "RAS_MeshObject.h"
61 #include "KX_ConvertActuators.h"
62 #include "KX_ConvertControllers.h"
63 #include "KX_ConvertSensors.h"
65 #include "SCA_LogicManager.h"
66 #include "SCA_EventManager.h"
67 #include "SCA_TimeEventManager.h"
69 #include "KX_Camera.h"
70 #include "KX_EmptyObject.h"
71 #include "MT_Point3.h"
72 #include "MT_Transform.h"
73 #include "MT_MinMax.h"
74 #include "SCA_IInputDevice.h"
75 #include "RAS_TexMatrix.h"
76 #include "RAS_ICanvas.h"
77 #include "RAS_MaterialBucket.h"
78 //#include "KX_BlenderPolyMaterial.h"
79 #include "RAS_Polygon.h"
80 #include "RAS_TexVert.h"
81 #include "RAS_BucketManager.h"
82 #include "RAS_IRenderTools.h"
83 #include "BL_Material.h"
84 #include "KX_BlenderMaterial.h"
85 #include "BL_Texture.h"
87 #include "DNA_action_types.h"
89 #include "BKE_global.h"
90 #include "BKE_object.h"
91 #include "BKE_scene.h"
92 #include "BL_SkinMeshObject.h"
93 #include "BL_ShapeDeformer.h"
94 #include "BL_SkinDeformer.h"
95 #include "BL_MeshDeformer.h"
96 //#include "BL_ArmatureController.h"
98 #include "BlenderWorldInfo.h"
100 #include "KX_KetsjiEngine.h"
101 #include "KX_BlenderSceneConverter.h"
103 #include"SND_Scene.h"
104 #include "SND_SoundListener.h"
106 /* This little block needed for linking to Blender... */
108 #include "BLI_winstuff.h"
111 /* This list includes only data type definitions */
112 #include "DNA_object_types.h"
113 #include "DNA_material_types.h"
114 #include "DNA_texture_types.h"
115 #include "DNA_image_types.h"
116 #include "DNA_lamp_types.h"
117 #include "DNA_group_types.h"
118 #include "DNA_scene_types.h"
119 #include "DNA_camera_types.h"
120 #include "DNA_property_types.h"
121 #include "DNA_text_types.h"
122 #include "DNA_sensor_types.h"
123 #include "DNA_controller_types.h"
124 #include "DNA_actuator_types.h"
125 #include "DNA_mesh_types.h"
126 #include "DNA_meshdata_types.h"
127 #include "DNA_view3d_types.h"
128 #include "DNA_world_types.h"
129 #include "DNA_sound_types.h"
130 #include "DNA_key_types.h"
131 #include "DNA_armature_types.h"
132 #include "DNA_object_force.h"
134 #include "MEM_guardedalloc.h"
135 #include "BKE_utildefines.h"
137 #include "BKE_mesh.h"
138 #include "MT_Point3.h"
140 #include "BLI_arithb.h"
143 #include "BKE_customdata.h"
144 #include "BKE_cdderivedmesh.h"
145 #include "BKE_DerivedMesh.h"
148 #include "BKE_material.h" /* give_current_material */
149 /* end of blender include block */
151 #include "KX_BlenderInputDevice.h"
152 #include "KX_ConvertProperties.h"
153 #include "KX_HashedPtr.h"
156 #include "KX_ScalarInterpolator.h"
158 #include "KX_IpoConvert.h"
159 #include "SYS_System.h"
165 // defines USE_ODE to choose physics engine
166 #include "KX_ConvertPhysicsObject.h"
169 // This file defines relationships between parents and children
170 // in the game engine.
172 #include "KX_SG_NodeRelationships.h"
173 #include "KX_SG_BoneParentNodeRelationship.h"
175 #include "BL_ArmatureObject.h"
176 #include "BL_DeformableGameObject.h"
181 #include "BSE_headerbuttons.h"
182 void update_for_newframe();
183 //void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
184 //#include "BKE_ipo.h"
185 //void do_all_data_ipos(void);
190 static int default_face_mode = TF_DYNAMIC;
192 static unsigned int KX_rgbaint2uint_new(unsigned int icol)
196 unsigned int integer;
198 } out_color, in_color;
200 in_color.integer = icol;
201 out_color.cp[0] = in_color.cp[3]; // red
202 out_color.cp[1] = in_color.cp[2]; // green
203 out_color.cp[2] = in_color.cp[1]; // blue
204 out_color.cp[3] = in_color.cp[0]; // alpha
206 return out_color.integer;
209 /* Now the real converting starts... */
210 static unsigned int KX_Mcol2uint_new(MCol col)
212 /* color has to be converted without endian sensitivity. So no shifting! */
216 unsigned int integer;
218 } out_color, in_color;
221 out_color.cp[0] = in_color.cp[3]; // red
222 out_color.cp[1] = in_color.cp[2]; // green
223 out_color.cp[2] = in_color.cp[1]; // blue
224 out_color.cp[3] = in_color.cp[0]; // alpha
226 return out_color.integer;
229 static void SetDefaultFaceType(Scene* scene)
231 default_face_mode = TF_DYNAMIC;
235 for(SETLOOPER(scene,base))
237 if (base->object->type == OB_LAMP)
239 default_face_mode = TF_DYNAMIC|TF_LIGHT;
247 static void GetRGB(short type,
256 unsigned int color = 0xFFFFFFFFL;
259 case 0: // vertex colors
262 c0 = KX_Mcol2uint_new(mmcol[0]);
263 c1 = KX_Mcol2uint_new(mmcol[1]);
264 c2 = KX_Mcol2uint_new(mmcol[2]);
266 c3 = KX_Mcol2uint_new(mmcol[3]);
267 }else // backup white
269 c0 = KX_rgbaint2uint_new(color);
270 c1 = KX_rgbaint2uint_new(color);
271 c2 = KX_rgbaint2uint_new(color);
273 c3 = KX_rgbaint2uint_new( color );
278 case 1: // material rgba
283 unsigned int integer;
285 col_converter.cp[3] = (unsigned char) (mat->r*255.0);
286 col_converter.cp[2] = (unsigned char) (mat->g*255.0);
287 col_converter.cp[1] = (unsigned char) (mat->b*255.0);
288 col_converter.cp[0] = (unsigned char) (mat->alpha*255.0);
289 color = col_converter.integer;
291 c0 = KX_rgbaint2uint_new(color);
292 c1 = KX_rgbaint2uint_new(color);
293 c2 = KX_rgbaint2uint_new(color);
295 c3 = KX_rgbaint2uint_new(color);
300 c0 = KX_rgbaint2uint_new(color);
301 c1 = KX_rgbaint2uint_new(color);
302 c2 = KX_rgbaint2uint_new(color);
304 c3 = KX_rgbaint2uint_new(color);
309 typedef struct MTF_localLayer
315 // ------------------------------------
316 BL_Material* ConvertMaterial(
319 const char *tfaceName,
324 MTF_localLayer *layers,
327 //this needs some type of manager
328 BL_Material *material = new BL_Material();
330 int numchan = -1, texalpha = 0;
331 bool validmat = (mat!=0);
332 bool validface = (tface!=0);
336 type = 1; // material color
338 material->IdMode = DEFAULT_BLENDER;
339 material->glslmat = (validmat)? glslmat: false;
341 // --------------------------------
344 // use vertex colors by explicitly setting
345 if(mat->mode &MA_VERTEXCOLP || glslmat)
349 material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
351 numchan = getNumTexChannels(mat);
354 // use the face texture if
355 // 1) it is set in the buttons
356 // 2) we have a face texture and a material but no valid texture in slot 1
357 bool facetex = false;
358 if(validface && mat->mode &MA_FACETEXTURE)
360 if(validface && !mat->mtex[0])
362 if(validface && mat->mtex[0]) {
363 MTex *tmp = mat->mtex[0];
364 if(!tmp->tex || (tmp->tex && !tmp->tex->ima))
367 numchan = numchan>MAXTEX?MAXTEX:numchan;
370 for(int i=0; i<numchan; i++) {
373 if(i==0 && facetex ) {
374 Image*tmp = (Image*)(tface->tpage);
377 material->img[i] = tmp;
378 material->texname[i] = material->img[i]->id.name;
379 material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
380 material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
381 material->flag[i] |= MIPMAP;
383 if(material->img[i]->flag & IMA_REFLECT)
384 material->mapping[i].mapping |= USEREFL;
387 mttmp = getImageFromMaterial( mat, i );
388 if(mttmp && mttmp->texco &TEXCO_UV)
390 STR_String uvName = mttmp->uvname;
392 if (!uvName.IsEmpty())
393 material->mapping[i].uvCoName = mttmp->uvname;
395 material->mapping[i].uvCoName = "";
397 material->mapping[i].mapping |= USEUV;
400 if(material->ras_mode & USE_LIGHT)
401 material->ras_mode &= ~USE_LIGHT;
402 if(tface->mode & TF_LIGHT)
403 material->ras_mode |= USE_LIGHT;
408 material->img[i] = 0;
409 material->texname[i] = "";
414 mttmp = getImageFromMaterial( mat, i );
417 if( mttmp->tex->type == TEX_IMAGE ) {
418 material->mtexname[i] = mttmp->tex->id.name;
419 material->img[i] = mttmp->tex->ima;
420 if( material->img[i] ) {
422 material->texname[i] = material->img[i]->id.name;
423 material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
424 // -----------------------
425 if( mttmp->tex->imaflag &TEX_USEALPHA ) {
426 material->flag[i] |= USEALPHA;
428 // -----------------------
429 else if( mttmp->tex->imaflag &TEX_CALCALPHA ) {
430 material->flag[i] |= CALCALPHA;
432 else if(mttmp->tex->flag &TEX_NEGALPHA) {
433 material->flag[i] |= USENEGALPHA;
436 material->color_blend[i] = mttmp->colfac;
437 material->flag[i] |= ( mttmp->mapto & MAP_ALPHA )?TEXALPHA:0;
438 material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0;
440 if(!glslmat && (material->flag[i] & TEXALPHA))
444 else if(mttmp->tex->type == TEX_ENVMAP) {
445 if( mttmp->tex->env->stype == ENV_LOAD ) {
447 material->mtexname[i] = mttmp->tex->id.name;
448 EnvMap *env = mttmp->tex->env;
449 env->ima = mttmp->tex->ima;
450 material->cubemap[i] = env;
452 if (material->cubemap[i])
454 if (!material->cubemap[i]->cube[0])
455 BL_Texture::SplitEnvMap(material->cubemap[i]);
457 material->texname[i]= material->cubemap[i]->ima->id.name;
458 material->mapping[i].mapping |= USEENV;
462 material->flag[i] |= (mat->ipo!=0)?HASIPO:0;
463 /// --------------------------------
465 material->mapping[i].mapping |= ( mttmp->texco & TEXCO_REFL )?USEREFL:0;
467 if(mttmp->texco & TEXCO_OBJECT) {
468 material->mapping[i].mapping |= USEOBJ;
470 material->mapping[i].objconame = mttmp->object->id.name;
472 else if(mttmp->texco &TEXCO_REFL)
473 material->mapping[i].mapping |= USEREFL;
474 else if(mttmp->texco &(TEXCO_ORCO|TEXCO_GLOB))
475 material->mapping[i].mapping |= USEORCO;
476 else if(mttmp->texco &TEXCO_UV)
478 STR_String uvName = mttmp->uvname;
480 if (!uvName.IsEmpty())
481 material->mapping[i].uvCoName = mttmp->uvname;
483 material->mapping[i].uvCoName = "";
484 material->mapping[i].mapping |= USEUV;
486 else if(mttmp->texco &TEXCO_NORM)
487 material->mapping[i].mapping |= USENORM;
488 else if(mttmp->texco &TEXCO_TANGENT)
489 material->mapping[i].mapping |= USETANG;
491 material->mapping[i].mapping |= DISABLE;
493 material->mapping[i].scale[0] = mttmp->size[0];
494 material->mapping[i].scale[1] = mttmp->size[1];
495 material->mapping[i].scale[2] = mttmp->size[2];
496 material->mapping[i].offsets[0] = mttmp->ofs[0];
497 material->mapping[i].offsets[1] = mttmp->ofs[1];
498 material->mapping[i].offsets[2] = mttmp->ofs[2];
500 material->mapping[i].projplane[0] = mttmp->projx;
501 material->mapping[i].projplane[1] = mttmp->projy;
502 material->mapping[i].projplane[2] = mttmp->projz;
503 /// --------------------------------
505 switch( mttmp->blendtype ) {
507 material->blend_mode[i] = BLEND_MIX;
510 material->blend_mode[i] = BLEND_MUL;
513 material->blend_mode[i] = BLEND_ADD;
516 material->blend_mode[i] = BLEND_SUB;
519 material->blend_mode[i] = BLEND_SCR;
527 // above one tex the switches here
529 switch(valid_index) {
531 material->IdMode = DEFAULT_BLENDER;
534 material->IdMode = ONETEX;
537 material->IdMode = GREATERTHAN2;
540 material->SetUsers(mat->id.us);
542 material->num_enabled = valid_index;
544 material->speccolor[0] = mat->specr;
545 material->speccolor[1] = mat->specg;
546 material->speccolor[2] = mat->specb;
547 material->hard = (float)mat->har/4.0f;
548 material->matcolor[0] = mat->r;
549 material->matcolor[1] = mat->g;
550 material->matcolor[2] = mat->b;
551 material->matcolor[3] = mat->alpha;
552 material->alpha = mat->alpha;
553 material->emit = mat->emit;
554 material->spec_f = mat->spec;
555 material->ref = mat->ref;
556 material->amb = mat->amb;
558 material->ras_mode |= (mat->mode & MA_WIRE)? WIRE: 0;
563 // check for tface tex to fallback on
567 if(tface->mode) material->ras_mode |= USE_LIGHT;
569 material->img[0] = (Image*)(tface->tpage);
570 // ------------------------
571 if(material->img[0]) {
572 material->texname[0] = material->img[0]->id.name;
573 material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
574 material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
575 material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
579 material->SetUsers(-1);
580 material->num_enabled = valid;
581 material->IdMode = TEXFACE;
582 material->speccolor[0] = 1.f;
583 material->speccolor[1] = 1.f;
584 material->speccolor[2] = 1.f;
585 material->hard = 35.f;
586 material->matcolor[0] = 0.5f;
587 material->matcolor[1] = 0.5f;
588 material->matcolor[2] = 0.5f;
589 material->spec_f = 0.5f;
590 material->ref = 0.8f;
594 const char *uvName = "", *uv2Name = "";
597 uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f);
601 material->ras_mode |= !(
602 (mface->flag & ME_HIDE) ||
603 (tface->mode & TF_INVISIBLE)
606 material->transp = tface->transp;
607 material->tile = tface->tile;
608 material->mode = tface->mode;
610 uv[0].setValue(tface->uv[0]);
611 uv[1].setValue(tface->uv[1]);
612 uv[2].setValue(tface->uv[2]);
615 uv[3].setValue(tface->uv[3]);
621 material->ras_mode |= (POLY_VIS| (validmat?0:USE_LIGHT));
622 material->mode = default_face_mode;
623 material->transp = TF_SOLID;
626 uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f);
629 // with ztransp enabled, enforce alpha blending mode
630 if(validmat && (mat->mode & MA_ZTRA) && (material->transp == TF_SOLID))
631 material->transp = TF_ALPHA;
633 // always zsort alpha + add
634 if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) && (material->transp != TF_CLIP)) {
635 material->ras_mode |= ALPHA;
636 material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
640 material->ras_mode |= (material->mode & TF_DYNAMIC)? COLLIDER: 0;
642 // these flags are irrelevant at this point, remove so they
643 // don't hurt material bucketing
644 material->mode &= ~(TF_DYNAMIC|TF_ALPHASORT|TF_TEX);
649 bool isFirstSet = true;
651 // only two sets implemented, but any of the eight
652 // sets can make up the two layers
653 for (int vind = 0; vind<material->num_enabled; vind++)
655 BL_Mapping &map = material->mapping[vind];
657 if (map.uvCoName.IsEmpty())
661 for (int lay=0; lay<MAX_MTFACE; lay++)
663 MTF_localLayer& layer = layers[lay];
664 if (layer.face == 0) break;
666 if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
670 uvSet[0].setValue(layer.face->uv[0]);
671 uvSet[1].setValue(layer.face->uv[1]);
672 uvSet[2].setValue(layer.face->uv[2]);
675 uvSet[3].setValue(layer.face->uv[3]);
677 uvSet[3].setValue(0.0f, 0.0f);
681 uv[0] = uvSet[0]; uv[1] = uvSet[1];
682 uv[2] = uvSet[2]; uv[3] = uvSet[3];
686 else if(strcmp(layer.name, uvName) != 0)
688 uv2[0] = uvSet[0]; uv2[1] = uvSet[1];
689 uv2[2] = uvSet[2]; uv2[3] = uvSet[3];
690 map.mapping |= USECUSTOMUV;
691 uv2Name = layer.name;
700 GetRGB(type,mface,mmcol,mat,rgb[0],rgb[1],rgb[2], rgb[3]);
702 // swap the material color, so MCol on TF_BMFONT works
703 if (validmat && type==1 && (tface && tface->mode & TF_BMFONT))
705 rgb[0] = KX_rgbaint2uint_new(rgb[0]);
706 rgb[1] = KX_rgbaint2uint_new(rgb[1]);
707 rgb[2] = KX_rgbaint2uint_new(rgb[2]);
708 rgb[3] = KX_rgbaint2uint_new(rgb[3]);
711 material->SetConversionRGB(rgb);
712 material->SetConversionUV(uvName, uv);
713 material->SetConversionUV2(uv2Name, uv2);
716 material->matname =(mat->id.name);
718 material->tface = tface;
719 material->material = mat;
724 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter)
726 RAS_MeshObject *meshobj;
727 bool skinMesh = false;
728 int lightlayer = blenderobj->lay;
730 // Get DerivedMesh data
731 DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj);
733 MVert *mvert = dm->getVertArray(dm);
734 int totvert = dm->getNumVerts(dm);
736 MFace *mface = dm->getFaceArray(dm);
737 MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE));
738 MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL));
739 float (*tangent)[3] = NULL;
740 int totface = dm->getNumFaces(dm);
741 const char *tfaceName = "";
744 DM_add_tangent_layer(dm);
745 tangent = (float(*)[3])dm->getFaceDataArray(dm, CD_TANGENT);
748 // Determine if we need to make a skinned mesh
749 if (mesh->dvert || mesh->key || ((blenderobj->gameflag & OB_SOFT_BODY) != 0))
751 meshobj = new BL_SkinMeshObject(mesh, lightlayer);
755 meshobj = new RAS_MeshObject(mesh, lightlayer);
757 // Extract avaiable layers
758 MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
759 for (int lay=0; lay<MAX_MTFACE; lay++) {
760 layers[lay].face = 0;
761 layers[lay].name = "";
765 for (int i=0; i<dm->faceData.totlayer; i++)
767 if (dm->faceData.layers[i].type == CD_MTFACE)
769 assert(validLayers <= 8);
771 layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data);
772 layers[validLayers].name = dm->faceData.layers[i].name;
773 if(tface == layers[validLayers].face)
774 tfaceName = layers[validLayers].name;
779 meshobj->SetName(mesh->id.name);
780 meshobj->m_sharedvertex_map.resize(totvert);
782 for (int f=0;f<totface;f++,mface++)
785 bool collider = true;
786 MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
787 MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
788 unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
790 MT_Point3 pt0, pt1, pt2, pt3;
791 MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0);
792 MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
794 /* get coordinates, normals and tangents */
795 pt0.setValue(mvert[mface->v1].co);
796 pt1.setValue(mvert[mface->v2].co);
797 pt2.setValue(mvert[mface->v3].co);
798 if (mface->v4) pt3.setValue(mvert[mface->v4].co);
800 if(mface->flag & ME_SMOOTH) {
801 float n0[3], n1[3], n2[3], n3[3];
803 NormalShortToFloat(n0, mvert[mface->v1].no);
804 NormalShortToFloat(n1, mvert[mface->v2].no);
805 NormalShortToFloat(n2, mvert[mface->v3].no);
811 NormalShortToFloat(n3, mvert[mface->v4].no);
819 CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
820 mvert[mface->v3].co, mvert[mface->v4].co, fno);
822 CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
823 mvert[mface->v3].co, fno);
825 no0 = no1 = no2 = no3 = MT_Vector3(fno);
829 tan0 = tangent[f*4 + 0];
830 tan1 = tangent[f*4 + 1];
831 tan2 = tangent[f*4 + 2];
834 tan3 = tangent[f*4 + 3];
838 ma = give_current_material(blenderobj, mface->mat_nr+1);
842 RAS_IPolyMaterial* polymat = NULL;
843 BL_Material *bl_mat = NULL;
845 if(converter->GetMaterials()) {
846 /* do Blender Multitexture and Blender GLSL materials */
850 /* first is the BL_Material */
851 bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol,
852 lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
854 bl_mat->material_index = (int)mface->mat_nr;
856 visible = ((bl_mat->ras_mode & POLY_VIS)!=0);
857 collider = ((bl_mat->ras_mode & COLLIDER)!=0);
859 /* vertex colors and uv's were stored in bl_mat temporarily */
860 bl_mat->GetConversionRGB(rgb);
861 rgb0 = rgb[0]; rgb1 = rgb[1];
862 rgb2 = rgb[2]; rgb3 = rgb[3];
864 bl_mat->GetConversionUV(uv);
865 uv0 = uv[0]; uv1 = uv[1];
866 uv2 = uv[2]; uv3 = uv[3];
868 bl_mat->GetConversionUV2(uv);
869 uv20 = uv[0]; uv21 = uv[1];
870 uv22 = uv[2]; uv23 = uv[3];
872 /* then the KX_BlenderMaterial */
873 polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer);
876 /* do Texture Face materials */
877 Image* bima = (tface)? (Image*)tface->tpage: NULL;
878 STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
881 short mode=0, tile=0;
882 int tilexrep=4,tileyrep = 4;
885 tilexrep = bima->xrep;
886 tileyrep = bima->yrep;
889 /* get tface properties if available */
891 /* TF_DYNAMIC means the polygon is a collision face */
892 collider = ((tface->mode & TF_DYNAMIC) != 0);
893 transp = tface->transp;
897 visible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
899 uv0.setValue(tface->uv[0]);
900 uv1.setValue(tface->uv[1]);
901 uv2.setValue(tface->uv[2]);
904 uv3.setValue(tface->uv[3]);
907 /* no texfaces, set COLLSION true and everything else FALSE */
908 mode = default_face_mode;
913 /* get vertex colors */
915 /* we have vertex colors */
916 rgb0 = KX_Mcol2uint_new(mcol[0]);
917 rgb1 = KX_Mcol2uint_new(mcol[1]);
918 rgb2 = KX_Mcol2uint_new(mcol[2]);
921 rgb3 = KX_Mcol2uint_new(mcol[3]);
924 /* no vertex colors, take from material, otherwise white */
925 unsigned int color = 0xFFFFFFFFL;
932 unsigned int integer;
935 col_converter.cp[3] = (unsigned char) (ma->r*255.0);
936 col_converter.cp[2] = (unsigned char) (ma->g*255.0);
937 col_converter.cp[1] = (unsigned char) (ma->b*255.0);
938 col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
940 color = col_converter.integer;
943 rgb0 = KX_rgbaint2uint_new(color);
944 rgb1 = KX_rgbaint2uint_new(color);
945 rgb2 = KX_rgbaint2uint_new(color);
948 rgb3 = KX_rgbaint2uint_new(color);
951 // only zsort alpha + add
952 bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
953 bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
955 polymat = new KX_PolygonMaterial(imastr, ma,
956 tile, tilexrep, tileyrep,
957 mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol);
960 polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
961 polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
962 polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
965 polymat->m_specular.setValue(0.0f,0.0f,0.0f);
966 polymat->m_shininess = 35.0;
970 /* mark face as flat, so vertices are split */
971 bool flat = (mface->flag & ME_SMOOTH) == 0;
973 // see if a bucket was reused or a new one was created
974 // this way only one KX_BlenderMaterial object has to exist per bucket
976 RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
978 // this is needed to free up memory afterwards
979 converter->RegisterPolyMaterial(polymat);
980 if(converter->GetMaterials()) {
981 converter->RegisterBlenderMaterial(bl_mat);
984 // delete the material objects since they are no longer needed
985 // from now on, use the polygon material from the material bucket
987 if(converter->GetMaterials()) {
990 polymat = bucket->GetPolyMaterial();
993 int nverts = (mface->v4)? 4: 3;
994 RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts);
996 poly->SetVisible(visible);
997 poly->SetCollider(collider);
998 //poly->SetEdgeCode(mface->edcode);
1000 meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
1001 meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
1002 meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
1005 meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
1013 for (int lay=0; lay<MAX_MTFACE; lay++)
1015 MTF_localLayer &layer = layers[lay];
1016 if (layer.face == 0) break;
1021 meshobj->m_sharedvertex_map.clear();
1023 // pre calculate texture generation
1024 for(list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
1025 mit != meshobj->GetLastMaterial(); ++ mit) {
1026 mit->m_bucket->GetPolyMaterial()->OnConstruction();
1039 static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject,
1042 PHY_MaterialProps *materialProps = new PHY_MaterialProps;
1044 MT_assert(materialProps && "Create physics material properties failed");
1046 Material* blendermat = give_current_material(blenderobject, 0);
1050 MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f);
1052 materialProps->m_restitution = blendermat->reflect;
1053 materialProps->m_friction = blendermat->friction;
1054 materialProps->m_fh_spring = blendermat->fh;
1055 materialProps->m_fh_damping = blendermat->xyfrict;
1056 materialProps->m_fh_distance = blendermat->fhdist;
1057 materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
1060 //give some defaults
1061 materialProps->m_restitution = 0.f;
1062 materialProps->m_friction = 0.5;
1063 materialProps->m_fh_spring = 0.f;
1064 materialProps->m_fh_damping = 0.f;
1065 materialProps->m_fh_distance = 0.f;
1066 materialProps->m_fh_normal = false;
1070 return materialProps;
1073 static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject,
1076 PHY_ShapeProps *shapeProps = new PHY_ShapeProps;
1078 MT_assert(shapeProps);
1080 shapeProps->m_mass = blenderobject->mass;
1082 // This needs to be fixed in blender. For now, we use:
1084 // in Blender, inertia stands for the size value which is equivalent to
1085 // the sphere radius
1086 shapeProps->m_inertia = blenderobject->formfactor;
1088 MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
1089 MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
1091 shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
1092 shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
1094 shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0];
1095 shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
1096 shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2];
1097 shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0);
1099 shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0;
1100 shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
1109 //////////////////////////////////////////////////////////
1113 static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
1118 float mloc[3], msize[3];
1121 if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
1124 INIT_MINMAX(min, max);
1126 if (!loc) loc= mloc;
1127 if (!size) size= msize;
1130 for(a=0; a<me->totvert; a++, mvert++) {
1131 DO_MINMAX(mvert->co, min, max);
1135 loc[0]= (min[0]+max[0])/2.0;
1136 loc[1]= (min[1]+max[1])/2.0;
1137 loc[2]= (min[2]+max[2])/2.0;
1139 size[0]= (max[0]-min[0])/2.0;
1140 size[1]= (max[1]-min[1])/2.0;
1141 size[2]= (max[2]-min[2])/2.0;
1144 loc[0]= loc[1]= loc[2]= 0.0;
1145 size[0]= size[1]= size[2]= 0.0;
1148 bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
1149 bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
1151 bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
1152 bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
1154 bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
1155 bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
1158 for (a=0, mvert = me->mvert; a < me->totvert; a++, mvert++)
1160 float vert_radius = MT_Vector3(mvert->co).length2();
1161 if (vert_radius > radius)
1162 radius = vert_radius;
1164 return sqrt(radius);
1170 static void my_tex_space_mesh(Mesh *me)
1173 float *fp, loc[3], size[3], min[3], max[3];
1176 my_boundbox_mesh(me, loc, size);
1178 if(me->texflag & AUTOSPACE) {
1180 kb= me->key->refkey;
1183 INIT_MINMAX(min, max);
1185 fp= (float *)kb->data;
1186 for(a=0; a<kb->totelem; a++, fp+=3) {
1187 DO_MINMAX(fp, min, max);
1190 loc[0]= (min[0]+max[0])/2.0; loc[1]= (min[1]+max[1])/2.0; loc[2]= (min[2]+max[2])/2.0;
1191 size[0]= (max[0]-min[0])/2.0; size[1]= (max[1]-min[1])/2.0; size[2]= (max[2]-min[2])/2.0;
1194 loc[0]= loc[1]= loc[2]= 0.0;
1195 size[0]= size[1]= size[2]= 0.0;
1201 VECCOPY(me->loc, loc);
1202 VECCOPY(me->size, size);
1203 me->rot[0]= me->rot[1]= me->rot[2]= 0.0;
1205 if(me->size[0]==0.0) me->size[0]= 1.0;
1206 else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001;
1207 else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001;
1209 if(me->size[1]==0.0) me->size[1]= 1.0;
1210 else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001;
1211 else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001;
1213 if(me->size[2]==0.0) me->size[2]= 1.0;
1214 else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001;
1215 else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001;
1220 static void my_get_local_bounds(Object *ob, float *center, float *size)
1223 /* uses boundbox, function used by Ketsji */
1227 bb= ( (Mesh *)ob->data )->bb;
1230 my_tex_space_mesh((struct Mesh *)ob->data);
1231 bb= ( (Mesh *)ob->data )->bb;
1237 center[0]= center[1]= center[2]= 0.0;
1238 size[0] = size[1]=size[2]=0.0;
1247 center[0]= center[1]= center[2]= 0.0;
1248 size[0] = size[1]=size[2]=1.0;
1252 size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
1253 size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
1254 size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
1256 center[0]= 0.5*(bb->vec[0][0] + bb->vec[4][0]);
1257 center[1]= 0.5*(bb->vec[0][1] + bb->vec[2][1]);
1258 center[2]= 0.5*(bb->vec[0][2] + bb->vec[1][2]);
1265 //////////////////////////////////////////////////////
1271 void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
1272 struct Object* blenderobject,
1273 RAS_MeshObject* meshobj,
1275 int activeLayerBitInfo,
1276 e_PhysicsEngine physics_engine,
1277 KX_BlenderSceneConverter *converter,
1278 bool processCompoundChildren
1282 //SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
1283 //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
1284 //bool bRigidBody = (userigidbody == 0);
1286 // object has physics representation?
1287 if (!(blenderobject->gameflag & OB_COLLISION))
1290 // get Root Parent of blenderobject
1291 struct Object* parent= blenderobject->parent;
1292 while(parent && parent->parent) {
1293 parent= parent->parent;
1296 bool isCompoundChild = false;
1298 if (parent && (parent->gameflag & OB_DYNAMIC)) {
1300 if ((parent->gameflag & OB_CHILD) != 0)
1302 isCompoundChild = true;
1305 if (processCompoundChildren != isCompoundChild)
1309 PHY_ShapeProps* shapeprops =
1310 CreateShapePropsFromBlenderObject(blenderobject,
1314 PHY_MaterialProps* smmaterial =
1315 CreateMaterialFromBlenderObject(blenderobject, kxscene);
1317 KX_ObjectProperties objprop;
1318 objprop.m_lockXaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0;
1319 objprop.m_lockYaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0;
1320 objprop.m_lockZaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0;
1321 objprop.m_lockXRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0;
1322 objprop.m_lockYRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0;
1323 objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0;
1325 objprop.m_isCompoundChild = isCompoundChild;
1326 objprop.m_hasCompoundChildren = (blenderobject->gameflag & OB_CHILD) != 0;
1327 objprop.m_margin = blenderobject->margin;
1328 // ACTOR is now a separate feature
1329 objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
1330 objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
1331 objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
1332 objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
1334 if (objprop.m_softbody)
1336 ///for game soft bodies
1337 if (blenderobject->bsoft)
1339 objprop.m_gamesoftFlag = blenderobject->bsoft->flag;
1341 objprop.m_soft_linStiff = blenderobject->bsoft->linStiff;
1342 objprop.m_soft_angStiff = blenderobject->bsoft->angStiff; /* angular stiffness 0..1 */
1343 objprop.m_soft_volume= blenderobject->bsoft->volume; /* volume preservation 0..1 */
1345 objprop.m_soft_viterations= blenderobject->bsoft->viterations; /* Velocities solver iterations */
1346 objprop.m_soft_piterations= blenderobject->bsoft->piterations; /* Positions solver iterations */
1347 objprop.m_soft_diterations= blenderobject->bsoft->diterations; /* Drift solver iterations */
1348 objprop.m_soft_citerations= blenderobject->bsoft->citerations; /* Cluster solver iterations */
1350 objprop.m_soft_kSRHR_CL= blenderobject->bsoft->kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */
1351 objprop.m_soft_kSKHR_CL= blenderobject->bsoft->kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */
1352 objprop.m_soft_kSSHR_CL= blenderobject->bsoft->kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */
1353 objprop.m_soft_kSR_SPLT_CL= blenderobject->bsoft->kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1355 objprop.m_soft_kSK_SPLT_CL= blenderobject->bsoft->kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1356 objprop.m_soft_kSS_SPLT_CL= blenderobject->bsoft->kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1357 objprop.m_soft_kVCF= blenderobject->bsoft->kVCF; /* Velocities correction factor (Baumgarte) */
1358 objprop.m_soft_kDP= blenderobject->bsoft->kDP; /* Damping coefficient [0,1] */
1360 objprop.m_soft_kDG= blenderobject->bsoft->kDG; /* Drag coefficient [0,+inf] */
1361 objprop.m_soft_kLF= blenderobject->bsoft->kLF; /* Lift coefficient [0,+inf] */
1362 objprop.m_soft_kPR= blenderobject->bsoft->kPR; /* Pressure coefficient [-inf,+inf] */
1363 objprop.m_soft_kVC= blenderobject->bsoft->kVC; /* Volume conversation coefficient [0,+inf] */
1365 objprop.m_soft_kDF= blenderobject->bsoft->kDF; /* Dynamic friction coefficient [0,1] */
1366 objprop.m_soft_kMT= blenderobject->bsoft->kMT; /* Pose matching coefficient [0,1] */
1367 objprop.m_soft_kCHR= blenderobject->bsoft->kCHR; /* Rigid contacts hardness [0,1] */
1368 objprop.m_soft_kKHR= blenderobject->bsoft->kKHR; /* Kinetic contacts hardness [0,1] */
1370 objprop.m_soft_kSHR= blenderobject->bsoft->kSHR; /* Soft contacts hardness [0,1] */
1371 objprop.m_soft_kAHR= blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */
1372 objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
1373 objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/
1377 objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT;
1379 objprop.m_soft_linStiff = 0.5;;
1380 objprop.m_soft_angStiff = 1.f; /* angular stiffness 0..1 */
1381 objprop.m_soft_volume= 1.f; /* volume preservation 0..1 */
1384 objprop.m_soft_viterations= 0;
1385 objprop.m_soft_piterations= 1;
1386 objprop.m_soft_diterations= 0;
1387 objprop.m_soft_citerations= 4;
1389 objprop.m_soft_kSRHR_CL= 0.1f;
1390 objprop.m_soft_kSKHR_CL= 1.f;
1391 objprop.m_soft_kSSHR_CL= 0.5;
1392 objprop.m_soft_kSR_SPLT_CL= 0.5f;
1394 objprop.m_soft_kSK_SPLT_CL= 0.5f;
1395 objprop.m_soft_kSS_SPLT_CL= 0.5f;
1396 objprop.m_soft_kVCF= 1;
1397 objprop.m_soft_kDP= 0;
1399 objprop.m_soft_kDG= 0;
1400 objprop.m_soft_kLF= 0;
1401 objprop.m_soft_kPR= 0;
1402 objprop.m_soft_kVC= 0;
1404 objprop.m_soft_kDF= 0.2f;
1405 objprop.m_soft_kMT= 0.05f;
1406 objprop.m_soft_kCHR= 1.0f;
1407 objprop.m_soft_kKHR= 0.1f;
1409 objprop.m_soft_kSHR= 1.f;
1410 objprop.m_soft_kAHR= 0.7f;
1411 objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS;
1412 objprop.m_soft_numclusteriterations= 16;
1416 objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
1417 objprop.m_disableSleeping = (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0;//abuse the OB_COLLISION_RESPONSE flag
1418 //mmm, for now, taks this for the size of the dynamicobject
1419 // Blender uses inertia for radius of dynamic object
1420 objprop.m_radius = blenderobject->inertia;
1421 objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
1422 objprop.m_dynamic_parent=NULL;
1423 objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
1424 objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
1426 if ((blenderobject->gameflag & OB_SOFT_BODY) && !(blenderobject->gameflag & OB_BOUNDS))
1428 objprop.m_boundclass = KX_BOUNDMESH;
1432 my_get_local_bounds(blenderobject,objprop.m_boundobject.box.m_center,bb.m_extends);
1433 if (blenderobject->gameflag & OB_BOUNDS)
1435 switch (blenderobject->boundtype)
1438 objprop.m_boundclass = KX_BOUNDBOX;
1439 //mmm, has to be divided by 2 to be proper extends
1440 objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_extends[0];
1441 objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1];
1442 objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2];
1444 case OB_BOUND_POLYT:
1445 if (blenderobject->type == OB_MESH)
1447 objprop.m_boundclass = KX_BOUNDPOLYTOPE;
1450 // Object is not a mesh... fall through OB_BOUND_POLYH to
1452 case OB_BOUND_POLYH:
1453 if (blenderobject->type == OB_MESH)
1455 objprop.m_boundclass = KX_BOUNDMESH;
1458 // Object is not a mesh... can't use polyheder.
1459 // Fall through and become a sphere.
1460 case OB_BOUND_SPHERE:
1462 objprop.m_boundclass = KX_BOUNDSPHERE;
1463 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2]));
1466 case OB_BOUND_CYLINDER:
1468 objprop.m_boundclass = KX_BOUNDCYLINDER;
1469 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1470 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
1475 objprop.m_boundclass = KX_BOUNDCONE;
1476 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1477 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
1484 if (parent && (parent->gameflag & OB_DYNAMIC)) {
1486 KX_GameObject *parentgameobject = converter->FindGameObject(parent);
1487 objprop.m_dynamic_parent = parentgameobject;
1488 //cannot be dynamic:
1489 objprop.m_dyna = false;
1490 shapeprops->m_mass = 0.f;
1494 objprop.m_concave = (blenderobject->boundtype & 4) != 0;
1496 switch (physics_engine)
1500 KX_ConvertBulletObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
1504 #ifdef USE_SUMO_SOLID
1506 KX_ConvertSumoObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
1512 KX_ConvertODEEngineObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
1517 //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
1532 static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
1533 RAS_LightObject lightobj;
1534 KX_LightObject *gamelight;
1536 lightobj.m_att1 = la->att1;
1537 lightobj.m_att2 = (la->mode & LA_QUAD)?la->att2:0.0;
1538 lightobj.m_red = la->r;
1539 lightobj.m_green = la->g;
1540 lightobj.m_blue = la->b;
1541 lightobj.m_distance = la->dist;
1542 lightobj.m_energy = la->energy;
1543 lightobj.m_layer = layerflag;
1544 lightobj.m_spotblend = la->spotblend;
1545 lightobj.m_spotsize = la->spotsize;
1547 lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
1548 lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
1550 if (la->mode & LA_NEG)
1552 lightobj.m_red = -lightobj.m_red;
1553 lightobj.m_green = -lightobj.m_green;
1554 lightobj.m_blue = -lightobj.m_blue;
1557 if (la->type==LA_SUN) {
1558 lightobj.m_type = RAS_LightObject::LIGHT_SUN;
1559 } else if (la->type==LA_SPOT) {
1560 lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
1562 lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
1565 gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools,
1566 lightobj, converter->GetGLSLMaterials());
1568 BL_ConvertLampIpos(la, gamelight, converter);
1573 static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
1574 Camera* ca = static_cast<Camera*>(ob->data);
1575 RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob));
1576 KX_Camera *gamecamera;
1578 gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
1579 gamecamera->SetName(ca->id.name + 2);
1581 BL_ConvertCameraIpos(ca, gamecamera, converter);
1586 static KX_GameObject *gameobject_from_blenderobject(
1589 RAS_IRenderTools *rendertools,
1590 KX_BlenderSceneConverter *converter,
1591 Scene *blenderscene)
1593 KX_GameObject *gameobj = NULL;
1599 KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
1600 gameobj = gamelight;
1602 gamelight->AddRef();
1603 kxscene->GetLightList()->Add(gamelight);
1610 KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, converter);
1611 gameobj = gamecamera;
1613 //don't add a reference: the camera list in kxscene->m_cameras is not released at the end
1614 //gamecamera->AddRef();
1615 kxscene->AddCamera(gamecamera);
1622 Mesh* mesh = static_cast<Mesh*>(ob->data);
1623 RAS_MeshObject* meshobj = converter->FindGameMesh(mesh, ob->lay);
1624 float center[3], extents[3];
1625 float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents);
1628 meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter);
1629 converter->RegisterGameMesh(meshobj, mesh);
1632 // needed for python scripting
1633 kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
1635 gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_callbacks);
1637 // set transformation
1638 gameobj->AddMesh(meshobj);
1640 // for all objects: check whether they want to
1641 // respond to updates
1642 bool ignoreActivityCulling =
1643 ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
1644 gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
1646 // two options exists for deform: shape keys and armature
1647 // only support relative shape key
1648 bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE;
1649 bool bHasDvert = mesh->dvert != NULL && ob->defbase.first;
1650 bool bHasArmature = (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && bHasDvert);
1653 // not that we can have shape keys without dvert!
1654 BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj,
1655 ob, (BL_SkinMeshObject*)meshobj);
1656 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1658 dcont->LoadShapeDrivers(ob->parent);
1659 } else if (bHasArmature) {
1660 BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
1661 ob, (BL_SkinMeshObject*)meshobj);
1662 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1663 } else if (bHasDvert) {
1664 // this case correspond to a mesh that can potentially deform but not with the
1665 // object to which it is attached for the moment. A skin mesh was created in
1666 // BL_ConvertMesh() so must create a deformer too!
1667 BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
1668 ob, (BL_SkinMeshObject*)meshobj);
1669 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1672 MT_Point3 min = MT_Point3(center) - MT_Vector3(extents);
1673 MT_Point3 max = MT_Point3(center) + MT_Vector3(extents);
1674 SG_BBox bbox = SG_BBox(min, max);
1675 gameobj->GetSGNode()->SetBBox(bbox);
1676 gameobj->GetSGNode()->SetRadius(radius);
1683 gameobj = new BL_ArmatureObject(
1685 KX_Scene::m_callbacks,
1688 /* Get the current pose from the armature object and apply it as the rest pose */
1694 gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks);
1695 // set transformation
1701 gameobj->SetPhysicsEnvironment(kxscene->GetPhysicsEnvironment());
1702 gameobj->SetLayer(ob->lay);
1703 gameobj->SetBlenderObject(ob);
1704 /* set the visibility state based on the objects render option in the outliner */
1705 if(ob->restrictflag & OB_RESTRICT_RENDER) gameobj->SetVisible(0, 0);
1710 struct parentChildLink {
1711 struct Object* m_blenderchild;
1712 SG_Node* m_gamechildnode;
1715 #include "DNA_constraint_types.h"
1716 #include "BIF_editconstraint.h"
1718 bPoseChannel *get_active_posechannel2 (Object *ob)
1720 bArmature *arm= (bArmature*)ob->data;
1721 bPoseChannel *pchan;
1724 for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1725 if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer))
1732 ListBase *get_active_constraints2(Object *ob)
1737 if (ob->flag & OB_POSEMODE) {
1738 bPoseChannel *pchan;
1740 pchan = get_active_posechannel2(ob);
1742 return &pchan->constraints;
1745 return &ob->constraints;
1751 void RBJconstraints(Object *ob)//not used
1754 bConstraint *curcon;
1756 conlist = get_active_constraints2(ob);
1759 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) {
1761 printf("%i\n",curcon->type);
1768 #include "PHY_IPhysicsEnvironment.h"
1769 #include "KX_IPhysicsController.h"
1770 #include "PHY_DynamicTypes.h"
1772 KX_IPhysicsController* getPhId(CListValue* sumolist,STR_String busc){//not used
1774 for (int j=0;j<sumolist->GetCount();j++)
1776 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j);
1777 if (gameobje->GetName()==busc)
1778 return gameobje->GetPhysicsController();
1785 KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){
1787 for (int j=0;j<sumolist->GetCount();j++)
1789 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j);
1790 if (gameobje->GetName()==busc)
1798 // convert blender objects into ketsji gameobjects
1799 void BL_ConvertBlenderObjects(struct Main* maggie,
1800 const STR_String& scenename,
1802 KX_KetsjiEngine* ketsjiEngine,
1803 e_PhysicsEngine physics_engine,
1804 PyObject* pythondictionary,
1805 SCA_IInputDevice* keydev,
1806 RAS_IRenderTools* rendertools,
1807 RAS_ICanvas* canvas,
1808 KX_BlenderSceneConverter* converter,
1809 bool alwaysUseExpandFraming
1813 Scene *blenderscene = converter->GetBlenderSceneForName(scenename);
1818 // Get the frame settings of the canvas.
1819 // Get the aspect ratio of the canvas as designed by the user.
1821 RAS_FrameSettings::RAS_FrameType frame_type;
1824 vector<MT_Vector3> inivel,iniang;
1825 set<Group*> grouplist; // list of groups to be converted
1826 set<Object*> allblobj; // all objects converted
1827 set<Object*> groupobj; // objects from groups (never in active layer)
1829 if (alwaysUseExpandFraming) {
1830 frame_type = RAS_FrameSettings::e_frame_extend;
1831 aspect_width = canvas->GetWidth();
1832 aspect_height = canvas->GetHeight();
1834 if (blenderscene->framing.type == SCE_GAMEFRAMING_BARS) {
1835 frame_type = RAS_FrameSettings::e_frame_bars;
1836 } else if (blenderscene->framing.type == SCE_GAMEFRAMING_EXTEND) {
1837 frame_type = RAS_FrameSettings::e_frame_extend;
1839 frame_type = RAS_FrameSettings::e_frame_scale;
1842 aspect_width = blenderscene->r.xsch;
1843 aspect_height = blenderscene->r.ysch;
1846 RAS_FrameSettings frame_settings(
1848 blenderscene->framing.col[0],
1849 blenderscene->framing.col[1],
1850 blenderscene->framing.col[2],
1854 kxscene->SetFramingType(frame_settings);
1856 kxscene->SetGravity(MT_Vector3(0,0,(blenderscene->world != NULL) ? -blenderscene->world->gravity : -9.8));
1858 /* set activity culling parameters */
1859 if (blenderscene->world) {
1860 kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
1861 kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
1863 kxscene->SetActivityCulling(false);
1866 int activeLayerBitInfo = blenderscene->lay;
1868 // templist to find Root Parents (object with no parents)
1869 CListValue* templist = new CListValue();
1870 CListValue* sumolist = new CListValue();
1872 vector<parentChildLink> vec_parent_child;
1874 CListValue* objectlist = kxscene->GetObjectList();
1875 CListValue* inactivelist = kxscene->GetInactiveList();
1876 CListValue* parentlist = kxscene->GetRootParentList();
1878 SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
1879 SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
1881 CListValue* logicbrick_conversionlist = new CListValue();
1883 //SG_TreeFactory tf;
1885 // Convert actions to actionmap
1887 for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
1889 logicmgr->RegisterActionName(curAct->id.name, curAct);
1892 SetDefaultFaceType(blenderscene);
1893 // Let's support scene set.
1894 // Beware of name conflict in linked data, it will not crash but will create confusion
1895 // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have
1896 // no conflicting name for Object, Object data and Action.
1897 for (SETLOOPER(blenderscene, base))
1899 Object* blenderobject = base->object;
1900 allblobj.insert(blenderobject);
1902 KX_GameObject* gameobj = gameobject_from_blenderobject(
1909 bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
1912 if (converter->addInitFromFrame)
1913 if (!isInActiveLayer)
1916 if (gameobj&&addobj)
1920 if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra;
1924 blenderobject->loc[0]+blenderobject->dloc[0],
1925 blenderobject->loc[1]+blenderobject->dloc[1],
1926 blenderobject->loc[2]+blenderobject->dloc[2]
1928 MT_Vector3 eulxyz(blenderobject->rot);
1929 MT_Vector3 scale(blenderobject->size);
1930 if (converter->addInitFromFrame){//rcruiz
1931 float eulxyzPrev[3];
1932 blenderscene->r.cfra=blenderscene->r.sfra-1;
1933 update_for_newframe();
1934 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
1935 blenderobject->loc[1]+blenderobject->dloc[1],
1936 blenderobject->loc[2]+blenderobject->dloc[2]
1938 eulxyzPrev[0]=blenderobject->rot[0];
1939 eulxyzPrev[1]=blenderobject->rot[1];
1940 eulxyzPrev[2]=blenderobject->rot[2];
1942 double fps = (double) blenderscene->r.frs_sec/
1943 (double) blenderscene->r.frs_sec_base;
1945 tmp.scale(fps, fps, fps);
1946 inivel.push_back(tmp);
1947 tmp=eulxyz-eulxyzPrev;
1948 tmp.scale(fps, fps, fps);
1949 iniang.push_back(tmp);
1950 blenderscene->r.cfra=blenderscene->r.sfra;
1951 update_for_newframe();
1954 gameobj->NodeSetLocalPosition(pos);
1955 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
1956 gameobj->NodeSetLocalScale(scale);
1957 gameobj->NodeUpdateGS(0,true);
1959 BL_ConvertIpos(blenderobject,gameobj,converter);
1960 BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
1962 sumolist->Add(gameobj->AddRef());
1964 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
1967 gameobj->SetName(blenderobject->id.name);
1969 // templist to find Root Parents (object with no parents)
1970 templist->Add(gameobj->AddRef());
1972 // update children/parent hierarchy
1973 if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
1975 // blender has an additional 'parentinverse' offset in each object
1976 SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
1978 // define a normal parent relationship for this node.
1979 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
1980 parentinversenode->SetParentRelation(parent_relation);
1982 parentChildLink pclink;
1983 pclink.m_blenderchild = blenderobject;
1984 pclink.m_gamechildnode = parentinversenode;
1985 vec_parent_child.push_back(pclink);
1987 float* fl = (float*) blenderobject->parentinv;
1988 MT_Transform parinvtrans(fl);
1989 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
1990 // problem here: the parent inverse transform combines scaling and rotation
1991 // in the basis but the scenegraph needs separate rotation and scaling.
1992 // This is not important for OpenGL (it uses 4x4 matrix) but it is important
1993 // for the physic engine that needs a separate scaling
1994 //parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
1996 // Extract the rotation and the scaling from the basis
1997 MT_Matrix3x3 ori(parinvtrans.getBasis());
1998 MT_Vector3 x(ori.getColumn(0));
1999 MT_Vector3 y(ori.getColumn(1));
2000 MT_Vector3 z(ori.getColumn(2));
2001 MT_Vector3 parscale(x.length(), y.length(), z.length());
2002 if (!MT_fuzzyZero(parscale[0]))
2004 if (!MT_fuzzyZero(parscale[1]))
2006 if (!MT_fuzzyZero(parscale[2]))
2008 ori.setColumn(0, x);
2009 ori.setColumn(1, y);
2010 ori.setColumn(2, z);
2011 parentinversenode->SetLocalOrientation(ori);
2012 parentinversenode->SetLocalScale(parscale);
2014 parentinversenode->AddChild(gameobj->GetSGNode());
2017 // needed for python scripting
2018 logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
2020 // needed for group duplication
2021 logicmgr->RegisterGameObj(blenderobject, gameobj);
2022 for (int i = 0; i < gameobj->GetMeshCount(); i++)
2023 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
2025 converter->RegisterGameObject(gameobj, blenderobject);
2026 // this was put in rapidly, needs to be looked at more closely
2027 // only draw/use objects in active 'blender' layers
2029 logicbrick_conversionlist->Add(gameobj->AddRef());
2031 if (converter->addInitFromFrame){
2032 posPrev=gameobj->NodeGetWorldPosition();
2033 angor=gameobj->NodeGetWorldOrientation();
2035 if (isInActiveLayer)
2037 objectlist->Add(gameobj->AddRef());
2038 //tf.Add(gameobj->GetSGNode());
2040 gameobj->NodeUpdateGS(0,true);
2041 gameobj->AddMeshUser();
2046 //we must store this object otherwise it will be deleted
2047 //at the end of this function if it is not a root object
2048 inactivelist->Add(gameobj->AddRef());
2050 if (gameobj->IsDupliGroup())
2051 grouplist.insert(blenderobject->dup_group);
2052 if (converter->addInitFromFrame){
2053 gameobj->NodeSetLocalPosition(posPrev);
2054 gameobj->NodeSetLocalOrientation(angor);
2058 /* Note about memory leak issues:
2059 When a CValue derived class is created, m_refcount is initialized to 1
2060 so the class must be released after being used to make sure that it won't
2061 hang in memory. If the object needs to be stored for a long time,
2062 use AddRef() so that this Release() does not free the object.
2063 Make sure that for any AddRef() there is a Release()!!!!
2064 Do the same for any object derived from CValue, CExpression and NG_NetworkMessage
2071 if (!grouplist.empty())
2073 // now convert the group referenced by dupli group object
2074 // keep track of all groups already converted
2075 set<Group*> allgrouplist = grouplist;
2076 set<Group*> tempglist;
2078 while (!grouplist.empty())
2080 set<Group*>::iterator git;
2082 tempglist.swap(grouplist);
2083 for (git=tempglist.begin(); git!=tempglist.end(); git++)
2085 Group* group = *git;
2087 for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
2089 Object* blenderobject = go->ob;
2090 if (converter->FindGameObject(blenderobject) == NULL)
2092 allblobj.insert(blenderobject);
2093 groupobj.insert(blenderobject);
2094 KX_GameObject* gameobj = gameobject_from_blenderobject(
2101 // this code is copied from above except that
2102 // object from groups are never in active layer
2103 bool isInActiveLayer = false;
2106 if (converter->addInitFromFrame)
2107 if (!isInActiveLayer)
2110 if (gameobj&&addobj)
2114 if (converter->addInitFromFrame)
2115 blenderscene->r.cfra=blenderscene->r.sfra;
2118 blenderobject->loc[0]+blenderobject->dloc[0],
2119 blenderobject->loc[1]+blenderobject->dloc[1],
2120 blenderobject->loc[2]+blenderobject->dloc[2]
2122 MT_Vector3 eulxyz(blenderobject->rot);
2123 MT_Vector3 scale(blenderobject->size);
2124 if (converter->addInitFromFrame){//rcruiz
2125 float eulxyzPrev[3];
2126 blenderscene->r.cfra=blenderscene->r.sfra-1;
2127 update_for_newframe();
2128 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
2129 blenderobject->loc[1]+blenderobject->dloc[1],
2130 blenderobject->loc[2]+blenderobject->dloc[2]
2132 eulxyzPrev[0]=blenderobject->rot[0];
2133 eulxyzPrev[1]=blenderobject->rot[1];
2134 eulxyzPrev[2]=blenderobject->rot[2];
2136 double fps = (double) blenderscene->r.frs_sec/
2137 (double) blenderscene->r.frs_sec_base;
2139 tmp.scale(fps, fps, fps);
2140 inivel.push_back(tmp);
2141 tmp=eulxyz-eulxyzPrev;
2142 tmp.scale(fps, fps, fps);
2143 iniang.push_back(tmp);
2144 blenderscene->r.cfra=blenderscene->r.sfra;
2145 update_for_newframe();
2148 gameobj->NodeSetLocalPosition(pos);
2149 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
2150 gameobj->NodeSetLocalScale(scale);
2151 gameobj->NodeUpdateGS(0,true);
2153 BL_ConvertIpos(blenderobject,gameobj,converter);
2154 BL_ConvertMaterialIpos(blenderobject,gameobj, converter);
2156 sumolist->Add(gameobj->AddRef());
2158 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
2161 gameobj->SetName(blenderobject->id.name);
2163 // templist to find Root Parents (object with no parents)
2164 templist->Add(gameobj->AddRef());
2166 // update children/parent hierarchy
2167 if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
2169 // blender has an additional 'parentinverse' offset in each object
2170 SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
2172 // define a normal parent relationship for this node.
2173 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
2174 parentinversenode->SetParentRelation(parent_relation);
2176 parentChildLink pclink;
2177 pclink.m_blenderchild = blenderobject;
2178 pclink.m_gamechildnode = parentinversenode;
2179 vec_parent_child.push_back(pclink);
2181 float* fl = (float*) blenderobject->parentinv;
2182 MT_Transform parinvtrans(fl);
2183 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
2185 // Extract the rotation and the scaling from the basis
2186 MT_Matrix3x3 ori(parinvtrans.getBasis());
2187 MT_Vector3 x(ori.getColumn(0));
2188 MT_Vector3 y(ori.getColumn(1));
2189 MT_Vector3 z(ori.getColumn(2));
2190 MT_Vector3 localscale(x.length(), y.length(), z.length());
2191 if (!MT_fuzzyZero(localscale[0]))
2193 if (!MT_fuzzyZero(localscale[1]))
2195 if (!MT_fuzzyZero(localscale[2]))
2197 ori.setColumn(0, x);
2198 ori.setColumn(1, y);
2199 ori.setColumn(2, z);
2200 parentinversenode->SetLocalOrientation(ori);
2201 parentinversenode->SetLocalScale(localscale);
2203 parentinversenode->AddChild(gameobj->GetSGNode());
2206 // needed for python scripting
2207 logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
2209 // needed for group duplication
2210 logicmgr->RegisterGameObj(blenderobject, gameobj);
2211 for (int i = 0; i < gameobj->GetMeshCount(); i++)
2212 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
2214 converter->RegisterGameObject(gameobj, blenderobject);
2215 // this was put in rapidly, needs to be looked at more closely
2216 // only draw/use objects in active 'blender' layers
2218 logicbrick_conversionlist->Add(gameobj->AddRef());
2220 if (converter->addInitFromFrame){
2221 posPrev=gameobj->NodeGetWorldPosition();
2222 angor=gameobj->NodeGetWorldOrientation();
2224 if (isInActiveLayer)
2226 objectlist->Add(gameobj->AddRef());
2227 //tf.Add(gameobj->GetSGNode());
2229 gameobj->NodeUpdateGS(0,true);
2230 gameobj->AddMeshUser();
2234 //we must store this object otherwise it will be deleted
2235 //at the end of this function if it is not a root object
2236 inactivelist->Add(gameobj->AddRef());
2239 if (gameobj->IsDupliGroup())
2241 // check that the group is not already converted
2242 if (allgrouplist.insert(blenderobject->dup_group).second)
2243 grouplist.insert(blenderobject->dup_group);
2245 if (converter->addInitFromFrame){
2246 gameobj->NodeSetLocalPosition(posPrev);
2247 gameobj->NodeSetLocalOrientation(angor);
2259 // non-camera objects not supported as camera currently
2260 if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) {
2261 KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
2264 kxscene->SetActiveCamera(gamecamera);
2268 set<Object*>::iterator oit;
2269 for(oit=allblobj.begin(); oit!=allblobj.end(); oit++)
2271 Object* blenderobj = *oit;
2272 if (blenderobj->type==OB_MESH) {
2273 Mesh *me = (Mesh*)blenderobj->data;
2276 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)converter->FindGameObject(blenderobj);
2278 if (obj && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE && blenderobj->partype==PARSKEL){
2279 KX_GameObject *par = converter->FindGameObject(blenderobj->parent);
2280 if (par && obj->GetDeformer())
2281 ((BL_SkinDeformer*)obj->GetDeformer())->SetArmature((BL_ArmatureObject*) par);
2287 // create hierarchy information
2289 vector<parentChildLink>::iterator pcit;
2291 for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
2294 struct Object* blenderchild = pcit->m_blenderchild;
2295 struct Object* blenderparent = blenderchild->parent;
2296 KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
2297 KX_GameObject* childobj = converter->FindGameObject(blenderchild);
2301 if (!parentobj || objectlist->SearchValue(childobj) != objectlist->SearchValue(parentobj))
2303 // special case: the parent and child object are not in the same layer.
2304 // This weird situation is used in Apricot for test purposes.
2305 // Resolve it by not converting the child
2306 childobj->GetSGNode()->DisconnectFromParent();
2307 delete pcit->m_gamechildnode;
2308 // Now destroy the child object but also all its descendent that may already be linked
2309 // Remove the child reference in the local list!
2310 // Note: there may be descendents already if the children of the child were processed
2311 // by this loop before the child. In that case, we must remove the children also
2312 CListValue* childrenlist = (CListValue*)childobj->PyGetChildrenRecursive(childobj);
2313 childrenlist->Add(childobj->AddRef());
2314 for ( i=0;i<childrenlist->GetCount();i++)
2316 KX_GameObject* obj = static_cast<KX_GameObject*>(childrenlist->GetValue(i));
2317 if (templist->RemoveValue(obj))
2319 if (sumolist->RemoveValue(obj))
2321 if (logicbrick_conversionlist->RemoveValue(obj))
2324 childrenlist->Release();
2325 // now destroy recursively
2326 kxscene->RemoveObject(childobj);
2330 switch (blenderchild->partype)
2334 // creat a new vertex parent relationship for this node.
2335 KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
2336 pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
2341 // creat a new slow parent relationship for this node.
2342 KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
2343 pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
2348 // parent this to a bone
2349 Bone *parent_bone = get_named_bone(get_armature(blenderchild->parent), blenderchild->parsubstr);
2352 KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone);
2353 pcit->m_gamechildnode->SetParentRelation(bone_parent_relation);
2358 case PARSKEL: // skinned - ignore
2369 parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode);
2371 vec_parent_child.clear();
2373 // find 'root' parents (object that has not parents in SceneGraph)
2374 for (i=0;i<templist->GetCount();++i)
2376 KX_GameObject* gameobj = (KX_GameObject*) templist->GetValue(i);
2377 if (gameobj->GetSGNode()->GetSGParent() == 0)
2379 parentlist->Add(gameobj->AddRef());
2380 gameobj->NodeUpdateGS(0,true);
2384 bool processCompoundChildren = false;
2386 // create physics information
2387 for (i=0;i<sumolist->GetCount();i++)
2389 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2390 struct Object* blenderobject = converter->FindBlenderObject(gameobj);
2391 int nummeshes = gameobj->GetMeshCount();
2392 RAS_MeshObject* meshobj = 0;
2395 meshobj = gameobj->GetMesh(0);
2397 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
2398 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
2401 processCompoundChildren = true;
2402 // create physics information
2403 for (i=0;i<sumolist->GetCount();i++)
2405 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2406 struct Object* blenderobject = converter->FindBlenderObject(gameobj);
2407 int nummeshes = gameobj->GetMeshCount();
2408 RAS_MeshObject* meshobj = 0;
2411 meshobj = gameobj->GetMesh(0);
2413 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
2414 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
2418 //set ini linearVel and int angularVel //rcruiz
2419 if (converter->addInitFromFrame)
2420 for (i=0;i<sumolist->GetCount();i++)
2422 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2423 if (gameobj->IsDynamic()){
2424 gameobj->setLinearVelocity(inivel[i],false);
2425 gameobj->setAngularVelocity(iniang[i],false);
2431 // create physics joints
2432 for (i=0;i<sumolist->GetCount();i++)
2434 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2435 struct Object* blenderobject = converter->FindBlenderObject(gameobj);
2437 bConstraint *curcon;
2438 conlist = get_active_constraints2(blenderobject);
2441 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) {
2442 if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT){
2444 bRigidBodyJointConstraint *dat=(bRigidBodyJointConstraint *)curcon->data;
2448 PHY_IPhysicsController* physctr2 = 0;
2452 KX_GameObject *gotar=getGameOb(dat->tar->id.name,sumolist);
2453 if (gotar && gotar->GetPhysicsController())
2454 physctr2 = (PHY_IPhysicsController*) gotar->GetPhysicsController()->GetUserData();
2457 if (gameobj->GetPhysicsController())
2459 float radsPerDeg = 6.283185307179586232f / 360.f;
2461 PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) gameobj->GetPhysicsController()->GetUserData();
2462 //we need to pass a full constraint frame, not just axis
2464 //localConstraintFrameBasis
2465 MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*dat->axX,radsPerDeg*dat->axY,radsPerDeg*dat->axZ));
2466 MT_Vector3 axis0 = localCFrame.getColumn(0);
2467 MT_Vector3 axis1 = localCFrame.getColumn(1);
2468 MT_Vector3 axis2 = localCFrame.getColumn(2);
2470 int constraintId = kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,
2471 (float)dat->pivY,(float)dat->pivZ,
2472 (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
2473 (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
2474 (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),dat->flag);
2477 //if it is a generic 6DOF constraint, set all the limits accordingly
2478 if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT)
2482 for (dof=0;dof<6;dof++)
2484 if (dat->flag & dofbit)
2486 kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
2489 //minLimit > maxLimit means free(disabled limit) for this degree of freedom
2490 kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1);
2503 templist->Release();
2504 sumolist->Release();
2506 int executePriority=0; /* incremented by converter routines */
2508 // convert global sound stuff
2510 /* XXX, glob is the very very wrong place for this
2511 * to be, re-enable once the listener has been moved into
2514 SND_Scene* soundscene = kxscene->GetSoundScene();
2515 SND_SoundListener* listener = soundscene->GetListener();
2516 if (listener && G.listener)
2518 listener->SetDopplerFactor(G.listener->dopplerfactor);
2519 listener->SetDopplerVelocity(G.listener->dopplervelocity);
2520 listener->SetGain(G.listener->gain);
2525 KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene->world);
2526 converter->RegisterWorldInfo(worldinfo);
2527 kxscene->SetWorldInfo(worldinfo);
2529 #define CONVERT_LOGIC
2530 #ifdef CONVERT_LOGIC
2531 // convert logic bricks, sensors, controllers and actuators
2532 for (i=0;i<logicbrick_conversionlist->GetCount();i++)
2534 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
2535 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
2536 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
2537 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
2538 BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, layerMask,isInActiveLayer,rendertools,converter);
2540 for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
2542 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
2543 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
2544 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
2545 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
2546 BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,layerMask,isInActiveLayer,converter);
2548 for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
2550 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
2551 struct Object* blenderobj = converter->FindBlenderObject(gameobj);
2552 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
2553 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
2554 BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter);
2555 // set the init state to all objects
2556 gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
2558 // apply the initial state to controllers, only on the active objects as this registers the sensors
2559 for ( i=0;i<objectlist->GetCount();i++)
2561 KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i));
2562 gameobj->ResetState();