|
Blender
V2.59
|
00001 /* 00002 * $Id: BL_BlenderDataConversion.cpp 38501 2011-07-19 01:41:45Z dfelinto $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * Convert blender data to ketsji 00029 */ 00030 00036 #if defined(WIN32) && !defined(FREE_WINDOWS) 00037 #pragma warning (disable : 4786) 00038 #endif 00039 00040 #include <math.h> 00041 00042 #include "BL_BlenderDataConversion.h" 00043 #include "KX_BlenderGL.h" 00044 #include "KX_BlenderScalarInterpolator.h" 00045 00046 #include "RAS_IPolygonMaterial.h" 00047 #include "KX_PolygonMaterial.h" 00048 00049 // Expressions 00050 #include "ListValue.h" 00051 #include "IntValue.h" 00052 // Collision & Fuzzics LTD 00053 00054 #include "PHY_Pro.h" 00055 00056 00057 #include "KX_Scene.h" 00058 #include "KX_GameObject.h" 00059 #include "RAS_FramingManager.h" 00060 #include "RAS_MeshObject.h" 00061 00062 #include "KX_ConvertActuators.h" 00063 #include "KX_ConvertControllers.h" 00064 #include "KX_ConvertSensors.h" 00065 00066 #include "SCA_LogicManager.h" 00067 #include "SCA_EventManager.h" 00068 #include "SCA_TimeEventManager.h" 00069 #include "KX_Light.h" 00070 #include "KX_Camera.h" 00071 #include "KX_EmptyObject.h" 00072 #include "KX_FontObject.h" 00073 #include "MT_Point3.h" 00074 #include "MT_Transform.h" 00075 #include "MT_MinMax.h" 00076 #include "SCA_IInputDevice.h" 00077 #include "RAS_TexMatrix.h" 00078 #include "RAS_ICanvas.h" 00079 #include "RAS_MaterialBucket.h" 00080 //#include "KX_BlenderPolyMaterial.h" 00081 #include "RAS_Polygon.h" 00082 #include "RAS_TexVert.h" 00083 #include "RAS_BucketManager.h" 00084 #include "RAS_IRenderTools.h" 00085 #include "BL_Material.h" 00086 #include "KX_BlenderMaterial.h" 00087 #include "BL_Texture.h" 00088 00089 #include "DNA_action_types.h" 00090 #include "BKE_main.h" 00091 #include "BKE_global.h" 00092 #include "BKE_object.h" 00093 #include "BL_ModifierDeformer.h" 00094 #include "BL_ShapeDeformer.h" 00095 #include "BL_SkinDeformer.h" 00096 #include "BL_MeshDeformer.h" 00097 #include "KX_SoftBodyDeformer.h" 00098 //#include "BL_ArmatureController.h" 00099 #include "BLI_utildefines.h" 00100 #include "BlenderWorldInfo.h" 00101 00102 #include "KX_KetsjiEngine.h" 00103 #include "KX_BlenderSceneConverter.h" 00104 00105 /* This little block needed for linking to Blender... */ 00106 #ifdef WIN32 00107 #include "BLI_winstuff.h" 00108 #endif 00109 00110 /* This list includes only data type definitions */ 00111 #include "DNA_object_types.h" 00112 #include "DNA_material_types.h" 00113 #include "DNA_texture_types.h" 00114 #include "DNA_image_types.h" 00115 #include "DNA_lamp_types.h" 00116 #include "DNA_group_types.h" 00117 #include "DNA_scene_types.h" 00118 #include "DNA_camera_types.h" 00119 #include "DNA_property_types.h" 00120 #include "DNA_text_types.h" 00121 #include "DNA_sensor_types.h" 00122 #include "DNA_controller_types.h" 00123 #include "DNA_actuator_types.h" 00124 #include "DNA_mesh_types.h" 00125 #include "DNA_meshdata_types.h" 00126 #include "DNA_view3d_types.h" 00127 #include "DNA_world_types.h" 00128 #include "DNA_sound_types.h" 00129 #include "DNA_key_types.h" 00130 #include "DNA_armature_types.h" 00131 #include "DNA_object_force.h" 00132 00133 #include "MEM_guardedalloc.h" 00134 00135 #include "BKE_key.h" 00136 #include "BKE_mesh.h" 00137 #include "MT_Point3.h" 00138 00139 #include "BLI_math.h" 00140 00141 extern "C" { 00142 #include "BKE_scene.h" 00143 #include "BKE_customdata.h" 00144 #include "BKE_cdderivedmesh.h" 00145 #include "BKE_DerivedMesh.h" 00146 #include "BKE_material.h" /* give_current_material */ 00147 00148 extern Material defmaterial; /* material.c */ 00149 } 00150 00151 /* end of blender include block */ 00152 00153 #include "KX_BlenderInputDevice.h" 00154 #include "KX_ConvertProperties.h" 00155 #include "KX_HashedPtr.h" 00156 00157 00158 #include "KX_ScalarInterpolator.h" 00159 00160 #include "KX_IpoConvert.h" 00161 #include "BL_System.h" 00162 00163 #include "SG_Node.h" 00164 #include "SG_BBox.h" 00165 #include "SG_Tree.h" 00166 00167 #include "KX_ConvertPhysicsObject.h" 00168 #ifdef USE_BULLET 00169 #include "CcdPhysicsEnvironment.h" 00170 #include "CcdGraphicController.h" 00171 #endif 00172 #include "KX_MotionState.h" 00173 00174 // This file defines relationships between parents and children 00175 // in the game engine. 00176 00177 #include "KX_SG_NodeRelationships.h" 00178 #include "KX_SG_BoneParentNodeRelationship.h" 00179 00180 #include "BL_ArmatureObject.h" 00181 #include "BL_DeformableGameObject.h" 00182 00183 #ifdef __cplusplus 00184 extern "C" { 00185 #endif 00186 //XXX #include "BSE_headerbuttons.h" 00187 //XXX void update_for_newframe(); 00188 //void scene_update_for_newframe(struct Scene *sce, unsigned int lay); 00189 //#include "BKE_ipo.h" 00190 //void do_all_data_ipos(void); 00191 #ifdef __cplusplus 00192 } 00193 #endif 00194 00195 static int default_face_mode = TF_DYNAMIC; 00196 00197 static unsigned int KX_rgbaint2uint_new(unsigned int icol) 00198 { 00199 union 00200 { 00201 unsigned int integer; 00202 unsigned char cp[4]; 00203 } out_color, in_color; 00204 00205 in_color.integer = icol; 00206 out_color.cp[0] = in_color.cp[3]; // red 00207 out_color.cp[1] = in_color.cp[2]; // green 00208 out_color.cp[2] = in_color.cp[1]; // blue 00209 out_color.cp[3] = in_color.cp[0]; // alpha 00210 00211 return out_color.integer; 00212 } 00213 00214 /* Now the real converting starts... */ 00215 static unsigned int KX_Mcol2uint_new(MCol col) 00216 { 00217 /* color has to be converted without endian sensitivity. So no shifting! */ 00218 union 00219 { 00220 MCol col; 00221 unsigned int integer; 00222 unsigned char cp[4]; 00223 } out_color, in_color; 00224 00225 in_color.col = col; 00226 out_color.cp[0] = in_color.cp[3]; // red 00227 out_color.cp[1] = in_color.cp[2]; // green 00228 out_color.cp[2] = in_color.cp[1]; // blue 00229 out_color.cp[3] = in_color.cp[0]; // alpha 00230 00231 return out_color.integer; 00232 } 00233 00234 static void SetDefaultFaceType(Scene* scene) 00235 { 00236 default_face_mode = TF_DYNAMIC; 00237 Scene *sce_iter; 00238 Base *base; 00239 00240 for(SETLOOPER(scene, sce_iter, base)) 00241 { 00242 if (base->object->type == OB_LAMP) 00243 { 00244 default_face_mode = TF_DYNAMIC|TF_LIGHT; 00245 return; 00246 } 00247 } 00248 } 00249 00250 00251 // -- 00252 static void GetRGB(short type, 00253 MFace* mface, 00254 MCol* mmcol, 00255 Material *mat, 00256 unsigned int &c0, 00257 unsigned int &c1, 00258 unsigned int &c2, 00259 unsigned int &c3) 00260 { 00261 unsigned int color = 0xFFFFFFFFL; 00262 switch(type) 00263 { 00264 case 0: // vertex colors 00265 { 00266 if(mmcol) { 00267 c0 = KX_Mcol2uint_new(mmcol[0]); 00268 c1 = KX_Mcol2uint_new(mmcol[1]); 00269 c2 = KX_Mcol2uint_new(mmcol[2]); 00270 if (mface->v4) 00271 c3 = KX_Mcol2uint_new(mmcol[3]); 00272 }else // backup white 00273 { 00274 c0 = KX_rgbaint2uint_new(color); 00275 c1 = KX_rgbaint2uint_new(color); 00276 c2 = KX_rgbaint2uint_new(color); 00277 if (mface->v4) 00278 c3 = KX_rgbaint2uint_new( color ); 00279 } 00280 } break; 00281 00282 00283 case 1: // material rgba 00284 { 00285 if (mat) { 00286 union { 00287 unsigned char cp[4]; 00288 unsigned int integer; 00289 } col_converter; 00290 col_converter.cp[3] = (unsigned char) (mat->r*255.0); 00291 col_converter.cp[2] = (unsigned char) (mat->g*255.0); 00292 col_converter.cp[1] = (unsigned char) (mat->b*255.0); 00293 col_converter.cp[0] = (unsigned char) (mat->alpha*255.0); 00294 color = col_converter.integer; 00295 } 00296 c0 = KX_rgbaint2uint_new(color); 00297 c1 = KX_rgbaint2uint_new(color); 00298 c2 = KX_rgbaint2uint_new(color); 00299 if (mface->v4) 00300 c3 = KX_rgbaint2uint_new(color); 00301 } break; 00302 00303 default: // white 00304 { 00305 c0 = KX_rgbaint2uint_new(color); 00306 c1 = KX_rgbaint2uint_new(color); 00307 c2 = KX_rgbaint2uint_new(color); 00308 if (mface->v4) 00309 c3 = KX_rgbaint2uint_new(color); 00310 } break; 00311 } 00312 } 00313 00314 typedef struct MTF_localLayer 00315 { 00316 MTFace *face; 00317 const char *name; 00318 }MTF_localLayer; 00319 00320 // ------------------------------------ 00321 bool ConvertMaterial( 00322 BL_Material *material, 00323 Material *mat, 00324 MTFace* tface, 00325 const char *tfaceName, 00326 MFace* mface, 00327 MCol* mmcol, 00328 MTF_localLayer *layers, 00329 bool glslmat) 00330 { 00331 material->Initialize(); 00332 int numchan = -1, texalpha = 0; 00333 bool validmat = (mat!=0); 00334 bool validface = (tface!=0); 00335 00336 short type = 0; 00337 if( validmat ) 00338 type = 1; // material color 00339 00340 material->IdMode = DEFAULT_BLENDER; 00341 material->glslmat = (validmat)? glslmat: false; 00342 material->materialindex = mface->mat_nr; 00343 00344 // -------------------------------- 00345 if(validmat) { 00346 00347 // use vertex colors by explicitly setting 00348 if(mat->mode &MA_VERTEXCOLP || glslmat) 00349 type = 0; 00350 00351 // use lighting? 00352 material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT; 00353 MTex *mttmp = 0; 00354 numchan = getNumTexChannels(mat); 00355 int valid_index = 0; 00356 00357 // use the face texture if 00358 // 1) it is set in the buttons 00359 // 2) we have a face texture and a material but no valid texture in slot 1 00360 bool facetex = false; 00361 if(validface && mat->mode &MA_FACETEXTURE) 00362 facetex = true; 00363 if(validface && !mat->mtex[0]) 00364 facetex = true; 00365 if(validface && mat->mtex[0]) { 00366 MTex *tmp = mat->mtex[0]; 00367 if(!tmp->tex || (tmp->tex && !tmp->tex->ima)) 00368 facetex = true; 00369 } 00370 numchan = numchan>MAXTEX?MAXTEX:numchan; 00371 00372 // foreach MTex 00373 for(int i=0; i<numchan; i++) { 00374 // use face tex 00375 00376 if(i==0 && facetex ) { 00377 Image*tmp = (Image*)(tface->tpage); 00378 00379 if(tmp) { 00380 material->img[i] = tmp; 00381 material->texname[i] = material->img[i]->id.name; 00382 material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0; 00383 material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0; 00384 material->flag[i] |= MIPMAP; 00385 00386 if(material->img[i]->flag & IMA_REFLECT) 00387 material->mapping[i].mapping |= USEREFL; 00388 else 00389 { 00390 mttmp = getImageFromMaterial( mat, i ); 00391 if(mttmp && mttmp->texco &TEXCO_UV) 00392 { 00393 STR_String uvName = mttmp->uvname; 00394 00395 if (!uvName.IsEmpty()) 00396 material->mapping[i].uvCoName = mttmp->uvname; 00397 else 00398 material->mapping[i].uvCoName = ""; 00399 } 00400 material->mapping[i].mapping |= USEUV; 00401 } 00402 00403 if(material->ras_mode & USE_LIGHT) 00404 material->ras_mode &= ~USE_LIGHT; 00405 if(tface->mode & TF_LIGHT) 00406 material->ras_mode |= USE_LIGHT; 00407 00408 valid_index++; 00409 } 00410 else { 00411 material->img[i] = 0; 00412 material->texname[i] = ""; 00413 } 00414 continue; 00415 } 00416 00417 mttmp = getImageFromMaterial( mat, i ); 00418 if( mttmp ) { 00419 if( mttmp->tex ) { 00420 if( mttmp->tex->type == TEX_IMAGE ) { 00421 material->mtexname[i] = mttmp->tex->id.name; 00422 material->img[i] = mttmp->tex->ima; 00423 if( material->img[i] ) { 00424 00425 material->texname[i] = material->img[i]->id.name; 00426 material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0; 00427 // ----------------------- 00428 if( mttmp->tex->imaflag &TEX_USEALPHA ) { 00429 material->flag[i] |= USEALPHA; 00430 } 00431 // ----------------------- 00432 else if( mttmp->tex->imaflag &TEX_CALCALPHA ) { 00433 material->flag[i] |= CALCALPHA; 00434 } 00435 else if(mttmp->tex->flag &TEX_NEGALPHA) { 00436 material->flag[i] |= USENEGALPHA; 00437 } 00438 00439 material->color_blend[i] = mttmp->colfac; 00440 material->flag[i] |= ( mttmp->mapto & MAP_ALPHA )?TEXALPHA:0; 00441 material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0; 00442 00443 if(!glslmat && (material->flag[i] & TEXALPHA)) 00444 texalpha = 1; 00445 } 00446 } 00447 else if(mttmp->tex->type == TEX_ENVMAP) { 00448 if( mttmp->tex->env->stype == ENV_LOAD ) { 00449 00450 material->mtexname[i] = mttmp->tex->id.name; 00451 EnvMap *env = mttmp->tex->env; 00452 env->ima = mttmp->tex->ima; 00453 material->cubemap[i] = env; 00454 00455 if (material->cubemap[i]) 00456 { 00457 if (!material->cubemap[i]->cube[0]) 00458 BL_Texture::SplitEnvMap(material->cubemap[i]); 00459 00460 material->texname[i]= material->cubemap[i]->ima->id.name; 00461 material->mapping[i].mapping |= USEENV; 00462 } 00463 } 00464 } 00465 #if 0 /* this flag isnt used anymore */ 00466 material->flag[i] |= (BKE_animdata_from_id(mat->id) != NULL) ? HASIPO : 0; 00467 #endif 00468 00469 // mapping methods 00470 material->mapping[i].mapping |= ( mttmp->texco & TEXCO_REFL )?USEREFL:0; 00471 00472 if(mttmp->texco & TEXCO_OBJECT) { 00473 material->mapping[i].mapping |= USEOBJ; 00474 if(mttmp->object) 00475 material->mapping[i].objconame = mttmp->object->id.name; 00476 } 00477 else if(mttmp->texco &TEXCO_REFL) 00478 material->mapping[i].mapping |= USEREFL; 00479 else if(mttmp->texco &(TEXCO_ORCO|TEXCO_GLOB)) 00480 material->mapping[i].mapping |= USEORCO; 00481 else if(mttmp->texco &TEXCO_UV) 00482 { 00483 STR_String uvName = mttmp->uvname; 00484 00485 if (!uvName.IsEmpty()) 00486 material->mapping[i].uvCoName = mttmp->uvname; 00487 else 00488 material->mapping[i].uvCoName = ""; 00489 material->mapping[i].mapping |= USEUV; 00490 } 00491 else if(mttmp->texco &TEXCO_NORM) 00492 material->mapping[i].mapping |= USENORM; 00493 else if(mttmp->texco &TEXCO_TANGENT) 00494 material->mapping[i].mapping |= USETANG; 00495 else 00496 material->mapping[i].mapping |= DISABLE; 00497 00498 material->mapping[i].scale[0] = mttmp->size[0]; 00499 material->mapping[i].scale[1] = mttmp->size[1]; 00500 material->mapping[i].scale[2] = mttmp->size[2]; 00501 material->mapping[i].offsets[0] = mttmp->ofs[0]; 00502 material->mapping[i].offsets[1] = mttmp->ofs[1]; 00503 material->mapping[i].offsets[2] = mttmp->ofs[2]; 00504 00505 material->mapping[i].projplane[0] = mttmp->projx; 00506 material->mapping[i].projplane[1] = mttmp->projy; 00507 material->mapping[i].projplane[2] = mttmp->projz; 00509 00510 switch( mttmp->blendtype ) { 00511 case MTEX_BLEND: 00512 material->blend_mode[i] = BLEND_MIX; 00513 break; 00514 case MTEX_MUL: 00515 material->blend_mode[i] = BLEND_MUL; 00516 break; 00517 case MTEX_ADD: 00518 material->blend_mode[i] = BLEND_ADD; 00519 break; 00520 case MTEX_SUB: 00521 material->blend_mode[i] = BLEND_SUB; 00522 break; 00523 case MTEX_SCREEN: 00524 material->blend_mode[i] = BLEND_SCR; 00525 break; 00526 } 00527 valid_index++; 00528 } 00529 } 00530 } 00531 00532 // above one tex the switches here 00533 // are not used 00534 switch(valid_index) { 00535 case 0: 00536 material->IdMode = DEFAULT_BLENDER; 00537 break; 00538 case 1: 00539 material->IdMode = ONETEX; 00540 break; 00541 default: 00542 material->IdMode = GREATERTHAN2; 00543 break; 00544 } 00545 material->SetUsers(mat->id.us); 00546 00547 material->num_enabled = valid_index; 00548 00549 material->speccolor[0] = mat->specr; 00550 material->speccolor[1] = mat->specg; 00551 material->speccolor[2] = mat->specb; 00552 material->hard = (float)mat->har/4.0f; 00553 material->matcolor[0] = mat->r; 00554 material->matcolor[1] = mat->g; 00555 material->matcolor[2] = mat->b; 00556 material->matcolor[3] = mat->alpha; 00557 material->alpha = mat->alpha; 00558 material->emit = mat->emit; 00559 material->spec_f = mat->spec; 00560 material->ref = mat->ref; 00561 material->amb = mat->amb; 00562 00563 material->ras_mode |= (mat->material_type == MA_TYPE_WIRE)? WIRE: 0; 00564 } 00565 else { 00566 int valid = 0; 00567 00568 // check for tface tex to fallback on 00569 if( validface ){ 00570 00571 // no light bugfix 00572 if(tface->mode) material->ras_mode |= USE_LIGHT; 00573 00574 material->img[0] = (Image*)(tface->tpage); 00575 // ------------------------ 00576 if(material->img[0]) { 00577 material->texname[0] = material->img[0]->id.name; 00578 material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0; 00579 material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0; 00580 material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0; 00581 valid++; 00582 } 00583 } 00584 material->SetUsers(-1); 00585 material->num_enabled = valid; 00586 material->IdMode = TEXFACE; 00587 material->speccolor[0] = 1.f; 00588 material->speccolor[1] = 1.f; 00589 material->speccolor[2] = 1.f; 00590 material->hard = 35.f; 00591 material->matcolor[0] = 0.5f; 00592 material->matcolor[1] = 0.5f; 00593 material->matcolor[2] = 0.5f; 00594 material->spec_f = 0.5f; 00595 material->ref = 0.8f; 00596 } 00597 MT_Point2 uv[4]; 00598 MT_Point2 uv2[4]; 00599 const char *uvName = "", *uv2Name = ""; 00600 00601 00602 uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f); 00603 00604 if( validface ) { 00605 00606 material->ras_mode |= (tface->mode & TF_INVISIBLE)?0:POLY_VIS; 00607 00608 material->transp = tface->transp; 00609 material->tile = tface->tile; 00610 material->mode = tface->mode; 00611 00612 uv[0].setValue(tface->uv[0]); 00613 uv[1].setValue(tface->uv[1]); 00614 uv[2].setValue(tface->uv[2]); 00615 00616 if (mface->v4) 00617 uv[3].setValue(tface->uv[3]); 00618 00619 uvName = tfaceName; 00620 } 00621 else { 00622 // nothing at all 00623 material->ras_mode |= (POLY_VIS| (validmat?0:USE_LIGHT)); 00624 material->mode = default_face_mode; 00625 material->transp = TF_SOLID; 00626 material->tile = 0; 00627 00628 uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f); 00629 } 00630 00631 // with ztransp enabled, enforce alpha blending mode 00632 if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->transp == TF_SOLID)) 00633 material->transp = TF_ALPHA; 00634 00635 // always zsort alpha + add 00636 if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) && (material->transp != TF_CLIP)) { 00637 material->ras_mode |= ALPHA; 00638 material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0; 00639 } 00640 00641 // collider or not? 00642 material->ras_mode |= (material->mode & TF_DYNAMIC)? COLLIDER: 0; 00643 00644 // these flags are irrelevant at this point, remove so they 00645 // don't hurt material bucketing 00646 material->mode &= ~(TF_DYNAMIC|TF_ALPHASORT|TF_TEX); 00647 00648 // get uv sets 00649 if(validmat) 00650 { 00651 bool isFirstSet = true; 00652 00653 // only two sets implemented, but any of the eight 00654 // sets can make up the two layers 00655 for (int vind = 0; vind<material->num_enabled; vind++) 00656 { 00657 BL_Mapping &map = material->mapping[vind]; 00658 00659 if (map.uvCoName.IsEmpty()) 00660 isFirstSet = false; 00661 else 00662 { 00663 for (int lay=0; lay<MAX_MTFACE; lay++) 00664 { 00665 MTF_localLayer& layer = layers[lay]; 00666 if (layer.face == 0) break; 00667 00668 if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) 00669 { 00670 MT_Point2 uvSet[4]; 00671 00672 uvSet[0].setValue(layer.face->uv[0]); 00673 uvSet[1].setValue(layer.face->uv[1]); 00674 uvSet[2].setValue(layer.face->uv[2]); 00675 00676 if (mface->v4) 00677 uvSet[3].setValue(layer.face->uv[3]); 00678 else 00679 uvSet[3].setValue(0.0f, 0.0f); 00680 00681 if (isFirstSet) 00682 { 00683 uv[0] = uvSet[0]; uv[1] = uvSet[1]; 00684 uv[2] = uvSet[2]; uv[3] = uvSet[3]; 00685 isFirstSet = false; 00686 uvName = layer.name; 00687 } 00688 else if(strcmp(layer.name, uvName) != 0) 00689 { 00690 uv2[0] = uvSet[0]; uv2[1] = uvSet[1]; 00691 uv2[2] = uvSet[2]; uv2[3] = uvSet[3]; 00692 map.mapping |= USECUSTOMUV; 00693 uv2Name = layer.name; 00694 } 00695 } 00696 } 00697 } 00698 } 00699 } 00700 00701 unsigned int rgb[4]; 00702 GetRGB(type,mface,mmcol,mat,rgb[0],rgb[1],rgb[2], rgb[3]); 00703 00704 // swap the material color, so MCol on TF_BMFONT works 00705 if (validmat && type==1 && (tface && tface->mode & TF_BMFONT)) 00706 { 00707 rgb[0] = KX_rgbaint2uint_new(rgb[0]); 00708 rgb[1] = KX_rgbaint2uint_new(rgb[1]); 00709 rgb[2] = KX_rgbaint2uint_new(rgb[2]); 00710 rgb[3] = KX_rgbaint2uint_new(rgb[3]); 00711 } 00712 00713 material->SetConversionRGB(rgb); 00714 material->SetConversionUV(uvName, uv); 00715 material->SetConversionUV2(uv2Name, uv2); 00716 00717 if(validmat) 00718 material->matname =(mat->id.name); 00719 00720 material->tface = tface; 00721 material->material = mat; 00722 return true; 00723 } 00724 00725 /* blenderobj can be NULL, make sure its checked for */ 00726 RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter) 00727 { 00728 RAS_MeshObject *meshobj; 00729 int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object. 00730 00731 if ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL) 00732 return meshobj; 00733 // Get DerivedMesh data 00734 DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj); 00735 00736 MVert *mvert = dm->getVertArray(dm); 00737 int totvert = dm->getNumVerts(dm); 00738 00739 MFace *mface = dm->getFaceArray(dm); 00740 MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE)); 00741 MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL)); 00742 float (*tangent)[4] = NULL; 00743 int totface = dm->getNumFaces(dm); 00744 const char *tfaceName = ""; 00745 00746 if(tface) { 00747 DM_add_tangent_layer(dm); 00748 tangent = (float(*)[4])dm->getFaceDataArray(dm, CD_TANGENT); 00749 } 00750 00751 meshobj = new RAS_MeshObject(mesh); 00752 00753 // Extract avaiable layers 00754 MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE]; 00755 for (int lay=0; lay<MAX_MTFACE; lay++) { 00756 layers[lay].face = 0; 00757 layers[lay].name = ""; 00758 } 00759 00760 int validLayers = 0; 00761 for (int i=0; i<dm->faceData.totlayer; i++) 00762 { 00763 if (dm->faceData.layers[i].type == CD_MTFACE) 00764 { 00765 assert(validLayers <= 8); 00766 00767 layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data); 00768 layers[validLayers].name = dm->faceData.layers[i].name; 00769 if(tface == layers[validLayers].face) 00770 tfaceName = layers[validLayers].name; 00771 validLayers++; 00772 } 00773 } 00774 00775 meshobj->SetName(mesh->id.name + 2); 00776 meshobj->m_sharedvertex_map.resize(totvert); 00777 RAS_IPolyMaterial* polymat = NULL; 00778 STR_String imastr; 00779 // These pointers will hold persistent material structure during the conversion 00780 // to avoid countless allocation/deallocation of memory. 00781 BL_Material* bl_mat = NULL; 00782 KX_BlenderMaterial* kx_blmat = NULL; 00783 KX_PolygonMaterial* kx_polymat = NULL; 00784 00785 for (int f=0;f<totface;f++,mface++) 00786 { 00787 Material* ma = 0; 00788 bool collider = true; 00789 MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0); 00790 MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0); 00791 unsigned int rgb0,rgb1,rgb2,rgb3 = 0; 00792 00793 MT_Point3 pt0, pt1, pt2, pt3; 00794 MT_Vector3 no0(0,0,0), no1(0,0,0), no2(0,0,0), no3(0,0,0); 00795 MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0); 00796 00797 /* get coordinates, normals and tangents */ 00798 pt0.setValue(mvert[mface->v1].co); 00799 pt1.setValue(mvert[mface->v2].co); 00800 pt2.setValue(mvert[mface->v3].co); 00801 if (mface->v4) pt3.setValue(mvert[mface->v4].co); 00802 00803 if(mface->flag & ME_SMOOTH) { 00804 float n0[3], n1[3], n2[3], n3[3]; 00805 00806 normal_short_to_float_v3(n0, mvert[mface->v1].no); 00807 normal_short_to_float_v3(n1, mvert[mface->v2].no); 00808 normal_short_to_float_v3(n2, mvert[mface->v3].no); 00809 no0 = n0; 00810 no1 = n1; 00811 no2 = n2; 00812 00813 if(mface->v4) { 00814 normal_short_to_float_v3(n3, mvert[mface->v4].no); 00815 no3 = n3; 00816 } 00817 } 00818 else { 00819 float fno[3]; 00820 00821 if(mface->v4) 00822 normal_quad_v3( fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); 00823 else 00824 normal_tri_v3( fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co); 00825 00826 no0 = no1 = no2 = no3 = MT_Vector3(fno); 00827 } 00828 00829 if(tangent) { 00830 tan0 = tangent[f*4 + 0]; 00831 tan1 = tangent[f*4 + 1]; 00832 tan2 = tangent[f*4 + 2]; 00833 00834 if (mface->v4) 00835 tan3 = tangent[f*4 + 3]; 00836 } 00837 if(blenderobj) 00838 ma = give_current_material(blenderobj, mface->mat_nr+1); 00839 else 00840 ma = mesh->mat ? mesh->mat[mface->mat_nr]:NULL; 00841 00842 /* ckeck for texface since texface _only_ is used as a fallback */ 00843 if(ma == NULL && tface == NULL) { 00844 ma= &defmaterial; 00845 } 00846 00847 { 00848 bool visible = true; 00849 bool twoside = false; 00850 00851 if(converter->GetMaterials()) { 00852 /* do Blender Multitexture and Blender GLSL materials */ 00853 unsigned int rgb[4]; 00854 MT_Point2 uv[4]; 00855 00856 /* first is the BL_Material */ 00857 if (!bl_mat) 00858 bl_mat = new BL_Material(); 00859 ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, 00860 layers, converter->GetGLSLMaterials()); 00861 00862 visible = ((bl_mat->ras_mode & POLY_VIS)!=0); 00863 collider = ((bl_mat->ras_mode & COLLIDER)!=0); 00864 twoside = ((bl_mat->mode & TF_TWOSIDE)!=0); 00865 00866 /* vertex colors and uv's were stored in bl_mat temporarily */ 00867 bl_mat->GetConversionRGB(rgb); 00868 rgb0 = rgb[0]; rgb1 = rgb[1]; 00869 rgb2 = rgb[2]; rgb3 = rgb[3]; 00870 00871 bl_mat->GetConversionUV(uv); 00872 uv0 = uv[0]; uv1 = uv[1]; 00873 uv2 = uv[2]; uv3 = uv[3]; 00874 00875 bl_mat->GetConversionUV2(uv); 00876 uv20 = uv[0]; uv21 = uv[1]; 00877 uv22 = uv[2]; uv23 = uv[3]; 00878 00879 /* then the KX_BlenderMaterial */ 00880 if (kx_blmat == NULL) 00881 kx_blmat = new KX_BlenderMaterial(); 00882 00883 kx_blmat->Initialize(scene, bl_mat); 00884 polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat); 00885 } 00886 else { 00887 /* do Texture Face materials */ 00888 Image* bima = (tface)? (Image*)tface->tpage: NULL; 00889 imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; 00890 00891 char transp=0; 00892 short mode=0, tile=0; 00893 int tilexrep=4,tileyrep = 4; 00894 00895 if (bima) { 00896 tilexrep = bima->xrep; 00897 tileyrep = bima->yrep; 00898 } 00899 00900 /* get tface properties if available */ 00901 if(tface) { 00902 /* TF_DYNAMIC means the polygon is a collision face */ 00903 collider = ((tface->mode & TF_DYNAMIC) != 0); 00904 transp = tface->transp; 00905 tile = tface->tile; 00906 mode = tface->mode; 00907 00908 visible = !(tface->mode & TF_INVISIBLE); 00909 twoside = ((tface->mode & TF_TWOSIDE)!=0); 00910 00911 uv0.setValue(tface->uv[0]); 00912 uv1.setValue(tface->uv[1]); 00913 uv2.setValue(tface->uv[2]); 00914 00915 if (mface->v4) 00916 uv3.setValue(tface->uv[3]); 00917 } 00918 else { 00919 /* no texfaces, set COLLSION true and everything else FALSE */ 00920 mode = default_face_mode; 00921 transp = TF_SOLID; 00922 tile = 0; 00923 } 00924 00925 /* get vertex colors */ 00926 if (mcol) { 00927 /* we have vertex colors */ 00928 rgb0 = KX_Mcol2uint_new(mcol[0]); 00929 rgb1 = KX_Mcol2uint_new(mcol[1]); 00930 rgb2 = KX_Mcol2uint_new(mcol[2]); 00931 00932 if (mface->v4) 00933 rgb3 = KX_Mcol2uint_new(mcol[3]); 00934 } 00935 else { 00936 /* no vertex colors, take from material, otherwise white */ 00937 unsigned int color = 0xFFFFFFFFL; 00938 00939 if (ma) 00940 { 00941 union 00942 { 00943 unsigned char cp[4]; 00944 unsigned int integer; 00945 } col_converter; 00946 00947 col_converter.cp[3] = (unsigned char) (ma->r*255.0); 00948 col_converter.cp[2] = (unsigned char) (ma->g*255.0); 00949 col_converter.cp[1] = (unsigned char) (ma->b*255.0); 00950 col_converter.cp[0] = (unsigned char) (ma->alpha*255.0); 00951 00952 color = col_converter.integer; 00953 } 00954 00955 rgb0 = KX_rgbaint2uint_new(color); 00956 rgb1 = KX_rgbaint2uint_new(color); 00957 rgb2 = KX_rgbaint2uint_new(color); 00958 00959 if (mface->v4) 00960 rgb3 = KX_rgbaint2uint_new(color); 00961 } 00962 00963 // only zsort alpha + add 00964 bool alpha = (transp == TF_ALPHA || transp == TF_ADD); 00965 bool zsort = (mode & TF_ALPHASORT)? alpha: 0; 00966 00967 if (kx_polymat == NULL) 00968 kx_polymat = new KX_PolygonMaterial(); 00969 kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr, 00970 tile, tilexrep, tileyrep, 00971 mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol); 00972 polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat); 00973 00974 if (ma) { 00975 polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec; 00976 polymat->m_shininess = (float)ma->har/4.0f; // 0 < ma->har <= 512 00977 polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref); 00978 } 00979 else { 00980 polymat->m_specular.setValue(0.0f,0.0f,0.0f); 00981 polymat->m_shininess = 35.0; 00982 } 00983 } 00984 00985 /* mark face as flat, so vertices are split */ 00986 bool flat = (mface->flag & ME_SMOOTH) == 0; 00987 00988 // see if a bucket was reused or a new one was created 00989 // this way only one KX_BlenderMaterial object has to exist per bucket 00990 bool bucketCreated; 00991 RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated); 00992 if (bucketCreated) { 00993 // this is needed to free up memory afterwards 00994 converter->RegisterPolyMaterial(polymat); 00995 if(converter->GetMaterials()) { 00996 converter->RegisterBlenderMaterial(bl_mat); 00997 // the poly material has been stored in the bucket, next time we must create a new one 00998 bl_mat = NULL; 00999 kx_blmat = NULL; 01000 } else { 01001 // the poly material has been stored in the bucket, next time we must create a new one 01002 kx_polymat = NULL; 01003 } 01004 } else { 01005 // from now on, use the polygon material from the material bucket 01006 polymat = bucket->GetPolyMaterial(); 01007 // keep the material pointers, they will be reused for next face 01008 } 01009 01010 int nverts = (mface->v4)? 4: 3; 01011 RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts); 01012 01013 poly->SetVisible(visible); 01014 poly->SetCollider(collider); 01015 poly->SetTwoside(twoside); 01016 //poly->SetEdgeCode(mface->edcode); 01017 01018 meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1); 01019 meshobj->AddVertex(poly,1,pt1,uv1,uv21,tan1,rgb1,no1,flat,mface->v2); 01020 meshobj->AddVertex(poly,2,pt2,uv2,uv22,tan2,rgb2,no2,flat,mface->v3); 01021 01022 if (nverts==4) 01023 meshobj->AddVertex(poly,3,pt3,uv3,uv23,tan3,rgb3,no3,flat,mface->v4); 01024 } 01025 01026 if (tface) 01027 tface++; 01028 if (mcol) 01029 mcol+=4; 01030 01031 for (int lay=0; lay<MAX_MTFACE; lay++) 01032 { 01033 MTF_localLayer &layer = layers[lay]; 01034 if (layer.face == 0) break; 01035 01036 layer.face++; 01037 } 01038 } 01039 // keep meshobj->m_sharedvertex_map for reinstance phys mesh. 01040 // 2.49a and before it did: meshobj->m_sharedvertex_map.clear(); 01041 // but this didnt save much ram. - Campbell 01042 meshobj->EndConversion(); 01043 01044 // pre calculate texture generation 01045 for(list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial(); 01046 mit != meshobj->GetLastMaterial(); ++ mit) { 01047 mit->m_bucket->GetPolyMaterial()->OnConstruction(lightlayer); 01048 } 01049 01050 if (layers) 01051 delete []layers; 01052 01053 dm->release(dm); 01054 // cleanup material 01055 if (bl_mat) 01056 delete bl_mat; 01057 if (kx_blmat) 01058 delete kx_blmat; 01059 if (kx_polymat) 01060 delete kx_polymat; 01061 converter->RegisterGameMesh(meshobj, mesh); 01062 return meshobj; 01063 } 01064 01065 01066 01067 static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject) 01068 { 01069 PHY_MaterialProps *materialProps = new PHY_MaterialProps; 01070 01071 MT_assert(materialProps && "Create physics material properties failed"); 01072 01073 Material* blendermat = give_current_material(blenderobject, 0); 01074 01075 if (blendermat) 01076 { 01077 MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f); 01078 01079 materialProps->m_restitution = blendermat->reflect; 01080 materialProps->m_friction = blendermat->friction; 01081 materialProps->m_fh_spring = blendermat->fh; 01082 materialProps->m_fh_damping = blendermat->xyfrict; 01083 materialProps->m_fh_distance = blendermat->fhdist; 01084 materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0; 01085 } 01086 else { 01087 //give some defaults 01088 materialProps->m_restitution = 0.f; 01089 materialProps->m_friction = 0.5; 01090 materialProps->m_fh_spring = 0.f; 01091 materialProps->m_fh_damping = 0.f; 01092 materialProps->m_fh_distance = 0.f; 01093 materialProps->m_fh_normal = false; 01094 01095 } 01096 01097 return materialProps; 01098 } 01099 01100 static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject) 01101 { 01102 PHY_ShapeProps *shapeProps = new PHY_ShapeProps; 01103 01104 MT_assert(shapeProps); 01105 01106 shapeProps->m_mass = blenderobject->mass; 01107 01108 // This needs to be fixed in blender. For now, we use: 01109 01110 // in Blender, inertia stands for the size value which is equivalent to 01111 // the sphere radius 01112 shapeProps->m_inertia = blenderobject->formfactor; 01113 01114 MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f); 01115 MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f); 01116 01117 shapeProps->m_lin_drag = 1.0 - blenderobject->damping; 01118 shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping; 01119 01120 shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0]; 01121 shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1]; 01122 shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2]; 01123 shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0); 01124 01125 shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0; 01126 shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0; 01127 01128 // velocity clamping XXX 01129 shapeProps->m_clamp_vel_min = blenderobject->min_vel; 01130 shapeProps->m_clamp_vel_max = blenderobject->max_vel; 01131 01132 return shapeProps; 01133 } 01134 01135 01136 01137 01138 01140 01141 01142 01143 static float my_boundbox_mesh(Mesh *me, float *loc, float *size) 01144 { 01145 MVert *mvert; 01146 BoundBox *bb; 01147 float min[3], max[3]; 01148 float mloc[3], msize[3]; 01149 float radius=0.0f, vert_radius, *co; 01150 int a; 01151 01152 if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox"); 01153 bb= me->bb; 01154 01155 INIT_MINMAX(min, max); 01156 01157 if (!loc) loc= mloc; 01158 if (!size) size= msize; 01159 01160 mvert= me->mvert; 01161 for(a=0; a<me->totvert; a++, mvert++) { 01162 co= mvert->co; 01163 01164 /* bounds */ 01165 DO_MINMAX(co, min, max); 01166 01167 /* radius */ 01168 vert_radius= co[0]*co[0] + co[1]*co[1] + co[2]*co[2]; 01169 if (vert_radius > radius) 01170 radius= vert_radius; 01171 } 01172 01173 if(me->totvert) { 01174 loc[0]= (min[0]+max[0])/2.0f; 01175 loc[1]= (min[1]+max[1])/2.0f; 01176 loc[2]= (min[2]+max[2])/2.0f; 01177 01178 size[0]= (max[0]-min[0])/2.0f; 01179 size[1]= (max[1]-min[1])/2.0f; 01180 size[2]= (max[2]-min[2])/2.0f; 01181 } 01182 else { 01183 loc[0]= loc[1]= loc[2]= 0.0f; 01184 size[0]= size[1]= size[2]= 0.0f; 01185 } 01186 01187 bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0]; 01188 bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0]; 01189 01190 bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1]; 01191 bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1]; 01192 01193 bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2]; 01194 bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2]; 01195 01196 return sqrt(radius); 01197 } 01198 01199 01200 01201 01202 static void my_tex_space_mesh(Mesh *me) 01203 { 01204 KeyBlock *kb; 01205 float *fp, loc[3], size[3], min[3], max[3]; 01206 int a; 01207 01208 my_boundbox_mesh(me, loc, size); 01209 01210 if(me->texflag & AUTOSPACE) { 01211 if(me->key) { 01212 kb= me->key->refkey; 01213 if (kb) { 01214 01215 INIT_MINMAX(min, max); 01216 01217 fp= (float *)kb->data; 01218 for(a=0; a<kb->totelem; a++, fp+=3) { 01219 DO_MINMAX(fp, min, max); 01220 } 01221 if(kb->totelem) { 01222 loc[0]= (min[0]+max[0])/2.0f; loc[1]= (min[1]+max[1])/2.0f; loc[2]= (min[2]+max[2])/2.0f; 01223 size[0]= (max[0]-min[0])/2.0f; size[1]= (max[1]-min[1])/2.0f; size[2]= (max[2]-min[2])/2.0f; 01224 } 01225 else { 01226 loc[0]= loc[1]= loc[2]= 0.0; 01227 size[0]= size[1]= size[2]= 0.0; 01228 } 01229 01230 } 01231 } 01232 01233 VECCOPY(me->loc, loc); 01234 VECCOPY(me->size, size); 01235 me->rot[0]= me->rot[1]= me->rot[2]= 0.0f; 01236 01237 if(me->size[0]==0.0) me->size[0]= 1.0f; 01238 else if(me->size[0]>0.0 && me->size[0]< 0.00001f) me->size[0]= 0.00001f; 01239 else if(me->size[0]<0.0 && me->size[0]> -0.00001f) me->size[0]= -0.00001f; 01240 01241 if(me->size[1]==0.0) me->size[1]= 1.0f; 01242 else if(me->size[1]>0.0 && me->size[1]< 0.00001f) me->size[1]= 0.00001f; 01243 else if(me->size[1]<0.0 && me->size[1]> -0.00001f) me->size[1]= -0.00001f; 01244 01245 if(me->size[2]==0.0) me->size[2]= 1.0f; 01246 else if(me->size[2]>0.0 && me->size[2]< 0.00001f) me->size[2]= 0.00001f; 01247 else if(me->size[2]<0.0 && me->size[2]> -0.00001f) me->size[2]= -0.00001f; 01248 } 01249 01250 } 01251 01252 static void my_get_local_bounds(Object *ob, DerivedMesh *dm, float *center, float *size) 01253 { 01254 BoundBox *bb= NULL; 01255 /* uses boundbox, function used by Ketsji */ 01256 switch (ob->type) 01257 { 01258 case OB_MESH: 01259 if (dm) 01260 { 01261 float min_r[3], max_r[3]; 01262 INIT_MINMAX(min_r, max_r); 01263 dm->getMinMax(dm, min_r, max_r); 01264 size[0]= 0.5f*fabsf(max_r[0] - min_r[0]); 01265 size[1]= 0.5f*fabsf(max_r[1] - min_r[1]); 01266 size[2]= 0.5f*fabsf(max_r[2] - min_r[2]); 01267 01268 center[0]= 0.5f*(max_r[0] + min_r[0]); 01269 center[1]= 0.5f*(max_r[1] + min_r[1]); 01270 center[2]= 0.5f*(max_r[2] + min_r[2]); 01271 return; 01272 } else 01273 { 01274 bb= ( (Mesh *)ob->data )->bb; 01275 if(bb==0) 01276 { 01277 my_tex_space_mesh((struct Mesh *)ob->data); 01278 bb= ( (Mesh *)ob->data )->bb; 01279 } 01280 } 01281 break; 01282 case OB_CURVE: 01283 case OB_SURF: 01284 center[0]= center[1]= center[2]= 0.0; 01285 size[0] = size[1]=size[2]=0.0; 01286 break; 01287 case OB_FONT: 01288 center[0]= center[1]= center[2]= 0.0; 01289 size[0] = size[1]=size[2]=1.0; 01290 break; 01291 case OB_MBALL: 01292 bb= ob->bb; 01293 break; 01294 } 01295 01296 if(bb==NULL) 01297 { 01298 center[0]= center[1]= center[2]= 0.0; 01299 size[0] = size[1]=size[2]=1.0; 01300 } 01301 else 01302 { 01303 size[0]= 0.5f*fabs(bb->vec[0][0] - bb->vec[4][0]); 01304 size[1]= 0.5f*fabs(bb->vec[0][1] - bb->vec[2][1]); 01305 size[2]= 0.5f*fabs(bb->vec[0][2] - bb->vec[1][2]); 01306 01307 center[0]= 0.5f*(bb->vec[0][0] + bb->vec[4][0]); 01308 center[1]= 0.5f*(bb->vec[0][1] + bb->vec[2][1]); 01309 center[2]= 0.5f*(bb->vec[0][2] + bb->vec[1][2]); 01310 } 01311 } 01312 01313 01314 01315 01317 01318 01319 void BL_CreateGraphicObjectNew(KX_GameObject* gameobj, 01320 const MT_Point3& localAabbMin, 01321 const MT_Point3& localAabbMax, 01322 KX_Scene* kxscene, 01323 bool isActive, 01324 e_PhysicsEngine physics_engine) 01325 { 01326 if (gameobj->GetMeshCount() > 0) 01327 { 01328 switch (physics_engine) 01329 { 01330 #ifdef USE_BULLET 01331 case UseBullet: 01332 { 01333 CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); 01334 assert(env); 01335 PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); 01336 CcdGraphicController* ctrl = new CcdGraphicController(env, motionstate); 01337 gameobj->SetGraphicController(ctrl); 01338 ctrl->setNewClientInfo(gameobj->getClientInfo()); 01339 ctrl->setLocalAabb(localAabbMin, localAabbMax); 01340 if (isActive) { 01341 // add first, this will create the proxy handle, only if the object is visible 01342 if (gameobj->GetVisible()) 01343 env->addCcdGraphicController(ctrl); 01344 // update the mesh if there is a deformer, this will also update the bounding box for modifiers 01345 RAS_Deformer* deformer = gameobj->GetDeformer(); 01346 if (deformer) 01347 deformer->UpdateBuckets(); 01348 } 01349 } 01350 break; 01351 #endif 01352 default: 01353 break; 01354 } 01355 } 01356 } 01357 01358 void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, 01359 struct Object* blenderobject, 01360 RAS_MeshObject* meshobj, 01361 KX_Scene* kxscene, 01362 int activeLayerBitInfo, 01363 e_PhysicsEngine physics_engine, 01364 KX_BlenderSceneConverter *converter, 01365 bool processCompoundChildren 01366 ) 01367 01368 { 01369 //SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/ 01370 //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0); 01371 //bool bRigidBody = (userigidbody == 0); 01372 01373 // object has physics representation? 01374 if (!(blenderobject->gameflag & OB_COLLISION)) 01375 return; 01376 01377 // get Root Parent of blenderobject 01378 struct Object* parent= blenderobject->parent; 01379 while(parent && parent->parent) { 01380 parent= parent->parent; 01381 } 01382 01383 bool isCompoundChild = false; 01384 bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD); 01385 01386 /* When the parent is not OB_DYNAMIC and has no OB_COLLISION then it gets no bullet controller 01387 * and cant be apart of the parents compound shape */ 01388 if (parent && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) { 01389 01390 if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD)) 01391 { 01392 isCompoundChild = true; 01393 } 01394 } 01395 if (processCompoundChildren != isCompoundChild) 01396 return; 01397 01398 01399 PHY_ShapeProps* shapeprops = 01400 CreateShapePropsFromBlenderObject(blenderobject); 01401 01402 01403 PHY_MaterialProps* smmaterial = 01404 CreateMaterialFromBlenderObject(blenderobject); 01405 01406 KX_ObjectProperties objprop; 01407 objprop.m_lockXaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0; 01408 objprop.m_lockYaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0; 01409 objprop.m_lockZaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0; 01410 objprop.m_lockXRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0; 01411 objprop.m_lockYRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0; 01412 objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0; 01413 01414 objprop.m_isCompoundChild = isCompoundChild; 01415 objprop.m_hasCompoundChildren = hasCompoundChildren; 01416 objprop.m_margin = blenderobject->margin; 01417 01418 // ACTOR is now a separate feature 01419 objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0; 01420 objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0; 01421 objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0; 01422 objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0; 01423 01425 if (objprop.m_angular_rigidbody || !objprop.m_dyna ) 01426 { 01427 objprop.m_contactProcessingThreshold = blenderobject->m_contactProcessingThreshold; 01428 } else 01429 { 01430 objprop.m_contactProcessingThreshold = 0.f; 01431 } 01432 01433 objprop.m_sensor = (blenderobject->gameflag & OB_SENSOR) != 0; 01434 01435 if (objprop.m_softbody) 01436 { 01438 if (blenderobject->bsoft) 01439 { 01440 objprop.m_gamesoftFlag = blenderobject->bsoft->flag; 01442 objprop.m_soft_linStiff = blenderobject->bsoft->linStiff; 01443 objprop.m_soft_angStiff = blenderobject->bsoft->angStiff; /* angular stiffness 0..1 */ 01444 objprop.m_soft_volume= blenderobject->bsoft->volume; /* volume preservation 0..1 */ 01445 01446 objprop.m_soft_viterations= blenderobject->bsoft->viterations; /* Velocities solver iterations */ 01447 objprop.m_soft_piterations= blenderobject->bsoft->piterations; /* Positions solver iterations */ 01448 objprop.m_soft_diterations= blenderobject->bsoft->diterations; /* Drift solver iterations */ 01449 objprop.m_soft_citerations= blenderobject->bsoft->citerations; /* Cluster solver iterations */ 01450 01451 objprop.m_soft_kSRHR_CL= blenderobject->bsoft->kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */ 01452 objprop.m_soft_kSKHR_CL= blenderobject->bsoft->kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */ 01453 objprop.m_soft_kSSHR_CL= blenderobject->bsoft->kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */ 01454 objprop.m_soft_kSR_SPLT_CL= blenderobject->bsoft->kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ 01455 01456 objprop.m_soft_kSK_SPLT_CL= blenderobject->bsoft->kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ 01457 objprop.m_soft_kSS_SPLT_CL= blenderobject->bsoft->kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ 01458 objprop.m_soft_kVCF= blenderobject->bsoft->kVCF; /* Velocities correction factor (Baumgarte) */ 01459 objprop.m_soft_kDP= blenderobject->bsoft->kDP; /* Damping coefficient [0,1] */ 01460 01461 objprop.m_soft_kDG= blenderobject->bsoft->kDG; /* Drag coefficient [0,+inf] */ 01462 objprop.m_soft_kLF= blenderobject->bsoft->kLF; /* Lift coefficient [0,+inf] */ 01463 objprop.m_soft_kPR= blenderobject->bsoft->kPR; /* Pressure coefficient [-inf,+inf] */ 01464 objprop.m_soft_kVC= blenderobject->bsoft->kVC; /* Volume conversation coefficient [0,+inf] */ 01465 01466 objprop.m_soft_kDF= blenderobject->bsoft->kDF; /* Dynamic friction coefficient [0,1] */ 01467 objprop.m_soft_kMT= blenderobject->bsoft->kMT; /* Pose matching coefficient [0,1] */ 01468 objprop.m_soft_kCHR= blenderobject->bsoft->kCHR; /* Rigid contacts hardness [0,1] */ 01469 objprop.m_soft_kKHR= blenderobject->bsoft->kKHR; /* Kinetic contacts hardness [0,1] */ 01470 01471 objprop.m_soft_kSHR= blenderobject->bsoft->kSHR; /* Soft contacts hardness [0,1] */ 01472 objprop.m_soft_kAHR= blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */ 01473 objprop.m_soft_collisionflags= blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ 01474 objprop.m_soft_numclusteriterations= blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/ 01475 //objprop.m_soft_welding = blenderobject->bsoft->welding; /* welding */ 01476 /* disable welding: it doesn't bring any additional stability and it breaks the relation between soft body collision shape and graphic mesh */ 01477 objprop.m_soft_welding = 0.f; 01478 objprop.m_margin = blenderobject->bsoft->margin; 01479 objprop.m_contactProcessingThreshold = 0.f; 01480 } else 01481 { 01482 objprop.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT; 01483 01484 objprop.m_soft_linStiff = 0.5;; 01485 objprop.m_soft_angStiff = 1.f; /* angular stiffness 0..1 */ 01486 objprop.m_soft_volume= 1.f; /* volume preservation 0..1 */ 01487 01488 01489 objprop.m_soft_viterations= 0; 01490 objprop.m_soft_piterations= 1; 01491 objprop.m_soft_diterations= 0; 01492 objprop.m_soft_citerations= 4; 01493 01494 objprop.m_soft_kSRHR_CL= 0.1f; 01495 objprop.m_soft_kSKHR_CL= 1.f; 01496 objprop.m_soft_kSSHR_CL= 0.5; 01497 objprop.m_soft_kSR_SPLT_CL= 0.5f; 01498 01499 objprop.m_soft_kSK_SPLT_CL= 0.5f; 01500 objprop.m_soft_kSS_SPLT_CL= 0.5f; 01501 objprop.m_soft_kVCF= 1; 01502 objprop.m_soft_kDP= 0; 01503 01504 objprop.m_soft_kDG= 0; 01505 objprop.m_soft_kLF= 0; 01506 objprop.m_soft_kPR= 0; 01507 objprop.m_soft_kVC= 0; 01508 01509 objprop.m_soft_kDF= 0.2f; 01510 objprop.m_soft_kMT= 0.05f; 01511 objprop.m_soft_kCHR= 1.0f; 01512 objprop.m_soft_kKHR= 0.1f; 01513 01514 objprop.m_soft_kSHR= 1.f; 01515 objprop.m_soft_kAHR= 0.7f; 01516 objprop.m_soft_collisionflags= OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS; 01517 objprop.m_soft_numclusteriterations= 16; 01518 objprop.m_soft_welding = 0.f; 01519 objprop.m_margin = 0.f; 01520 objprop.m_contactProcessingThreshold = 0.f; 01521 } 01522 } 01523 01524 objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0; 01525 objprop.m_disableSleeping = (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0;//abuse the OB_COLLISION_RESPONSE flag 01526 //mmm, for now, taks this for the size of the dynamicobject 01527 // Blender uses inertia for radius of dynamic object 01528 objprop.m_radius = blenderobject->inertia; 01529 objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0; 01530 objprop.m_dynamic_parent=NULL; 01531 objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0; 01532 objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH; 01533 01534 if ((blenderobject->gameflag & OB_SOFT_BODY) && !(blenderobject->gameflag & OB_BOUNDS)) 01535 { 01536 objprop.m_boundclass = KX_BOUNDMESH; 01537 } 01538 01539 KX_BoxBounds bb; 01540 DerivedMesh* dm = NULL; 01541 if (gameobj->GetDeformer()) 01542 dm = gameobj->GetDeformer()->GetPhysicsMesh(); 01543 my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,bb.m_extends); 01544 if (blenderobject->gameflag & OB_BOUNDS) 01545 { 01546 switch (blenderobject->boundtype) 01547 { 01548 case OB_BOUND_BOX: 01549 objprop.m_boundclass = KX_BOUNDBOX; 01550 //mmm, has to be divided by 2 to be proper extends 01551 objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_extends[0]; 01552 objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1]; 01553 objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2]; 01554 break; 01555 case OB_BOUND_POLYT: 01556 if (blenderobject->type == OB_MESH) 01557 { 01558 objprop.m_boundclass = KX_BOUNDPOLYTOPE; 01559 break; 01560 } 01561 // Object is not a mesh... fall through OB_BOUND_POLYH to 01562 // OB_BOUND_SPHERE 01563 case OB_BOUND_POLYH: 01564 if (blenderobject->type == OB_MESH) 01565 { 01566 objprop.m_boundclass = KX_BOUNDMESH; 01567 break; 01568 } 01569 // Object is not a mesh... can't use polyhedron. 01570 // Fall through and become a sphere. 01571 case OB_BOUND_SPHERE: 01572 { 01573 objprop.m_boundclass = KX_BOUNDSPHERE; 01574 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2])); 01575 break; 01576 } 01577 case OB_BOUND_CYLINDER: 01578 { 01579 objprop.m_boundclass = KX_BOUNDCYLINDER; 01580 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]); 01581 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2]; 01582 break; 01583 } 01584 case OB_BOUND_CONE: 01585 { 01586 objprop.m_boundclass = KX_BOUNDCONE; 01587 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]); 01588 objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2]; 01589 break; 01590 } 01591 case OB_BOUND_CAPSULE: 01592 { 01593 objprop.m_boundclass = KX_BOUNDCAPSULE; 01594 objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]); 01595 objprop.m_boundobject.c.m_height = 2.f*(bb.m_extends[2]-objprop.m_boundobject.c.m_radius); 01596 if (objprop.m_boundobject.c.m_height < 0.f) 01597 objprop.m_boundobject.c.m_height = 0.f; 01598 break; 01599 } 01600 } 01601 } 01602 01603 01604 if (parent/* && (parent->gameflag & OB_DYNAMIC)*/) { 01605 // parented object cannot be dynamic 01606 KX_GameObject *parentgameobject = converter->FindGameObject(parent); 01607 objprop.m_dynamic_parent = parentgameobject; 01608 //cannot be dynamic: 01609 objprop.m_dyna = false; 01610 objprop.m_softbody = false; 01611 shapeprops->m_mass = 0.f; 01612 } 01613 01614 01615 objprop.m_concave = (blenderobject->boundtype & 4) != 0; 01616 01617 switch (physics_engine) 01618 { 01619 #ifdef USE_BULLET 01620 case UseBullet: 01621 KX_ConvertBulletObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, &objprop); 01622 break; 01623 01624 #endif 01625 case UseDynamo: 01626 //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop); 01627 break; 01628 01629 case UseNone: 01630 default: 01631 break; 01632 } 01633 delete shapeprops; 01634 delete smmaterial; 01635 if (dm) { 01636 dm->needsFree = 1; 01637 dm->release(dm); 01638 } 01639 } 01640 01641 01642 01643 01644 01645 static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) { 01646 RAS_LightObject lightobj; 01647 KX_LightObject *gamelight; 01648 01649 lightobj.m_att1 = la->att1; 01650 lightobj.m_att2 = (la->mode & LA_QUAD) ? la->att2 : 0.0f; 01651 lightobj.m_red = la->r; 01652 lightobj.m_green = la->g; 01653 lightobj.m_blue = la->b; 01654 lightobj.m_distance = la->dist; 01655 lightobj.m_energy = la->energy; 01656 lightobj.m_layer = layerflag; 01657 lightobj.m_spotblend = la->spotblend; 01658 lightobj.m_spotsize = la->spotsize; 01659 01660 lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0; 01661 lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0; 01662 01663 bool glslmat = converter->GetGLSLMaterials(); 01664 01665 // in GLSL NEGATIVE LAMP is handled inside the lamp update function 01666 if(glslmat==0) { 01667 if (la->mode & LA_NEG) 01668 { 01669 lightobj.m_red = -lightobj.m_red; 01670 lightobj.m_green = -lightobj.m_green; 01671 lightobj.m_blue = -lightobj.m_blue; 01672 } 01673 } 01674 01675 if (la->type==LA_SUN) { 01676 lightobj.m_type = RAS_LightObject::LIGHT_SUN; 01677 } else if (la->type==LA_SPOT) { 01678 lightobj.m_type = RAS_LightObject::LIGHT_SPOT; 01679 } else { 01680 lightobj.m_type = RAS_LightObject::LIGHT_NORMAL; 01681 } 01682 01683 gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, 01684 lightobj, glslmat); 01685 01686 BL_ConvertLampIpos(la, gamelight, converter); 01687 01688 return gamelight; 01689 } 01690 01691 static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) { 01692 Camera* ca = static_cast<Camera*>(ob->data); 01693 RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist); 01694 KX_Camera *gamecamera; 01695 01696 gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); 01697 gamecamera->SetName(ca->id.name + 2); 01698 01699 BL_ConvertCameraIpos(ca, gamecamera, converter); 01700 01701 return gamecamera; 01702 } 01703 01704 static KX_GameObject *gameobject_from_blenderobject( 01705 Object *ob, 01706 KX_Scene *kxscene, 01707 RAS_IRenderTools *rendertools, 01708 KX_BlenderSceneConverter *converter) 01709 { 01710 KX_GameObject *gameobj = NULL; 01711 01712 switch(ob->type) 01713 { 01714 case OB_LAMP: 01715 { 01716 KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter); 01717 gameobj = gamelight; 01718 01719 gamelight->AddRef(); 01720 kxscene->GetLightList()->Add(gamelight); 01721 01722 break; 01723 } 01724 01725 case OB_CAMERA: 01726 { 01727 KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, converter); 01728 gameobj = gamecamera; 01729 01730 //don't add a reference: the camera list in kxscene->m_cameras is not released at the end 01731 //gamecamera->AddRef(); 01732 kxscene->AddCamera(gamecamera); 01733 01734 break; 01735 } 01736 01737 case OB_MESH: 01738 { 01739 Mesh* mesh = static_cast<Mesh*>(ob->data); 01740 float center[3], extents[3]; 01741 float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents); 01742 RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter); 01743 01744 // needed for python scripting 01745 kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); 01746 01747 gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_callbacks); 01748 01749 // set transformation 01750 gameobj->AddMesh(meshobj); 01751 01752 // for all objects: check whether they want to 01753 // respond to updates 01754 bool ignoreActivityCulling = 01755 ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0); 01756 gameobj->SetIgnoreActivityCulling(ignoreActivityCulling); 01757 gameobj->SetOccluder((ob->gameflag & OB_OCCLUDER) != 0, false); 01758 01759 // two options exists for deform: shape keys and armature 01760 // only support relative shape key 01761 bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE; 01762 bool bHasDvert = mesh->dvert != NULL && ob->defbase.first; 01763 bool bHasArmature = (BL_ModifierDeformer::HasArmatureDeformer(ob) && ob->parent && ob->parent->type == OB_ARMATURE && bHasDvert); 01764 bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(ob); 01765 #ifdef USE_BULLET 01766 bool bHasSoftBody = (!ob->parent && (ob->gameflag & OB_SOFT_BODY)); 01767 #endif 01768 if (bHasModifier) { 01769 BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL_DeformableGameObject *)gameobj, 01770 kxscene->GetBlenderScene(), ob, meshobj); 01771 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); 01772 if (bHasShapeKey && bHasArmature) 01773 dcont->LoadShapeDrivers(ob->parent); 01774 } else if (bHasShapeKey) { 01775 // not that we can have shape keys without dvert! 01776 BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, 01777 ob, meshobj); 01778 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); 01779 if (bHasArmature) 01780 dcont->LoadShapeDrivers(ob->parent); 01781 } else if (bHasArmature) { 01782 BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj, 01783 ob, meshobj); 01784 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); 01785 } else if (bHasDvert) { 01786 // this case correspond to a mesh that can potentially deform but not with the 01787 // object to which it is attached for the moment. A skin mesh was created in 01788 // BL_ConvertMesh() so must create a deformer too! 01789 BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj, 01790 ob, meshobj); 01791 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); 01792 #ifdef USE_BULLET 01793 } else if (bHasSoftBody) { 01794 KX_SoftBodyDeformer *dcont = new KX_SoftBodyDeformer(meshobj, (BL_DeformableGameObject*)gameobj); 01795 ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); 01796 #endif 01797 } 01798 01799 MT_Point3 min = MT_Point3(center) - MT_Vector3(extents); 01800 MT_Point3 max = MT_Point3(center) + MT_Vector3(extents); 01801 SG_BBox bbox = SG_BBox(min, max); 01802 gameobj->GetSGNode()->SetBBox(bbox); 01803 gameobj->GetSGNode()->SetRadius(radius); 01804 01805 break; 01806 } 01807 01808 case OB_ARMATURE: 01809 { 01810 gameobj = new BL_ArmatureObject( 01811 kxscene, 01812 KX_Scene::m_callbacks, 01813 ob, 01814 kxscene->GetBlenderScene() // handle 01815 ); 01816 /* Get the current pose from the armature object and apply it as the rest pose */ 01817 break; 01818 } 01819 01820 case OB_EMPTY: 01821 { 01822 gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks); 01823 // set transformation 01824 break; 01825 } 01826 01827 case OB_FONT: 01828 { 01829 /* font objects have no bounding box */ 01830 gameobj = new KX_FontObject(kxscene,KX_Scene::m_callbacks, rendertools, ob); 01831 01832 /* add to the list only the visible fonts */ 01833 if((ob->lay & kxscene->GetBlenderScene()->lay) != 0) 01834 kxscene->AddFont(static_cast<KX_FontObject*>(gameobj)); 01835 break; 01836 } 01837 01838 } 01839 if (gameobj) 01840 { 01841 gameobj->SetLayer(ob->lay); 01842 gameobj->SetBlenderObject(ob); 01843 /* set the visibility state based on the objects render option in the outliner */ 01844 if(ob->restrictflag & OB_RESTRICT_RENDER) gameobj->SetVisible(0, 0); 01845 } 01846 return gameobj; 01847 } 01848 01849 struct parentChildLink { 01850 struct Object* m_blenderchild; 01851 SG_Node* m_gamechildnode; 01852 }; 01853 01854 #include "DNA_constraint_types.h" 01855 //XXX #include "BIF_editconstraint.h" 01856 01857 bPoseChannel *get_active_posechannel2 (Object *ob) 01858 { 01859 bArmature *arm= (bArmature*)ob->data; 01860 bPoseChannel *pchan; 01861 01862 /* find active */ 01863 for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) { 01864 if(pchan->bone && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer)) 01865 return pchan; 01866 } 01867 01868 return NULL; 01869 } 01870 01871 ListBase *get_active_constraints2(Object *ob) 01872 { 01873 if (!ob) 01874 return NULL; 01875 01876 // XXX - shouldnt we care about the pose data and not the mode??? 01877 if (ob->mode & OB_MODE_POSE) { 01878 bPoseChannel *pchan; 01879 01880 pchan = get_active_posechannel2(ob); 01881 if (pchan) 01882 return &pchan->constraints; 01883 } 01884 else 01885 return &ob->constraints; 01886 01887 return NULL; 01888 } 01889 01890 01891 void RBJconstraints(Object *ob)//not used 01892 { 01893 ListBase *conlist; 01894 bConstraint *curcon; 01895 01896 conlist = get_active_constraints2(ob); 01897 01898 if (conlist) { 01899 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) { 01900 01901 printf("%i\n",curcon->type); 01902 } 01903 01904 01905 } 01906 } 01907 01908 #include "PHY_IPhysicsEnvironment.h" 01909 #include "KX_IPhysicsController.h" 01910 #include "PHY_DynamicTypes.h" 01911 01912 KX_IPhysicsController* getPhId(CListValue* sumolist,STR_String busc){//not used 01913 01914 for (int j=0;j<sumolist->GetCount();j++) 01915 { 01916 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); 01917 if (gameobje->GetName()==busc) 01918 return gameobje->GetPhysicsController(); 01919 } 01920 01921 return 0; 01922 01923 } 01924 01925 KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){ 01926 01927 for (int j=0;j<sumolist->GetCount();j++) 01928 { 01929 KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); 01930 if (gameobje->GetName()==busc) 01931 return gameobje; 01932 } 01933 01934 return 0; 01935 01936 } 01937 01938 // convert blender objects into ketsji gameobjects 01939 void BL_ConvertBlenderObjects(struct Main* maggie, 01940 KX_Scene* kxscene, 01941 KX_KetsjiEngine* ketsjiEngine, 01942 e_PhysicsEngine physics_engine, 01943 RAS_IRenderTools* rendertools, 01944 RAS_ICanvas* canvas, 01945 KX_BlenderSceneConverter* converter, 01946 bool alwaysUseExpandFraming 01947 ) 01948 { 01949 01950 Scene *blenderscene = kxscene->GetBlenderScene(); 01951 // for SETLOOPER 01952 Scene *sce_iter; 01953 Base *base; 01954 01955 // Get the frame settings of the canvas. 01956 // Get the aspect ratio of the canvas as designed by the user. 01957 01958 RAS_FrameSettings::RAS_FrameType frame_type; 01959 int aspect_width; 01960 int aspect_height; 01961 vector<MT_Vector3> inivel,iniang; 01962 set<Group*> grouplist; // list of groups to be converted 01963 set<Object*> allblobj; // all objects converted 01964 set<Object*> groupobj; // objects from groups (never in active layer) 01965 01966 if (alwaysUseExpandFraming) { 01967 frame_type = RAS_FrameSettings::e_frame_extend; 01968 aspect_width = canvas->GetWidth(); 01969 aspect_height = canvas->GetHeight(); 01970 } else { 01971 if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { 01972 frame_type = RAS_FrameSettings::e_frame_bars; 01973 } else if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_EXTEND) { 01974 frame_type = RAS_FrameSettings::e_frame_extend; 01975 } else { 01976 frame_type = RAS_FrameSettings::e_frame_scale; 01977 } 01978 01979 aspect_width = blenderscene->r.xsch*blenderscene->r.xasp; 01980 aspect_height = blenderscene->r.ysch*blenderscene->r.yasp; 01981 } 01982 01983 RAS_FrameSettings frame_settings( 01984 frame_type, 01985 blenderscene->gm.framing.col[0], 01986 blenderscene->gm.framing.col[1], 01987 blenderscene->gm.framing.col[2], 01988 aspect_width, 01989 aspect_height 01990 ); 01991 kxscene->SetFramingType(frame_settings); 01992 01993 kxscene->SetGravity(MT_Vector3(0,0, -blenderscene->gm.gravity)); 01994 01995 /* set activity culling parameters */ 01996 kxscene->SetActivityCulling( (blenderscene->gm.mode & WO_ACTIVITY_CULLING) != 0); 01997 kxscene->SetActivityCullingRadius(blenderscene->gm.activityBoxRadius); 01998 kxscene->SetDbvtCulling((blenderscene->gm.mode & WO_DBVT_CULLING) != 0); 01999 02000 // no occlusion culling by default 02001 kxscene->SetDbvtOcclusionRes(0); 02002 02003 int activeLayerBitInfo = blenderscene->lay; 02004 02005 // list of all object converted, active and inactive 02006 CListValue* sumolist = new CListValue(); 02007 02008 vector<parentChildLink> vec_parent_child; 02009 02010 CListValue* objectlist = kxscene->GetObjectList(); 02011 CListValue* inactivelist = kxscene->GetInactiveList(); 02012 CListValue* parentlist = kxscene->GetRootParentList(); 02013 02014 SCA_LogicManager* logicmgr = kxscene->GetLogicManager(); 02015 SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager(); 02016 02017 CListValue* logicbrick_conversionlist = new CListValue(); 02018 02019 //SG_TreeFactory tf; 02020 02021 // Convert actions to actionmap 02022 bAction *curAct; 02023 for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next) 02024 { 02025 logicmgr->RegisterActionName(curAct->id.name + 2, curAct); 02026 } 02027 02028 SetDefaultFaceType(blenderscene); 02029 // Let's support scene set. 02030 // Beware of name conflict in linked data, it will not crash but will create confusion 02031 // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have 02032 // no conflicting name for Object, Object data and Action. 02033 for (SETLOOPER(blenderscene, sce_iter, base)) 02034 { 02035 Object* blenderobject = base->object; 02036 allblobj.insert(blenderobject); 02037 02038 KX_GameObject* gameobj = gameobject_from_blenderobject( 02039 base->object, 02040 kxscene, 02041 rendertools, 02042 converter); 02043 02044 bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0; 02045 bool addobj=true; 02046 02047 if (converter->addInitFromFrame) 02048 if (!isInActiveLayer) 02049 addobj=false; 02050 02051 if (gameobj&&addobj) 02052 { 02053 MT_Point3 posPrev; 02054 MT_Matrix3x3 angor; 02055 if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra; 02056 02057 MT_Point3 pos; 02058 pos.setValue( 02059 blenderobject->loc[0]+blenderobject->dloc[0], 02060 blenderobject->loc[1]+blenderobject->dloc[1], 02061 blenderobject->loc[2]+blenderobject->dloc[2] 02062 ); 02063 MT_Vector3 eulxyz(blenderobject->rot); 02064 MT_Vector3 scale(blenderobject->size); 02065 if (converter->addInitFromFrame){//rcruiz 02066 float eulxyzPrev[3]; 02067 blenderscene->r.cfra=blenderscene->r.sfra-1; 02068 //XXX update_for_newframe(); 02069 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], 02070 blenderobject->loc[1]+blenderobject->dloc[1], 02071 blenderobject->loc[2]+blenderobject->dloc[2] 02072 ); 02073 eulxyzPrev[0]=blenderobject->rot[0]; 02074 eulxyzPrev[1]=blenderobject->rot[1]; 02075 eulxyzPrev[2]=blenderobject->rot[2]; 02076 02077 double fps = (double) blenderscene->r.frs_sec/ 02078 (double) blenderscene->r.frs_sec_base; 02079 02080 tmp.scale(fps, fps, fps); 02081 inivel.push_back(tmp); 02082 tmp=eulxyz-eulxyzPrev; 02083 tmp.scale(fps, fps, fps); 02084 iniang.push_back(tmp); 02085 blenderscene->r.cfra=blenderscene->r.sfra; 02086 //XXX update_for_newframe(); 02087 } 02088 02089 gameobj->NodeSetLocalPosition(pos); 02090 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); 02091 gameobj->NodeSetLocalScale(scale); 02092 gameobj->NodeUpdateGS(0); 02093 02094 BL_ConvertIpos(blenderobject,gameobj,converter); 02095 BL_ConvertMaterialIpos(blenderobject, gameobj, converter); 02096 02097 sumolist->Add(gameobj->AddRef()); 02098 02099 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); 02100 02101 gameobj->SetName(blenderobject->id.name + 2); 02102 02103 // update children/parent hierarchy 02104 if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) 02105 { 02106 // blender has an additional 'parentinverse' offset in each object 02107 SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); 02108 SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); 02109 02110 // define a normal parent relationship for this node. 02111 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); 02112 parentinversenode->SetParentRelation(parent_relation); 02113 02114 parentChildLink pclink; 02115 pclink.m_blenderchild = blenderobject; 02116 pclink.m_gamechildnode = parentinversenode; 02117 vec_parent_child.push_back(pclink); 02118 02119 float* fl = (float*) blenderobject->parentinv; 02120 MT_Transform parinvtrans(fl); 02121 parentinversenode->SetLocalPosition(parinvtrans.getOrigin()); 02122 // problem here: the parent inverse transform combines scaling and rotation 02123 // in the basis but the scenegraph needs separate rotation and scaling. 02124 // This is not important for OpenGL (it uses 4x4 matrix) but it is important 02125 // for the physic engine that needs a separate scaling 02126 //parentinversenode->SetLocalOrientation(parinvtrans.getBasis()); 02127 02128 // Extract the rotation and the scaling from the basis 02129 MT_Matrix3x3 ori(parinvtrans.getBasis()); 02130 MT_Vector3 x(ori.getColumn(0)); 02131 MT_Vector3 y(ori.getColumn(1)); 02132 MT_Vector3 z(ori.getColumn(2)); 02133 MT_Vector3 parscale(x.length(), y.length(), z.length()); 02134 if (!MT_fuzzyZero(parscale[0])) 02135 x /= parscale[0]; 02136 if (!MT_fuzzyZero(parscale[1])) 02137 y /= parscale[1]; 02138 if (!MT_fuzzyZero(parscale[2])) 02139 z /= parscale[2]; 02140 ori.setColumn(0, x); 02141 ori.setColumn(1, y); 02142 ori.setColumn(2, z); 02143 parentinversenode->SetLocalOrientation(ori); 02144 parentinversenode->SetLocalScale(parscale); 02145 02146 parentinversenode->AddChild(gameobj->GetSGNode()); 02147 } 02148 02149 // needed for python scripting 02150 logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); 02151 02152 // needed for group duplication 02153 logicmgr->RegisterGameObj(blenderobject, gameobj); 02154 for (int i = 0; i < gameobj->GetMeshCount(); i++) 02155 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject); 02156 02157 converter->RegisterGameObject(gameobj, blenderobject); 02158 // this was put in rapidly, needs to be looked at more closely 02159 // only draw/use objects in active 'blender' layers 02160 02161 logicbrick_conversionlist->Add(gameobj->AddRef()); 02162 02163 if (converter->addInitFromFrame){ 02164 posPrev=gameobj->NodeGetWorldPosition(); 02165 angor=gameobj->NodeGetWorldOrientation(); 02166 } 02167 if (isInActiveLayer) 02168 { 02169 objectlist->Add(gameobj->AddRef()); 02170 //tf.Add(gameobj->GetSGNode()); 02171 02172 gameobj->NodeUpdateGS(0); 02173 gameobj->AddMeshUser(); 02174 02175 } 02176 else 02177 { 02178 //we must store this object otherwise it will be deleted 02179 //at the end of this function if it is not a root object 02180 inactivelist->Add(gameobj->AddRef()); 02181 } 02182 if (gameobj->IsDupliGroup()) 02183 grouplist.insert(blenderobject->dup_group); 02184 if (converter->addInitFromFrame){ 02185 gameobj->NodeSetLocalPosition(posPrev); 02186 gameobj->NodeSetLocalOrientation(angor); 02187 } 02188 02189 } 02190 /* Note about memory leak issues: 02191 When a CValue derived class is created, m_refcount is initialized to 1 02192 so the class must be released after being used to make sure that it won't 02193 hang in memory. If the object needs to be stored for a long time, 02194 use AddRef() so that this Release() does not free the object. 02195 Make sure that for any AddRef() there is a Release()!!!! 02196 Do the same for any object derived from CValue, CExpression and NG_NetworkMessage 02197 */ 02198 if (gameobj) 02199 gameobj->Release(); 02200 02201 } 02202 02203 if (!grouplist.empty()) 02204 { 02205 // now convert the group referenced by dupli group object 02206 // keep track of all groups already converted 02207 set<Group*> allgrouplist = grouplist; 02208 set<Group*> tempglist; 02209 // recurse 02210 while (!grouplist.empty()) 02211 { 02212 set<Group*>::iterator git; 02213 tempglist.clear(); 02214 tempglist.swap(grouplist); 02215 for (git=tempglist.begin(); git!=tempglist.end(); git++) 02216 { 02217 Group* group = *git; 02218 GroupObject* go; 02219 for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next) 02220 { 02221 Object* blenderobject = go->ob; 02222 if (converter->FindGameObject(blenderobject) == NULL) 02223 { 02224 allblobj.insert(blenderobject); 02225 groupobj.insert(blenderobject); 02226 KX_GameObject* gameobj = gameobject_from_blenderobject( 02227 blenderobject, 02228 kxscene, 02229 rendertools, 02230 converter); 02231 02232 // this code is copied from above except that 02233 // object from groups are never in active layer 02234 bool isInActiveLayer = false; 02235 bool addobj=true; 02236 02237 if (converter->addInitFromFrame) 02238 if (!isInActiveLayer) 02239 addobj=false; 02240 02241 if (gameobj&&addobj) 02242 { 02243 MT_Point3 posPrev; 02244 MT_Matrix3x3 angor; 02245 if (converter->addInitFromFrame) 02246 blenderscene->r.cfra=blenderscene->r.sfra; 02247 02248 MT_Point3 pos( 02249 blenderobject->loc[0]+blenderobject->dloc[0], 02250 blenderobject->loc[1]+blenderobject->dloc[1], 02251 blenderobject->loc[2]+blenderobject->dloc[2] 02252 ); 02253 MT_Vector3 eulxyz(blenderobject->rot); 02254 MT_Vector3 scale(blenderobject->size); 02255 if (converter->addInitFromFrame){//rcruiz 02256 float eulxyzPrev[3]; 02257 blenderscene->r.cfra=blenderscene->r.sfra-1; 02258 //XXX update_for_newframe(); 02259 MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], 02260 blenderobject->loc[1]+blenderobject->dloc[1], 02261 blenderobject->loc[2]+blenderobject->dloc[2] 02262 ); 02263 eulxyzPrev[0]=blenderobject->rot[0]; 02264 eulxyzPrev[1]=blenderobject->rot[1]; 02265 eulxyzPrev[2]=blenderobject->rot[2]; 02266 02267 double fps = (double) blenderscene->r.frs_sec/ 02268 (double) blenderscene->r.frs_sec_base; 02269 02270 tmp.scale(fps, fps, fps); 02271 inivel.push_back(tmp); 02272 tmp=eulxyz-eulxyzPrev; 02273 tmp.scale(fps, fps, fps); 02274 iniang.push_back(tmp); 02275 blenderscene->r.cfra=blenderscene->r.sfra; 02276 //XXX update_for_newframe(); 02277 } 02278 02279 gameobj->NodeSetLocalPosition(pos); 02280 gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); 02281 gameobj->NodeSetLocalScale(scale); 02282 gameobj->NodeUpdateGS(0); 02283 02284 BL_ConvertIpos(blenderobject,gameobj,converter); 02285 BL_ConvertMaterialIpos(blenderobject,gameobj, converter); 02286 02287 sumolist->Add(gameobj->AddRef()); 02288 02289 BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); 02290 02291 02292 gameobj->SetName(blenderobject->id.name + 2); 02293 02294 // update children/parent hierarchy 02295 if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) 02296 { 02297 // blender has an additional 'parentinverse' offset in each object 02298 SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); 02299 SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); 02300 02301 // define a normal parent relationship for this node. 02302 KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); 02303 parentinversenode->SetParentRelation(parent_relation); 02304 02305 parentChildLink pclink; 02306 pclink.m_blenderchild = blenderobject; 02307 pclink.m_gamechildnode = parentinversenode; 02308 vec_parent_child.push_back(pclink); 02309 02310 float* fl = (float*) blenderobject->parentinv; 02311 MT_Transform parinvtrans(fl); 02312 parentinversenode->SetLocalPosition(parinvtrans.getOrigin()); 02313 02314 // Extract the rotation and the scaling from the basis 02315 MT_Matrix3x3 ori(parinvtrans.getBasis()); 02316 MT_Vector3 x(ori.getColumn(0)); 02317 MT_Vector3 y(ori.getColumn(1)); 02318 MT_Vector3 z(ori.getColumn(2)); 02319 MT_Vector3 localscale(x.length(), y.length(), z.length()); 02320 if (!MT_fuzzyZero(localscale[0])) 02321 x /= localscale[0]; 02322 if (!MT_fuzzyZero(localscale[1])) 02323 y /= localscale[1]; 02324 if (!MT_fuzzyZero(localscale[2])) 02325 z /= localscale[2]; 02326 ori.setColumn(0, x); 02327 ori.setColumn(1, y); 02328 ori.setColumn(2, z); 02329 parentinversenode->SetLocalOrientation(ori); 02330 parentinversenode->SetLocalScale(localscale); 02331 02332 parentinversenode->AddChild(gameobj->GetSGNode()); 02333 } 02334 02335 // needed for python scripting 02336 logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); 02337 02338 // needed for group duplication 02339 logicmgr->RegisterGameObj(blenderobject, gameobj); 02340 for (int i = 0; i < gameobj->GetMeshCount(); i++) 02341 logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject); 02342 02343 converter->RegisterGameObject(gameobj, blenderobject); 02344 // this was put in rapidly, needs to be looked at more closely 02345 // only draw/use objects in active 'blender' layers 02346 02347 logicbrick_conversionlist->Add(gameobj->AddRef()); 02348 02349 if (converter->addInitFromFrame){ 02350 posPrev=gameobj->NodeGetWorldPosition(); 02351 angor=gameobj->NodeGetWorldOrientation(); 02352 } 02353 if (isInActiveLayer) 02354 { 02355 objectlist->Add(gameobj->AddRef()); 02356 //tf.Add(gameobj->GetSGNode()); 02357 02358 gameobj->NodeUpdateGS(0); 02359 gameobj->AddMeshUser(); 02360 } 02361 else 02362 { 02363 //we must store this object otherwise it will be deleted 02364 //at the end of this function if it is not a root object 02365 inactivelist->Add(gameobj->AddRef()); 02366 02367 } 02368 if (gameobj->IsDupliGroup()) 02369 { 02370 // check that the group is not already converted 02371 if (allgrouplist.insert(blenderobject->dup_group).second) 02372 grouplist.insert(blenderobject->dup_group); 02373 } 02374 if (converter->addInitFromFrame){ 02375 gameobj->NodeSetLocalPosition(posPrev); 02376 gameobj->NodeSetLocalOrientation(angor); 02377 } 02378 02379 } 02380 if (gameobj) 02381 gameobj->Release(); 02382 } 02383 } 02384 } 02385 } 02386 } 02387 02388 // non-camera objects not supported as camera currently 02389 if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) { 02390 KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera); 02391 02392 if(gamecamera) 02393 kxscene->SetActiveCamera(gamecamera); 02394 } 02395 02396 // Set up armatures 02397 set<Object*>::iterator oit; 02398 for(oit=allblobj.begin(); oit!=allblobj.end(); oit++) 02399 { 02400 Object* blenderobj = *oit; 02401 if (blenderobj->type==OB_MESH) { 02402 Mesh *me = (Mesh*)blenderobj->data; 02403 02404 if (me->dvert){ 02405 BL_DeformableGameObject *obj = (BL_DeformableGameObject*)converter->FindGameObject(blenderobj); 02406 02407 if (obj && BL_ModifierDeformer::HasArmatureDeformer(blenderobj) && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE){ 02408 KX_GameObject *par = converter->FindGameObject(blenderobj->parent); 02409 if (par && obj->GetDeformer()) 02410 ((BL_SkinDeformer*)obj->GetDeformer())->SetArmature((BL_ArmatureObject*) par); 02411 } 02412 } 02413 } 02414 } 02415 02416 // create hierarchy information 02417 int i; 02418 vector<parentChildLink>::iterator pcit; 02419 02420 for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit) 02421 { 02422 02423 struct Object* blenderchild = pcit->m_blenderchild; 02424 struct Object* blenderparent = blenderchild->parent; 02425 KX_GameObject* parentobj = converter->FindGameObject(blenderparent); 02426 KX_GameObject* childobj = converter->FindGameObject(blenderchild); 02427 02428 assert(childobj); 02429 02430 if (!parentobj || objectlist->SearchValue(childobj) != objectlist->SearchValue(parentobj)) 02431 { 02432 // special case: the parent and child object are not in the same layer. 02433 // This weird situation is used in Apricot for test purposes. 02434 // Resolve it by not converting the child 02435 childobj->GetSGNode()->DisconnectFromParent(); 02436 delete pcit->m_gamechildnode; 02437 // Now destroy the child object but also all its descendent that may already be linked 02438 // Remove the child reference in the local list! 02439 // Note: there may be descendents already if the children of the child were processed 02440 // by this loop before the child. In that case, we must remove the children also 02441 CListValue* childrenlist = childobj->GetChildrenRecursive(); 02442 childrenlist->Add(childobj->AddRef()); 02443 for ( i=0;i<childrenlist->GetCount();i++) 02444 { 02445 KX_GameObject* obj = static_cast<KX_GameObject*>(childrenlist->GetValue(i)); 02446 if (sumolist->RemoveValue(obj)) 02447 obj->Release(); 02448 if (logicbrick_conversionlist->RemoveValue(obj)) 02449 obj->Release(); 02450 } 02451 childrenlist->Release(); 02452 02453 // now destroy recursively 02454 converter->UnregisterGameObject(childobj); // removing objects during conversion make sure this runs too 02455 kxscene->RemoveObject(childobj); 02456 02457 continue; 02458 } 02459 02460 switch (blenderchild->partype) 02461 { 02462 case PARVERT1: 02463 { 02464 // creat a new vertex parent relationship for this node. 02465 KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New(); 02466 pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation); 02467 break; 02468 } 02469 case PARSLOW: 02470 { 02471 // creat a new slow parent relationship for this node. 02472 KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf); 02473 pcit->m_gamechildnode->SetParentRelation(slow_parent_relation); 02474 break; 02475 } 02476 case PARBONE: 02477 { 02478 // parent this to a bone 02479 Bone *parent_bone = get_named_bone( (bArmature *)(blenderchild->parent)->data, blenderchild->parsubstr); 02480 02481 if(parent_bone) { 02482 KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone); 02483 pcit->m_gamechildnode->SetParentRelation(bone_parent_relation); 02484 } 02485 02486 break; 02487 } 02488 case PARSKEL: // skinned - ignore 02489 break; 02490 case PAROBJECT: 02491 case PARCURVE: 02492 case PARKEY: 02493 case PARVERT3: 02494 default: 02495 // unhandled 02496 break; 02497 } 02498 02499 parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode); 02500 } 02501 vec_parent_child.clear(); 02502 02503 // find 'root' parents (object that has not parents in SceneGraph) 02504 for (i=0;i<sumolist->GetCount();++i) 02505 { 02506 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); 02507 if (gameobj->GetSGNode()->GetSGParent() == 0) 02508 { 02509 parentlist->Add(gameobj->AddRef()); 02510 gameobj->NodeUpdateGS(0); 02511 } 02512 } 02513 02514 // create graphic controller for culling 02515 if (kxscene->GetDbvtCulling()) 02516 { 02517 bool occlusion = false; 02518 for (i=0; i<sumolist->GetCount();i++) 02519 { 02520 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); 02521 if (gameobj->GetMeshCount() > 0) 02522 { 02523 MT_Point3 box[2]; 02524 gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity()); 02525 // box[0] is the min, box[1] is the max 02526 bool isactive = objectlist->SearchValue(gameobj); 02527 BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine); 02528 if (gameobj->GetOccluder()) 02529 occlusion = true; 02530 } 02531 } 02532 if (occlusion) 02533 kxscene->SetDbvtOcclusionRes(blenderscene->gm.occlusionRes); 02534 } 02535 if (blenderscene->world) 02536 kxscene->GetPhysicsEnvironment()->setNumTimeSubSteps(blenderscene->gm.physubstep); 02537 02538 // now that the scenegraph is complete, let's instantiate the deformers. 02539 // We need that to create reusable derived mesh and physic shapes 02540 for (i=0;i<sumolist->GetCount();++i) 02541 { 02542 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); 02543 if (gameobj->GetDeformer()) 02544 gameobj->GetDeformer()->UpdateBuckets(); 02545 } 02546 02547 // Set up armature constraints 02548 for (i=0;i<sumolist->GetCount();++i) 02549 { 02550 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); 02551 if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) 02552 ((BL_ArmatureObject*)gameobj)->LoadConstraints(converter); 02553 } 02554 02555 bool processCompoundChildren = false; 02556 02557 // create physics information 02558 for (i=0;i<sumolist->GetCount();i++) 02559 { 02560 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); 02561 struct Object* blenderobject = gameobj->GetBlenderObject(); 02562 int nummeshes = gameobj->GetMeshCount(); 02563 RAS_MeshObject* meshobj = 0; 02564 if (nummeshes > 0) 02565 { 02566 meshobj = gameobj->GetMesh(0); 02567 } 02568 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0; 02569 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren); 02570 } 02571 02572 processCompoundChildren = true; 02573 // create physics information 02574 for (i=0;i<sumolist->GetCount();i++) 02575 { 02576 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); 02577 struct Object* blenderobject = gameobj->GetBlenderObject(); 02578 int nummeshes = gameobj->GetMeshCount(); 02579 RAS_MeshObject* meshobj = 0; 02580 if (nummeshes > 0) 02581 { 02582 meshobj = gameobj->GetMesh(0); 02583 } 02584 int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0; 02585 BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren); 02586 } 02587 02588 //set ini linearVel and int angularVel //rcruiz 02589 if (converter->addInitFromFrame) 02590 for (i=0;i<sumolist->GetCount();i++) 02591 { 02592 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); 02593 if (gameobj->IsDynamic()){ 02594 gameobj->setLinearVelocity(inivel[i],false); 02595 gameobj->setAngularVelocity(iniang[i],false); 02596 } 02597 02598 02599 } 02600 02601 // create physics joints 02602 for (i=0;i<sumolist->GetCount();i++) 02603 { 02604 KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); 02605 struct Object* blenderobject = gameobj->GetBlenderObject(); 02606 ListBase *conlist; 02607 bConstraint *curcon; 02608 conlist = get_active_constraints2(blenderobject); 02609 02610 if((gameobj->GetLayer()&activeLayerBitInfo)==0) 02611 continue; 02612 02613 if (conlist) { 02614 for (curcon = (bConstraint *)conlist->first; curcon; curcon=(bConstraint *)curcon->next) { 02615 if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT){ 02616 02617 bRigidBodyJointConstraint *dat=(bRigidBodyJointConstraint *)curcon->data; 02618 02619 if (!dat->child){ 02620 02621 PHY_IPhysicsController* physctr2 = 0; 02622 02623 if (dat->tar) 02624 { 02625 KX_GameObject *gotar=getGameOb(dat->tar->id.name+2,sumolist); 02626 if (gotar && ((gotar->GetLayer()&activeLayerBitInfo)!=0) && gotar->GetPhysicsController()) 02627 physctr2 = (PHY_IPhysicsController*) gotar->GetPhysicsController()->GetUserData(); 02628 } 02629 02630 if (gameobj->GetPhysicsController()) 02631 { 02632 PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) gameobj->GetPhysicsController()->GetUserData(); 02633 //we need to pass a full constraint frame, not just axis 02634 02635 //localConstraintFrameBasis 02636 MT_Matrix3x3 localCFrame(MT_Vector3(dat->axX,dat->axY,dat->axZ)); 02637 MT_Vector3 axis0 = localCFrame.getColumn(0); 02638 MT_Vector3 axis1 = localCFrame.getColumn(1); 02639 MT_Vector3 axis2 = localCFrame.getColumn(2); 02640 02641 int constraintId = kxscene->GetPhysicsEnvironment()->createConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX, 02642 (float)dat->pivY,(float)dat->pivZ, 02643 (float)axis0.x(),(float)axis0.y(),(float)axis0.z(), 02644 (float)axis1.x(),(float)axis1.y(),(float)axis1.z(), 02645 (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),dat->flag); 02646 if (constraintId) 02647 { 02648 //if it is a generic 6DOF constraint, set all the limits accordingly 02649 if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT) 02650 { 02651 int dof; 02652 int dofbit=1; 02653 for (dof=0;dof<6;dof++) 02654 { 02655 if (dat->flag & dofbit) 02656 { 02657 kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]); 02658 } else 02659 { 02660 //minLimit > maxLimit means free(disabled limit) for this degree of freedom 02661 kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1); 02662 } 02663 dofbit<<=1; 02664 } 02665 } 02666 else if(dat->type == PHY_CONE_TWIST_CONSTRAINT) 02667 { 02668 int dof; 02669 int dofbit = 1<<3; // bitflag use_angular_limit_x 02670 02671 for (dof=3;dof<6;dof++) 02672 { 02673 if(dat->flag & dofbit) 02674 { 02675 kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]); 02676 } 02677 else 02678 { 02679 //maxLimit < 0 means free(disabled limit) for this degree of freedom 02680 kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1); 02681 } 02682 dofbit<<=1; 02683 } 02684 } 02685 else if (dat->type == PHY_LINEHINGE_CONSTRAINT) 02686 { 02687 int dof = 3; // dof for angular x 02688 int dofbit = 1<<3; // bitflag use_angular_limit_x 02689 02690 if (dat->flag & dofbit) 02691 { 02692 kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof, 02693 dat->minLimit[dof],dat->maxLimit[dof]); 02694 } else 02695 { 02696 //minLimit > maxLimit means free(disabled limit) for this degree of freedom 02697 kxscene->GetPhysicsEnvironment()->setConstraintParam(constraintId,dof,1,-1); 02698 } 02699 } 02700 } 02701 } 02702 } 02703 } 02704 } 02705 } 02706 } 02707 02708 sumolist->Release(); 02709 02710 // convert world 02711 KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene, blenderscene->world); 02712 converter->RegisterWorldInfo(worldinfo); 02713 kxscene->SetWorldInfo(worldinfo); 02714 02715 #define CONVERT_LOGIC 02716 #ifdef CONVERT_LOGIC 02717 // convert logic bricks, sensors, controllers and actuators 02718 for (i=0;i<logicbrick_conversionlist->GetCount();i++) 02719 { 02720 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); 02721 struct Object* blenderobj = gameobj->GetBlenderObject(); 02722 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; 02723 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; 02724 BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,layerMask,isInActiveLayer,rendertools,converter); 02725 } 02726 for ( i=0;i<logicbrick_conversionlist->GetCount();i++) 02727 { 02728 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); 02729 struct Object* blenderobj = gameobj->GetBlenderObject(); 02730 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; 02731 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; 02732 BL_ConvertControllers(blenderobj,gameobj,logicmgr, layerMask,isInActiveLayer,converter); 02733 } 02734 for ( i=0;i<logicbrick_conversionlist->GetCount();i++) 02735 { 02736 KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); 02737 struct Object* blenderobj = gameobj->GetBlenderObject(); 02738 int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; 02739 bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; 02740 BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,layerMask,isInActiveLayer,canvas,converter); 02741 // set the init state to all objects 02742 gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state); 02743 } 02744 // apply the initial state to controllers, only on the active objects as this registers the sensors 02745 for ( i=0;i<objectlist->GetCount();i++) 02746 { 02747 KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i)); 02748 gameobj->ResetState(); 02749 } 02750 02751 #endif //CONVERT_LOGIC 02752 02753 logicbrick_conversionlist->Release(); 02754 02755 // Calculate the scene btree - 02756 // too slow - commented out. 02757 //kxscene->SetNodeTree(tf.MakeTree()); 02758 02759 // instantiate dupli group, we will loop trough the object 02760 // that are in active layers. Note that duplicating group 02761 // has the effect of adding objects at the end of objectlist. 02762 // Only loop through the first part of the list. 02763 int objcount = objectlist->GetCount(); 02764 for (i=0;i<objcount;i++) 02765 { 02766 KX_GameObject* gameobj = (KX_GameObject*) objectlist->GetValue(i); 02767 if (gameobj->IsDupliGroup()) 02768 { 02769 kxscene->DupliGroupRecurse(gameobj, 0); 02770 } 02771 } 02772 02773 KX_Camera *activecam = kxscene->GetActiveCamera(); 02774 MT_Scalar distance = (activecam)? activecam->GetCameraFar() - activecam->GetCameraNear(): 100.0f; 02775 RAS_BucketManager *bucketmanager = kxscene->GetBucketManager(); 02776 bucketmanager->OptimizeBuckets(distance); 02777 }