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