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 /** \file gameengine/Converter/BL_BlenderDataConversion.cpp
36 #if defined(WIN32) && !defined(FREE_WINDOWS)
37 #pragma warning (disable : 4786)
42 #include "BL_BlenderDataConversion.h"
43 #include "KX_BlenderGL.h"
44 #include "KX_BlenderScalarInterpolator.h"
46 #include "RAS_IPolygonMaterial.h"
47 #include "KX_PolygonMaterial.h"
50 #include "ListValue.h"
52 // Collision & Fuzzics LTD
58 #include "KX_GameObject.h"
59 #include "RAS_FramingManager.h"
60 #include "RAS_MeshObject.h"
62 #include "KX_ConvertActuators.h"
63 #include "KX_ConvertControllers.h"
64 #include "KX_ConvertSensors.h"
66 #include "SCA_LogicManager.h"
67 #include "SCA_EventManager.h"
68 #include "SCA_TimeEventManager.h"
70 #include "KX_Camera.h"
71 #include "KX_EmptyObject.h"
72 #include "KX_FontObject.h"
73 #include "MT_Point3.h"
74 #include "MT_Transform.h"
75 #include "MT_MinMax.h"
76 #include "SCA_IInputDevice.h"
77 #include "RAS_TexMatrix.h"
78 #include "RAS_ICanvas.h"
79 #include "RAS_MaterialBucket.h"
80 //#include "KX_BlenderPolyMaterial.h"
81 #include "RAS_Polygon.h"
82 #include "RAS_TexVert.h"
83 #include "RAS_BucketManager.h"
84 #include "RAS_IRenderTools.h"
85 #include "BL_Material.h"
86 #include "KX_BlenderMaterial.h"
87 #include "BL_Texture.h"
89 #include "DNA_action_types.h"
91 #include "BKE_global.h"
92 #include "BKE_object.h"
93 #include "BL_ModifierDeformer.h"
94 #include "BL_ShapeDeformer.h"
95 #include "BL_SkinDeformer.h"
96 #include "BL_MeshDeformer.h"
97 #include "KX_SoftBodyDeformer.h"
98 //#include "BL_ArmatureController.h"
99 #include "BLI_utildefines.h"
100 #include "BlenderWorldInfo.h"
102 #include "KX_KetsjiEngine.h"
103 #include "KX_BlenderSceneConverter.h"
105 /* This little block needed for linking to Blender... */
107 #include "BLI_winstuff.h"
110 /* This list includes only data type definitions */
111 #include "DNA_object_types.h"
112 #include "DNA_material_types.h"
113 #include "DNA_texture_types.h"
114 #include "DNA_image_types.h"
115 #include "DNA_lamp_types.h"
116 #include "DNA_group_types.h"
117 #include "DNA_scene_types.h"
118 #include "DNA_camera_types.h"
119 #include "DNA_property_types.h"
120 #include "DNA_text_types.h"
121 #include "DNA_sensor_types.h"
122 #include "DNA_controller_types.h"
123 #include "DNA_actuator_types.h"
124 #include "DNA_mesh_types.h"
125 #include "DNA_meshdata_types.h"
126 #include "DNA_view3d_types.h"
127 #include "DNA_world_types.h"
128 #include "DNA_sound_types.h"
129 #include "DNA_key_types.h"
130 #include "DNA_armature_types.h"
131 #include "DNA_object_force.h"
133 #include "MEM_guardedalloc.h"
136 #include "BKE_mesh.h"
137 #include "MT_Point3.h"
139 #include "BLI_math.h"
142 #include "BKE_scene.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 "BL_System.h"
165 #include "KX_ConvertPhysicsObject.h"
167 #include "CcdPhysicsEnvironment.h"
168 #include "CcdGraphicController.h"
170 #include "KX_MotionState.h"
172 // This file defines relationships between parents and children
173 // in the game engine.
175 #include "KX_SG_NodeRelationships.h"
176 #include "KX_SG_BoneParentNodeRelationship.h"
178 #include "BL_ArmatureObject.h"
179 #include "BL_DeformableGameObject.h"
184 //XXX #include "BSE_headerbuttons.h"
185 //XXX void update_for_newframe();
186 //void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
187 //#include "BKE_ipo.h"
188 //void do_all_data_ipos(void);
193 static int default_face_mode = TF_DYNAMIC;
195 static unsigned int KX_rgbaint2uint_new(unsigned int icol)
199 unsigned int integer;
201 } out_color, in_color;
203 in_color.integer = icol;
204 out_color.cp[0] = in_color.cp[3]; // red
205 out_color.cp[1] = in_color.cp[2]; // green
206 out_color.cp[2] = in_color.cp[1]; // blue
207 out_color.cp[3] = in_color.cp[0]; // alpha
209 return out_color.integer;
212 /* Now the real converting starts... */
213 static unsigned int KX_Mcol2uint_new(MCol col)
215 /* color has to be converted without endian sensitivity. So no shifting! */
219 unsigned int integer;
221 } out_color, in_color;
224 out_color.cp[0] = in_color.cp[3]; // red
225 out_color.cp[1] = in_color.cp[2]; // green
226 out_color.cp[2] = in_color.cp[1]; // blue
227 out_color.cp[3] = in_color.cp[0]; // alpha
229 return out_color.integer;
232 static void SetDefaultFaceType(Scene* scene)
234 default_face_mode = TF_DYNAMIC;
238 for(SETLOOPER(scene, sce_iter, base))
240 if (base->object->type == OB_LAMP)
242 default_face_mode = TF_DYNAMIC|TF_LIGHT;
250 static void GetRGB(short type,
259 unsigned int color = 0xFFFFFFFFL;
262 case 0: // vertex colors
265 c0 = KX_Mcol2uint_new(mmcol[0]);
266 c1 = KX_Mcol2uint_new(mmcol[1]);
267 c2 = KX_Mcol2uint_new(mmcol[2]);
269 c3 = KX_Mcol2uint_new(mmcol[3]);
270 }else // backup white
272 c0 = KX_rgbaint2uint_new(color);
273 c1 = KX_rgbaint2uint_new(color);
274 c2 = KX_rgbaint2uint_new(color);
276 c3 = KX_rgbaint2uint_new( color );
281 case 1: // material rgba
286 unsigned int integer;
288 col_converter.cp[3] = (unsigned char) (mat->r*255.0);
289 col_converter.cp[2] = (unsigned char) (mat->g*255.0);
290 col_converter.cp[1] = (unsigned char) (mat->b*255.0);
291 col_converter.cp[0] = (unsigned char) (mat->alpha*255.0);
292 color = col_converter.integer;
294 c0 = KX_rgbaint2uint_new(color);
295 c1 = KX_rgbaint2uint_new(color);
296 c2 = KX_rgbaint2uint_new(color);
298 c3 = KX_rgbaint2uint_new(color);
303 c0 = KX_rgbaint2uint_new(color);
304 c1 = KX_rgbaint2uint_new(color);
305 c2 = KX_rgbaint2uint_new(color);
307 c3 = KX_rgbaint2uint_new(color);
312 typedef struct MTF_localLayer
318 // ------------------------------------
319 bool ConvertMaterial(
320 BL_Material *material,
323 const char *tfaceName,
326 MTF_localLayer *layers,
329 material->Initialize();
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;
340 material->materialindex = mface->mat_nr;
342 // --------------------------------
345 // use vertex colors by explicitly setting
346 if(mat->mode &MA_VERTEXCOLP || glslmat)
350 material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
352 numchan = getNumTexChannels(mat);
355 // use the face texture if
356 // 1) it is set in the buttons
357 // 2) we have a face texture and a material but no valid texture in slot 1
358 bool facetex = false;
359 if(validface && mat->mode &MA_FACETEXTURE)
361 if(validface && !mat->mtex[0])
363 if(validface && mat->mtex[0]) {
364 MTex *tmp = mat->mtex[0];
365 if(!tmp->tex || (tmp->tex && !tmp->tex->ima))
368 numchan = numchan>MAXTEX?MAXTEX:numchan;
371 for(int i=0; i<numchan; i++) {
374 if(i==0 && facetex ) {
375 Image*tmp = (Image*)(tface->tpage);
378 material->img[i] = tmp;
379 material->texname[i] = material->img[i]->id.name;
380 material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
381 material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
382 material->flag[i] |= MIPMAP;
384 if(material->img[i]->flag & IMA_REFLECT)
385 material->mapping[i].mapping |= USEREFL;
388 mttmp = getImageFromMaterial( mat, i );
389 if(mttmp && mttmp->texco &TEXCO_UV)
391 STR_String uvName = mttmp->uvname;
393 if (!uvName.IsEmpty())
394 material->mapping[i].uvCoName = mttmp->uvname;
396 material->mapping[i].uvCoName = "";
398 material->mapping[i].mapping |= USEUV;
401 if(material->ras_mode & USE_LIGHT)
402 material->ras_mode &= ~USE_LIGHT;
403 if(tface->mode & TF_LIGHT)
404 material->ras_mode |= USE_LIGHT;
409 material->img[i] = 0;
410 material->texname[i] = "";
415 mttmp = getImageFromMaterial( mat, i );
418 if( mttmp->tex->type == TEX_IMAGE ) {
419 material->mtexname[i] = mttmp->tex->id.name;
420 material->img[i] = mttmp->tex->ima;
421 if( material->img[i] ) {
423 material->texname[i] = material->img[i]->id.name;
424 material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
425 // -----------------------
426 if( mttmp->tex->imaflag &TEX_USEALPHA ) {
427 material->flag[i] |= USEALPHA;
429 // -----------------------
430 else if( mttmp->tex->imaflag &TEX_CALCALPHA ) {
431 material->flag[i] |= CALCALPHA;
433 else if(mttmp->tex->flag &TEX_NEGALPHA) {
434 material->flag[i] |= USENEGALPHA;
437 material->color_blend[i] = mttmp->colfac;
438 material->flag[i] |= ( mttmp->mapto & MAP_ALPHA )?TEXALPHA:0;
439 material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0;
441 if(!glslmat && (material->flag[i] & TEXALPHA))
445 else if(mttmp->tex->type == TEX_ENVMAP) {
446 if( mttmp->tex->env->stype == ENV_LOAD ) {
448 material->mtexname[i] = mttmp->tex->id.name;
449 EnvMap *env = mttmp->tex->env;
450 env->ima = mttmp->tex->ima;
451 material->cubemap[i] = env;
453 if (material->cubemap[i])
455 if (!material->cubemap[i]->cube[0])
456 BL_Texture::SplitEnvMap(material->cubemap[i]);
458 material->texname[i]= material->cubemap[i]->ima->id.name;
459 material->mapping[i].mapping |= USEENV;
463 #if 0 /* this flag isnt used anymore */
464 material->flag[i] |= (BKE_animdata_from_id(mat->id) != NULL) ? HASIPO : 0;
466 /// --------------------------------
468 material->mapping[i].mapping |= ( mttmp->texco & TEXCO_REFL )?USEREFL:0;
470 if(mttmp->texco & TEXCO_OBJECT) {
471 material->mapping[i].mapping |= USEOBJ;
473 material->mapping[i].objconame = mttmp->object->id.name;
475 else if(mttmp->texco &TEXCO_REFL)
476 material->mapping[i].mapping |= USEREFL;
477 else if(mttmp->texco &(TEXCO_ORCO|TEXCO_GLOB))
478 material->mapping[i].mapping |= USEORCO;
479 else if(mttmp->texco &TEXCO_UV)
481 STR_String uvName = mttmp->uvname;
483 if (!uvName.IsEmpty())
484 material->mapping[i].uvCoName = mttmp->uvname;
486 material->mapping[i].uvCoName = "";
487 material->mapping[i].mapping |= USEUV;
489 else if(mttmp->texco &TEXCO_NORM)
490 material->mapping[i].mapping |= USENORM;
491 else if(mttmp->texco &TEXCO_TANGENT)
492 material->mapping[i].mapping |= USETANG;
494 material->mapping[i].mapping |= DISABLE;
496 material->mapping[i].scale[0] = mttmp->size[0];
497 material->mapping[i].scale[1] = mttmp->size[1];
498 material->mapping[i].scale[2] = mttmp->size[2];
499 material->mapping[i].offsets[0] = mttmp->ofs[0];
500 material->mapping[i].offsets[1] = mttmp->ofs[1];
501 material->mapping[i].offsets[2] = mttmp->ofs[2];
503 material->mapping[i].projplane[0] = mttmp->projx;
504 material->mapping[i].projplane[1] = mttmp->projy;
505 material->mapping[i].projplane[2] = mttmp->projz;
506 /// --------------------------------
508 switch( mttmp->blendtype ) {
510 material->blend_mode[i] = BLEND_MIX;
513 material->blend_mode[i] = BLEND_MUL;
516 material->blend_mode[i] = BLEND_ADD;
519 material->blend_mode[i] = BLEND_SUB;
522 material->blend_mode[i] = BLEND_SCR;
530 // above one tex the switches here
532 switch(valid_index) {
534 material->IdMode = DEFAULT_BLENDER;
537 material->IdMode = ONETEX;
540 material->IdMode = GREATERTHAN2;
543 material->SetUsers(mat->id.us);
545 material->num_enabled = valid_index;
547 material->speccolor[0] = mat->specr;
548 material->speccolor[1] = mat->specg;
549 material->speccolor[2] = mat->specb;
550 material->hard = (float)mat->har/4.0f;
551 material->matcolor[0] = mat->r;
552 material->matcolor[1] = mat->g;
553 material->matcolor[2] = mat->b;
554 material->matcolor[3] = mat->alpha;
555 material->alpha = mat->alpha;
556 material->emit = mat->emit;
557 material->spec_f = mat->spec;
558 material->ref = mat->ref;
559 material->amb = mat->amb;
561 material->ras_mode |= (mat->material_type == MA_TYPE_WIRE)? WIRE: 0;
566 // check for tface tex to fallback on
570 if(tface->mode) material->ras_mode |= USE_LIGHT;
572 material->img[0] = (Image*)(tface->tpage);
573 // ------------------------
574 if(material->img[0]) {
575 material->texname[0] = material->img[0]->id.name;
576 material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
577 material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
578 material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
582 material->SetUsers(-1);
583 material->num_enabled = valid;
584 material->IdMode = TEXFACE;
585 material->speccolor[0] = 1.f;
586 material->speccolor[1] = 1.f;
587 material->speccolor[2] = 1.f;
588 material->hard = 35.f;
589 material->matcolor[0] = 0.5f;
590 material->matcolor[1] = 0.5f;
591 material->matcolor[2] = 0.5f;
592 material->spec_f = 0.5f;
593 material->ref = 0.8f;
597 const char *uvName = "", *uv2Name = "";
600 uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f);
604 material->ras_mode |= (tface->mode & TF_INVISIBLE)?0:POLY_VIS;
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_TRANSP) && (mat->mode & MA_ZTRANSP) && (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;
723 /* blenderobj can be NULL, make sure its checked for */
724 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter)
726 RAS_MeshObject *meshobj;
727 int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object.
729 if ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL)
731 // Get DerivedMesh data
732 DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj);
734 MVert *mvert = dm->getVertArray(dm);
735 int totvert = dm->getNumVerts(dm);
737 MFace *mface = dm->getFaceArray(dm);
738 MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE));
739 MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL));
740 float (*tangent)[4] = NULL;
741 int totface = dm->getNumFaces(dm);
742 const char *tfaceName = "";
745 DM_add_tangent_layer(dm);
746 tangent = (float(*)[4])dm->getFaceDataArray(dm, CD_TANGENT);
749 meshobj = new RAS_MeshObject(mesh);
751 // Extract avaiable layers
752 MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
753 for (int lay=0; lay<MAX_MTFACE; lay++) {
754 layers[lay].face = 0;
755 layers[lay].name = "";
759 for (int i=0; i<dm->faceData.totlayer; i++)
761 if (dm->faceData.layers[i].type == CD_MTFACE)
763 assert(validLayers <= 8);
765 layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data);
766 layers[validLayers].name = dm->faceData.layers[i].name;
767 if(tface == layers[validLayers].face)
768 tfaceName = layers[validLayers].name;
773 meshobj->SetName(mesh->id.name + 2);
774 meshobj->m_sharedvertex_map.resize(totvert);
775 RAS_IPolyMaterial* polymat = NULL;
777 // These pointers will hold persistent material structure during the conversion
778 // to avoid countless allocation/deallocation of memory.
779 BL_Material* bl_mat = NULL;
780 KX_BlenderMaterial* kx_blmat = NULL;
781 KX_PolygonMaterial* kx_polymat = NULL;
783 for (int f=0;f<totface;f++,mface++)
786 bool collider = true;
787 MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
788 MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
789 unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
791 MT_Point3 pt0, pt1, pt2, pt3;
792 MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0);
793 MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
795 /* get coordinates, normals and tangents */
796 pt0.setValue(mvert[mface->v1].co);
797 pt1.setValue(mvert[mface->v2].co);
798 pt2.setValue(mvert[mface->v3].co);
799 if (mface->v4) pt3.setValue(mvert[mface->v4].co);
801 if(mface->flag & ME_SMOOTH) {
802 float n0[3], n1[3], n2[3], n3[3];
804 normal_short_to_float_v3(n0, mvert[mface->v1].no);
805 normal_short_to_float_v3(n1, mvert[mface->v2].no);
806 normal_short_to_float_v3(n2, mvert[mface->v3].no);
812 normal_short_to_float_v3(n3, mvert[mface->v4].no);
820 normal_quad_v3( fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
822 normal_tri_v3( fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
824 no0 = no1 = no2 = no3 = MT_Vector3(fno);
828 tan0 = tangent[f*4 + 0];
829 tan1 = tangent[f*4 + 1];
830 tan2 = tangent[f*4 + 2];
833 tan3 = tangent[f*4 + 3];
836 ma = give_current_material(blenderobj, mface->mat_nr+1);
838 ma = mesh->mat ? mesh->mat[mface->mat_nr]:NULL;
840 /* ckeck for texface since texface _only_ is used as a fallback */
841 if(ma == NULL && tface == NULL) {
842 extern Material defmaterial; /* material.c */
848 bool twoside = false;
850 if(converter->GetMaterials()) {
851 /* do Blender Multitexture and Blender GLSL materials */
855 /* first is the BL_Material */
857 bl_mat = new BL_Material();
858 ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol,
859 layers, converter->GetGLSLMaterials());
861 visible = ((bl_mat->ras_mode & POLY_VIS)!=0);
862 collider = ((bl_mat->ras_mode & COLLIDER)!=0);
863 twoside = ((bl_mat->mode & TF_TWOSIDE)!=0);
865 /* vertex colors and uv's were stored in bl_mat temporarily */
866 bl_mat->GetConversionRGB(rgb);
867 rgb0 = rgb[0]; rgb1 = rgb[1];
868 rgb2 = rgb[2]; rgb3 = rgb[3];
870 bl_mat->GetConversionUV(uv);
871 uv0 = uv[0]; uv1 = uv[1];
872 uv2 = uv[2]; uv3 = uv[3];
874 bl_mat->GetConversionUV2(uv);
875 uv20 = uv[0]; uv21 = uv[1];
876 uv22 = uv[2]; uv23 = uv[3];
878 /* then the KX_BlenderMaterial */
879 if (kx_blmat == NULL)
880 kx_blmat = new KX_BlenderMaterial();
882 kx_blmat->Initialize(scene, bl_mat);
883 polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
886 /* do Texture Face materials */
887 Image* bima = (tface)? (Image*)tface->tpage: NULL;
888 imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
891 short mode=0, tile=0;
892 int tilexrep=4,tileyrep = 4;
895 tilexrep = bima->xrep;
896 tileyrep = bima->yrep;
899 /* get tface properties if available */
901 /* TF_DYNAMIC means the polygon is a collision face */
902 collider = ((tface->mode & TF_DYNAMIC) != 0);
903 transp = tface->transp;
907 visible = !(tface->mode & TF_INVISIBLE);
908 twoside = ((tface->mode & TF_TWOSIDE)!=0);
910 uv0.setValue(tface->uv[0]);
911 uv1.setValue(tface->uv[1]);
912 uv2.setValue(tface->uv[2]);
915 uv3.setValue(tface->uv[3]);
918 /* no texfaces, set COLLSION true and everything else FALSE */
919 mode = default_face_mode;
924 /* get vertex colors */
926 /* we have vertex colors */
927 rgb0 = KX_Mcol2uint_new(mcol[0]);
928 rgb1 = KX_Mcol2uint_new(mcol[1]);
929 rgb2 = KX_Mcol2uint_new(mcol[2]);
932 rgb3 = KX_Mcol2uint_new(mcol[3]);
935 /* no vertex colors, take from material, otherwise white */
936 unsigned int color = 0xFFFFFFFFL;
943 unsigned int integer;
946 col_converter.cp[3] = (unsigned char) (ma->r*255.0);
947 col_converter.cp[2] = (unsigned char) (ma->g*255.0);
948 col_converter.cp[1] = (unsigned char) (ma->b*255.0);
949 col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
951 color = col_converter.integer;
954 rgb0 = KX_rgbaint2uint_new(color);
955 rgb1 = KX_rgbaint2uint_new(color);
956 rgb2 = KX_rgbaint2uint_new(color);
959 rgb3 = KX_rgbaint2uint_new(color);
962 // only zsort alpha + add
963 bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
964 bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
966 if (kx_polymat == NULL)
967 kx_polymat = new KX_PolygonMaterial();
968 kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr,
969 tile, tilexrep, tileyrep,
970 mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol);
971 polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat);
974 polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
975 polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512
976 polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
979 polymat->m_specular.setValue(0.0f,0.0f,0.0f);
980 polymat->m_shininess = 35.0;
984 /* mark face as flat, so vertices are split */
985 bool flat = (mface->flag & ME_SMOOTH) == 0;
987 // see if a bucket was reused or a new one was created
988 // this way only one KX_BlenderMaterial object has to exist per bucket
990 RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
992 // this is needed to free up memory afterwards
993 converter->RegisterPolyMaterial(polymat);
994 if(converter->GetMaterials()) {
995 converter->RegisterBlenderMaterial(bl_mat);
996 // the poly material has been stored in the bucket, next time we must create a new one
1000 // the poly material has been stored in the bucket, next time we must create a new one
1004 // from now on, use the polygon material from the material bucket
1005 polymat = bucket->GetPolyMaterial();
1006 // keep the material pointers, they will be reused for next face
1009 int nverts = (mface->v4)? 4: 3;
1010 RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts);
1012 poly->SetVisible(visible);
1013 poly->SetCollider(collider);
1014 poly->SetTwoside(twoside);
1015 //poly->SetEdgeCode(mface->edcode);
1017 meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
1018 meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2);
1019 meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3);
1022 meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4);
1030 for (int lay=0; lay<MAX_MTFACE; lay++)
1032 MTF_localLayer &layer = layers[lay];
1033 if (layer.face == 0) break;
1038 // keep meshobj->m_sharedvertex_map for reinstance phys mesh.
1039 // 2.49a and before it did: meshobj->m_sharedvertex_map.clear();
1040 // but this didnt save much ram. - Campbell
1041 meshobj->EndConversion();
1043 // pre calculate texture generation
1044 for(list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();
1045 mit != meshobj->GetLastMaterial(); ++ mit) {
1046 mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer);
1060 converter->RegisterGameMesh(meshobj, mesh);
1066 static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject)
1068 PHY_MaterialProps *materialProps = new PHY_MaterialProps;
1070 MT_assert(materialProps && "Create physics material properties failed");
1072 Material* blendermat = give_current_material(blenderobject, 0);
1076 MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f);
1078 materialProps->m_restitution = blendermat->reflect;
1079 materialProps->m_friction = blendermat->friction;
1080 materialProps->m_fh_spring = blendermat->fh;
1081 materialProps->m_fh_damping = blendermat->xyfrict;
1082 materialProps->m_fh_distance = blendermat->fhdist;
1083 materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
1086 //give some defaults
1087 materialProps->m_restitution = 0.f;
1088 materialProps->m_friction = 0.5;
1089 materialProps->m_fh_spring = 0.f;
1090 materialProps->m_fh_damping = 0.f;
1091 materialProps->m_fh_distance = 0.f;
1092 materialProps->m_fh_normal = false;
1096 return materialProps;
1099 static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject)
1101 PHY_ShapeProps *shapeProps = new PHY_ShapeProps;
1103 MT_assert(shapeProps);
1105 shapeProps->m_mass = blenderobject->mass;
1107 // This needs to be fixed in blender. For now, we use:
1109 // in Blender, inertia stands for the size value which is equivalent to
1110 // the sphere radius
1111 shapeProps->m_inertia = blenderobject->formfactor;
1113 MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
1114 MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
1116 shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
1117 shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
1119 shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0];
1120 shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
1121 shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2];
1122 shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0);
1124 shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0;
1125 shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
1127 // velocity clamping XXX
1128 shapeProps->m_clamp_vel_min = blenderobject->min_vel;
1129 shapeProps->m_clamp_vel_max = blenderobject->max_vel;
1138 //////////////////////////////////////////////////////////
1142 static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
1146 float min[3], max[3];
1147 float mloc[3], msize[3];
1148 float radius=0.0f, vert_radius, *co;
1151 if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
1154 INIT_MINMAX(min, max);
1156 if (!loc) loc= mloc;
1157 if (!size) size= msize;
1160 for(a=0; a<me->totvert; a++, mvert++) {
1164 DO_MINMAX(co, min, max);
1167 vert_radius= co[0]*co[0] + co[1]*co[1] + co[2]*co[2];
1168 if (vert_radius > radius)
1169 radius= vert_radius;
1173 loc[0]= (min[0]+max[0])/2.0f;
1174 loc[1]= (min[1]+max[1])/2.0f;
1175 loc[2]= (min[2]+max[2])/2.0f;
1177 size[0]= (max[0]-min[0])/2.0f;
1178 size[1]= (max[1]-min[1])/2.0f;
1179 size[2]= (max[2]-min[2])/2.0f;
1182 loc[0]= loc[1]= loc[2]= 0.0f;
1183 size[0]= size[1]= size[2]= 0.0f;
1186 bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
1187 bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
1189 bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
1190 bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
1192 bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
1193 bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
1195 return sqrt(radius);
1201 static void my_tex_space_mesh(Mesh *me)
1204 float *fp, loc[3], size[3], min[3], max[3];
1207 my_boundbox_mesh(me, loc, size);
1209 if(me->texflag & AUTOSPACE) {
1211 kb= me->key->refkey;
1214 INIT_MINMAX(min, max);
1216 fp= (float *)kb->data;
1217 for(a=0; a<kb->totelem; a++, fp+=3) {
1218 DO_MINMAX(fp, min, max);
1221 loc[0]= (min[0]+max[0])/2.0f; loc[1]= (min[1]+max[1])/2.0f; loc[2]= (min[2]+max[2])/2.0f;
1222 size[0]= (max[0]-min[0])/2.0f; size[1]= (max[1]-min[1])/2.0f; size[2]= (max[2]-min[2])/2.0f;
1225 loc[0]= loc[1]= loc[2]= 0.0;
1226 size[0]= size[1]= size[2]= 0.0;
1232 VECCOPY(me->loc, loc);
1233 VECCOPY(me->size, size);
1234 me->rot[0]= me->rot[1]= me->rot[2]= 0.0f;
1236 if(me->size[0]==0.0) me->size[0]= 1.0f;
1237 else if(me->size[0]>0.0 && me->size[0]< 0.00001f) me->size[0]= 0.00001f;
1238 else if(me->size[0]<0.0 && me->size[0]> -0.00001f) me->size[0]= -0.00001f;
1240 if(me->size[1]==0.0) me->size[1]= 1.0f;
1241 else if(me->size[1]>0.0 && me->size[1]< 0.00001f) me->size[1]= 0.00001f;
1242 else if(me->size[1]<0.0 && me->size[1]> -0.00001f) me->size[1]= -0.00001f;
1244 if(me->size[2]==0.0) me->size[2]= 1.0f;
1245 else if(me->size[2]>0.0 && me->size[2]< 0.00001f) me->size[2]= 0.00001f;
1246 else if(me->size[2]<0.0 && me->size[2]> -0.00001f) me->size[2]= -0.00001f;
1251 static void my_get_local_bounds(Object *ob, DerivedMesh *dm, float *center, float *size)
1254 /* uses boundbox, function used by Ketsji */
1260 float min_r[3], max_r[3];
1261 INIT_MINMAX(min_r, max_r);
1262 dm->getMinMax(dm, min_r, max_r);
1263 size[0]= 0.5f*fabsf(max_r[0] - min_r[0]);
1264 size[1]= 0.5f*fabsf(max_r[1] - min_r[1]);
1265 size[2]= 0.5f*fabsf(max_r[2] - min_r[2]);
1267 center[0]= 0.5f*(max_r[0] + min_r[0]);
1268 center[1]= 0.5f*(max_r[1] + min_r[1]);
1269 center[2]= 0.5f*(max_r[2] + min_r[2]);
1273 bb= ( (Mesh *)ob->data )->bb;
1276 my_tex_space_mesh((struct Mesh *)ob->data);
1277 bb= ( (Mesh *)ob->data )->bb;
1283 center[0]= center[1]= center[2]= 0.0;
1284 size[0] = size[1]=size[2]=0.0;
1287 center[0]= center[1]= center[2]= 0.0;
1288 size[0] = size[1]=size[2]=1.0;
1297 center[0]= center[1]= center[2]= 0.0;
1298 size[0] = size[1]=size[2]=1.0;
1302 size[0]= 0.5f*fabs(bb->vec[0][0] - bb->vec[4][0]);
1303 size[1]= 0.5f*fabs(bb->vec[0][1] - bb->vec[2][1]);
1304 size[2]= 0.5f*fabs(bb->vec[0][2] - bb->vec[1][2]);
1306 center[0]= 0.5f*(bb->vec[0][0] + bb->vec[4][0]);
1307 center[1]= 0.5f*(bb->vec[0][1] + bb->vec[2][1]);
1308 center[2]= 0.5f*(bb->vec[0][2] + bb->vec[1][2]);
1315 //////////////////////////////////////////////////////
1318 void BL_CreateGraphicObjectNew(KX_GameObject* gameobj,
1319 const MT_Point3& localAabbMin,
1320 const MT_Point3& localAabbMax,
1323 e_PhysicsEngine physics_engine)
1325 if (gameobj->GetMeshCount() > 0)
1327 switch (physics_engine)
1332 CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
1334 PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
1335 CcdGraphicController* ctrl = new CcdGraphicController(env, motionstate);
1336 gameobj->SetGraphicController(ctrl);
1337 ctrl->setNewClientInfo(gameobj->getClientInfo());
1338 ctrl->setLocalAabb(localAabbMin, localAabbMax);
1340 // add first, this will create the proxy handle, only if the object is visible
1341 if (gameobj->GetVisible())
1342 env->addCcdGraphicController(ctrl);
1343 // update the mesh if there is a deformer, this will also update the bounding box for modifiers
1344 RAS_Deformer* deformer = gameobj->GetDeformer();
1346 deformer->UpdateBuckets();
1357 void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
1358 struct Object* blenderobject,
1359 RAS_MeshObject* meshobj,
1361 int activeLayerBitInfo,
1362 e_PhysicsEngine physics_engine,
1363 KX_BlenderSceneConverter *converter,
1364 bool processCompoundChildren
1368 //SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
1369 //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
1370 //bool bRigidBody = (userigidbody == 0);
1372 // object has physics representation?
1373 if (!(blenderobject->gameflag & OB_COLLISION))
1376 // get Root Parent of blenderobject
1377 struct Object* parent= blenderobject->parent;
1378 while(parent && parent->parent) {
1379 parent= parent->parent;
1382 bool isCompoundChild = false;
1383 bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD);
1385 /* When the parent is not OB_DYNAMIC and has no OB_COLLISION then it gets no bullet controller
1386 * and cant be apart of the parents compound shape */
1387 if (parent && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) {
1389 if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD))
1391 isCompoundChild = true;
1394 if (processCompoundChildren != isCompoundChild)
1398 PHY_ShapeProps* shapeprops =
1399 CreateShapePropsFromBlenderObject(blenderobject);
1402 PHY_MaterialProps* smmaterial =
1403 CreateMaterialFromBlenderObject(blenderobject);
1405 KX_ObjectProperties objprop;
1406 objprop.m_lockXaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0;
1407 objprop.m_lockYaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0;
1408 objprop.m_lockZaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0;
1409 objprop.m_lockXRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0;
1410 objprop.m_lockYRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0;
1411 objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0;
1413 objprop.m_isCompoundChild = isCompoundChild;
1414 objprop.m_hasCompoundChildren = hasCompoundChildren;
1415 objprop.m_margin = blenderobject->margin;
1417 // ACTOR is now a separate feature
1418 objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
1419 objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
1420 objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
1421 objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
1423 ///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
1424 if (objprop.m_angular_rigidbody || !objprop.m_dyna )
1426 objprop.m_contactProcessingThreshold = blenderobject->m_contactProcessingThreshold;
1429 objprop.m_contactProcessingThreshold = 0.f;
1432 objprop.m_sensor = (blenderobject->gameflag & OB_SENSOR) != 0;
1434 if (objprop.m_softbody)
1436 ///for game soft bodies
1437 if (blenderobject->bsoft)
1439 objprop.m_gamesoftFlag = blenderobject->bsoft->flag;
1441 objprop.m_soft_linStiff = blenderobject->bsoft->linStiff;
1442 objprop.m_soft_angStiff = blenderobject->bsoft->angStiff; /* angular stiffness 0..1 */
1443 objprop.m_soft_volume= blenderobject->bsoft->volume; /* volume preservation 0..1 */
1445 objprop.m_soft_viterations= blenderobject->bsoft->viterations; /* Velocities solver iterations */
1446 objprop.m_soft_piterations= blenderobject->bsoft->piterations; /* Positions solver iterations */
1447 objprop.m_soft_diterations= blenderobject->bsoft->diterations; /* Drift solver iterations */
1448 objprop.m_soft_citerations= blenderobject->bsoft->citerations; /* Cluster solver iterations */
1450 objprop.m_soft_kSRHR_CL= blenderobject->bsoft->kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */
1451 objprop.m_soft_kSKHR_CL= blenderobject->bsoft->kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */
1452 objprop.m_soft_kSSHR_CL= blenderobject->bsoft->kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */
1453 objprop.m_soft_kSR_SPLT_CL= blenderobject->bsoft->kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1455 objprop.m_soft_kSK_SPLT_CL= blenderobject->bsoft->kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1456 objprop.m_soft_kSS_SPLT_CL= blenderobject->bsoft->kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
1457 objprop.m_soft_kVCF= blenderobject->bsoft->kVCF; /* Velocities correction factor (Baumgarte) */
1458 objprop.m_soft_kDP= blenderobject->bsoft->kDP; /* Damping coefficient [0,1] */
1460 objprop.m_soft_kDG= blenderobject->bsoft->kDG; /* Drag coefficient [0,+inf] */
1461 objprop.m_soft_kLF= blenderobject->bsoft->kLF; /* Lift coefficient [0,+inf] */
1462 objprop.m_soft_kPR= blenderobject->bsoft->kPR; /* Pressure coefficient [-inf,+inf] */
1463 objprop.m_soft_kVC= blenderobject->bsoft->kVC; /* Volume conversation coefficient [0,+inf] */
1465 objprop.m_soft_kDF= blenderobject->bsoft->kDF; /* Dynamic friction coefficient [0,1] */
1466 objprop.m_soft_kMT= blenderobject->bsoft->kMT; /* Pose matching coefficient [0,1] */
1467 objprop.m_soft_kCHR= blenderobject->bsoft->kCHR; /* Rigid contacts hardness [0,1] */
1468 objprop.m_soft_kKHR= blenderobject->bsoft->kKHR; /* Kinetic contacts hardness [0,1] */
1470 objprop.m_soft_kSHR= blenderobject->bsoft->kSHR; /* Soft contacts hardness [0,1] */
1471 objprop.m_soft_kAHR= blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */
1472 objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
1473 objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/
1474 //objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */
1475 /* disable welding: it doesn't bring any additional stability and it breaks the relation between soft body collision shape and graphic mesh */
1476 objprop.m_soft_welding = 0.f;
1477 objprop.m_margin = blenderobject->bsoft->margin;
1478 objprop.m_contactProcessingThreshold = 0.f;
1481 objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT;
1483 objprop.m_soft_linStiff = 0.5;;
1484 objprop.m_soft_angStiff = 1.f; /* angular stiffness 0..1 */
1485 objprop.m_soft_volume= 1.f; /* volume preservation 0..1 */
1488 objprop.m_soft_viterations= 0;
1489 objprop.m_soft_piterations= 1;
1490 objprop.m_soft_diterations= 0;
1491 objprop.m_soft_citerations= 4;
1493 objprop.m_soft_kSRHR_CL= 0.1f;
1494 objprop.m_soft_kSKHR_CL= 1.f;
1495 objprop.m_soft_kSSHR_CL= 0.5;
1496 objprop.m_soft_kSR_SPLT_CL= 0.5f;
1498 objprop.m_soft_kSK_SPLT_CL= 0.5f;
1499 objprop.m_soft_kSS_SPLT_CL= 0.5f;
1500 objprop.m_soft_kVCF= 1;
1501 objprop.m_soft_kDP= 0;
1503 objprop.m_soft_kDG= 0;
1504 objprop.m_soft_kLF= 0;
1505 objprop.m_soft_kPR= 0;
1506 objprop.m_soft_kVC= 0;
1508 objprop.m_soft_kDF= 0.2f;
1509 objprop.m_soft_kMT= 0.05f;
1510 objprop.m_soft_kCHR= 1.0f;
1511 objprop.m_soft_kKHR= 0.1f;
1513 objprop.m_soft_kSHR= 1.f;
1514 objprop.m_soft_kAHR= 0.7f;
1515 objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS;
1516 objprop.m_soft_numclusteriterations= 16;
1517 objprop.m_soft_welding = 0.f;
1518 objprop.m_margin = 0.f;
1519 objprop.m_contactProcessingThreshold = 0.f;
1523 objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
1524 objprop.m_disableSleeping = (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0;//abuse the OB_COLLISION_RESPONSE flag
1525 //mmm, for now, taks this for the size of the dynamicobject
1526 // Blender uses inertia for radius of dynamic object
1527 objprop.m_radius = blenderobject->inertia;
1528 objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
1529 objprop.m_dynamic_parent=NULL;
1530 objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
1531 objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
1533 if ((blenderobject->gameflag & OB_SOFT_BODY) && !(blenderobject->gameflag & OB_BOUNDS))
1535 objprop.m_boundclass = KX_BOUNDMESH;
1539 DerivedMesh* dm = NULL;
1540 if (gameobj->GetDeformer())
1541 dm = gameobj->GetDeformer()->GetPhysicsMesh();
1542 my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,bb.m_extends);
1543 if (blenderobject->gameflag & OB_BOUNDS)
1545 switch (blenderobject->boundtype)
1548 objprop.m_boundclass = KX_BOUNDBOX;
1549 //mmm, has to be divided by 2 to be proper extends
1550 objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_extends[0];
1551 objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1];
1552 objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2];
1554 case OB_BOUND_POLYT:
1555 if (blenderobject->type == OB_MESH)
1557 objprop.m_boundclass = KX_BOUNDPOLYTOPE;
1560 // Object is not a mesh... fall through OB_BOUND_POLYH to
1562 case OB_BOUND_POLYH:
1563 if (blenderobject->type == OB_MESH)
1565 objprop.m_boundclass = KX_BOUNDMESH;
1568 // Object is not a mesh... can't use polyhedron.
1569 // Fall through and become a sphere.
1570 case OB_BOUND_SPHERE:
1572 objprop.m_boundclass = KX_BOUNDSPHERE;
1573 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2]));
1576 case OB_BOUND_CYLINDER:
1578 objprop.m_boundclass = KX_BOUNDCYLINDER;
1579 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1580 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
1585 objprop.m_boundclass = KX_BOUNDCONE;
1586 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1587 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
1590 case OB_BOUND_CAPSULE:
1592 objprop.m_boundclass = KX_BOUNDCAPSULE;
1593 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
1594 objprop.m_boundobject.c.m_height = 2.f*(bb.m_extends[2]-objprop.m_boundobject.c.m_radius);
1595 if (objprop.m_boundobject.c.m_height < 0.f)
1596 objprop.m_boundobject.c.m_height = 0.f;
1603 if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) {
1604 // parented object cannot be dynamic
1605 KX_GameObject *parentgameobject = converter->FindGameObject(parent);
1606 objprop.m_dynamic_parent = parentgameobject;
1607 //cannot be dynamic:
1608 objprop.m_dyna = false;
1609 objprop.m_softbody = false;
1610 shapeprops->m_mass = 0.f;
1614 objprop.m_concave = (blenderobject->boundtype & 4) != 0;
1616 switch (physics_engine)
1620 KX_ConvertBulletObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, &objprop);
1625 //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
1644 static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
1645 RAS_LightObject lightobj;
1646 KX_LightObject *gamelight;
1648 lightobj.m_att1 = la->att1;
1649 lightobj.m_att2 = (la->mode & LA_QUAD) ? la->att2 : 0.0f;
1650 lightobj.m_red = la->r;
1651 lightobj.m_green = la->g;
1652 lightobj.m_blue = la->b;
1653 lightobj.m_distance = la->dist;
1654 lightobj.m_energy = la->energy;
1655 lightobj.m_layer = layerflag;
1656 lightobj.m_spotblend = la->spotblend;
1657 lightobj.m_spotsize = la->spotsize;
1659 lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
1660 lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
1662 bool glslmat = converter->GetGLSLMaterials();
1664 // in GLSL NEGATIVE LAMP is handled inside the lamp update function
1666 if (la->mode & LA_NEG)
1668 lightobj.m_red = -lightobj.m_red;
1669 lightobj.m_green = -lightobj.m_green;
1670 lightobj.m_blue = -lightobj.m_blue;
1674 if (la->type==LA_SUN) {
1675 lightobj.m_type = RAS_LightObject::LIGHT_SUN;
1676 } else if (la->type==LA_SPOT) {
1677 lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
1679 lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
1682 gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools,
1685 BL_ConvertLampIpos(la, gamelight, converter);
1690 static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
1691 Camera* ca = static_cast<Camera*>(ob->data);
1692 RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist);
1693 KX_Camera *gamecamera;
1695 gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
1696 gamecamera->SetName(ca->id.name + 2);
1698 BL_ConvertCameraIpos(ca, gamecamera, converter);
1703 static KX_GameObject *gameobject_from_blenderobject(
1706 RAS_IRenderTools *rendertools,
1707 KX_BlenderSceneConverter *converter)
1709 KX_GameObject *gameobj = NULL;
1715 KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
1716 gameobj = gamelight;
1718 gamelight->AddRef();
1719 kxscene->GetLightList()->Add(gamelight);
1726 KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, converter);
1727 gameobj = gamecamera;
1729 //don't add a reference: the camera list in kxscene->m_cameras is not released at the end
1730 //gamecamera->AddRef();
1731 kxscene->AddCamera(gamecamera);
1738 Mesh* mesh = static_cast<Mesh*>(ob->data);
1739 float center[3], extents[3];
1740 float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents);
1741 RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter);
1743 // needed for python scripting
1744 kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
1746 gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_callbacks);
1748 // set transformation
1749 gameobj->AddMesh(meshobj);
1751 // for all objects: check whether they want to
1752 // respond to updates
1753 bool ignoreActivityCulling =
1754 ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
1755 gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
1756 gameobj->SetOccluder((ob->gameflag & OB_OCCLUDER) != 0, false);
1758 // two options exists for deform: shape keys and armature
1759 // only support relative shape key
1760 bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE;
1761 bool bHasDvert = mesh->dvert != NULL && ob->defbase.first;
1762 bool bHasArmature = (BL_ModifierDeformer::HasArmatureDeformer(ob) && ob->parent && ob->parent->type == OB_ARMATURE && bHasDvert);
1763 bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(ob);
1765 bool bHasSoftBody = (!ob->parent && (ob->gameflag & OB_SOFT_BODY));
1768 BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL_DeformableGameObject *)gameobj,
1769 kxscene->GetBlenderScene(), ob, meshobj);
1770 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1771 if (bHasShapeKey && bHasArmature)
1772 dcont->LoadShapeDrivers(ob->parent);
1773 } else if (bHasShapeKey) {
1774 // not that we can have shape keys without dvert!
1775 BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj,
1777 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1779 dcont->LoadShapeDrivers(ob->parent);
1780 } else if (bHasArmature) {
1781 BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
1783 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1784 } else if (bHasDvert) {
1785 // this case correspond to a mesh that can potentially deform but not with the
1786 // object to which it is attached for the moment. A skin mesh was created in
1787 // BL_ConvertMesh() so must create a deformer too!
1788 BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
1790 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1792 } else if (bHasSoftBody) {
1793 KX_SoftBodyDeformer *dcont = new KX_SoftBodyDeformer(meshobj, (BL_DeformableGameObject*)gameobj);
1794 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
1798 MT_Point3 min = MT_Point3(center) - MT_Vector3(extents);
1799 MT_Point3 max = MT_Point3(center) + MT_Vector3(extents);
1800 SG_BBox bbox = SG_BBox(min, max);
1801 gameobj->GetSGNode()->SetBBox(bbox);
1802 gameobj->GetSGNode()->SetRadius(radius);
1809 gameobj = new BL_ArmatureObject(
1811 KX_Scene::m_callbacks,
1813 kxscene->GetBlenderScene() // handle
1815 /* Get the current pose from the armature object and apply it as the rest pose */
1821 gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks);
1822 // set transformation
1828 /* font objects have no bounding box */
1829 gameobj = new KX_FontObject(kxscene,KX_Scene::m_callbacks, rendertools, ob);
1831 /* add to the list only the visible fonts */
1832 if((ob->lay & kxscene->GetBlenderScene()->lay) != 0)
1833 kxscene->AddFont(static_cast<KX_FontObject*>(gameobj));
1840 gameobj->SetLayer(ob->lay);
1841 gameobj->SetBlenderObject(ob);
1842 gameobj->SetObjectColor(ob->col);
1843 /* set the visibility state based on the objects render option in the outliner */
1844 if(ob->restrictflag & OB_RESTRICT_RENDER) gameobj->SetVisible(0, 0);
1849 struct parentChildLink {
1850 struct Object* m_blenderchild;
1851 SG_Node* m_gamechildnode;
1854 #include "DNA_constraint_types.h"
1855 //XXX #include "BIF_editconstraint.h"
1857 bPoseChannel *get_active_posechannel2 (Object *ob)
1859 bArmature *arm= (bArmature*)ob->data;
1860 bPoseChannel *pchan;
1863 for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1864 if(pchan->bone && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer))
1871 ListBase *get_active_constraints2(Object *ob)
1876 // XXX - shouldnt we care about the pose data and not the mode???
1877 if (ob->mode & OB_MODE_POSE) {
1878 bPoseChannel *pchan;
1880 pchan = get_active_posechannel2(ob);
1882 return &pchan->constraints;
1885 return &ob->constraints;
1891 void RBJconstraints(Object *ob)//not used
1894 bConstraint *curcon;
1896 conlist = get_active_constraints2(ob);
1899 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) {
1901 printf("%i\n",curcon->type);
1908 #include "PHY_IPhysicsEnvironment.h"
1909 #include "KX_IPhysicsController.h"
1910 #include "PHY_DynamicTypes.h"
1912 KX_IPhysicsController* getPhId(CListValue* sumolist,STR_String busc){//not used
1914 for (int j=0;j<sumolist->GetCount();j++)
1916 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j);
1917 if (gameobje->GetName()==busc)
1918 return gameobje->GetPhysicsController();
1925 KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){
1927 for (int j=0;j<sumolist->GetCount();j++)
1929 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j);
1930 if (gameobje->GetName()==busc)
1938 // convert blender objects into ketsji gameobjects
1939 void BL_ConvertBlenderObjects(struct Main* maggie,
1941 KX_KetsjiEngine* ketsjiEngine,
1942 e_PhysicsEngine physics_engine,
1943 RAS_IRenderTools* rendertools,
1944 RAS_ICanvas* canvas,
1945 KX_BlenderSceneConverter* converter,
1946 bool alwaysUseExpandFraming
1950 Scene *blenderscene = kxscene->GetBlenderScene();
1955 // Get the frame settings of the canvas.
1956 // Get the aspect ratio of the canvas as designed by the user.
1958 RAS_FrameSettings::RAS_FrameType frame_type;
1961 vector<MT_Vector3> inivel,iniang;
1962 set<Group*> grouplist; // list of groups to be converted
1963 set<Object*> allblobj; // all objects converted
1964 set<Object*> groupobj; // objects from groups (never in active layer)
1966 if (alwaysUseExpandFraming) {
1967 frame_type = RAS_FrameSettings::e_frame_extend;
1968 aspect_width = canvas->GetWidth();
1969 aspect_height = canvas->GetHeight();
1971 if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_BARS) {
1972 frame_type = RAS_FrameSettings::e_frame_bars;
1973 } else if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_EXTEND) {
1974 frame_type = RAS_FrameSettings::e_frame_extend;
1976 frame_type = RAS_FrameSettings::e_frame_scale;
1979 aspect_width = blenderscene->gm.xsch;
1980 aspect_height = blenderscene->gm.ysch;
1983 RAS_FrameSettings frame_settings(
1985 blenderscene->gm.framing.col[0],
1986 blenderscene->gm.framing.col[1],
1987 blenderscene->gm.framing.col[2],
1991 kxscene->SetFramingType(frame_settings);
1993 kxscene->SetGravity(MT_Vector3(0,0, -blenderscene->gm.gravity));
1995 /* set activity culling parameters */
1996 kxscene->SetActivityCulling( (blenderscene->gm.mode & WO_ACTIVITY_CULLING) != 0);
1997 kxscene->SetActivityCullingRadius(blenderscene->gm.activityBoxRadius);
1998 kxscene->SetDbvtCulling((blenderscene->gm.mode & WO_DBVT_CULLING) != 0);
2000 // no occlusion culling by default
2001 kxscene->SetDbvtOcclusionRes(0);
2003 int activeLayerBitInfo = blenderscene->lay;
2005 // list of all object converted, active and inactive
2006 CListValue* sumolist = new CListValue();
2008 vector<parentChildLink> vec_parent_child;
2010 CListValue* objectlist = kxscene->GetObjectList();
2011 CListValue* inactivelist = kxscene->GetInactiveList();
2012 CListValue* parentlist = kxscene->GetRootParentList();
2014 SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
2015 SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
2017 CListValue* logicbrick_conversionlist = new CListValue();
2019 //SG_TreeFactory tf;
2021 // Convert actions to actionmap
2023 for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
2025 logicmgr->RegisterActionName(curAct->id.name + 2, curAct);
2028 SetDefaultFaceType(blenderscene);
2029 // Let's support scene set.
2030 // Beware of name conflict in linked data, it will not crash but will create confusion
2031 // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have
2032 // no conflicting name for Object, Object data and Action.
2033 for (SETLOOPER(blenderscene, sce_iter, base))
2035 Object* blenderobject = base->object;
2036 allblobj.insert(blenderobject);
2038 KX_GameObject* gameobj = gameobject_from_blenderobject(
2044 bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
2047 if (converter->addInitFromFrame)
2048 if (!isInActiveLayer)
2051 if (gameobj&&addobj)
2055 if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra;
2059 blenderobject->loc[0]+blenderobject->dloc[0],
2060 blenderobject->loc[1]+blenderobject->dloc[1],
2061 blenderobject->loc[2]+blenderobject->dloc[2]
2063 MT_Vector3 eulxyz(blenderobject->rot);
2064 MT_Vector3 scale(blenderobject->size);
2065 if (converter->addInitFromFrame){//rcruiz
2066 float eulxyzPrev[3];
2067 blenderscene->r.cfra=blenderscene->r.sfra-1;
2068 //XXX update_for_newframe();
2069 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
2070 blenderobject->loc[1]+blenderobject->dloc[1],
2071 blenderobject->loc[2]+blenderobject->dloc[2]
2073 eulxyzPrev[0]=blenderobject->rot[0];
2074 eulxyzPrev[1]=blenderobject->rot[1];
2075 eulxyzPrev[2]=blenderobject->rot[2];
2077 double fps = (double) blenderscene->r.frs_sec/
2078 (double) blenderscene->r.frs_sec_base;
2080 tmp.scale(fps, fps, fps);
2081 inivel.push_back(tmp);
2082 tmp=eulxyz-eulxyzPrev;
2083 tmp.scale(fps, fps, fps);
2084 iniang.push_back(tmp);
2085 blenderscene->r.cfra=blenderscene->r.sfra;
2086 //XXX update_for_newframe();
2089 gameobj->NodeSetLocalPosition(pos);
2090 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
2091 gameobj->NodeSetLocalScale(scale);
2092 gameobj->NodeUpdateGS(0);
2094 BL_ConvertIpos(blenderobject,gameobj,converter);
2095 BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
2097 sumolist->Add(gameobj->AddRef());
2099 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
2101 gameobj->SetName(blenderobject->id.name + 2);
2103 // update children/parent hierarchy
2104 if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
2106 // blender has an additional 'parentinverse' offset in each object
2107 SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc);
2108 SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback);
2110 // define a normal parent relationship for this node.
2111 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
2112 parentinversenode->SetParentRelation(parent_relation);
2114 parentChildLink pclink;
2115 pclink.m_blenderchild = blenderobject;
2116 pclink.m_gamechildnode = parentinversenode;
2117 vec_parent_child.push_back(pclink);
2119 float* fl = (float*) blenderobject->parentinv;
2120 MT_Transform parinvtrans(fl);
2121 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
2122 // problem here: the parent inverse transform combines scaling and rotation
2123 // in the basis but the scenegraph needs separate rotation and scaling.
2124 // This is not important for OpenGL (it uses 4x4 matrix) but it is important
2125 // for the physic engine that needs a separate scaling
2126 //parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
2128 // Extract the rotation and the scaling from the basis
2129 MT_Matrix3x3 ori(parinvtrans.getBasis());
2130 MT_Vector3 x(ori.getColumn(0));
2131 MT_Vector3 y(ori.getColumn(1));
2132 MT_Vector3 z(ori.getColumn(2));
2133 MT_Vector3 parscale(x.length(), y.length(), z.length());
2134 if (!MT_fuzzyZero(parscale[0]))
2136 if (!MT_fuzzyZero(parscale[1]))
2138 if (!MT_fuzzyZero(parscale[2]))
2140 ori.setColumn(0, x);
2141 ori.setColumn(1, y);
2142 ori.setColumn(2, z);
2143 parentinversenode->SetLocalOrientation(ori);
2144 parentinversenode->SetLocalScale(parscale);
2146 parentinversenode->AddChild(gameobj->GetSGNode());
2149 // needed for python scripting
2150 logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
2152 // needed for group duplication
2153 logicmgr->RegisterGameObj(blenderobject, gameobj);
2154 for (int i = 0; i < gameobj->GetMeshCount(); i++)
2155 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
2157 converter->RegisterGameObject(gameobj, blenderobject);
2158 // this was put in rapidly, needs to be looked at more closely
2159 // only draw/use objects in active 'blender' layers
2161 logicbrick_conversionlist->Add(gameobj->AddRef());
2163 if (converter->addInitFromFrame){
2164 posPrev=gameobj->NodeGetWorldPosition();
2165 angor=gameobj->NodeGetWorldOrientation();
2167 if (isInActiveLayer)
2169 objectlist->Add(gameobj->AddRef());
2170 //tf.Add(gameobj->GetSGNode());
2172 gameobj->NodeUpdateGS(0);
2173 gameobj->AddMeshUser();
2178 //we must store this object otherwise it will be deleted
2179 //at the end of this function if it is not a root object
2180 inactivelist->Add(gameobj->AddRef());
2182 if (gameobj->IsDupliGroup())
2183 grouplist.insert(blenderobject->dup_group);
2184 if (converter->addInitFromFrame){
2185 gameobj->NodeSetLocalPosition(posPrev);
2186 gameobj->NodeSetLocalOrientation(angor);
2190 /* Note about memory leak issues:
2191 When a CValue derived class is created, m_refcount is initialized to 1
2192 so the class must be released after being used to make sure that it won't
2193 hang in memory. If the object needs to be stored for a long time,
2194 use AddRef() so that this Release() does not free the object.
2195 Make sure that for any AddRef() there is a Release()!!!!
2196 Do the same for any object derived from CValue, CExpression and NG_NetworkMessage
2203 if (!grouplist.empty())
2205 // now convert the group referenced by dupli group object
2206 // keep track of all groups already converted
2207 set<Group*> allgrouplist = grouplist;
2208 set<Group*> tempglist;
2210 while (!grouplist.empty())
2212 set<Group*>::iterator git;
2214 tempglist.swap(grouplist);
2215 for (git=tempglist.begin(); git!=tempglist.end(); git++)
2217 Group* group = *git;
2219 for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
2221 Object* blenderobject = go->ob;
2222 if (converter->FindGameObject(blenderobject) == NULL)
2224 allblobj.insert(blenderobject);
2225 groupobj.insert(blenderobject);
2226 KX_GameObject* gameobj = gameobject_from_blenderobject(
2232 // this code is copied from above except that
2233 // object from groups are never in active layer
2234 bool isInActiveLayer = false;
2237 if (converter->addInitFromFrame)
2238 if (!isInActiveLayer)
2241 if (gameobj&&addobj)
2245 if (converter->addInitFromFrame)
2246 blenderscene->r.cfra=blenderscene->r.sfra;
2249 blenderobject->loc[0]+blenderobject->dloc[0],
2250 blenderobject->loc[1]+blenderobject->dloc[1],
2251 blenderobject->loc[2]+blenderobject->dloc[2]
2253 MT_Vector3 eulxyz(blenderobject->rot);
2254 MT_Vector3 scale(blenderobject->size);
2255 if (converter->addInitFromFrame){//rcruiz
2256 float eulxyzPrev[3];
2257 blenderscene->r.cfra=blenderscene->r.sfra-1;
2258 //XXX update_for_newframe();
2259 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
2260 blenderobject->loc[1]+blenderobject->dloc[1],
2261 blenderobject->loc[2]+blenderobject->dloc[2]
2263 eulxyzPrev[0]=blenderobject->rot[0];
2264 eulxyzPrev[1]=blenderobject->rot[1];
2265 eulxyzPrev[2]=blenderobject->rot[2];
2267 double fps = (double) blenderscene->r.frs_sec/
2268 (double) blenderscene->r.frs_sec_base;
2270 tmp.scale(fps, fps, fps);
2271 inivel.push_back(tmp);
2272 tmp=eulxyz-eulxyzPrev;
2273 tmp.scale(fps, fps, fps);
2274 iniang.push_back(tmp);
2275 blenderscene->r.cfra=blenderscene->r.sfra;
2276 //XXX update_for_newframe();
2279 gameobj->NodeSetLocalPosition(pos);
2280 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
2281 gameobj->NodeSetLocalScale(scale);
2282 gameobj->NodeUpdateGS(0);
2284 BL_ConvertIpos(blenderobject,gameobj,converter);
2285 BL_ConvertMaterialIpos(blenderobject,gameobj, converter);
2287 sumolist->Add(gameobj->AddRef());
2289 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
2292 gameobj->SetName(blenderobject->id.name + 2);
2294 // update children/parent hierarchy
2295 if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
2297 // blender has an additional 'parentinverse' offset in each object
2298 SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc);
2299 SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback);
2301 // define a normal parent relationship for this node.
2302 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
2303 parentinversenode->SetParentRelation(parent_relation);
2305 parentChildLink pclink;
2306 pclink.m_blenderchild = blenderobject;
2307 pclink.m_gamechildnode = parentinversenode;
2308 vec_parent_child.push_back(pclink);
2310 float* fl = (float*) blenderobject->parentinv;
2311 MT_Transform parinvtrans(fl);
2312 parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
2314 // Extract the rotation and the scaling from the basis
2315 MT_Matrix3x3 ori(parinvtrans.getBasis());
2316 MT_Vector3 x(ori.getColumn(0));
2317 MT_Vector3 y(ori.getColumn(1));
2318 MT_Vector3 z(ori.getColumn(2));
2319 MT_Vector3 localscale(x.length(), y.length(), z.length());
2320 if (!MT_fuzzyZero(localscale[0]))
2322 if (!MT_fuzzyZero(localscale[1]))
2324 if (!MT_fuzzyZero(localscale[2]))
2326 ori.setColumn(0, x);
2327 ori.setColumn(1, y);
2328 ori.setColumn(2, z);
2329 parentinversenode->SetLocalOrientation(ori);
2330 parentinversenode->SetLocalScale(localscale);
2332 parentinversenode->AddChild(gameobj->GetSGNode());
2335 // needed for python scripting
2336 logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
2338 // needed for group duplication
2339 logicmgr->RegisterGameObj(blenderobject, gameobj);
2340 for (int i = 0; i < gameobj->GetMeshCount(); i++)
2341 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
2343 converter->RegisterGameObject(gameobj, blenderobject);
2344 // this was put in rapidly, needs to be looked at more closely
2345 // only draw/use objects in active 'blender' layers
2347 logicbrick_conversionlist->Add(gameobj->AddRef());
2349 if (converter->addInitFromFrame){
2350 posPrev=gameobj->NodeGetWorldPosition();
2351 angor=gameobj->NodeGetWorldOrientation();
2353 if (isInActiveLayer)
2355 objectlist->Add(gameobj->AddRef());
2356 //tf.Add(gameobj->GetSGNode());
2358 gameobj->NodeUpdateGS(0);
2359 gameobj->AddMeshUser();
2363 //we must store this object otherwise it will be deleted
2364 //at the end of this function if it is not a root object
2365 inactivelist->Add(gameobj->AddRef());
2368 if (gameobj->IsDupliGroup())
2370 // check that the group is not already converted
2371 if (allgrouplist.insert(blenderobject->dup_group).second)
2372 grouplist.insert(blenderobject->dup_group);
2374 if (converter->addInitFromFrame){
2375 gameobj->NodeSetLocalPosition(posPrev);
2376 gameobj->NodeSetLocalOrientation(angor);
2388 // non-camera objects not supported as camera currently
2389 if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) {
2390 KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
2393 kxscene->SetActiveCamera(gamecamera);
2397 set<Object*>::iterator oit;
2398 for(oit=allblobj.begin(); oit!=allblobj.end(); oit++)
2400 Object* blenderobj = *oit;
2401 if (blenderobj->type==OB_MESH) {
2402 Mesh *me = (Mesh*)blenderobj->data;
2405 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)converter->FindGameObject(blenderobj);
2407 if (obj && BL_ModifierDeformer::HasArmatureDeformer(blenderobj) && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE){
2408 KX_GameObject *par = converter->FindGameObject(blenderobj->parent);
2409 if (par && obj->GetDeformer())
2410 ((BL_SkinDeformer*)obj->GetDeformer())->SetArmature((BL_ArmatureObject*) par);
2416 // create hierarchy information
2418 vector<parentChildLink>::iterator pcit;
2420 for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
2423 struct Object* blenderchild = pcit->m_blenderchild;
2424 struct Object* blenderparent = blenderchild->parent;
2425 KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
2426 KX_GameObject* childobj = converter->FindGameObject(blenderchild);
2430 if (!parentobj || objectlist->SearchValue(childobj) != objectlist->SearchValue(parentobj))
2432 // special case: the parent and child object are not in the same layer.
2433 // This weird situation is used in Apricot for test purposes.
2434 // Resolve it by not converting the child
2435 childobj->GetSGNode()->DisconnectFromParent();
2436 delete pcit->m_gamechildnode;
2437 // Now destroy the child object but also all its descendent that may already be linked
2438 // Remove the child reference in the local list!
2439 // Note: there may be descendents already if the children of the child were processed
2440 // by this loop before the child. In that case, we must remove the children also
2441 CListValue* childrenlist = childobj->GetChildrenRecursive();
2442 childrenlist->Add(childobj->AddRef());
2443 for ( i=0;i<childrenlist->GetCount();i++)
2445 KX_GameObject* obj = static_cast<KX_GameObject*>(childrenlist->GetValue(i));
2446 if (sumolist->RemoveValue(obj))
2448 if (logicbrick_conversionlist->RemoveValue(obj))
2451 childrenlist->Release();
2453 // now destroy recursively
2454 converter->UnregisterGameObject(childobj); // removing objects during conversion make sure this runs too
2455 kxscene->RemoveObject(childobj);
2460 switch (blenderchild->partype)
2464 // creat a new vertex parent relationship for this node.
2465 KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
2466 pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
2471 // creat a new slow parent relationship for this node.
2472 KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
2473 pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
2478 // parent this to a bone
2479 Bone *parent_bone = get_named_bone( (bArmature *)(blenderchild->parent)->data, blenderchild->parsubstr);
2482 KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone);
2483 pcit->m_gamechildnode->SetParentRelation(bone_parent_relation);
2488 case PARSKEL: // skinned - ignore
2499 parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode);
2501 vec_parent_child.clear();
2503 // find 'root' parents (object that has not parents in SceneGraph)
2504 for (i=0;i<sumolist->GetCount();++i)
2506 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2507 if (gameobj->GetSGNode()->GetSGParent() == 0)
2509 parentlist->Add(gameobj->AddRef());
2510 gameobj->NodeUpdateGS(0);
2514 // create graphic controller for culling
2515 if (kxscene->GetDbvtCulling())
2517 bool occlusion = false;
2518 for (i=0; i<sumolist->GetCount();i++)
2520 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2521 if (gameobj->GetMeshCount() > 0)
2524 gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity());
2525 // box[0] is the min, box[1] is the max
2526 bool isactive = objectlist->SearchValue(gameobj);
2527 BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine);
2528 if (gameobj->GetOccluder())
2533 kxscene->SetDbvtOcclusionRes(blenderscene->gm.occlusionRes);
2535 if (blenderscene->world)
2536 kxscene->GetPhysicsEnvironment()->setNumTimeSubSteps(blenderscene->gm.physubstep);
2538 // now that the scenegraph is complete, let's instantiate the deformers.
2539 // We need that to create reusable derived mesh and physic shapes
2540 for (i=0;i<sumolist->GetCount();++i)
2542 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2543 if (gameobj->GetDeformer())
2544 gameobj->GetDeformer()->UpdateBuckets();
2547 // Set up armature constraints
2548 for (i=0;i<sumolist->GetCount();++i)
2550 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2551 if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
2552 ((BL_ArmatureObject*)gameobj)->LoadConstraints(converter);
2555 bool processCompoundChildren = false;
2557 // create physics information
2558 for (i=0;i<sumolist->GetCount();i++)
2560 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2561 struct Object* blenderobject = gameobj->GetBlenderObject();
2562 int nummeshes = gameobj->GetMeshCount();
2563 RAS_MeshObject* meshobj = 0;
2566 meshobj = gameobj->GetMesh(0);
2568 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
2569 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
2572 processCompoundChildren = true;
2573 // create physics information
2574 for (i=0;i<sumolist->GetCount();i++)
2576 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2577 struct Object* blenderobject = gameobj->GetBlenderObject();
2578 int nummeshes = gameobj->GetMeshCount();
2579 RAS_MeshObject* meshobj = 0;
2582 meshobj = gameobj->GetMesh(0);
2584 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
2585 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
2588 //set ini linearVel and int angularVel //rcruiz
2589 if (converter->addInitFromFrame)
2590 for (i=0;i<sumolist->GetCount();i++)
2592 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2593 if (gameobj->IsDynamic()){
2594 gameobj->setLinearVelocity(inivel[i],false);
2595 gameobj->setAngularVelocity(iniang[i],false);
2601 // create physics joints
2602 for (i=0;i<sumolist->GetCount();i++)
2604 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
2605 struct Object* blenderobject = gameobj->GetBlenderObject();
2607 bConstraint *curcon;
2608 conlist = get_active_constraints2(blenderobject);
2611 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) {
2612 if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT){
2614 bRigidBodyJointConstraint *dat=(bRigidBodyJointConstraint *)curcon->data;
2618 PHY_IPhysicsController* physctr2 = 0;
2622 KX_GameObject *gotar=getGameOb(dat->tar->id.name+2,sumolist);
2623 if (gotar && gotar->GetPhysicsController())
2624 physctr2 = (PHY_IPhysicsController*) gotar->GetPhysicsController()->GetUserData();
2627 if (gameobj->GetPhysicsController())
2629 PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) gameobj->GetPhysicsController()->GetUserData();
2630 //we need to pass a full constraint frame, not just axis
2632 //localConstraintFrameBasis