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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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
31 #if defined(WIN32) && !defined(FREE_WINDOWS)
32 #pragma warning (disable : 4786)
37 #include "BL_BlenderDataConversion.h"
38 #include "KX_BlenderGL.h"
39 #include "KX_BlenderScalarInterpolator.h"
41 #include "RAS_IPolygonMaterial.h"
42 #include "KX_PolygonMaterial.h"
45 #include "ListValue.h"
47 // Collision & Fuzzics LTD
53 #include "KX_GameObject.h"
54 #include "RAS_FramingManager.h"
55 #include "RAS_MeshObject.h"
57 #include "KX_ConvertActuators.h"
58 #include "KX_ConvertControllers.h"
59 #include "KX_ConvertSensors.h"
61 #include "SCA_LogicManager.h"
62 #include "SCA_EventManager.h"
63 #include "SCA_TimeEventManager.h"
65 #include "KX_Camera.h"
66 #include "KX_EmptyObject.h"
67 #include "MT_Point3.h"
68 #include "MT_Transform.h"
69 #include "MT_MinMax.h"
70 #include "SCA_IInputDevice.h"
71 #include "RAS_TexMatrix.h"
72 #include "RAS_ICanvas.h"
73 #include "RAS_MaterialBucket.h"
74 //#include "KX_BlenderPolyMaterial.h"
75 #include "RAS_Polygon.h"
76 #include "RAS_TexVert.h"
77 #include "RAS_BucketManager.h"
78 #include "RAS_IRenderTools.h"
79 #include "BL_Material.h"
80 #include "KX_BlenderMaterial.h"
81 #include "BL_Texture.h"
83 #include "DNA_action_types.h"
85 #include "BKE_global.h"
86 #include "BKE_object.h"
87 #include "BL_ModifierDeformer.h"
88 #include "BL_ShapeDeformer.h"
89 #include "BL_SkinDeformer.h"
90 #include "BL_MeshDeformer.h"
91 #include "KX_SoftBodyDeformer.h"
92 //#include "BL_ArmatureController.h"
94 #include "BlenderWorldInfo.h"
96 #include "KX_KetsjiEngine.h"
97 #include "KX_BlenderSceneConverter.h"
99 /* This little block needed for linking to Blender... */
101 #include "BLI_winstuff.h"
104 /* This list includes only data type definitions */
105 #include "DNA_object_types.h"
106 #include "DNA_material_types.h"
107 #include "DNA_texture_types.h"
108 #include "DNA_image_types.h"
109 #include "DNA_lamp_types.h"
110 #include "DNA_group_types.h"
111 #include "DNA_scene_types.h"
112 #include "DNA_camera_types.h"
113 #include "DNA_property_types.h"
114 #include "DNA_text_types.h"
115 #include "DNA_sensor_types.h"
116 #include "DNA_controller_types.h"
117 #include "DNA_actuator_types.h"
118 #include "DNA_mesh_types.h"
119 #include "DNA_meshdata_types.h"
120 #include "DNA_view3d_types.h"
121 #include "DNA_world_types.h"
122 #include "DNA_sound_types.h"
123 #include "DNA_key_types.h"
124 #include "DNA_armature_types.h"
125 #include "DNA_object_force.h"
127 #include "MEM_guardedalloc.h"
128 #include "BKE_utildefines.h"
130 #include "BKE_mesh.h"
131 #include "MT_Point3.h"
133 #include "BLI_math.h"
136 #include "BKE_scene.h"
137 #include "BKE_customdata.h"
138 #include "BKE_cdderivedmesh.h"
139 #include "BKE_DerivedMesh.h"
142 #include "BKE_material.h" /* give_current_material */
143 /* end of blender include block */
145 #include "KX_BlenderInputDevice.h"
146 #include "KX_ConvertProperties.h"
147 #include "KX_HashedPtr.h"
150 #include "KX_ScalarInterpolator.h"
152 #include "KX_IpoConvert.h"
153 #include "SYS_System.h"
159 #include "KX_ConvertPhysicsObject.h"
161 #include "CcdPhysicsEnvironment.h"
162 #include "CcdGraphicController.h"
164 #include "KX_MotionState.h"
166 // This file defines relationships between parents and children
167 // in the game engine.
169 #include "KX_SG_NodeRelationships.h"
170 #include "KX_SG_BoneParentNodeRelationship.h"
172 #include "BL_ArmatureObject.h"
173 #include "BL_DeformableGameObject.h"
178 //XXX #include "BSE_headerbuttons.h"
179 //XXX void update_for_newframe();
180 //void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
181 //#include "BKE_ipo.h"
182 //void do_all_data_ipos(void);
187 static int default_face_mode = TF_DYNAMIC;
189 static unsigned int KX_rgbaint2uint_new(unsigned int icol)
193 unsigned int integer;
195 } out_color, in_color;
197 in_color.integer = icol;
198 out_color.cp[0] = in_color.cp[3]; // red
199 out_color.cp[1] = in_color.cp[2]; // green
200 out_color.cp[2] = in_color.cp[1]; // blue
201 out_color.cp[3] = in_color.cp[0]; // alpha
203 return out_color.integer;
206 /* Now the real converting starts... */
207 static unsigned int KX_Mcol2uint_new(MCol col)
209 /* color has to be converted without endian sensitivity. So no shifting! */
213 unsigned int integer;
215 } out_color, in_color;
218 out_color.cp[0] = in_color.cp[3]; // red
219 out_color.cp[1] = in_color.cp[2]; // green
220 out_color.cp[2] = in_color.cp[1]; // blue
221 out_color.cp[3] = in_color.cp[0]; // alpha
223 return out_color.integer;
226 static void SetDefaultFaceType(Scene* scene)
228 default_face_mode = TF_DYNAMIC;
232 for(SETLOOPER(scene,base))
234 if (base->object->type == OB_LAMP)
236 default_face_mode = TF_DYNAMIC|TF_LIGHT;
244 static void GetRGB(short type,
253 unsigned int color = 0xFFFFFFFFL;
256 case 0: // vertex colors
259 c0 = KX_Mcol2uint_new(mmcol[0]);
260 c1 = KX_Mcol2uint_new(mmcol[1]);
261 c2 = KX_Mcol2uint_new(mmcol[2]);
263 c3 = KX_Mcol2uint_new(mmcol[3]);
264 }else // backup white
266 c0 = KX_rgbaint2uint_new(color);
267 c1 = KX_rgbaint2uint_new(color);
268 c2 = KX_rgbaint2uint_new(color);
270 c3 = KX_rgbaint2uint_new( color );
275 case 1: // material rgba
280 unsigned int integer;
282 col_converter.cp[3] = (unsigned char) (mat->r*255.0);
283 col_converter.cp[2] = (unsigned char) (mat->g*255.0);
284 col_converter.cp[1] = (unsigned char) (mat->b*255.0);
285 col_converter.cp[0] = (unsigned char) (mat->alpha*255.0);
286 color = col_converter.integer;
288 c0 = KX_rgbaint2uint_new(color);
289 c1 = KX_rgbaint2uint_new(color);
290 c2 = KX_rgbaint2uint_new(color);
292 c3 = KX_rgbaint2uint_new(color);
297 c0 = KX_rgbaint2uint_new(color);
298 c1 = KX_rgbaint2uint_new(color);
299 c2 = KX_rgbaint2uint_new(color);
301 c3 = KX_rgbaint2uint_new(color);
306 typedef struct MTF_localLayer
312 // ------------------------------------
313 bool ConvertMaterial(
314 BL_Material *material,
317 const char *tfaceName,
320 MTF_localLayer *layers,
323 material->Initialize();
324 int numchan = -1, texalpha = 0;
325 bool validmat = (mat!=0);
326 bool validface = (tface!=0);
330 type = 1; // material color
332 material->IdMode = DEFAULT_BLENDER;
333 material->glslmat = (validmat)? glslmat: false;
334 material->materialindex = mface->mat_nr;
336 // --------------------------------
339 // use vertex colors by explicitly setting
340 if(mat->mode &MA_VERTEXCOLP || glslmat)
344 material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
346 numchan = getNumTexChannels(mat);
349 // use the face texture if
350 // 1) it is set in the buttons
351 // 2) we have a face texture and a material but no valid texture in slot 1
352 bool facetex = false;
353 if(validface && mat->mode &MA_FACETEXTURE)
355 if(validface && !mat->mtex[0])
357 if(validface && mat->mtex[0]) {
358 MTex *tmp = mat->mtex[0];
359 if(!tmp->tex || (tmp->tex && !tmp->tex->ima))
362 numchan = numchan>MAXTEX?MAXTEX:numchan;
365 for(int i=0; i<numchan; i++) {
368 if(i==0 && facetex ) {
369 Image*tmp = (Image*)(tface->tpage);
372 material->img[i] = tmp;
373 material->texname[i] = material->img[i]->id.name;
374 material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
375 material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
376 material->flag[i] |= MIPMAP;
378 if(material->img[i]->flag & IMA_REFLECT)
379 material->mapping[i].mapping |= USEREFL;
382 mttmp = getImageFromMaterial( mat, i );
383 if(mttmp && mttmp->texco &TEXCO_UV)
385 STR_String uvName = mttmp->uvname;
387 if (!uvName.IsEmpty())
388 material->mapping[i].uvCoName = mttmp->uvname;
390 material->mapping[i].uvCoName = "";
392 material->mapping[i].mapping |= USEUV;
395 if(material->ras_mode & USE_LIGHT)
396 material->ras_mode &= ~USE_LIGHT;
397 if(tface->mode & TF_LIGHT)
398 material->ras_mode |= USE_LIGHT;
403 material->img[i] = 0;
404 material->texname[i] = "";
409 mttmp = getImageFromMaterial( mat, i );
412 if( mttmp->tex->type == TEX_IMAGE ) {
413 material->mtexname[i] = mttmp->tex->id.name;
414 material->img[i] = mttmp->tex->ima;
415 if( material->img[i] ) {
417 material->texname[i] = material->img[i]->id.name;
418 material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
419 // -----------------------
420 if( mttmp->tex->imaflag &TEX_USEALPHA ) {
421 material->flag[i] |= USEALPHA;
423 // -----------------------
424 else if( mttmp->tex->imaflag &TEX_CALCALPHA ) {
425 material->flag[i] |= CALCALPHA;
427 else if(mttmp->tex->flag &TEX_NEGALPHA) {
428 material->flag[i] |= USENEGALPHA;
431 material->color_blend[i] = mttmp->colfac;
432 material->flag[i] |= ( mttmp->mapto & MAP_ALPHA )?TEXALPHA:0;
433 material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0;
435 if(!glslmat && (material->flag[i] & TEXALPHA))
439 else if(mttmp->tex->type == TEX_ENVMAP) {
440 if( mttmp->tex->env->stype == ENV_LOAD ) {
442 material->mtexname[i] = mttmp->tex->id.name;
443 EnvMap *env = mttmp->tex->env;
444 env->ima = mttmp->tex->ima;
445 material->cubemap[i] = env;
447 if (material->cubemap[i])
449 if (!material->cubemap[i]->cube[0])
450 BL_Texture::SplitEnvMap(material->cubemap[i]);
452 material->texname[i]= material->cubemap[i]->ima->id.name;
453 material->mapping[i].mapping |= USEENV;
457 material->flag[i] |= (mat->ipo!=0)?HASIPO:0;
458 /// --------------------------------
460 material->mapping[i].mapping |= ( mttmp->texco & TEXCO_REFL )?USEREFL:0;
462 if(mttmp->texco & TEXCO_OBJECT) {
463 material->mapping[i].mapping |= USEOBJ;
465 material->mapping[i].objconame = mttmp->object->id.name;
467 else if(mttmp->texco &TEXCO_REFL)
468 material->mapping[i].mapping |= USEREFL;
469 else if(mttmp->texco &(TEXCO_ORCO|TEXCO_GLOB))
470 material->mapping[i].mapping |= USEORCO;
471 else if(mttmp->texco &TEXCO_UV)
473 STR_String uvName = mttmp->uvname;
475 if (!uvName.IsEmpty())
476 material->mapping[i].uvCoName = mttmp->uvname;
478 material->mapping[i].uvCoName = "";
479 material->mapping[i].mapping |= USEUV;
481 else if(mttmp->texco &TEXCO_NORM)
482 material->mapping[i].mapping |= USENORM;
483 else if(mttmp->texco &TEXCO_TANGENT)
484 material->mapping[i].mapping |= USETANG;
486 material->mapping[i].mapping |= DISABLE;
488 material->mapping[i].scale[0] = mttmp->size[0];
489 material->mapping[i].scale[1] = mttmp->size[1];
490 material->mapping[i].scale[2] = mttmp->size[2];
491 material->mapping[i].offsets[0] = mttmp->ofs[0];
492 material->mapping[i].offsets[1] = mttmp->ofs[1];
493 material->mapping[i].offsets[2] = mttmp->ofs[2];
495 material->mapping[i].projplane[0] = mttmp->projx;
496 material->mapping[i].projplane[1] = mttmp->projy;
497 material->mapping[i].projplane[2] = mttmp->projz;
498 /// --------------------------------
500 switch( mttmp->blendtype ) {
502 material->blend_mode[i] = BLEND_MIX;
505 material->blend_mode[i] = BLEND_MUL;
508 material->blend_mode[i] = BLEND_ADD;
511 material->blend_mode[i] = BLEND_SUB;
514 material->blend_mode[i] = BLEND_SCR;
522 // above one tex the switches here
524 switch(valid_index) {
526 material->IdMode = DEFAULT_BLENDER;
529 material->IdMode = ONETEX;
532 material->IdMode = GREATERTHAN2;
535 material->SetUsers(mat->id.us);
537 material->num_enabled = valid_index;
539 material->speccolor[0] = mat->specr;
540 material->speccolor[1] = mat->specg;
541 material->speccolor[2] = mat->specb;
542 material->hard = (float)mat->har/4.0f;
543 material->matcolor[0] = mat->r;
544 material->matcolor[1] = mat->g;
545 material->matcolor[2] = mat->b;
546 material->matcolor[3] = mat->alpha;
547 material->alpha = mat->alpha;
548 material->emit = mat->emit;
549 material->spec_f = mat->spec;
550 material->ref = mat->ref;
551 material->amb = mat->amb;
553 material->ras_mode |= (mat->material_type == MA_TYPE_WIRE)? WIRE: 0;
558 // check for tface tex to fallback on
562 if(tface->mode) material->ras_mode |= USE_LIGHT;
564 material->img[0] = (Image*)(tface->tpage);
565 // ------------------------
566 if(material->img[0]) {
567 material->texname[0] = material->img[0]->id.name;
568 material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
569 material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
570 material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
574 material->SetUsers(-1);
575 material->num_enabled = valid;
576 material->IdMode = TEXFACE;
577 material->speccolor[0] = 1.f;
578 material->speccolor[1] = 1.f;
579 material->speccolor[2] = 1.f;
580 material->hard = 35.f;
581 material->matcolor[0] = 0.5f;
582 material->matcolor[1] = 0.5f;
583 material->matcolor[2] = 0.5f;
584 material->spec_f = 0.5f;
585 material->ref = 0.8f;
589 const char *uvName = "", *uv2Name = "";
592 uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f);
596 material->ras_mode |= (tface->mode & TF_INVISIBLE)?0:POLY_VIS;
598 material->transp = tface->transp;
599 material->tile = tface->tile;
600 material->mode = tface->mode;
602 uv[0].setValue(tface->uv[0]);
603 uv[1].setValue(tface->uv[1]);
604 uv[2].setValue(tface->uv[2]);
607 uv[3].setValue(tface->uv[3]);
613 material->ras_mode |= (POLY_VIS| (validmat?0:USE_LIGHT));
614 material->mode = default_face_mode;
615 material->transp = TF_SOLID;
618 uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f);
621 // with ztransp enabled, enforce alpha blending mode
622 if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->transp == TF_SOLID))
623 material->transp = TF_ALPHA;
625 // always zsort alpha + add
626 if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) && (material->transp != TF_CLIP)) {
627 material->ras_mode |= ALPHA;
628 material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
632 material->ras_mode |= (material->mode & TF_DYNAMIC)? COLLIDER: 0;
634 // these flags are irrelevant at this point, remove so they
635 // don't hurt material bucketing
636 material->mode &= ~(TF_DYNAMIC|TF_ALPHASORT|TF_TEX);
641 bool isFirstSet = true;
643 // only two sets implemented, but any of the eight
644 // sets can make up the two layers
645 for (int vind = 0; vind<material->num_enabled; vind++)
647 BL_Mapping &map = material->mapping[vind];
649 if (map.uvCoName.IsEmpty())
653 for (int lay=0; lay<MAX_MTFACE; lay++)
655 MTF_localLayer& layer = layers[lay];
656 if (layer.face == 0) break;
658 if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
662 uvSet[0].setValue(layer.face->uv[0]);
663 uvSet[1].setValue(layer.face->uv[1]);
664 uvSet[2].setValue(layer.face->uv[2]);
667 uvSet[3].setValue(layer.face->uv[3]);
669 uvSet[3].setValue(0.0f, 0.0f);
673 uv[0] = uvSet[0]; uv[1] = uvSet[1];
674 uv[2] = uvSet[2]; uv[3] = uvSet[3];
678 else if(strcmp(layer.name, uvName) != 0)
680 uv2[0] = uvSet[0]; uv2[1] = uvSet[1];
681 uv2[2] = uvSet[2]; uv2[3] = uvSet[3];
682 map.mapping |= USECUSTOMUV;
683 uv2Name = layer.name;
692 GetRGB(type,mface,mmcol,mat,rgb[0],rgb[1],rgb[2], rgb[3]);
694 // swap the material color, so MCol on TF_BMFONT works
695 if (validmat && type==1 && (tface && tface->mode & TF_BMFONT))
697 rgb[0] = KX_rgbaint2uint_new(rgb[0]);
698 rgb[1] = KX_rgbaint2uint_new(rgb[1]);
699 rgb[2] = KX_rgbaint2uint_new(rgb[2]);
700 rgb[3] = KX_rgbaint2uint_new(rgb[3]);
703 material->SetConversionRGB(rgb);
704 material->SetConversionUV(uvName, uv);
705 material->SetConversionUV2(uv2Name, uv2);
708 material->matname =(mat->id.name);
710 material->tface = tface;
711 material->material = mat;
715 /* blenderobj can be NULL, make sure its checked for */
716 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter)
718 RAS_MeshObject *meshobj;
719 int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object.
721 if ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL)
723 // Get DerivedMesh data
724 DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj);
726 MVert *mvert = dm->getVertArray(dm);
727 int totvert = dm->getNumVerts(dm);
729 MFace *mface = dm->getFaceArray(dm);
730 MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE));
731 MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL));
732 float (*tangent)[3] = NULL;
733 int totface = dm->getNumFaces(dm);
734 const char *tfaceName = "";
737 DM_add_tangent_layer(dm);
738 tangent = (float(*)[3])dm->getFaceDataArray(dm, CD_TANGENT);
741 meshobj = new RAS_MeshObject(mesh);
743 // Extract avaiable layers
744 MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
745 for (int lay=0; lay<MAX_MTFACE; lay++) {
746 layers[lay].face = 0;
747 layers[lay].name = "";
751 for (int i=0; i<dm->faceData.totlayer; i++)
753 if (dm->faceData.layers[i].type == CD_MTFACE)
755 assert(validLayers <= 8);
757 layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data);
758 layers[validLayers].name = dm->faceData.layers[i].name;
759 if(tface == layers[validLayers].face)
760 tfaceName = layers[validLayers].name;
765 meshobj->SetName(mesh->id.name + 2);
766 meshobj->m_sharedvertex_map.resize(totvert);
767 RAS_IPolyMaterial* polymat = NULL;
769 // These pointers will hold persistent material structure during the conversion
770 // to avoid countless allocation/deallocation of memory.
771 BL_Material* bl_mat = NULL;
772 KX_BlenderMaterial* kx_blmat = NULL;
773 KX_PolygonMaterial* kx_polymat = NULL;
775 for (int f=0;f<totface;f++,mface++)
778 bool collider = true;
779 MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
780 MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
781 unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
783 MT_Point3 pt0, pt1, pt2, pt3;
784 MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0);
785 MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
787 /* get coordinates, normals and tangents */
788 pt0.setValue(mvert[mface->v1].co);
789 pt1.setValue(mvert[mface->v2].co);
790 pt2.setValue(mvert[mface->v3].co);
791 if (mface->v4) pt3.setValue(mvert[mface->v4].co);
793 if(mface->flag & ME_SMOOTH) {
794 float n0[3], n1[3], n2[3], n3[3];
796 normal_short_to_float_v3(n0, mvert[mface->v1].no);
797 normal_short_to_float_v3(n1, mvert[mface->v2].no);
798 normal_short_to_float_v3(n2, mvert[mface->v3].no);
804 normal_short_to_float_v3(n3, mvert[mface->v4].no);
812 normal_quad_v3( fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
814 normal_tri_v3( fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
816 no0 = no1 = no2 = no3 = MT_Vector3(fno);
820 tan0 = tangent[f*4 + 0];
821 tan1 = tangent[f*4 + 1];
822 tan2 = tangent[f*4 + 2];
825 tan3 = tangent[f*4 + 3];
828 ma = give_current_material(blenderobj, mface->mat_nr+1);
830 ma = mesh->mat ? mesh->mat[mface->mat_nr]:NULL;
834 bool twoside = false;
836 if(converter->GetMaterials()) {
837 /* do Blender Multitexture and Blender GLSL materials */
841 /* first is the BL_Material */
843 bl_mat = new BL_Material();
844 ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
845 layers, converter->GetGLSLMaterials());
847 visible = ((bl_mat->ras_mode & POLY_VIS)!=0);
848 collider = ((bl_mat->ras_mode & COLLIDER)!=0);
849 twoside = ((bl_mat->mode & TF_TWOSIDE)!=0);
851 /* vertex colors and uv's were stored in bl_mat temporarily */
852 bl_mat->GetConversionRGB(rgb);
853 rgb0 = rgb[0]; rgb1 = rgb[1];
854 rgb2 = rgb[2]; rgb3 = rgb[3];
856 bl_mat->GetConversionUV(uv);
857 uv0 = uv[0]; uv1 = uv[1];
858 uv2 = uv[2]; uv3 = uv[3];
860 bl_mat->GetConversionUV2(uv);
861 uv20 = uv[0]; uv21 = uv[1];
862 uv22 = uv[2]; uv23 = uv[3];
864 /* then the KX_BlenderMaterial */
865 if (kx_blmat == NULL)
866 kx_blmat = new KX_BlenderMaterial();
868 kx_blmat->Initialize(scene, bl_mat);
869 polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
872 /* do Texture Face materials */
873 Image* bima = (tface)? (Image*)tface->tpage: NULL;
874 imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
877 short mode=0, tile=0;
878 int tilexrep=4,tileyrep = 4;
881 tilexrep = bima->xrep;
882 tileyrep = bima->yrep;
885 /* get tface properties if available */
887 /* TF_DYNAMIC means the polygon is a collision face */
888 collider = ((tface->mode & TF_DYNAMIC) != 0);
889 transp = tface->transp;
893 visible = !(tface->mode & TF_INVISIBLE);
894 twoside = ((tface->mode & TF_TWOSIDE)!=0);
896 uv0.setValue(tface->uv[0]);
897 uv1.setValue(tface->uv[1]);
898 uv2.setValue(tface->uv[2]);
901 uv3.setValue(tface->uv[3]);
904 /* no texfaces, set COLLSION true and everything else FALSE */
905 mode = default_face_mode;
910 /* get vertex colors */
912 /* we have vertex colors */
913 rgb0 = KX_Mcol2uint_new(mcol[0]);
914 rgb1 = KX_Mcol2uint_new(mcol[1]);
915 rgb2 = KX_Mcol2uint_new(mcol[2]);
918 rgb3 = KX_Mcol2uint_new(mcol[3]);
921 /* no vertex colors, take from material, otherwise white */
922 unsigned int color = 0xFFFFFFFFL;
929 unsigned int integer;
932 col_converter.cp[3] = (unsigned char) (ma->r*255.0);
933 col_converter.cp[2] = (unsigned char) (ma->g*255.0);
934 col_converter.cp[1] = (unsigned char) (ma->b*255.0);
935 col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
937 color = col_converter.integer;
940 rgb0 = KX_rgbaint2uint_new(color);
941 rgb1 = KX_rgbaint2uint_new(color);
942 rgb2 = KX_rgbaint2uint_new(color);
945 rgb3 = KX_rgbaint2uint_new(color);
948 // only zsort alpha + add
949 bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
950 bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
952 if (kx_polymat == NULL)
953 kx_polymat = new KX_PolygonMaterial();
954 kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
955 tile, tilexrep, tileyrep,
956 mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol);
957 polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
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);
982 // the poly material has been stored in the bucket, next time we must create a new one
986 // the poly material has been stored in the bucket, next time we must create a new one
990 // from now on, use the polygon material from the material bucket
991 polymat = bucket->GetPolyMaterial();
992 // keep the material pointers, they will be reused for next face
995 int nverts = (mface->v4)? 4: 3;
996 RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts);
998 poly->SetVisible(visible);
999 poly->SetCollider(collider);
1000 poly->SetTwoside(twoside);
1001 //poly->SetEdgeCode(mface->edcode);
1003 meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
1004 meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
1005 meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
1008 meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
1016 for (int lay=0; lay<MAX_MTFACE; lay++)
1018 MTF_localLayer &layer = layers[lay];
1019 if (layer.face == 0) break;
1024 // keep meshobj->m_sharedvertex_map for reinstance phys mesh.
1025 // 2.49a and before it did: meshobj->m_sharedvertex_map.clear();
1026 // but this didnt save much ram. - Campbell
1027 meshobj->EndConversion();
1029 // pre calculate texture generation
1030 for(list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
1031 mit != meshobj->GetLastMaterial(); ++ mit) {
1032 mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer);
1046 converter->RegisterGameMesh(meshobj, mesh);
1052 static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject)
1054 PHY_MaterialProps *materialProps = new PHY_MaterialProps;
1056 MT_assert(materialProps && "Create physics material properties failed");
1058 Material* blendermat = give_current_material(blenderobject, 0);
1062 MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f);
1064 materialProps->m_restitution = blendermat->reflect;
1065 materialProps->m_friction = blendermat->friction;
1066 materialProps->m_fh_spring = blendermat->fh;
1067 materialProps->m_fh_damping = blendermat->xyfrict;
1068 materialProps->m_fh_distance = blendermat->fhdist;
1069 materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
1072 //give some defaults
1073 materialProps->m_restitution = 0.f;
1074 materialProps->m_friction = 0.5;
1075 materialProps->m_fh_spring = 0.f;
1076 materialProps->m_fh_damping = 0.f;
1077 materialProps->m_fh_distance = 0.f;
1078 materialProps->m_fh_normal = false;
1082 return materialProps;
1085 static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject)
1087 PHY_ShapeProps *shapeProps = new PHY_ShapeProps;
1089 MT_assert(shapeProps);
1091 shapeProps->m_mass = blenderobject->mass;
1093 // This needs to be fixed in blender. For now, we use:
1095 // in Blender, inertia stands for the size value which is equivalent to
1096 // the sphere radius
1097 shapeProps->m_inertia = blenderobject->formfactor;
1099 MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
1100 MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
1102 shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
1103 shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
1105 shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0];
1106 shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
1107 shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2];
1108 shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0);
1110 shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0;
1111 shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
1113 // velocity clamping XXX
1114 shapeProps->m_clamp_vel_min = blenderobject->min_vel;
1115 shapeProps->m_clamp_vel_max = blenderobject->max_vel;
1124 //////////////////////////////////////////////////////////
1128 static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
1133 float mloc[3], msize[3];
1134 float radius=0.0f, vert_radius, *co;
1137 if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
1140 INIT_MINMAX(min, max);
1142 if (!loc) loc= mloc;
1143 if (!size) size= msize;
1146 for(a=0; a<me->totvert; a++, mvert++) {
1150 DO_MINMAX(co, min, max);
1153 vert_radius= co[0]*co[0] + co[1]*co[1] + co[2]*co[2];
1154 if (vert_radius > radius)
1155 radius= vert_radius;
1159 loc[0]= (min[0]+max[0])/2.0;
1160 loc[1]= (min[1]+max[1])/2.0;
1161 loc[2]= (min[2]+max[2])/2.0;
1163 size[0]= (max[0]-min[0])/2.0;
1164 size[1]= (max[1]-min[1])/2.0;
1165 size[2]= (max[2]-min[2])/2.0;
1168 loc[0]= loc[1]= loc[2]= 0.0;
1169 size[0]= size[1]= size[2]= 0.0;
1172 bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
1173 bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
1175 bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
1176 bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
1178 bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
1179 bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
1181 return sqrt(radius);
1187 static void my_tex_space_mesh(Mesh *me)
1190 float *fp, loc[3], size[3], min[3], max[3];
1193 my_boundbox_mesh(me, loc, size);
1195 if(me->texflag & AUTOSPACE) {
1197 kb= me->key->refkey;
1200 INIT_MINMAX(min, max);
1202 fp= (float *)kb->data;
1203 for(a=0; a<kb->totelem; a++, fp+=3) {
1204 DO_MINMAX(fp, min, max);
1207 loc[0]= (min[0]+max[0])/2.0; loc[1]= (min[1]+max[1])/2.0; loc[2]= (min[2]+max[2])/2.0;
1208 size[0]= (max[0]-min[0])/2.0; size[1]= (max[1]-min[1])/2.0; size[2]= (max[2]-min[2])/2.0;
1211 loc[0]= loc[1]= loc[2]= 0.0;
1212 size[0]= size[1]= size[2]= 0.0;
1218 VECCOPY(me->loc, loc);
1219 VECCOPY(me->size, size);
1220 me->rot[0]= me->rot[1]= me->rot[2]= 0.0;
1222 if(me->size[0]==0.0) me->size[0]= 1.0;
1223 else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001;
1224 else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001;
1226 if(me->size[1]==0.0) me->size[1]= 1.0;
1227 else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001;
1228 else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001;
1230 if(me->size[2]==0.0) me->size[2]= 1.0;
1231 else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001;
1232 else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001;
1237 static void my_get_local_bounds(Object *ob, DerivedMesh *dm, float *center, float *size)
1240 /* uses boundbox, function used by Ketsji */
1246 float min_r[3], max_r[3];
1247 INIT_MINMAX(min_r, max_r);
1248 dm->getMinMax(dm, min_r, max_r);
1249 size[0]= 0.5*fabs(max_r[0] - min_r[0]);
1250 size[1]= 0.5*fabs(max_r[1] - min_r[1]);
1251 size[2]= 0.5*fabs(max_r[2] - min_r[2]);
1253 center[0]= 0.5*(max_r[0] + min_r[0]);
1254 center[1]= 0.5*(max_r[1] + min_r[1]);
1255 center[2]= 0.5*(max_r[2] + min_r[2]);
1259 bb= ( (Mesh *)ob->data )->bb;
1262 my_tex_space_mesh((struct Mesh *)ob->data);
1263 bb= ( (Mesh *)ob->data )->bb;
1270 center[0]= center[1]= center[2]= 0.0;
1271 size[0] = size[1]=size[2]=0.0;
1280 center[0]= center[1]= center[2]= 0.0;
1281 size[0] = size[1]=size[2]=1.0;
1285 size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
1286 size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
1287 size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
1289 center[0]= 0.5*(bb->vec[0][0] + bb->vec[4][0]);
1290 center[1]= 0.5*(bb->vec[0][1] + bb->vec[2][1]);
1291 center[2]= 0.5*(bb->vec[0][2] + bb->vec[1][2]);
1298 //////////////////////////////////////////////////////
1301 void BL_CreateGraphicObjectNew(KX_GameObject* gameobj,
1302 const MT_Point3& localAabbMin,
1303 const MT_Point3& localAabbMax,
1306 e_PhysicsEngine physics_engine)
1308 if (gameobj->GetMeshCount() > 0)
1310 switch (physics_engine)
1315 CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
1317 PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
1318 CcdGraphicController* ctrl = new CcdGraphicController(env, motionstate);
1319 gameobj->SetGraphicController(ctrl);
1320 ctrl->setNewClientInfo(gameobj->getClientInfo());
1321 ctrl->setLocalAabb(localAabbMin, localAabbMax);
1323 // add first, this will create the proxy handle, only if the object is visible
1324 if (gameobj->GetVisible())
1325 env->addCcdGraphicController(ctrl);
1326 // update the mesh if there is a deformer, this will also update the bounding box for modifiers
1327 RAS_Deformer* deformer = gameobj->GetDeformer();
1329 deformer->UpdateBuckets();
1340 void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
1341 struct Object* blenderobject,
1342 RAS_MeshObject* meshobj,
1344 int activeLayerBitInfo,
1345 e_PhysicsEngine physics_engine,
1346 KX_BlenderSceneConverter *converter,
1347 bool processCompoundChildren
1351 //SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
1352 //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
1353 //bool bRigidBody = (userigidbody == 0);
1355 // object has physics representation?
1356 if (!(blenderobject->gameflag & OB_COLLISION))
1359 // get Root Parent of blenderobject
1360 struct Object* parent= blenderobject->parent;
1361 while(parent && parent->parent) {
1362 parent= parent->parent;
1365 bool isCompoundChild = false;
1366 bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD);
1368 /* When the parent is not OB_DYNAMIC and has no OB_COLLISION then it gets no bullet controller
1369 * and cant be apart of the parents compound shape */
1370 if (parent && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) {
1372 if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD))
1374 isCompoundChild = true;
1377 if (processCompoundChildren != isCompoundChild)
1381 PHY_ShapeProps* shapeprops =
1382 CreateShapePropsFromBlenderObject(blenderobject);
1385 PHY_MaterialProps* smmaterial =
1386 CreateMaterialFromBlenderObject(blenderobject);
1388 KX_ObjectProperties objprop;
1389 objprop.m_lockXaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0;
1390 objprop.m_lockYaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0;
1391 objprop.m_lockZaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0;
1392 objprop.m_lockXRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0;
1393 objprop.m_lockYRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0;
1394 objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0;
1396 objprop.m_isCompoundChild = isCompoundChild;
1397 objprop.m_hasCompoundChildren = hasCompoundChildren;
1398 objprop.m_margin = blenderobject->margin;
1400 // ACTOR is now a separate feature
1401 objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
1402 objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
1403 objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
1404 objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
1406 ///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
1407 if (objprop.m_angular_rigidbody || !objprop.m_dyna )
1409 objprop.m_contactProcessingThreshold = blenderobject->m_contactProcessingThreshold;
1412 objprop.m_contactProcessingThreshold = 0.f;
1415 objprop.m_sensor = (blenderobject->gameflag & OB_SENSOR) != 0;
1417 if (objprop.m_softbody)
1419 ///for game soft bodies
1420 if (blenderobject->bsoft)
1422 objprop.m_gamesoftFlag = blenderobject->bsoft->flag;
1424 objprop.m_soft_linStiff = blenderobject->bsoft->linStiff;
1425 objprop.m_soft_angStiff = blenderobject->bsoft->angStiff; /* angular stiffness 0..1 */
1426 objprop.m_soft_volume= blenderobject->bsoft->volume; /* volume preservation 0..1 */
1428 objprop.m_soft_viterations= blenderobject->bsoft->viterations; /* Velocities solver iterations */
1429 objprop.m_soft_piterations= blenderobject->bsoft->piterations; /* Positions solver iterations */
1430 objprop.m_soft_diterations= blenderobject->bsoft->diterations; /* Drift solver iterations */
1431 objprop.m_soft_citerations= blenderobject->bsoft->citerations; /* Cluster solver iterations */
1433 objprop.m_soft_kSRHR_CL= blenderobject->bsoft->kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */
1434 objprop.m_soft_kSKHR_CL= blenderobject->bsoft->kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */
1435 objprop.m_soft_kSSHR_CL= blenderobject->bsoft->kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */
1436 objprop.m_soft_kSR_SPLT_CL= blenderobject->bsoft->kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1438 objprop.m_soft_kSK_SPLT_CL= blenderobject->bsoft->kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1439 objprop.m_soft_kSS_SPLT_CL= blenderobject->bsoft->kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1440 objprop.m_soft_kVCF= blenderobject->bsoft->kVCF; /* Velocities correction factor (Baumgarte) */
1441 objprop.m_soft_kDP= blenderobject->bsoft->kDP; /* Damping coefficient [0,1] */
1443 objprop.m_soft_kDG= blenderobject->bsoft->kDG; /* Drag coefficient [0,+inf] */
1444 objprop.m_soft_kLF= blenderobject->bsoft->kLF; /* Lift coefficient [0,+inf] */
1445 objprop.m_soft_kPR= blenderobject->bsoft->kPR; /* Pressure coefficient [-inf,+inf] */
1446 objprop.m_soft_kVC= blenderobject->bsoft->kVC; /* Volume conversation coefficient [0,+inf] */
1448 objprop.m_soft_kDF= blenderobject->bsoft->kDF; /* Dynamic friction coefficient [0,1] */
1449 objprop.m_soft_kMT= blenderobject->bsoft->kMT; /* Pose matching coefficient [0,1] */
1450 objprop.m_soft_kCHR= blenderobject->bsoft->kCHR; /* Rigid contacts hardness [0,1] */
1451 objprop.m_soft_kKHR= blenderobject->bsoft->kKHR; /* Kinetic contacts hardness [0,1] */
1453 objprop.m_soft_kSHR= blenderobject->bsoft->kSHR; /* Soft contacts hardness [0,1] */
1454 objprop.m_soft_kAHR= blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */
1455 objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
1456 objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/
1457 //objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */
1458 /* disable welding: it doesn't bring any additional stability and it breaks the relation between soft body collision shape and graphic mesh */
1459 objprop.m_soft_welding = 0.f;
1460 objprop.m_margin = blenderobject->bsoft->margin;
1461 objprop.m_contactProcessingThreshold = 0.f;
1464 objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT;
1466 objprop.m_soft_linStiff = 0.5;;
1467 objprop.m_soft_angStiff = 1.f; /* angular stiffness 0..1 */
1468 objprop.m_soft_volume= 1.f; /* volume preservation 0..1 */
1471 objprop.m_soft_viterations= 0;
1472 objprop.m_soft_piterations= 1;
1473 objprop.m_soft_diterations= 0;
1474 objprop.m_soft_citerations= 4;
1476 objprop.m_soft_kSRHR_CL= 0.1f;
1477 objprop.m_soft_kSKHR_CL= 1.f;
1478 objprop.m_soft_kSSHR_CL= 0.5;
1479 objprop.m_soft_kSR_SPLT_CL= 0.5f;
1481 objprop.m_soft_kSK_SPLT_CL= 0.5f;
1482 objprop.m_soft_kSS_SPLT_CL= 0.5f;
1483 objprop.m_soft_kVCF= 1;
1484 objprop.m_soft_kDP= 0;
1486 objprop.m_soft_kDG= 0;
1487 objprop.m_soft_kLF= 0;
1488 objprop.m_soft_kPR= 0;
1489 objprop.m_soft_kVC= 0;
1491 objprop.m_soft_kDF= 0.2f;
1492 objprop.m_soft_kMT= 0.05f;
1493 objprop.m_soft_kCHR= 1.0f;
1494 objprop.m_soft_kKHR= 0.1f;
1496 objprop.m_soft_kSHR= 1.f;
1497 objprop.m_soft_kAHR= 0.7f;
1498 objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS;
1499 objprop.m_soft_numclusteriterations= 16;
1500 objprop.m_soft_welding = 0.f;
1501 objprop.m_margin = 0.f;
1502 objprop.m_contactProcessingThreshold = 0.f;
1506 objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
1507 objprop.m_disableSleeping = (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0;//abuse the OB_COLLISION_RESPONSE flag
1508 //mmm, for now, taks this for the size of the dynamicobject
1509 // Blender uses inertia for radius of dynamic object
1510 objprop.m_radius = blenderobject->inertia;
1511 objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
1512 objprop.m_dynamic_parent=NULL;
1513 objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
1514 objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
1516 if ((blenderobject->gameflag & OB_SOFT_BODY) && !(blenderobject->gameflag & OB_BOUNDS))
1518 objprop.m_boundclass = KX_BOUNDMESH;
1522 DerivedMesh* dm = NULL;
1523 if (gameobj->GetDeformer())
1524 dm = gameobj->GetDeformer()->GetFinalMesh();
1525 my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,bb.m_extends);
1526 if (blenderobject->gameflag & OB_BOUNDS)
1528 switch (blenderobject->boundtype)
1531 objprop.m_boundclass = KX_BOUNDBOX;
1532 //mmm, has to be divided by 2 to be proper extends
1533 objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_extends[0];
1534 objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1];
1535 objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2];
1537 case OB_BOUND_POLYT:
1538 if (blenderobject->type == OB_MESH)
1540 objprop.m_boundclass = KX_BOUNDPOLYTOPE;
1543 // Object is not a mesh... fall through OB_BOUND_POLYH to
1545 case OB_BOUND_POLYH:
1546 if (blenderobject->type == OB_MESH)
1548 objprop.m_boundclass = KX_BOUNDMESH;
1551 // Object is not a mesh... can't use polyhedron.
1552 // Fall through and become a sphere.
1553 case OB_BOUND_SPHERE:
1555 objprop.m_boundclass = KX_BOUNDSPHERE;
1556 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2]));
1559 case OB_BOUND_CYLINDER:
1561 objprop.m_boundclass = KX_BOUNDCYLINDER;
1562 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1563 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
1568 objprop.m_boundclass = KX_BOUNDCONE;
1569 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1570 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
1573 case OB_BOUND_CAPSULE:
1575 objprop.m_boundclass = KX_BOUNDCAPSULE;
1576 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1577 objprop.m_boundobject.c.m_height = 2.f*(bb.m_extends[2]-objprop.m_boundobject.c.m_radius);
1578 if (objprop.m_boundobject.c.m_height < 0.f)
1579 objprop.m_boundobject.c.m_height = 0.f;
1586 if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) {
1587 // parented object cannot be dynamic
1588 KX_GameObject *parentgameobject = converter->FindGameObject(parent);
1589 objprop.m_dynamic_parent = parentgameobject;
1590 //cannot be dynamic:
1591 objprop.m_dyna = false;
1592 objprop.m_softbody = false;
1593 shapeprops->m_mass = 0.f;
1597 objprop.m_concave = (blenderobject->boundtype & 4) != 0;
1599 switch (physics_engine)
1603 KX_ConvertBulletObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, &objprop);
1608 //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
1623 static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
1624 RAS_LightObject lightobj;
1625 KX_LightObject *gamelight;
1627 lightobj.m_att1 = la->att1;
1628 lightobj.m_att2 = (la->mode & LA_QUAD)?la->att2:0.0;
1629 lightobj.m_red = la->r;
1630 lightobj.m_green = la->g;
1631 lightobj.m_blue = la->b;
1632 lightobj.m_distance = la->dist;
1633 lightobj.m_energy = la->energy;
1634 lightobj.m_layer = layerflag;
1635 lightobj.m_spotblend = la->spotblend;
1636 lightobj.m_spotsize = la->spotsize;
1638 lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
1639 lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
1641 bool glslmat = converter->GetGLSLMaterials();
1643 // in GLSL NEGATIVE LAMP is handled inside the lamp update function
1645 if (la->mode & LA_NEG)
1647 lightobj.m_red = -lightobj.m_red;
1648 lightobj.m_green = -lightobj.m_green;
1649 lightobj.m_blue = -lightobj.m_blue;
1653 if (la->type==LA_SUN) {
1654 lightobj.m_type = RAS_LightObject::LIGHT_SUN;
1655 } else if (la->type==LA_SPOT) {
1656 lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
1658 lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
1661 gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools,
1664 BL_ConvertLampIpos(la, gamelight, converter);
1669 static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
1670 Camera* ca = static_cast<Camera*>(ob->data);
1671 RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist);
1672 KX_Camera *gamecamera;
1674 gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
1675 gamecamera->SetName(ca->id.name + 2);
1677 BL_ConvertCameraIpos(ca, gamecamera, converter);
1682 static KX_GameObject *gameobject_from_blenderobject(
1685 RAS_IRenderTools *rendertools,
1686 KX_BlenderSceneConverter *converter)
1688 KX_GameObject *gameobj = NULL;
1694 KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
1695 gameobj = gamelight;
1697 gamelight->AddRef();
1698 kxscene->GetLightList()->Add(gamelight);
1705 KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, converter);
1706 gameobj = gamecamera;
1708 //don't add a reference: the camera list in kxscene->m_cameras is not released at the end
1709 //gamecamera->AddRef();
1710 kxscene->AddCamera(gamecamera);
1717 Mesh* mesh = static_cast<Mesh*>(ob->data);
1718 float center[3], extents[3];
1719 float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents);
1720 RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter);
1722 // needed for python scripting
1723 kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
1725 gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_callbacks);
1727 // set transformation
1728 gameobj->AddMesh(meshobj);
1730 // for all objects: check whether they want to
1731 // respond to updates
1732 bool ignoreActivityCulling =
1733 ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
1734 gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
1735 gameobj->SetOccluder((ob->gameflag & OB_OCCLUDER) != 0, false);
1737 // two options exists for deform: shape keys and armature
1738 // only support relative shape key
1739 bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE;
1740 bool bHasDvert = mesh->dvert != NULL && ob->defbase.first;
1741 bool bHasArmature = (BL_ModifierDeformer::HasArmatureDeformer(ob) && ob->parent && ob->parent->type == OB_ARMATURE && bHasDvert);
1742 bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(ob);
1743 bool bHasSoftBody = (!ob->parent && (ob->gameflag & OB_SOFT_BODY));
1746 BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL_DeformableGameObject *)gameobj,
1747 kxscene->GetBlenderScene(), ob, meshobj);
1748 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1749 if (bHasShapeKey && bHasArmature)
1750 dcont->LoadShapeDrivers(ob->parent);
1751 } else if (bHasShapeKey) {
1752 // not that we can have shape keys without dvert!
1753 BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj,
1755 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1757 dcont->LoadShapeDrivers(ob->parent);
1758 } else if (bHasArmature) {
1759 BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
1761 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1762 } else if (bHasDvert) {
1763 // this case correspond to a mesh that can potentially deform but not with the
1764 // object to which it is attached for the moment. A skin mesh was created in
1765 // BL_ConvertMesh() so must create a deformer too!
1766 BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
1768 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1769 } else if (bHasSoftBody) {
1770 KX_SoftBodyDeformer *dcont = new KX_SoftBodyDeformer(meshobj, (BL_DeformableGameObject*)gameobj);
1771 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1774 MT_Point3 min = MT_Point3(center) - MT_Vector3(extents);
1775 MT_Point3 max = MT_Point3(center) + MT_Vector3(extents);
1776 SG_BBox bbox = SG_BBox(min, max);
1777 gameobj->GetSGNode()->SetBBox(bbox);
1778 gameobj->GetSGNode()->SetRadius(radius);
1785 gameobj = new BL_ArmatureObject(
1787 KX_Scene::m_callbacks,
1789 kxscene->GetBlenderScene() // handle
1791 /* Get the current pose from the armature object and apply it as the rest pose */
1797 gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks);
1798 // set transformation
1804 gameobj->SetLayer(ob->lay);
1805 gameobj->SetBlenderObject(ob);
1806 /* set the visibility state based on the objects render option in the outliner */
1807 if(ob->restrictflag & OB_RESTRICT_RENDER) gameobj->SetVisible(0, 0);
1812 struct parentChildLink {
1813 struct Object* m_blenderchild;
1814 SG_Node* m_gamechildnode;
1817 #include "DNA_constraint_types.h"
1818 //XXX #include "BIF_editconstraint.h"
1820 bPoseChannel *get_active_posechannel2 (Object *ob)
1822 bArmature *arm= (bArmature*)ob->data;
1823 bPoseChannel *pchan;
1826 for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1827 if(pchan->bone && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer))
1834 ListBase *get_active_constraints2(Object *ob)
1839 // XXX - shouldnt we care about the pose data and not the mode???
1840 if (ob->mode & OB_MODE_POSE) {
1841 bPoseChannel *pchan;
1843 pchan = get_active_posechannel2(ob);
1845 return &pchan->constraints;
1848 return &ob->constraints;
1854 void RBJconstraints(Object *ob)//not used
1857 bConstraint *curcon;
1859 conlist = get_active_constraints2(ob);
1862 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) {
1864 printf("%i\n",curcon->type);
1871 #include "PHY_IPhysicsEnvironment.h"
1872 #include "KX_IPhysicsController.h"
1873 #include "PHY_DynamicTypes.h"
1875 KX_IPhysicsController* getPhId(CListValue* sumolist,STR_String busc){//not used
1877 for (int j=0;j<sumolist->GetCount();j++)
1879 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j);
1880 if (gameobje->GetName()==busc)
1881 return gameobje->GetPhysicsController();
1888 KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){
1890 for (int j=0;j<sumolist->GetCount();j++)
1892 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j);
1893 if (gameobje->GetName()==busc)
1901 // convert blender objects into ketsji gameobjects
1902 void BL_ConvertBlenderObjects(struct Main* maggie,
1904 KX_KetsjiEngine* ketsjiEngine,
1905 e_PhysicsEngine physics_engine,
1906 RAS_IRenderTools* rendertools,
1907 RAS_ICanvas* canvas,
1908 KX_BlenderSceneConverter* converter,
1909 bool alwaysUseExpandFraming
1913 Scene *blenderscene = kxscene->GetBlenderScene();
1918 // Get the frame settings of the canvas.
1919 // Get the aspect ratio of the canvas as designed by the user.
1921 RAS_FrameSettings::RAS_FrameType frame_type;
1924 vector<MT_Vector3> inivel,iniang;
1925 set<Group*> grouplist; // list of groups to be converted
1926 set<Object*> allblobj; // all objects converted
1927 set<Object*> groupobj; // objects from groups (never in active layer)
1929 if (alwaysUseExpandFraming) {
1930 frame_type = RAS_FrameSettings::e_frame_extend;
1931 aspect_width = canvas->GetWidth();
1932 aspect_height = canvas->GetHeight();
1934 if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_BARS) {
1935 frame_type = RAS_FrameSettings::e_frame_bars;
1936 } else if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_EXTEND) {
1937 frame_type = RAS_FrameSettings::e_frame_extend;
1939 frame_type = RAS_FrameSettings::e_frame_scale;
1942 aspect_width = blenderscene->gm.xsch;
1943 aspect_height = blenderscene->gm.ysch;
1946 RAS_FrameSettings frame_settings(
1948 blenderscene->gm.framing.col[0],
1949 blenderscene->gm.framing.col[1],
1950 blenderscene->gm.framing.col[2],
1954 kxscene->SetFramingType(frame_settings);
1956 kxscene->SetGravity(MT_Vector3(0,0, -blenderscene->gm.gravity));
1958 /* set activity culling parameters */
1959 kxscene->SetActivityCulling( (blenderscene->gm.mode & WO_ACTIVITY_CULLING) != 0);
1960 kxscene->SetActivityCullingRadius(blenderscene->gm.activityBoxRadius);
1961 kxscene->SetDbvtCulling((blenderscene->gm.mode & WO_DBVT_CULLING) != 0);
1963 // no occlusion culling by default
1964 kxscene->SetDbvtOcclusionRes(0);
1966 int activeLayerBitInfo = blenderscene->lay;
1968 // list of all object converted, active and inactive
1969 CListValue* sumolist = new CListValue();
1971 vector<parentChildLink> vec_parent_child;
1973 CListValue* objectlist = kxscene->GetObjectList();
1974 CListValue* inactivelist = kxscene->GetInactiveList();
1975 CListValue* parentlist = kxscene->GetRootParentList();
1977 SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
1978 SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
1980 CListValue* logicbrick_conversionlist = new CListValue();
1982 //SG_TreeFactory tf;
1984 // Convert actions to actionmap
1986 for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
1988 logicmgr->RegisterActionName(curAct->id.name + 2, curAct);
1991 SetDefaultFaceType(blenderscene);
1992 // Let's support scene set.
1993 // Beware of name conflict in linked data, it will not crash but will create confusion
1994 // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have
1995 // no conflicting name for Object, Object data and Action.
1996 for (SETLOOPER(blenderscene, base))
1998 Object* blenderobject = base->object;
1999 allblobj.insert(blenderobject);
2001 KX_GameObject* gameobj = gameobject_from_blenderobject(
2007 bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
2010 if (converter->addInitFromFrame)
2011 if (!isInActiveLayer)
2014 if (gameobj&&addobj)
2018 if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra;
2022 blenderobject->loc[0]+blenderobject->dloc[0],
2023 blenderobject->loc[1]+blenderobject->dloc[1],
2024 blenderobject->loc[2]+blenderobject->dloc[2]
2026 MT_Vector3 eulxyz(blenderobject->rot);
2027 MT_Vector3 scale(blenderobject->size);
2028 if (converter->addInitFromFrame){//rcruiz
2029 float eulxyzPrev[3];
2030 blenderscene->r.cfra=blenderscene->r.sfra-1;
2031 //XXX update_for_newframe();
2032 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
2033 blenderobject->loc[1]+blenderobject->dloc[1],
2034 blenderobject->loc[2]+blenderobject->dloc[2]
2036 eulxyzPrev[0]=blenderobject->rot[0];
2037 eulxyzPrev[1]=blenderobject->rot[1];
2038 eulxyzPrev[2]=blenderobject->rot[2];
2040 double fps = (double) blenderscene->r.frs_sec/
2041 (double) blenderscene->r.frs_sec_base;
2043 tmp.scale(fps, fps, fps);
2044 inivel.push_back(tmp);
2045 tmp=eulxyz-eulxyzPrev;
2046 tmp.scale(fps, fps, fps);
2047 iniang.push_back(tmp);
2048 blenderscene->r.cfra=blenderscene->r.sfra;
2049 //XXX update_for_newframe();
2052 gameobj->NodeSetLocalPosition(pos);
2053 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
2054 gameobj->NodeSetLocalScale(scale);
2055 gameobj->NodeUpdateGS(0);
2057 BL_ConvertIpos(blenderobject,gameobj,converter);
2058 BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
2060 sumolist->Add(gameobj->AddRef());
2062 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
2064 gameobj->SetName(blenderobject->id.name + 2);
2066 // update children/parent hierarchy
2067 if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
2069 // blender has an additional 'parentinverse' offset in each object
2070 SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc);
2071 SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback);
2073 // define a normal parent relationship for this node.
2074 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
2075 parentinversenode->SetParentRelation(parent_relation);
2077 parentChildLink pclink;
2078 pclink.m_blenderchild = blenderobject;
2079 pclink.m_gamechildnode = parentinversenode;
2080 vec_parent_child.push_back(pclink);
2082 float* fl = (float*) blenderobject->parentinv;
2083 MT_Transform parinvtrans(fl);
2084 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
2085 // problem here: the parent inverse transform combines scaling and rotation
2086 // in the basis but the scenegraph needs separate rotation and scaling.
2087 // This is not important for OpenGL (it uses 4x4 matrix) but it is important
2088 // for the physic engine that needs a separate scaling
2089 //parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
2091 // Extract the rotation and the scaling from the basis
2092 MT_Matrix3x3 ori(parinvtrans.getBasis());
2093 MT_Vector3 x(ori.getColumn(0));
2094 MT_Vector3 y(ori.getColumn(1));
2095 MT_Vector3 z(ori.getColumn(2));
2096 MT_Vector3 parscale(x.length(), y.length(), z.length());
2097 if (!MT_fuzzyZero(parscale[0]))
2099 if (!MT_fuzzyZero(parscale[1]))
2101 if (!MT_fuzzyZero(parscale[2]))
2103 ori.setColumn(0, x);
2104 ori.setColumn(1, y);
2105 ori.setColumn(2, z);
2106 parentinversenode->SetLocalOrientation(ori);
2107 parentinversenode->SetLocalScale(parscale);
2109 parentinversenode->AddChild(gameobj->GetSGNode());
2112 // needed for python scripting
2113 logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
2115 // needed for group duplication
2116 logicmgr->RegisterGameObj(blenderobject, gameobj);
2117 for (int i = 0; i < gameobj->GetMeshCount(); i++)
2118 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
2120 converter->RegisterGameObject(gameobj, blenderobject);
2121 // this was put in rapidly, needs to be looked at more closely
2122 // only draw/use objects in active 'blender' layers
2124 logicbrick_conversionlist->Add(gameobj->AddRef());
2126 if (converter->addInitFromFrame){
2127 posPrev=gameobj->NodeGetWorldPosition();
2128 angor=gameobj->NodeGetWorldOrientation();
2130 if (isInActiveLayer)
2132 objectlist->Add(gameobj->AddRef());
2133 //tf.Add(gameobj->GetSGNode());
2135 gameobj->NodeUpdateGS(0);
2136 gameobj->AddMeshUser();
2141 //we must store this object otherwise it will be deleted
2142 //at the end of this function if it is not a root object
2143 inactivelist->Add(gameobj->AddRef());
2145 if (gameobj->IsDupliGroup())
2146 grouplist.insert(blenderobject->dup_group);
2147 if (converter->addInitFromFrame){
2148 gameobj->NodeSetLocalPosition(posPrev);
2149 gameobj->NodeSetLocalOrientation(angor);
2153 /* Note about memory leak issues:
2154 When a CValue derived class is created, m_refcount is initialized to 1
2155 so the class must be released after being used to make sure that it won't
2156 hang in memory. If the object needs to be stored for a long time,
2157 use AddRef() so that this Release() does not free the object.
2158 Make sure that for any AddRef() there is a Release()!!!!
2159 Do the same for any object derived from CValue, CExpression and NG_NetworkMessage
2166 if (!grouplist.empty())
2168 // now convert the group referenced by dupli group object
2169 // keep track of all groups already converted
2170 set<Group*> allgrouplist = grouplist;
2171 set<Group*> tempglist;
2173 while (!grouplist.empty())
2175 set<Group*>::iterator git;
2177 tempglist.swap(grouplist);
2178 for (git=tempglist.begin(); git!=tempglist.end(); git++)
2180 Group* group = *git;
2182 for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
2184 Object* blenderobject = go->ob;
2185 if (converter->FindGameObject(blenderobject) == NULL)
2187 allblobj.insert(blenderobject);
2188 groupobj.insert(blenderobject);
2189 KX_GameObject* gameobj = gameobject_from_blenderobject(
2195 // this code is copied from above except that
2196 // object from groups are never in active layer
2197 bool isInActiveLayer = false;
2200 if (converter->addInitFromFrame)
2201 if (!isInActiveLayer)
2204 if (gameobj&&addobj)
2208 if (converter->addInitFromFrame)
2209 blenderscene->r.cfra=blenderscene->r.sfra;
2212 blenderobject->loc[0]+blenderobject->dloc[0],
2213 blenderobject->loc[1]+blenderobject->dloc[1],
2214 blenderobject->loc[2]+blenderobject->dloc[2]
2216 MT_Vector3 eulxyz(blenderobject->rot);
2217 MT_Vector3 scale(blenderobject->size);
2218 if (converter->addInitFromFrame){//rcruiz
2219 float eulxyzPrev[3];
2220 blenderscene->r.cfra=blenderscene->r.sfra-1;
2221 //XXX update_for_newframe();
2222 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
2223 blenderobject->loc[1]+blenderobject->dloc[1],
2224 blenderobject->loc[2]+blenderobject->dloc[2]
2226 eulxyzPrev[0]=blenderobject->rot[0];
2227 eulxyzPrev[1]=blenderobject->rot[1];
2228 eulxyzPrev[2]=blenderobject->rot[2];
2230 double fps = (double) blenderscene->r.frs_sec/
2231 (double) blenderscene->r.frs_sec_base;
2233 tmp.scale(fps, fps, fps);
2234 inivel.push_back(tmp);
2235 tmp=eulxyz-eulxyzPrev;
2236 tmp.scale(fps, fps, fps);
2237 iniang.push_back(tmp);
2238 blenderscene->r.cfra=blenderscene->r.sfra;
2239 //XXX update_for_newframe();
2242 gameobj->NodeSetLocalPosition(pos);
2243 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
2244 gameobj->NodeSetLocalScale(scale);
2245 gameobj->NodeUpdateGS(0);
2247 BL_ConvertIpos(blenderobject,gameobj,converter);
2248 BL_ConvertMaterialIpos(blenderobject,gameobj, converter);
2250 sumolist->Add(gameobj->AddRef());
2252 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
2255 gameobj->SetName(blenderobject->id.name + 2);
2257 // update children/parent hierarchy
2258 if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
2260 // blender has an additional 'parentinverse' offset in each object
2261 SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc);
2262 SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback);
2264 // define a normal parent relationship for this node.
2265 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
2266 parentinversenode->SetParentRelation(parent_relation);
2268 parentChildLink pclink;
2269 pclink.m_blenderchild = blenderobject;
2270 pclink.m_gamechildnode = parentinversenode;
2271 vec_parent_child.push_back(pclink);
2273 float* fl = (float*) blenderobject->parentinv;
2274 MT_Transform parinvtrans(fl);
2275 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
2277 // Extract the rotation and the scaling from the basis
2278 MT_Matrix3x3 ori(parinvtrans.getBasis());
2279 MT_Vector3 x(ori.getColumn(0));
2280 MT_Vector3 y(ori.getColumn(1));
2281 MT_Vector3 z(ori.getColumn(2));
2282 MT_Vector3 localscale(x.length(), y.length(), z.length());
2283 if (!MT_fuzzyZero(localscale[0]))
2285 if (!MT_fuzzyZero(localscale[1]))
2287 if (!MT_fuzzyZero(localscale[2]))
2289 ori.setColumn(0, x);
2290 ori.setColumn(1, y);
2291 ori.setColumn(2, z);
2292 parentinversenode->SetLocalOrientation(ori);
2293 parentinversenode->SetLocalScale(localscale);
2295 parentinversenode->AddChild(gameobj->GetSGNode());
2298 // needed for python scripting
2299 logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
2301 // needed for group duplication
2302 logicmgr->RegisterGameObj(blenderobject, gameobj);
2303 for (int i = 0; i < gameobj->GetMeshCount(); i++)
2304 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
2306 converter->RegisterGameObject(gameobj, blenderobject);
2307 // this was put in rapidly, needs to be looked at more closely
2308 // only draw/use objects in active 'blender' layers
2310 logicbrick_conversionlist->Add(gameobj->AddRef());
2312 if (converter->addInitFromFrame){
2313 posPrev=gameobj->NodeGetWorldPosition();
2314 angor=gameobj->NodeGetWorldOrientation();
2316 if (isInActiveLayer)
2318 objectlist->Add(gameobj->AddRef());
2319 //tf.Add(gameobj->GetSGNode());
2321 gameobj->NodeUpdateGS(0);
2322 gameobj->AddMeshUser();
2326 //we must store this object otherwise it will be deleted
2327 //at the end of this function if it is not a root object
2328 inactivelist->Add(gameobj->AddRef());
2331 if (gameobj->IsDupliGroup())
2333 // check that the group is not already converted
2334 if (allgrouplist.insert(blenderobject->dup_group).second)
2335 grouplist.insert(blenderobject->dup_group);
2337 if (converter->addInitFromFrame){
2338 gameobj->NodeSetLocalPosition(posPrev);
2339 gameobj->NodeSetLocalOrientation(angor);
2351 // non-camera objects not supported as camera currently
2352 if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) {
2353 KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
2356 kxscene->SetActiveCamera(gamecamera);
2360 set<Object*>::iterator oit;
2361 for(oit=allblobj.begin(); oit!=allblobj.end(); oit++)
2363 Object* blenderobj = *oit;
2364 if (blenderobj->type==OB_MESH) {
2365 Mesh *me = (Mesh*)blenderobj->data;
2368 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)converter->FindGameObject(blenderobj);
2370 if (obj && BL_ModifierDeformer::HasArmatureDeformer(blenderobj) && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE){
2371 KX_GameObject *par = converter->FindGameObject(blenderobj->parent);
2372 if (par && obj->GetDeformer())
2373 ((BL_SkinDeformer*)obj->GetDeformer())->SetArmature((BL_ArmatureObject*) par);
2379 // create hierarchy information
2381 vector<parentChildLink>::iterator pcit;
2383 for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
2386 struct Object* blenderchild = pcit->m_blenderchild;
2387 struct Object* blenderparent = blenderchild->parent;
2388 KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
2389 KX_GameObject* childobj = converter->FindGameObject(blenderchild);
2393 if (!parentobj || objectlist->SearchValue(childobj) != objectlist->SearchValue(parentobj))
2395 // special case: the parent and child object are not in the same layer.
2396 // This weird situation is used in Apricot for test purposes.
2397 // Resolve it by not converting the child
2398 childobj->GetSGNode()->DisconnectFromParent();
2399 delete pcit->m_gamechildnode;
2400 // Now destroy the child object but also all its descendent that may already be linked
2401 // Remove the child reference in the local list!
2402 // Note: there may be descendents already if the children of the child were processed
2403 // by this loop before the child. In that case, we must remove the children also
2404 CListValue* childrenlist = childobj->GetChildrenRecursive();
2405 childrenlist->Add(childobj->AddRef());
2406 for ( i=0;i<childrenlist->GetCount();i++)
2408 KX_GameObject* obj = static_cast<KX_GameObject*>(childrenlist->GetValue(i));
2409 if (sumolist->RemoveValue(obj))
2411 if (logicbrick_conversionlist->RemoveValue(obj))
2414 childrenlist->Release();
2416 // now destroy recursively
2417 converter->UnregisterGameObject(childobj); // removing objects during conversion make sure this runs too
2418 kxscene->RemoveObject(childobj);
2423 switch (blenderchild->partype)
2427 // creat a new vertex parent relationship for this node.
2428 KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
2429 pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
2434 // creat a new slow parent relationship for this node.
2435 KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
2436 pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
2441 // parent this to a bone
2442 Bone *parent_bone = get_named_bone( (bArmature *)(blenderchild->parent)->data, blenderchild->parsubstr);
2445 KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone);
2446 pcit->m_gamechildnode->SetParentRelation(bone_parent_relation);
2451 case PARSKEL: // skinned - ignore
2462 parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode);
2464 vec_parent_child.clear();
2466 // find 'root' parents (object that has not parents in SceneGraph)
2467 for (i=0;i<sumolist->GetCount();++i)
2469 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2470 if (gameobj->GetSGNode()->GetSGParent() == 0)
2472 parentlist->Add(gameobj->AddRef());
2473 gameobj->NodeUpdateGS(0);
2477 // create graphic controller for culling
2478 if (kxscene->GetDbvtCulling())
2480 bool occlusion = false;
2481 for (i=0; i<sumolist->GetCount();i++)
2483 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2484 if (gameobj->GetMeshCount() > 0)
2487 gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity());
2488 // box[0] is the min, box[1] is the max
2489 bool isactive = objectlist->SearchValue(gameobj);
2490 BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine);
2491 if (gameobj->GetOccluder())
2496 kxscene->SetDbvtOcclusionRes(blenderscene->gm.occlusionRes);
2498 if (blenderscene->world)
2499 kxscene->GetPhysicsEnvironment()->setNumTimeSubSteps(blenderscene->gm.physubstep);
2501 // now that the scenegraph is complete, let's instantiate the deformers.
2502 // We need that to create reusable derived mesh and physic shapes
2503 for (i=0;i<sumolist->GetCount();++i)
2505 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2506 if (gameobj->GetDeformer())
2507 gameobj->GetDeformer()->UpdateBuckets();
2510 // Set up armature constraints
2511 for (i=0;i<sumolist->GetCount();++i)
2513 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2514 if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
2515 ((BL_ArmatureObject*)gameobj)->LoadConstraints(converter);
2518 bool processCompoundChildren = false;
2520 // create physics information
2521 for (i=0;i<sumolist->GetCount();i++)
2523 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2524 struct Object* blenderobject = gameobj->GetBlenderObject();
2525 int nummeshes = gameobj->GetMeshCount();
2526 RAS_MeshObject* meshobj = 0;
2529 meshobj = gameobj->GetMesh(0);
2531 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
2532 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
2535 processCompoundChildren = true;
2536 // create physics information
2537 for (i=0;i<sumolist->GetCount();i++)
2539 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2540 struct Object* blenderobject = gameobj->GetBlenderObject();
2541 int nummeshes = gameobj->GetMeshCount();
2542 RAS_MeshObject* meshobj = 0;
2545 meshobj = gameobj->GetMesh(0);
2547 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
2548 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
2551 //set ini linearVel and int angularVel //rcruiz
2552 if (converter->addInitFromFrame)
2553 for (i=0;i<sumolist->GetCount();i++)
2555 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2556 if (gameobj->IsDynamic()){
2557 gameobj->setLinearVelocity(inivel[i],false);
2558 gameobj->setAngularVelocity(iniang[i],false);
2564 // create physics joints
2565 for (i=0;i<sumolist->GetCount();i++)
2567 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2568 struct Object* blenderobject = gameobj->GetBlenderObject();
2570 bConstraint *curcon;
2571 conlist = get_active_constraints2(blenderobject);
2574 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) {
2575 if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT){
2577 bRigidBodyJointConstraint *dat=(bRigidBodyJointConstraint *)curcon->data;