diff options
Diffstat (limited to 'source/gameengine/Converter/BL_BlenderDataConversion.cpp')
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 2473 |
1 files changed, 0 insertions, 2473 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp deleted file mode 100644 index 39f517e03e8..00000000000 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ /dev/null @@ -1,2473 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - * Convert blender data to ketsji - */ - -/** \file gameengine/Converter/BL_BlenderDataConversion.cpp - * \ingroup bgeconv - */ - -#ifdef _MSC_VER -# pragma warning (disable:4786) -#endif - -/* Since threaded object update we've disabled in-place - * curve evaluation (in cases when applying curve modifier - * with target curve non-evaluated yet). - * - * This requires game engine to take care of DAG and object - * evaluation (currently it's designed to export only objects - * it able to render). - * - * This workaround will make sure that curve_cache for curves - * is up-to-date. - */ - -/* TODO: Disabled for now, because of eval_ctx. */ -//#define THREADED_DAG_WORKAROUND - -#include <math.h> -#include <vector> -#include <algorithm> - -#include "BL_BlenderDataConversion.h" - -#include "MT_Transform.h" -#include "MT_MinMax.h" - -#include "PHY_Pro.h" -#include "PHY_IPhysicsEnvironment.h" - -#include "RAS_MeshObject.h" -#include "RAS_IRasterizer.h" -#include "RAS_ILightObject.h" - -#include "KX_ConvertActuators.h" -#include "KX_ConvertControllers.h" -#include "KX_ConvertSensors.h" -#include "SCA_LogicManager.h" -#include "SCA_TimeEventManager.h" - -#include "KX_ClientObjectInfo.h" -#include "KX_Scene.h" -#include "KX_GameObject.h" -#include "KX_Light.h" -#include "KX_Camera.h" -#include "KX_EmptyObject.h" -#include "KX_FontObject.h" - -#include "RAS_TexMatrix.h" -#include "RAS_ICanvas.h" -#include "RAS_Polygon.h" -#include "RAS_TexVert.h" -#include "RAS_BucketManager.h" -#include "RAS_IPolygonMaterial.h" -#include "BL_Material.h" -#include "KX_BlenderMaterial.h" -#include "BL_Texture.h" - -#include "BKE_main.h" -#include "BKE_global.h" -#include "BKE_object.h" -#include "BL_ModifierDeformer.h" -#include "BL_ShapeDeformer.h" -#include "BL_SkinDeformer.h" -#include "BL_MeshDeformer.h" -#include "KX_SoftBodyDeformer.h" -#include "BLI_utildefines.h" -#include "BLI_listbase.h" - -#include "KX_WorldInfo.h" - -#include "KX_KetsjiEngine.h" -#include "KX_BlenderSceneConverter.h" - -/* This little block needed for linking to Blender... */ -#ifdef WIN32 -#include "BLI_winstuff.h" -#endif - -/* This list includes only data type definitions */ -#include "DNA_object_types.h" -#include "DNA_material_types.h" -#include "DNA_texture_types.h" -#include "DNA_image_types.h" -#include "DNA_lamp_types.h" -#include "DNA_group_types.h" -#include "DNA_scene_types.h" -#include "DNA_camera_types.h" -#include "DNA_property_types.h" -#include "DNA_text_types.h" -#include "DNA_sensor_types.h" -#include "DNA_controller_types.h" -#include "DNA_actuator_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_view3d_types.h" -#include "DNA_world_types.h" -#include "DNA_sound_types.h" -#include "DNA_key_types.h" -#include "DNA_armature_types.h" -#include "DNA_action_types.h" -#include "DNA_object_force_types.h" -#include "DNA_constraint_types.h" - -#include "MEM_guardedalloc.h" - -#include "BKE_key.h" -#include "BKE_mesh.h" - -#include "BLI_math.h" - -extern "C" { -#include "BKE_scene.h" -#include "BKE_customdata.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_DerivedMesh.h" -#include "BKE_group.h" -#include "BKE_layer.h" -#include "BKE_material.h" /* give_current_material */ -#include "BKE_image.h" -#include "IMB_imbuf_types.h" -#include "BKE_displist.h" - -extern Material defmaterial; /* material.c */ -} - -/* end of blender include block */ - -#include "KX_BlenderInputDevice.h" -#include "KX_ConvertProperties.h" - -#include "SG_Node.h" -#include "SG_BBox.h" -#include "SG_Tree.h" -#include "KX_SG_NodeRelationships.h" -#include "KX_SG_BoneParentNodeRelationship.h" - -#ifdef WITH_BULLET -#include "CcdPhysicsEnvironment.h" -#include "CcdGraphicController.h" -#endif - -#include "KX_MotionState.h" - -#include "BL_ArmatureObject.h" -#include "BL_DeformableGameObject.h" - -#include "KX_NavMeshObject.h" -#include "KX_ObstacleSimulation.h" - -#include "BLI_threads.h" - - -static bool default_light_mode = 0; - -static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table() -{ - std::map<int, SCA_IInputDevice::KX_EnumInputs> m; - - /* The reverse table. In order to not confuse ourselves, we */ - /* immediately convert all events that come in to KX codes. */ - m[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE; - m[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE; - m[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE; - m[WHEELUPMOUSE ] = SCA_IInputDevice::KX_WHEELUPMOUSE; - m[WHEELDOWNMOUSE ] = SCA_IInputDevice::KX_WHEELDOWNMOUSE; - m[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX; - m[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY; - - // TIMERS - - m[TIMER0 ] = SCA_IInputDevice::KX_TIMER0; - m[TIMER1 ] = SCA_IInputDevice::KX_TIMER1; - m[TIMER2 ] = SCA_IInputDevice::KX_TIMER2; - - // SYSTEM - -#if 0 - /* **** XXX **** */ - m[KEYBD ] = SCA_IInputDevice::KX_KEYBD; - m[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD; - m[REDRAW ] = SCA_IInputDevice::KX_REDRAW; - m[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE; - m[QFULL ] = SCA_IInputDevice::KX_QFULL; - m[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE; - m[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW; - m[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE; - m[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT; - m[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME; - /* **** XXX **** */ -#endif - - // standard keyboard - - m[AKEY ] = SCA_IInputDevice::KX_AKEY; - m[BKEY ] = SCA_IInputDevice::KX_BKEY; - m[CKEY ] = SCA_IInputDevice::KX_CKEY; - m[DKEY ] = SCA_IInputDevice::KX_DKEY; - m[EKEY ] = SCA_IInputDevice::KX_EKEY; - m[FKEY ] = SCA_IInputDevice::KX_FKEY; - m[GKEY ] = SCA_IInputDevice::KX_GKEY; - m[HKEY ] = SCA_IInputDevice::KX_HKEY; - m[IKEY ] = SCA_IInputDevice::KX_IKEY; - m[JKEY ] = SCA_IInputDevice::KX_JKEY; - m[KKEY ] = SCA_IInputDevice::KX_KKEY; - m[LKEY ] = SCA_IInputDevice::KX_LKEY; - m[MKEY ] = SCA_IInputDevice::KX_MKEY; - m[NKEY ] = SCA_IInputDevice::KX_NKEY; - m[OKEY ] = SCA_IInputDevice::KX_OKEY; - m[PKEY ] = SCA_IInputDevice::KX_PKEY; - m[QKEY ] = SCA_IInputDevice::KX_QKEY; - m[RKEY ] = SCA_IInputDevice::KX_RKEY; - m[SKEY ] = SCA_IInputDevice::KX_SKEY; - m[TKEY ] = SCA_IInputDevice::KX_TKEY; - m[UKEY ] = SCA_IInputDevice::KX_UKEY; - m[VKEY ] = SCA_IInputDevice::KX_VKEY; - m[WKEY ] = SCA_IInputDevice::KX_WKEY; - m[XKEY ] = SCA_IInputDevice::KX_XKEY; - m[YKEY ] = SCA_IInputDevice::KX_YKEY; - m[ZKEY ] = SCA_IInputDevice::KX_ZKEY; - - m[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY; - m[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY; - m[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY; - m[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY; - m[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY; - m[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY; - m[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY; - m[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY; - m[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY; - m[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY; - - m[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY; - - m[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY; - m[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY; - m[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY; - m[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY; - m[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY; - m[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY; - - m[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY; - m[TABKEY ] = SCA_IInputDevice::KX_TABKEY; - m[RETKEY ] = SCA_IInputDevice::KX_RETKEY; - m[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY; - m[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY; - m[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY; - m[DELKEY ] = SCA_IInputDevice::KX_DELKEY; - m[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY; - m[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY; - m[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY; - m[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY; - m[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY; - m[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY; - m[PLUSKEY ] = SCA_IInputDevice::KX_PLUSKEY; - m[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY; - m[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY; - m[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY; - m[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY; - m[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY; - - m[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY; - m[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY; - m[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY; - m[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY; - - m[PAD2 ] = SCA_IInputDevice::KX_PAD2; - m[PAD4 ] = SCA_IInputDevice::KX_PAD4; - m[PAD6 ] = SCA_IInputDevice::KX_PAD6; - m[PAD8 ] = SCA_IInputDevice::KX_PAD8; - - m[PAD1 ] = SCA_IInputDevice::KX_PAD1; - m[PAD3 ] = SCA_IInputDevice::KX_PAD3; - m[PAD5 ] = SCA_IInputDevice::KX_PAD5; - m[PAD7 ] = SCA_IInputDevice::KX_PAD7; - m[PAD9 ] = SCA_IInputDevice::KX_PAD9; - - m[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD; - m[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY; - m[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY; - - m[PAD0 ] = SCA_IInputDevice::KX_PAD0; - m[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS; - m[PADENTER ] = SCA_IInputDevice::KX_PADENTER; - m[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY; - - - m[F1KEY ] = SCA_IInputDevice::KX_F1KEY; - m[F2KEY ] = SCA_IInputDevice::KX_F2KEY; - m[F3KEY ] = SCA_IInputDevice::KX_F3KEY; - m[F4KEY ] = SCA_IInputDevice::KX_F4KEY; - m[F5KEY ] = SCA_IInputDevice::KX_F5KEY; - m[F6KEY ] = SCA_IInputDevice::KX_F6KEY; - m[F7KEY ] = SCA_IInputDevice::KX_F7KEY; - m[F8KEY ] = SCA_IInputDevice::KX_F8KEY; - m[F9KEY ] = SCA_IInputDevice::KX_F9KEY; - m[F10KEY ] = SCA_IInputDevice::KX_F10KEY; - m[F11KEY ] = SCA_IInputDevice::KX_F11KEY; - m[F12KEY ] = SCA_IInputDevice::KX_F12KEY; - m[F13KEY ] = SCA_IInputDevice::KX_F13KEY; - m[F14KEY ] = SCA_IInputDevice::KX_F14KEY; - m[F15KEY ] = SCA_IInputDevice::KX_F15KEY; - m[F16KEY ] = SCA_IInputDevice::KX_F16KEY; - m[F17KEY ] = SCA_IInputDevice::KX_F17KEY; - m[F18KEY ] = SCA_IInputDevice::KX_F18KEY; - m[F19KEY ] = SCA_IInputDevice::KX_F19KEY; - - m[OSKEY ] = SCA_IInputDevice::KX_OSKEY; - - m[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; - m[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; - m[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; - m[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY; - m[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY; - m[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY; - - return m; -} - -static std::map<int, SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable = create_translate_table(); - -SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code) -{ - return gReverseKeyTranslateTable[key_code]; -} - -static unsigned int KX_rgbaint2uint_new(unsigned int icol) -{ - union - { - unsigned int integer; - unsigned char cp[4]; - } out_color, in_color; - - in_color.integer = icol; - out_color.cp[0] = in_color.cp[3]; // red - out_color.cp[1] = in_color.cp[2]; // green - out_color.cp[2] = in_color.cp[1]; // blue - out_color.cp[3] = in_color.cp[0]; // alpha - - return out_color.integer; -} - -/* Now the real converting starts... */ -static unsigned int KX_Mcol2uint_new(MCol col) -{ - /* color has to be converted without endian sensitivity. So no shifting! */ - union - { - MCol col; - unsigned int integer; - unsigned char cp[4]; - } out_color, in_color; - - in_color.col = col; - out_color.cp[0] = in_color.cp[3]; // red - out_color.cp[1] = in_color.cp[2]; // green - out_color.cp[2] = in_color.cp[1]; // blue - out_color.cp[3] = in_color.cp[0]; // alpha - - return out_color.integer; -} - -static void SetDefaultLightMode(Scene* scene) -{ - default_light_mode = false; - Scene *sce_iter; - Base *base; - - for (SETLOOPER(scene, sce_iter, base)) - { - if (base->object->type == OB_LAMP) - { - default_light_mode = true; - return; - } - } -} - - -static bool GetMaterialUseVColor(Material *ma, const bool glslmat) -{ - if (ma) { - /* glsl uses vertex colors, otherwise use material setting - * defmaterial doesn't have VERTEXCOLP as default [#34505] */ - return (glslmat || ma == &defmaterial || (ma->mode & MA_VERTEXCOLP) != 0); - } - else { - /* no material, use vertex colors */ - return true; - } -} - -// -- -static void GetRGB( - const bool use_vcol, - MFace* mface, - MCol* mmcol, - Material *mat, - unsigned int c[4]) -{ - unsigned int color = 0xFFFFFFFFL; - if (use_vcol == true) { - if (mmcol) { - c[0] = KX_Mcol2uint_new(mmcol[0]); - c[1] = KX_Mcol2uint_new(mmcol[1]); - c[2] = KX_Mcol2uint_new(mmcol[2]); - if (mface->v4) - c[3] = KX_Mcol2uint_new(mmcol[3]); - } - else { // backup white - c[0] = KX_rgbaint2uint_new(color); - c[1] = KX_rgbaint2uint_new(color); - c[2] = KX_rgbaint2uint_new(color); - if (mface->v4) - c[3] = KX_rgbaint2uint_new( color ); - } - } - else { - /* material rgba */ - if (mat) { - union { - unsigned char cp[4]; - unsigned int integer; - } col_converter; - col_converter.cp[3] = (unsigned char) (mat->r * 255.0f); - col_converter.cp[2] = (unsigned char) (mat->g * 255.0f); - col_converter.cp[1] = (unsigned char) (mat->b * 255.0f); - col_converter.cp[0] = (unsigned char) (mat->alpha * 255.0f); - color = col_converter.integer; - } - c[0] = KX_rgbaint2uint_new(color); - c[1] = KX_rgbaint2uint_new(color); - c[2] = KX_rgbaint2uint_new(color); - if (mface->v4) { - c[3] = KX_rgbaint2uint_new(color); - } - } - -#if 0 /* white, unused */ - { - c[0] = KX_rgbaint2uint_new(color); - c[1] = KX_rgbaint2uint_new(color); - c[2] = KX_rgbaint2uint_new(color); - if (mface->v4) - c[3] = KX_rgbaint2uint_new(color); - } -#endif -} - -typedef struct MTF_localLayer { - MTFace *face; - const char *name; -} MTF_localLayer; - -static void GetUVs(BL_Material *material, MTF_localLayer *layers, MFace *mface, MTFace *tface, MT_Point2 uvs[4][MAXTEX]) -{ - int unit = 0; - if (tface) - { - - uvs[0][0].setValue(tface->uv[0]); - uvs[1][0].setValue(tface->uv[1]); - uvs[2][0].setValue(tface->uv[2]); - - if (mface->v4) - uvs[3][0].setValue(tface->uv[3]); - } - else - { - uvs[0][0] = uvs[1][0] = uvs[2][0] = uvs[3][0] = MT_Point2(0.f, 0.f); - } - - vector<STR_String> found_layers; - - for (int vind = 0; vind<MAXTEX; vind++) - { - BL_Mapping &map = material->mapping[vind]; - - if (!(map.mapping & USEUV)) continue; - - if (std::find(found_layers.begin(), found_layers.end(), map.uvCoName) != found_layers.end()) - continue; - - //If no UVSet is specified, try grabbing one from the UV/Image editor - if (map.uvCoName.IsEmpty() && tface) - { - uvs[0][unit].setValue(tface->uv[0]); - uvs[1][unit].setValue(tface->uv[1]); - uvs[2][unit].setValue(tface->uv[2]); - - if (mface->v4) - uvs[3][unit].setValue(tface->uv[3]); - - ++unit; - continue; - } - - - for (int lay=0; lay<MAX_MTFACE; lay++) - { - MTF_localLayer& layer = layers[lay]; - if (layer.face == 0) break; - - if (map.uvCoName.IsEmpty() || strcmp(map.uvCoName.ReadPtr(), layer.name)==0) - { - uvs[0][unit].setValue(layer.face->uv[0]); - uvs[1][unit].setValue(layer.face->uv[1]); - uvs[2][unit].setValue(layer.face->uv[2]); - - if (mface->v4) - uvs[3][unit].setValue(layer.face->uv[3]); - else - uvs[3][unit].setValue(0.0f, 0.0f); - - ++unit; - found_layers.push_back(map.uvCoName); - break; - } - } - } -} - -// ------------------------------------ -static bool ConvertMaterial( - BL_Material *material, - Material *mat, - MTFace *tface, - const char *tfaceName, - MFace *mface, - MCol *mmcol, - bool glslmat) -{ - material->Initialize(); - int texalpha = 0; - const bool validmat = (mat != NULL); - const bool validface = (tface != NULL); - const bool use_vcol = GetMaterialUseVColor(mat, glslmat); - - material->IdMode = DEFAULT_BLENDER; - material->glslmat = (validmat) ? glslmat: false; - material->materialindex = mface->mat_nr; - - // -------------------------------- - if (validmat) { - - // use lighting? - material->ras_mode |= (mat->mode & MA_SHLESS) ? 0 : USE_LIGHT; - material->ras_mode |= (mat->game.flag & GEMAT_BACKCULL) ? 0 : TWOSIDED; - - // cast shadows? - material->ras_mode |= ((mat->mode2 & MA_CASTSHADOW) && (mat->mode & MA_SHADBUF)) ? CAST_SHADOW : 0; - - // only shadows? - material->ras_mode |= (mat->mode & MA_ONLYCAST) ? ONLY_SHADOW : 0; - - MTex *mttmp = NULL; - int valid_index = 0; - - /* In Multitexture use the face texture if and only if - * it is set in the buttons - * In GLSL is not working yet :/ 3.2011 */ - - // foreach MTex - for (int i = 0; i < MAXTEX; i++) { - // use face tex - if (i == 0) { -#if 0 - Image *tmp = (Image *)(tface->tpage); -#else - /* weak but better then nothing */ - Image *tmp = mat ? mat->edit_image : NULL; -#endif - - if (tmp) { - material->img[i] = tmp; - material->texname[i] = material->img[i]->id.name; - material->flag[i] |= MIPMAP; - - material->flag[i] |= (mat->game.alpha_blend & GEMAT_ALPHA_SORT) ? USEALPHA : 0; - material->flag[i] |= (mat->game.alpha_blend & GEMAT_ALPHA) ? USEALPHA : 0; - material->flag[i] |= (mat->game.alpha_blend & GEMAT_ADD) ? CALCALPHA : 0; - - if (material->img[i]->flag & IMA_REFLECT) { - material->mapping[i].mapping |= USEREFL; - } - else { - mttmp = getMTexFromMaterial(mat, i); - if (mttmp && (mttmp->texco & TEXCO_UV)) { - /* string may be "" but thats detected as empty after */ - material->mapping[i].uvCoName = mttmp->uvname; - } - material->mapping[i].mapping |= USEUV; - } - - valid_index++; - } - else { - material->img[i] = 0; - material->texname[i] = ""; - } - continue; - } - - mttmp = getMTexFromMaterial(mat, i); - if (mttmp) { - if (mttmp->tex) { - if (mttmp->tex->type == TEX_IMAGE) { - material->mtexname[i] = mttmp->tex->id.name; - material->img[i] = mttmp->tex->ima; - if (material->img[i]) { - - material->texname[i] = material->img[i]->id.name; - material->flag[i] |= (mttmp->tex->imaflag &TEX_MIPMAP) ? MIPMAP : 0; - if (material->img[i] && (material->img[i]->flag & IMA_IGNORE_ALPHA) == 0) { - material->flag[i] |= USEALPHA; - } - if (mttmp->tex->imaflag & TEX_CALCALPHA) { - material->flag[i] |= CALCALPHA; - } - else if (mttmp->tex->flag & TEX_NEGALPHA) { - material->flag[i] |= USENEGALPHA; - } - - material->color_blend[i] = mttmp->colfac; - material->flag[i] |= (mttmp->mapto & MAP_ALPHA) ? TEXALPHA : 0; - material->flag[i] |= (mttmp->texflag & MTEX_NEGATIVE) ? TEXNEG : 0; - - if (!glslmat && (material->flag[i] & TEXALPHA)) { - texalpha = 1; - } - } - } - else if (mttmp->tex->type == TEX_ENVMAP) { - if (mttmp->tex->env->stype == ENV_LOAD) { - material->mtexname[i] = mttmp->tex->id.name; - EnvMap *env = mttmp->tex->env; - env->ima = mttmp->tex->ima; - material->cubemap[i] = env; - - if (material->cubemap[i]) { - if (!material->cubemap[i]->cube[0]) { - BL_Texture::SplitEnvMap(material->cubemap[i]); - } - - material->texname[i] = material->cubemap[i]->ima->id.name; - material->mapping[i].mapping |= USEENV; - } - } - } -#if 0 /* this flag isn't used anymore */ - material->flag[i] |= (BKE_animdata_from_id(mat->id) != NULL) ? HASIPO : 0; -#endif - /// -------------------------------- - // mapping methods - if (mat->septex & (1 << i)) { - // If this texture slot isn't in use, set it to disabled to prevent multi-uv problems - material->mapping[i].mapping = DISABLE; - } - else { - material->mapping[i].mapping |= (mttmp->texco & TEXCO_REFL) ? USEREFL : 0; - - if (mttmp->texco & TEXCO_OBJECT) { - material->mapping[i].mapping |= USEOBJ; - if (mttmp->object) { - material->mapping[i].objconame = mttmp->object->id.name; - } - } - else if (mttmp->texco & TEXCO_REFL) { - material->mapping[i].mapping |= USEREFL; - } - else if (mttmp->texco & (TEXCO_ORCO | TEXCO_GLOB)) { - material->mapping[i].mapping |= USEORCO; - } - else if (mttmp->texco & TEXCO_UV) { - /* string may be "" but thats detected as empty after */ - material->mapping[i].uvCoName = mttmp->uvname; - material->mapping[i].mapping |= USEUV; - } - else if (mttmp->texco & TEXCO_NORM) { - material->mapping[i].mapping |= USENORM; - } - else if (mttmp->texco & TEXCO_TANGENT) { - material->mapping[i].mapping |= USETANG; - } - else { - material->mapping[i].mapping |= DISABLE; - } - - material->mapping[i].scale[0] = mttmp->size[0]; - material->mapping[i].scale[1] = mttmp->size[1]; - material->mapping[i].scale[2] = mttmp->size[2]; - material->mapping[i].offsets[0] = mttmp->ofs[0]; - material->mapping[i].offsets[1] = mttmp->ofs[1]; - material->mapping[i].offsets[2] = mttmp->ofs[2]; - - material->mapping[i].projplane[0] = mttmp->projx; - material->mapping[i].projplane[1] = mttmp->projy; - material->mapping[i].projplane[2] = mttmp->projz; - } - /// -------------------------------- - - switch (mttmp->blendtype) { - case MTEX_BLEND: - material->blend_mode[i] = BLEND_MIX; - break; - case MTEX_MUL: - material->blend_mode[i] = BLEND_MUL; - break; - case MTEX_ADD: - material->blend_mode[i] = BLEND_ADD; - break; - case MTEX_SUB: - material->blend_mode[i] = BLEND_SUB; - break; - case MTEX_SCREEN: - material->blend_mode[i] = BLEND_SCR; - break; - } - valid_index++; - } - } - } - - // above one tex the switches here - // are not used - switch (valid_index) { - case 0: - material->IdMode = DEFAULT_BLENDER; - break; - case 1: - material->IdMode = ONETEX; - break; - default: - material->IdMode = GREATERTHAN2; - break; - } - material->SetUsers(mat->id.us); - - material->num_enabled = valid_index; - - material->speccolor[0] = mat->specr; - material->speccolor[1] = mat->specg; - material->speccolor[2] = mat->specb; - material->hard = (float)mat->har / 4.0f; - material->matcolor[0] = mat->r; - material->matcolor[1] = mat->g; - material->matcolor[2] = mat->b; - material->matcolor[3] = mat->alpha; - material->alpha = mat->alpha; - material->emit = mat->emit; - material->spec_f = mat->spec; - material->ref = mat->ref; - material->amb = mat->amb; - - material->ras_mode |= (mat->material_type == MA_TYPE_WIRE) ? WIRE : 0; - } - else { // No Material - int valid = 0; - - // check for tface tex to fallback on - if (validface) { -#if 0 - material->img[0] = (Image *)(tface->tpage); -#else - material->img[0] = mat ? mat->edit_image : NULL; -#endif - // ------------------------ - if (material->img[0]) { - material->texname[0] = material->img[0]->id.name; - material->mapping[0].mapping |= ((material->img[0]->flag & IMA_REFLECT) != 0) ? USEREFL : 0; - - /* see if depth of the image is 32bits */ - if (BKE_image_has_alpha(material->img[0])) { - material->flag[0] |= USEALPHA; - material->alphablend = GEMAT_ALPHA; - } - else { - material->alphablend = GEMAT_SOLID; - } - valid++; - } - } - else { - material->alphablend = GEMAT_SOLID; - } - - material->SetUsers(-1); - material->num_enabled = valid; - material->IdMode = TEXFACE; - material->speccolor[0] = 1.0f; - material->speccolor[1] = 1.0f; - material->speccolor[2] = 1.0f; - material->hard = 35.0f; - material->matcolor[0] = 0.5f; - material->matcolor[1] = 0.5f; - material->matcolor[2] = 0.5f; - material->spec_f = 0.5f; - material->ref = 0.8f; - - // No material - old default TexFace properties - material->ras_mode |= USE_LIGHT; - } - - /* No material, what to do? let's see what is in the UV and set the material accordingly - * light and visible is always on */ - if (validface) { - /* nop */ - } - else { - // nothing at all - material->alphablend = GEMAT_SOLID; - material->tile = 0; - } - - if (validmat && validface) { - material->alphablend = mat->game.alpha_blend; - } - - // with ztransp enabled, enforce alpha blending mode - if (validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->alphablend == GEMAT_SOLID)) { - material->alphablend = GEMAT_ALPHA; - } - - // always zsort alpha + add - if ((ELEM(material->alphablend, GEMAT_ALPHA, GEMAT_ALPHA_SORT, GEMAT_ADD) || texalpha) && (material->alphablend != GEMAT_CLIP)) { - material->ras_mode |= ALPHA; - material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT)) ? ZSORT : 0; - } - - // XXX The RGB values here were meant to be temporary storage for the conversion process, - // but fonts now make use of them too, so we leave them in for now. - unsigned int rgb[4]; - GetRGB(use_vcol, mface, mmcol, mat, rgb); - - // swap the material color, so MCol on bitmap font works - if (validmat && (use_vcol == false) && (mat->game.flag & GEMAT_TEXT)) { - material->rgb[0] = KX_rgbaint2uint_new(rgb[0]); - material->rgb[1] = KX_rgbaint2uint_new(rgb[1]); - material->rgb[2] = KX_rgbaint2uint_new(rgb[2]); - material->rgb[3] = KX_rgbaint2uint_new(rgb[3]); - } - - if (validmat) { - material->matname =(mat->id.name); - } - material->material = mat; - return true; -} - -static RAS_MaterialBucket *material_from_mesh(Material *ma, MFace *mface, MTFace *tface, MCol *mcol, MTF_localLayer *layers, int lightlayer, unsigned int *rgb, MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT], const char *tfaceName, KX_Scene* scene, KX_BlenderSceneConverter *converter) -{ - RAS_IPolyMaterial* polymat = converter->FindCachedPolyMaterial(scene, ma); - BL_Material* bl_mat = converter->FindCachedBlenderMaterial(scene, ma); - KX_BlenderMaterial* kx_blmat = NULL; - - /* first is the BL_Material */ - if (!bl_mat) - { - bl_mat = new BL_Material(); - - ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, - converter->GetGLSLMaterials()); - - if (ma) - converter->CacheBlenderMaterial(scene, ma, bl_mat); - } - - const bool use_vcol = GetMaterialUseVColor(ma, bl_mat->glslmat); - GetRGB(use_vcol, mface, mcol, ma, rgb); - - GetUVs(bl_mat, layers, mface, tface, uvs); - - /* then the KX_BlenderMaterial */ - if (polymat == NULL) - { - kx_blmat = new KX_BlenderMaterial(); - - kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL), lightlayer); - polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat); - if (ma) - converter->CachePolyMaterial(scene, ma, polymat); - } - - // see if a bucket was reused or a new one was created - // this way only one KX_BlenderMaterial object has to exist per bucket - bool bucketCreated; - RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated); - - // this is needed to free up memory afterwards. - // the converter will also prevent duplicates from being registered, - // so just register everything. - converter->RegisterPolyMaterial(polymat); - converter->RegisterBlenderMaterial(bl_mat); - - return bucket; -} - -/* blenderobj can be NULL, make sure its checked for */ -RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter, bool libloading) -{ - RAS_MeshObject *meshobj; - int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object. - - // Without checking names, we get some reuse we don't want that can cause - // problems with material LoDs. - if (blenderobj && ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL)) { - const char *bge_name = meshobj->GetName().ReadPtr(); - const char *blender_name = ((ID *)blenderobj->data)->name + 2; - if (STREQ(bge_name, blender_name)) { - return meshobj; - } - } - - // Get DerivedMesh data - DerivedMesh *dm = CDDM_from_mesh(mesh); - DM_ensure_tessface(dm); - - MVert *mvert = dm->getVertArray(dm); - int totvert = dm->getNumVerts(dm); - - MFace *mface = dm->getTessFaceArray(dm); - MTFace *tface = static_cast<MTFace*>(dm->getTessFaceDataArray(dm, CD_MTFACE)); - MCol *mcol = static_cast<MCol*>(dm->getTessFaceDataArray(dm, CD_MCOL)); - float (*tangent)[4] = NULL; - int totface = dm->getNumTessFaces(dm); - const char *tfaceName = ""; - - /* needs to be rewritten for loopdata */ - if (tface) { - if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1) { - bool generate_data = false; - if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) { - DM_calc_loop_tangents(dm, true, NULL, 0); - generate_data = true; - } - DM_generate_tangent_tessface_data(dm, generate_data); - } - tangent = (float(*)[4])dm->getTessFaceDataArray(dm, CD_TANGENT); - } - - meshobj = new RAS_MeshObject(mesh); - - // Extract avaiable layers - MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE]; - for (int lay=0; lay<MAX_MTFACE; lay++) { - layers[lay].face = 0; - layers[lay].name = ""; - } - - int validLayers = 0; - for (int i=0; i<dm->faceData.totlayer; i++) - { - if (dm->faceData.layers[i].type == CD_MTFACE) - { - if (validLayers >= MAX_MTFACE) { - printf("%s: corrupted mesh %s - too many CD_MTFACE layers\n", __func__, mesh->id.name); - break; - } - - layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data); - layers[validLayers].name = dm->faceData.layers[i].name; - if (tface == layers[validLayers].face) - tfaceName = layers[validLayers].name; - validLayers++; - } - } - - meshobj->SetName(mesh->id.name + 2); - meshobj->m_sharedvertex_map.resize(totvert); - - Material* ma = 0; - MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT]; - unsigned int rgb[4] = {0}; - - MT_Point3 pt[4]; - MT_Vector3 no[4]; - MT_Vector4 tan[4]; - - /* ugh, if there is a less annoying way to do this please use that. - * since these are converted from floats to floats, theres no real - * advantage to use MT_ types - campbell */ - for (unsigned int i = 0; i < 4; i++) { - const float zero_vec[4] = {0.0f}; - pt[i].setValue(zero_vec); - no[i].setValue(zero_vec); - tan[i].setValue(zero_vec); - } - - /* we need to manually initialize the uvs (MoTo doesn't do that) [#34550] */ - for (unsigned int i = 0; i < RAS_TexVert::MAX_UNIT; i++) { - uvs[0][i] = uvs[1][i] = uvs[2][i] = uvs[3][i] = MT_Point2(0.f, 0.f); - } - - for (int f=0;f<totface;f++,mface++) - { - /* get coordinates, normals and tangents */ - pt[0].setValue(mvert[mface->v1].co); - pt[1].setValue(mvert[mface->v2].co); - pt[2].setValue(mvert[mface->v3].co); - if (mface->v4) pt[3].setValue(mvert[mface->v4].co); - - if (mface->flag & ME_SMOOTH) { - float n0[3], n1[3], n2[3], n3[3]; - - normal_short_to_float_v3(n0, mvert[mface->v1].no); - normal_short_to_float_v3(n1, mvert[mface->v2].no); - normal_short_to_float_v3(n2, mvert[mface->v3].no); - no[0] = n0; - no[1] = n1; - no[2] = n2; - - if (mface->v4) { - normal_short_to_float_v3(n3, mvert[mface->v4].no); - no[3] = n3; - } - } - else { - float fno[3]; - - if (mface->v4) - normal_quad_v3(fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); - else - normal_tri_v3(fno,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co); - - no[0] = no[1] = no[2] = no[3] = MT_Vector3(fno); - } - - if (tangent) { - tan[0] = tangent[f*4 + 0]; - tan[1] = tangent[f*4 + 1]; - tan[2] = tangent[f*4 + 2]; - - if (mface->v4) - tan[3] = tangent[f*4 + 3]; - } - if (blenderobj) - ma = give_current_material(blenderobj, mface->mat_nr+1); - else - ma = mesh->mat ? mesh->mat[mface->mat_nr]:NULL; - - // Check for blender material - if (ma == NULL) { - ma= &defmaterial; - } - - { - - RAS_MaterialBucket* bucket = material_from_mesh(ma, mface, tface, mcol, layers, lightlayer, rgb, uvs, tfaceName, scene, converter); - - // set render flags - bool visible = ((ma->game.flag & GEMAT_INVISIBLE)==0); - bool twoside = ((ma->game.flag & GEMAT_BACKCULL)==0); - bool collider = ((ma->game.flag & GEMAT_NOPHYSICS)==0); - - /* mark face as flat, so vertices are split */ - bool flat = (mface->flag & ME_SMOOTH) == 0; - - int nverts = (mface->v4)? 4: 3; - - RAS_Polygon *poly = meshobj->AddPolygon(bucket, nverts); - - poly->SetVisible(visible); - poly->SetCollider(collider); - poly->SetTwoside(twoside); - //poly->SetEdgeCode(mface->edcode); - - meshobj->AddVertex(poly,0,pt[0],uvs[0],tan[0],rgb[0],no[0],flat,mface->v1); - meshobj->AddVertex(poly,1,pt[1],uvs[1],tan[1],rgb[1],no[1],flat,mface->v2); - meshobj->AddVertex(poly,2,pt[2],uvs[2],tan[2],rgb[2],no[2],flat,mface->v3); - - if (nverts==4) - meshobj->AddVertex(poly,3,pt[3],uvs[3],tan[3],rgb[3],no[3],flat,mface->v4); - } - - if (tface) - tface++; - if (mcol) - mcol+=4; - - for (int lay=0; lay<MAX_MTFACE; lay++) - { - MTF_localLayer &layer = layers[lay]; - if (layer.face == 0) break; - - layer.face++; - } - } - // keep meshobj->m_sharedvertex_map for reinstance phys mesh. - // 2.49a and before it did: meshobj->m_sharedvertex_map.clear(); - // but this didnt save much ram. - Campbell - meshobj->EndConversion(); - - // pre calculate texture generation - // However, we want to delay this if we're libloading so we can make sure we have the right scene. - if (!libloading) { - for (list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial(); - mit != meshobj->GetLastMaterial(); ++ mit) { - mit->m_bucket->GetPolyMaterial()->OnConstruction(); - } - } - - if (layers) - delete []layers; - - dm->release(dm); - - converter->RegisterGameMesh(meshobj, mesh); - return meshobj; -} - - - -static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject) -{ - PHY_MaterialProps *materialProps = new PHY_MaterialProps; - - MT_assert(materialProps && "Create physics material properties failed"); - - Material* blendermat = give_current_material(blenderobject, 1); - - if (blendermat) - { - MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f); - - materialProps->m_restitution = blendermat->reflect; - materialProps->m_friction = blendermat->friction; - materialProps->m_fh_spring = blendermat->fh; - materialProps->m_fh_damping = blendermat->xyfrict; - materialProps->m_fh_distance = blendermat->fhdist; - materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0; - } - else { - //give some defaults - materialProps->m_restitution = 0.f; - materialProps->m_friction = 0.5; - materialProps->m_fh_spring = 0.f; - materialProps->m_fh_damping = 0.f; - materialProps->m_fh_distance = 0.f; - materialProps->m_fh_normal = false; - - } - - return materialProps; -} - -static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject) -{ - PHY_ShapeProps *shapeProps = new PHY_ShapeProps; - - MT_assert(shapeProps); - - shapeProps->m_mass = blenderobject->mass; - -// This needs to be fixed in blender. For now, we use: - -// in Blender, inertia stands for the size value which is equivalent to -// the sphere radius - shapeProps->m_inertia = blenderobject->formfactor; - - MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f); - MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f); - - shapeProps->m_lin_drag = 1.0f - blenderobject->damping; - shapeProps->m_ang_drag = 1.0f - blenderobject->rdamping; - - shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0]; - shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1]; - shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2]; - shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0); - - shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0; - shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0; - -// velocity clamping XXX - shapeProps->m_clamp_vel_min = blenderobject->min_vel; - shapeProps->m_clamp_vel_max = blenderobject->max_vel; - shapeProps->m_clamp_angvel_min = blenderobject->min_angvel; - shapeProps->m_clamp_angvel_max = blenderobject->max_angvel; - -// Character physics properties - shapeProps->m_step_height = blenderobject->step_height; - shapeProps->m_jump_speed = blenderobject->jump_speed; - shapeProps->m_fall_speed = blenderobject->fall_speed; - shapeProps->m_max_jumps = blenderobject->max_jumps; - - return shapeProps; -} - - - - - -////////////////////////////////////////////////////////// - - - -static float my_boundbox_mesh(Mesh *me, float *loc, float *size) -{ - MVert *mvert; - BoundBox *bb; - float min[3], max[3]; - float mloc[3], msize[3]; - float radius_sq=0.0f, vert_radius_sq, *co; - int a; - - if (me->bb==0) { - me->bb = BKE_boundbox_alloc_unit(); - } - bb= me->bb; - - INIT_MINMAX(min, max); - - if (!loc) loc= mloc; - if (!size) size= msize; - - mvert= me->mvert; - for (a = 0; a<me->totvert; a++, mvert++) { - co = mvert->co; - - /* bounds */ - minmax_v3v3_v3(min, max, co); - - /* radius */ - - vert_radius_sq = len_squared_v3(co); - if (vert_radius_sq > radius_sq) - radius_sq = vert_radius_sq; - } - - if (me->totvert) { - loc[0] = (min[0] + max[0]) / 2.0f; - loc[1] = (min[1] + max[1]) / 2.0f; - loc[2] = (min[2] + max[2]) / 2.0f; - - size[0] = (max[0] - min[0]) / 2.0f; - size[1] = (max[1] - min[1]) / 2.0f; - size[2] = (max[2] - min[2]) / 2.0f; - } - else { - loc[0] = loc[1] = loc[2] = 0.0f; - size[0] = size[1] = size[2] = 0.0f; - } - - bb->vec[0][0] = bb->vec[1][0] = bb->vec[2][0] = bb->vec[3][0] = loc[0]-size[0]; - bb->vec[4][0] = bb->vec[5][0] = bb->vec[6][0] = bb->vec[7][0] = loc[0]+size[0]; - - bb->vec[0][1] = bb->vec[1][1] = bb->vec[4][1] = bb->vec[5][1] = loc[1]-size[1]; - bb->vec[2][1] = bb->vec[3][1] = bb->vec[6][1] = bb->vec[7][1] = loc[1]+size[1]; - - bb->vec[0][2] = bb->vec[3][2] = bb->vec[4][2] = bb->vec[7][2] = loc[2]-size[2]; - bb->vec[1][2] = bb->vec[2][2] = bb->vec[5][2] = bb->vec[6][2] = loc[2]+size[2]; - - return sqrtf_signed(radius_sq); -} - -////////////////////////////////////////////////////// - - -static void BL_CreateGraphicObjectNew(KX_GameObject* gameobj, - const MT_Point3& localAabbMin, - const MT_Point3& localAabbMax, - KX_Scene* kxscene, - bool isActive, - e_PhysicsEngine physics_engine) -{ - if (gameobj->GetMeshCount() > 0) - { - switch (physics_engine) - { -#ifdef WITH_BULLET - case UseBullet: - { - CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); - assert(env); - PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); - CcdGraphicController* ctrl = new CcdGraphicController(env, motionstate); - gameobj->SetGraphicController(ctrl); - ctrl->SetNewClientInfo(gameobj->getClientInfo()); - ctrl->SetLocalAabb(localAabbMin, localAabbMax); - if (isActive) { - // add first, this will create the proxy handle, only if the object is visible - if (gameobj->GetVisible()) - env->AddCcdGraphicController(ctrl); - // update the mesh if there is a deformer, this will also update the bounding box for modifiers - RAS_Deformer* deformer = gameobj->GetDeformer(); - if (deformer) - deformer->UpdateBuckets(); - } - } - break; -#endif - default: - break; - } - } -} - -static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, - struct Object* blenderobject, - RAS_MeshObject* meshobj, - KX_Scene* kxscene, - int activeLayerBitInfo, - KX_BlenderSceneConverter *converter, - bool processCompoundChildren - ) - -{ - //SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/ - //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0); - //bool bRigidBody = (userigidbody == 0); - - // object has physics representation? - if (!(blenderobject->gameflag & OB_COLLISION)) { - // Respond to all collisions so that Near sensors work on No Collision - // objects. - gameobj->SetUserCollisionGroup(0xffff); - gameobj->SetUserCollisionMask(0xffff); - return; - } - - gameobj->SetUserCollisionGroup(blenderobject->col_group); - gameobj->SetUserCollisionMask(blenderobject->col_mask); - - // get Root Parent of blenderobject - struct Object* parent= blenderobject->parent; - while (parent && parent->parent) { - parent= parent->parent; - } - - bool isCompoundChild = false; - bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD) && !(blenderobject->gameflag & OB_SOFT_BODY); - - /* When the parent is not OB_DYNAMIC and has no OB_COLLISION then it gets no bullet controller - * and cant be apart of the parents compound shape, same goes for OB_SOFT_BODY */ - if (parent && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) { - if ((parent->gameflag & OB_CHILD)!=0 && (blenderobject->gameflag & OB_CHILD) && !(parent->gameflag & OB_SOFT_BODY)) { - isCompoundChild = true; - } - } - if (processCompoundChildren != isCompoundChild) - return; - - - PHY_ShapeProps* shapeprops = - CreateShapePropsFromBlenderObject(blenderobject); - - - PHY_MaterialProps* smmaterial = - CreateMaterialFromBlenderObject(blenderobject); - - DerivedMesh* dm = NULL; - if (gameobj->GetDeformer()) - dm = gameobj->GetDeformer()->GetPhysicsMesh(); - - class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); - - kxscene->GetPhysicsEnvironment()->ConvertObject(gameobj, meshobj, dm, kxscene, shapeprops, smmaterial, motionstate, activeLayerBitInfo, isCompoundChild, hasCompoundChildren); - - bool isActor = (blenderobject->gameflag & OB_ACTOR)!=0; - bool isSensor = (blenderobject->gameflag & OB_SENSOR) != 0; - gameobj->getClientInfo()->m_type = - (isSensor) ? ((isActor) ? KX_ClientObjectInfo::OBACTORSENSOR : KX_ClientObjectInfo::OBSENSOR) : - (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC; - - // should we record animation for this object? - if ((blenderobject->gameflag & OB_RECORD_ANIMATION) != 0) - gameobj->SetRecordAnimation(true); - - delete shapeprops; - delete smmaterial; - if (dm) { - dm->needsFree = 1; - dm->release(dm); - } -} - - - - - -static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRasterizer *rasterizer, KX_BlenderSceneConverter *converter) -{ - RAS_ILightObject *lightobj = rasterizer->CreateLight(); - KX_LightObject *gamelight; - - lightobj->m_att1 = la->att1; - lightobj->m_att2 = (la->mode & LA_QUAD) ? la->att2 : 0.0f; - lightobj->m_coeff_const = la->coeff_const; - lightobj->m_coeff_lin = la->coeff_lin; - lightobj->m_coeff_quad = la->coeff_quad; - lightobj->m_color[0] = la->r; - lightobj->m_color[1] = la->g; - lightobj->m_color[2] = la->b; - lightobj->m_distance = la->dist; - lightobj->m_energy = la->energy; - lightobj->m_shadowclipstart = la->clipsta; - lightobj->m_shadowclipend = la->clipend; - lightobj->m_shadowbias = la->bias; - lightobj->m_shadowbleedbias = la->bleedbias; - lightobj->m_shadowmaptype = la->shadowmap_type; - lightobj->m_shadowfrustumsize = la->shadow_frustum_size; - lightobj->m_shadowcolor[0] = la->shdwr; - lightobj->m_shadowcolor[1] = la->shdwg; - lightobj->m_shadowcolor[2] = la->shdwb; - lightobj->m_layer = layerflag; - lightobj->m_spotblend = la->spotblend; - lightobj->m_spotsize = la->spotsize; - - lightobj->m_nodiffuse = (la->mode & LA_NO_DIFF) != 0; - lightobj->m_nospecular = (la->mode & LA_NO_SPEC) != 0; - - bool glslmat = converter->GetGLSLMaterials(); - - // in GLSL NEGATIVE LAMP is handled inside the lamp update function - if (glslmat==0) { - if (la->mode & LA_NEG) - { - lightobj->m_color[0] = -lightobj->m_color[0]; - lightobj->m_color[1] = -lightobj->m_color[1]; - lightobj->m_color[2] = -lightobj->m_color[2]; - } - } - - if (la->type==LA_SUN) { - lightobj->m_type = RAS_ILightObject::LIGHT_SUN; - } else if (la->type==LA_SPOT) { - lightobj->m_type = RAS_ILightObject::LIGHT_SPOT; - } else { - lightobj->m_type = RAS_ILightObject::LIGHT_NORMAL; - } - - gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rasterizer, - lightobj, glslmat); - - return gamelight; -} - -static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) -{ - Camera* ca = static_cast<Camera*>(ob->data); - RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->sensor_x, ca->sensor_y, ca->sensor_fit, ca->shiftx, ca->shifty, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist); - KX_Camera *gamecamera; - - gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); - gamecamera->SetName(ca->id.name + 2); - - return gamecamera; -} - -static KX_GameObject *gameobject_from_blenderobject( - Object *ob, - KX_Scene *kxscene, - RAS_IRasterizer *rendertools, - KX_BlenderSceneConverter *converter, - bool libloading) -{ - KX_GameObject *gameobj = NULL; - Scene *blenderscene = kxscene->GetBlenderScene(); - - switch (ob->type) { - case OB_LAMP: - { - KX_LightObject* gamelight = gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter); - gameobj = gamelight; - - if (blenderscene->lay & ob->lay) - { - gamelight->AddRef(); - kxscene->GetLightList()->Add(gamelight); - } - - break; - } - - case OB_CAMERA: - { - KX_Camera* gamecamera = gamecamera_from_bcamera(ob, kxscene, converter); - gameobj = gamecamera; - - //don't add a reference: the camera list in kxscene->m_cameras is not released at the end - //gamecamera->AddRef(); - kxscene->AddCamera(gamecamera); - - break; - } - - case OB_MESH: - { - Mesh* mesh = static_cast<Mesh*>(ob->data); - float center[3], extents[3]; - float radius = my_boundbox_mesh((Mesh*) ob->data, center, extents); - RAS_MeshObject* meshobj = BL_ConvertMesh(mesh,ob,kxscene,converter, libloading); - - // needed for python scripting - kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj); - - if (ob->gameflag & OB_NAVMESH) - { - gameobj = new KX_NavMeshObject(kxscene,KX_Scene::m_callbacks); - gameobj->AddMesh(meshobj); - break; - } - - gameobj = new BL_DeformableGameObject(ob,kxscene,KX_Scene::m_callbacks); - - // set transformation - gameobj->AddMesh(meshobj); - - // gather levels of detail - if (BLI_listbase_count_at_most(&ob->lodlevels, 2) > 1) { - LodLevel *lod = ((LodLevel*)ob->lodlevels.first)->next; - Mesh* lodmesh = mesh; - Object* lodmatob = ob; - gameobj->AddLodMesh(meshobj); - for (; lod; lod = lod->next) { - if (!lod->source || lod->source->type != OB_MESH) continue; - if (lod->flags & OB_LOD_USE_MESH) { - lodmesh = static_cast<Mesh*>(lod->source->data); - } - if (lod->flags & OB_LOD_USE_MAT) { - lodmatob = lod->source; - } - gameobj->AddLodMesh(BL_ConvertMesh(lodmesh, lodmatob, kxscene, converter, libloading)); - } - if (blenderscene->gm.lodflag & SCE_LOD_USE_HYST) { - kxscene->SetLodHysteresis(true); - kxscene->SetLodHysteresisValue(blenderscene->gm.scehysteresis); - } - } - - // for all objects: check whether they want to - // respond to updates - bool ignoreActivityCulling = - ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0); - gameobj->SetIgnoreActivityCulling(ignoreActivityCulling); - gameobj->SetOccluder((ob->gameflag & OB_OCCLUDER) != 0, false); - - // we only want obcolor used if there is a material in the mesh - // that requires it - Material *mat= NULL; - bool bUseObjectColor=false; - - for (int i=0;i<mesh->totcol;i++) { - mat=mesh->mat[i]; - if (!mat) break; - if ((mat->shade_flag & MA_OBCOLOR)) { - bUseObjectColor = true; - break; - } - } - if (bUseObjectColor) - gameobj->SetObjectColor(ob->col); - - // two options exists for deform: shape keys and armature - // only support relative shape key - bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE; - bool bHasDvert = mesh->dvert != NULL && ob->defbase.first; - bool bHasArmature = (BL_ModifierDeformer::HasArmatureDeformer(ob) && ob->parent && ob->parent->type == OB_ARMATURE && bHasDvert); - bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(ob); -#ifdef WITH_BULLET - bool bHasSoftBody = (!ob->parent && (ob->gameflag & OB_SOFT_BODY)); -#endif - if (bHasModifier) { - BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL_DeformableGameObject *)gameobj, - kxscene->GetBlenderScene(), ob, meshobj); - ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); - } else if (bHasShapeKey) { - // not that we can have shape keys without dvert! - BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj, - ob, meshobj); - ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); - } else if (bHasArmature) { - BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj, - ob, meshobj); - ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); - } else if (bHasDvert) { - // this case correspond to a mesh that can potentially deform but not with the - // object to which it is attached for the moment. A skin mesh was created in - // BL_ConvertMesh() so must create a deformer too! - BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj, - ob, meshobj); - ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); -#ifdef WITH_BULLET - } else if (bHasSoftBody) { - KX_SoftBodyDeformer *dcont = new KX_SoftBodyDeformer(meshobj, (BL_DeformableGameObject*)gameobj); - ((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont); -#endif - } - - MT_Point3 min = MT_Point3(center) - MT_Vector3(extents); - MT_Point3 max = MT_Point3(center) + MT_Vector3(extents); - SG_BBox bbox = SG_BBox(min, max); - gameobj->GetSGNode()->SetBBox(bbox); - gameobj->GetSGNode()->SetRadius(radius); - - break; - } - - case OB_ARMATURE: - { - bArmature *arm = (bArmature*)ob->data; - gameobj = new BL_ArmatureObject( - kxscene, - KX_Scene::m_callbacks, - ob, - kxscene->GetBlenderScene(), // handle - arm->gevertdeformer - ); - /* Get the current pose from the armature object and apply it as the rest pose */ - break; - } - - case OB_EMPTY: - { - gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks); - // set transformation - break; - } - - case OB_FONT: - { - bool do_color_management = BKE_scene_check_color_management_enabled(blenderscene); - /* font objects have no bounding box */ - gameobj = new KX_FontObject(kxscene,KX_Scene::m_callbacks, rendertools, ob, do_color_management); - - /* add to the list only the visible fonts */ - if ((ob->lay & kxscene->GetBlenderScene()->lay) != 0) - kxscene->AddFont(static_cast<KX_FontObject*>(gameobj)); - break; - } - -#ifdef THREADED_DAG_WORKAROUND - case OB_CURVE: - { - if (ob->curve_cache == NULL) { - BKE_displist_make_curveTypes(blenderscene, ob, false); - } - } -#endif - - } - if (gameobj) - { - gameobj->SetLayer(ob->lay); - gameobj->SetBlenderObject(ob); - /* set the visibility state based on the objects render option in the outliner */ - if (ob->restrictflag & OB_RESTRICT_RENDER) gameobj->SetVisible(0, 0); - } - return gameobj; -} - -struct parentChildLink { - struct Object* m_blenderchild; - SG_Node* m_gamechildnode; -}; - -#if 0 -static bPoseChannel *get_active_posechannel2(Object *ob) -{ - bArmature *arm= (bArmature*)ob->data; - bPoseChannel *pchan; - - /* find active */ - for (pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if (pchan->bone && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer)) - return pchan; - } - - return NULL; -} -#endif - -static ListBase *get_active_constraints2(Object *ob) -{ - if (!ob) - return NULL; - - // XXX - shouldnt we care about the pose data and not the mode??? -#if 0 - if (ob->mode & OB_MODE_POSE) { - bPoseChannel *pchan; - - pchan = get_active_posechannel2(ob); - if (pchan) - return &pchan->constraints; - } - else -#endif - { - return &ob->constraints; - } - - return NULL; -} - -static void UNUSED_FUNCTION(print_active_constraints2)(Object *ob) //not used, use to debug -{ - bConstraint* curcon; - ListBase* conlist = get_active_constraints2(ob); - - if (conlist) { - for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) { - printf("%i\n",curcon->type); - } - } -} - -// Copy base layer to object layer like in BKE_scene_set_background -static void blenderSceneSetBackground(Scene *blenderscene) -{ - Scene *it; - Base *base; - - for (SETLOOPER(blenderscene, it, base)) { - base->object->lay = base->lay; - BKE_scene_object_base_flag_sync_from_base(base); - } -} - -static KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist) -{ - - for (int j=0;j<sumolist->GetCount();j++) - { - KX_GameObject* gameobje = (KX_GameObject*) sumolist->GetValue(j); - if (gameobje->GetName()==busc) - return gameobje; - } - - return 0; - -} - -static bool bl_isConstraintInList(KX_GameObject *gameobj, set<KX_GameObject*> convertedlist) -{ - set<KX_GameObject*>::iterator gobit; - for (gobit = convertedlist.begin(); gobit != convertedlist.end(); gobit++) { - if ((*gobit)->GetName() == gameobj->GetName()) - return true; - } - return false; -} - -/* helper for BL_ConvertBlenderObjects, avoids code duplication - * note: all var names match args are passed from the caller */ -static void bl_ConvertBlenderObject_Single( - KX_BlenderSceneConverter *converter, - Object *blenderobject, - vector<parentChildLink> &vec_parent_child, - CListValue* logicbrick_conversionlist, - CListValue* objectlist, CListValue* inactivelist, CListValue* sumolist, - KX_Scene* kxscene, KX_GameObject* gameobj, - SCA_LogicManager* logicmgr, SCA_TimeEventManager* timemgr, - bool isInActiveLayer - ) -{ - MT_Point3 pos( - blenderobject->loc[0]+blenderobject->dloc[0], - blenderobject->loc[1]+blenderobject->dloc[1], - blenderobject->loc[2]+blenderobject->dloc[2] - ); - - MT_Matrix3x3 rotation; - float rotmat[3][3]; - BKE_object_rot_to_mat3(blenderobject, rotmat, false); - rotation.setValue3x3((float*)rotmat); - - MT_Vector3 scale(blenderobject->size); - - gameobj->NodeSetLocalPosition(pos); - gameobj->NodeSetLocalOrientation(rotation); - gameobj->NodeSetLocalScale(scale); - gameobj->NodeUpdateGS(0); - - sumolist->Add(gameobj->AddRef()); - - BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); - - gameobj->SetName(blenderobject->id.name + 2); - - // update children/parent hierarchy - if (blenderobject->parent != 0) - { - // blender has an additional 'parentinverse' offset in each object - SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); - SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); - - // define a normal parent relationship for this node. - KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); - parentinversenode->SetParentRelation(parent_relation); - - parentChildLink pclink; - pclink.m_blenderchild = blenderobject; - pclink.m_gamechildnode = parentinversenode; - vec_parent_child.push_back(pclink); - - float* fl = (float*) blenderobject->parentinv; - MT_Transform parinvtrans(fl); - parentinversenode->SetLocalPosition(parinvtrans.getOrigin()); - // problem here: the parent inverse transform combines scaling and rotation - // in the basis but the scenegraph needs separate rotation and scaling. - // This is not important for OpenGL (it uses 4x4 matrix) but it is important - // for the physic engine that needs a separate scaling - //parentinversenode->SetLocalOrientation(parinvtrans.getBasis()); - - // Extract the rotation and the scaling from the basis - MT_Matrix3x3 ori(parinvtrans.getBasis()); - MT_Vector3 x(ori.getColumn(0)); - MT_Vector3 y(ori.getColumn(1)); - MT_Vector3 z(ori.getColumn(2)); - MT_Vector3 parscale(x.length(), y.length(), z.length()); - if (!MT_fuzzyZero(parscale[0])) - x /= parscale[0]; - if (!MT_fuzzyZero(parscale[1])) - y /= parscale[1]; - if (!MT_fuzzyZero(parscale[2])) - z /= parscale[2]; - ori.setColumn(0, x); - ori.setColumn(1, y); - ori.setColumn(2, z); - parentinversenode->SetLocalOrientation(ori); - parentinversenode->SetLocalScale(parscale); - - parentinversenode->AddChild(gameobj->GetSGNode()); - } - - // needed for python scripting - logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); - - // needed for group duplication - logicmgr->RegisterGameObj(blenderobject, gameobj); - for (int i = 0; i < gameobj->GetMeshCount(); i++) - logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject); - - converter->RegisterGameObject(gameobj, blenderobject); - // this was put in rapidly, needs to be looked at more closely - // only draw/use objects in active 'blender' layers - - logicbrick_conversionlist->Add(gameobj->AddRef()); - - if (isInActiveLayer) - { - objectlist->Add(gameobj->AddRef()); - //tf.Add(gameobj->GetSGNode()); - - gameobj->NodeUpdateGS(0); - gameobj->AddMeshUser(); - } - else - { - //we must store this object otherwise it will be deleted - //at the end of this function if it is not a root object - inactivelist->Add(gameobj->AddRef()); - } -} - - -// convert blender objects into ketsji gameobjects -void BL_ConvertBlenderObjects(struct Main* maggie, - KX_Scene* kxscene, - KX_KetsjiEngine* ketsjiEngine, - e_PhysicsEngine physics_engine, - RAS_IRasterizer* rendertools, - RAS_ICanvas* canvas, - KX_BlenderSceneConverter* converter, - bool alwaysUseExpandFraming, - bool libloading - ) -{ - -#define BL_CONVERTBLENDEROBJECT_SINGLE \ - bl_ConvertBlenderObject_Single(converter, \ - blenderobject, \ - vec_parent_child, \ - logicbrick_conversionlist, \ - objectlist, inactivelist, sumolist, \ - kxscene, gameobj, \ - logicmgr, timemgr, \ - isInActiveLayer \ - ) - - - - Scene *blenderscene = kxscene->GetBlenderScene(); - // for SETLOOPER - Scene *sce_iter; - Base *base; - - // Get the frame settings of the canvas. - // Get the aspect ratio of the canvas as designed by the user. - - RAS_FrameSettings::RAS_FrameType frame_type; - int aspect_width; - int aspect_height; - set<Group*> grouplist; // list of groups to be converted - set<Object*> allblobj; // all objects converted - set<Object*> groupobj; // objects from groups (never in active layer) - - // This is bad, but we use this to make sure the first time this is called - // is not in a separate thread. - BL_Texture::GetMaxUnits(); - - /* We have to ensure that group definitions are only converted once - * push all converted group members to this set. - * This will happen when a group instance is made from a linked group instance - * and both are on the active layer. */ - set<KX_GameObject*> convertedlist; - - if (alwaysUseExpandFraming) { - frame_type = RAS_FrameSettings::e_frame_extend; - aspect_width = canvas->GetWidth(); - aspect_height = canvas->GetHeight(); - } else { - if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { - frame_type = RAS_FrameSettings::e_frame_bars; - } else if (blenderscene->gm.framing.type == SCE_GAMEFRAMING_EXTEND) { - frame_type = RAS_FrameSettings::e_frame_extend; - } else { - frame_type = RAS_FrameSettings::e_frame_scale; - } - - aspect_width = (int)(blenderscene->r.xsch * blenderscene->r.xasp); - aspect_height = (int)(blenderscene->r.ysch * blenderscene->r.yasp); - } - - RAS_FrameSettings frame_settings( - frame_type, - blenderscene->gm.framing.col[0], - blenderscene->gm.framing.col[1], - blenderscene->gm.framing.col[2], - aspect_width, - aspect_height - ); - kxscene->SetFramingType(frame_settings); - - kxscene->SetGravity(MT_Vector3(0,0, -blenderscene->gm.gravity)); - - /* set activity culling parameters */ - kxscene->SetActivityCulling( (blenderscene->gm.mode & WO_ACTIVITY_CULLING) != 0); - kxscene->SetActivityCullingRadius(blenderscene->gm.activityBoxRadius); - kxscene->SetDbvtCulling((blenderscene->gm.mode & WO_DBVT_CULLING) != 0); - - // no occlusion culling by default - kxscene->SetDbvtOcclusionRes(0); - - int activeLayerBitInfo = blenderscene->lay; - - // list of all object converted, active and inactive - CListValue* sumolist = new CListValue(); - - vector<parentChildLink> vec_parent_child; - - CListValue* objectlist = kxscene->GetObjectList(); - CListValue* inactivelist = kxscene->GetInactiveList(); - CListValue* parentlist = kxscene->GetRootParentList(); - - SCA_LogicManager* logicmgr = kxscene->GetLogicManager(); - SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager(); - - CListValue* logicbrick_conversionlist = new CListValue(); - - //SG_TreeFactory tf; - - // Convert actions to actionmap - bAction *curAct; - for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next) - { - logicmgr->RegisterActionName(curAct->id.name + 2, curAct); - } - - SetDefaultLightMode(blenderscene); - - blenderSceneSetBackground(blenderscene); - - // Let's support scene set. - // Beware of name conflict in linked data, it will not crash but will create confusion - // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have - // no conflicting name for Object, Object data and Action. - for (SETLOOPER(blenderscene, sce_iter, base)) - { - Object* blenderobject = base->object; - allblobj.insert(blenderobject); - - KX_GameObject* gameobj = gameobject_from_blenderobject( - base->object, - kxscene, - rendertools, - converter, - libloading); - - bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0; - if (gameobj) - { - /* macro calls object conversion funcs */ - BL_CONVERTBLENDEROBJECT_SINGLE; - - if (gameobj->IsDupliGroup()) { - grouplist.insert(blenderobject->dup_group); - } - - /* Note about memory leak issues: - * When a CValue derived class is created, m_refcount is initialized to 1 - * so the class must be released after being used to make sure that it won't - * hang in memory. If the object needs to be stored for a long time, - * use AddRef() so that this Release() does not free the object. - * Make sure that for any AddRef() there is a Release()!!!! - * Do the same for any object derived from CValue, CExpression and NG_NetworkMessage - */ - gameobj->Release(); - } - } - - if (!grouplist.empty()) - { - // now convert the group referenced by dupli group object - // keep track of all groups already converted - set<Group*> allgrouplist = grouplist; - set<Group*> tempglist; - // recurse - while (!grouplist.empty()) - { - set<Group*>::iterator git; - tempglist.clear(); - tempglist.swap(grouplist); - for (git=tempglist.begin(); git!=tempglist.end(); git++) - { - Group* group = *git; - FOREACH_GROUP_OBJECT_BEGIN(group, blenderobject) - { - if (converter->FindGameObject(blenderobject) == NULL) - { - allblobj.insert(blenderobject); - groupobj.insert(blenderobject); - KX_GameObject* gameobj = gameobject_from_blenderobject( - blenderobject, - kxscene, - rendertools, - converter, - libloading); - - bool isInActiveLayer = false; - if (gameobj) { - /* Insert object to the constraint game object list - * so we can check later if there is a instance in the scene or - * an instance and its actual group definition. */ - convertedlist.insert((KX_GameObject*)gameobj->AddRef()); - - /* macro calls object conversion funcs */ - BL_CONVERTBLENDEROBJECT_SINGLE; - - if (gameobj->IsDupliGroup()) - { - if (allgrouplist.insert(blenderobject->dup_group).second) - { - grouplist.insert(blenderobject->dup_group); - } - } - - /* see comment above re: mem leaks */ - gameobj->Release(); - } - } - } - FOREACH_GROUP_OBJECT_END; - } - } - } - - // non-camera objects not supported as camera currently - if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) { - KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera); - - if (gamecamera) - kxscene->SetActiveCamera(gamecamera); - } - - // Set up armatures - set<Object*>::iterator oit; - for (oit=allblobj.begin(); oit!=allblobj.end(); oit++) - { - Object* blenderobj = *oit; - if (blenderobj->type==OB_MESH) { - Mesh *me = (Mesh*)blenderobj->data; - - if (me->dvert) { - BL_DeformableGameObject *obj = (BL_DeformableGameObject*)converter->FindGameObject(blenderobj); - - if (obj && BL_ModifierDeformer::HasArmatureDeformer(blenderobj) && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE) { - KX_GameObject *par = converter->FindGameObject(blenderobj->parent); - if (par && obj->GetDeformer()) - ((BL_SkinDeformer*)obj->GetDeformer())->SetArmature((BL_ArmatureObject*) par); - } - } - } - } - - // create hierarchy information - int i; - vector<parentChildLink>::iterator pcit; - - for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit) - { - - struct Object* blenderchild = pcit->m_blenderchild; - struct Object* blenderparent = blenderchild->parent; - KX_GameObject* parentobj = converter->FindGameObject(blenderparent); - KX_GameObject* childobj = converter->FindGameObject(blenderchild); - - assert(childobj); - - if (!parentobj || objectlist->SearchValue(childobj) != objectlist->SearchValue(parentobj)) - { - // special case: the parent and child object are not in the same layer. - // This weird situation is used in Apricot for test purposes. - // Resolve it by not converting the child - childobj->GetSGNode()->DisconnectFromParent(); - delete pcit->m_gamechildnode; - // Now destroy the child object but also all its descendent that may already be linked - // Remove the child reference in the local list! - // Note: there may be descendents already if the children of the child were processed - // by this loop before the child. In that case, we must remove the children also - CListValue* childrenlist = childobj->GetChildrenRecursive(); - childrenlist->Add(childobj->AddRef()); - for ( i=0;i<childrenlist->GetCount();i++) - { - KX_GameObject* obj = static_cast<KX_GameObject*>(childrenlist->GetValue(i)); - if (sumolist->RemoveValue(obj)) - obj->Release(); - if (logicbrick_conversionlist->RemoveValue(obj)) - obj->Release(); - } - childrenlist->Release(); - - // now destroy recursively - converter->UnregisterGameObject(childobj); // removing objects during conversion make sure this runs too - kxscene->RemoveObject(childobj); - - continue; - } - - switch (blenderchild->partype) - { - case PARVERT1: - { - // creat a new vertex parent relationship for this node. - KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New(); - pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation); - break; - } - case PARSLOW: - { - // creat a new slow parent relationship for this node. - KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf); - pcit->m_gamechildnode->SetParentRelation(slow_parent_relation); - break; - } - case PARBONE: - { - // parent this to a bone - Bone *parent_bone = BKE_armature_find_bone_name(BKE_armature_from_object(blenderchild->parent), - blenderchild->parsubstr); - - if (parent_bone) { - KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone); - pcit->m_gamechildnode->SetParentRelation(bone_parent_relation); - } - - break; - } - case PARSKEL: // skinned - ignore - break; - case PAROBJECT: - case PARVERT3: - default: - // unhandled - break; - } - - parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode); - } - vec_parent_child.clear(); - - // find 'root' parents (object that has not parents in SceneGraph) - for (i=0;i<sumolist->GetCount();++i) - { - KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); - if (gameobj->GetSGNode()->GetSGParent() == 0) - { - parentlist->Add(gameobj->AddRef()); - gameobj->NodeUpdateGS(0); - } - } - - // create graphic controller for culling - if (kxscene->GetDbvtCulling()) - { - bool occlusion = false; - for (i=0; i<sumolist->GetCount();i++) - { - KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); - if (gameobj->GetMeshCount() > 0) - { - MT_Point3 box[2]; - gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity()); - // box[0] is the min, box[1] is the max - bool isactive = objectlist->SearchValue(gameobj); - BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine); - if (gameobj->GetOccluder()) - occlusion = true; - } - } - if (occlusion) - kxscene->SetDbvtOcclusionRes(blenderscene->gm.occlusionRes); - } - if (blenderscene->world) - kxscene->GetPhysicsEnvironment()->SetNumTimeSubSteps(blenderscene->gm.physubstep); - - // now that the scenegraph is complete, let's instantiate the deformers. - // We need that to create reusable derived mesh and physic shapes - for (i=0;i<sumolist->GetCount();++i) - { - KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); - if (gameobj->GetDeformer()) - gameobj->GetDeformer()->UpdateBuckets(); - } - - // Set up armature constraints and shapekey drivers - for (i=0;i<sumolist->GetCount();++i) - { - KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); - if (gameobj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE) - { - BL_ArmatureObject *armobj = (BL_ArmatureObject*)gameobj; - armobj->LoadConstraints(converter); - - CListValue *children = armobj->GetChildren(); - for (int j=0; j<children->GetCount();++j) - { - BL_ShapeDeformer *deform = dynamic_cast<BL_ShapeDeformer*>(((KX_GameObject*)children->GetValue(j))->GetDeformer()); - if (deform) - deform->LoadShapeDrivers(armobj); - } - - children->Release(); - } - } - - bool processCompoundChildren = false; - // create physics information - for (i=0;i<sumolist->GetCount();i++) - { - KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); - struct Object* blenderobject = gameobj->GetBlenderObject(); - int nummeshes = gameobj->GetMeshCount(); - RAS_MeshObject* meshobj = 0; - if (nummeshes > 0) - { - meshobj = gameobj->GetMesh(0); - } - int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0; - BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,converter,processCompoundChildren); - } - - processCompoundChildren = true; - // create physics information - for (i=0;i<sumolist->GetCount();i++) - { - KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); - struct Object* blenderobject = gameobj->GetBlenderObject(); - int nummeshes = gameobj->GetMeshCount(); - RAS_MeshObject* meshobj = 0; - if (nummeshes > 0) - { - meshobj = gameobj->GetMesh(0); - } - int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0; - BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,converter,processCompoundChildren); - } - - // create physics joints - for (i=0;i<sumolist->GetCount();i++) - { - PHY_IPhysicsEnvironment *physEnv = kxscene->GetPhysicsEnvironment(); - KX_GameObject *gameobj = (KX_GameObject *)sumolist->GetValue(i); - struct Object *blenderobject = gameobj->GetBlenderObject(); - ListBase *conlist = get_active_constraints2(blenderobject); - bConstraint *curcon; - - if (!conlist) - continue; - - for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) { - if (curcon->type != CONSTRAINT_TYPE_RIGIDBODYJOINT) - continue; - - bRigidBodyJointConstraint *dat = (bRigidBodyJointConstraint *)curcon->data; - - /* Skip if no target or a child object is selected or constraints are deactivated */ - if (!dat->tar || dat->child || (curcon->flag & CONSTRAINT_OFF)) - continue; - - /* Store constraints of grouped and instanced objects for all layers */ - gameobj->AddConstraint(dat); - - /** if it's during libload we only add constraints in the object but - * doesn't create it. Constraint will be replicated later in scene->MergeScene - */ - if (libloading) - continue; - - /* Skipped already converted constraints. - * This will happen when a group instance is made from a linked group instance - * and both are on the active layer. */ - if (bl_isConstraintInList(gameobj, convertedlist)) - continue; - - KX_GameObject *gotar = getGameOb(dat->tar->id.name + 2, sumolist); - - if (gotar && (gotar->GetLayer()&activeLayerBitInfo) && gotar->GetPhysicsController() && - (gameobj->GetLayer()&activeLayerBitInfo) && gameobj->GetPhysicsController()) - { - physEnv->SetupObjectConstraints(gameobj, gotar, dat); - } - } - } - - /* cleanup converted set of group objects */ - set<KX_GameObject*>::iterator gobit; - for (gobit = convertedlist.begin(); gobit != convertedlist.end(); gobit++) - (*gobit)->Release(); - - convertedlist.clear(); - sumolist->Release(); - - // convert world - KX_WorldInfo* worldinfo = new KX_WorldInfo(blenderscene, blenderscene->world); - converter->RegisterWorldInfo(worldinfo); - kxscene->SetWorldInfo(worldinfo); - - //create object representations for obstacle simulation - KX_ObstacleSimulation* obssimulation = kxscene->GetObstacleSimulation(); - if (obssimulation) - { - for ( i=0;i<objectlist->GetCount();i++) - { - KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i)); - struct Object* blenderobject = gameobj->GetBlenderObject(); - if (blenderobject->gameflag & OB_HASOBSTACLE) - { - obssimulation->AddObstacleForObj(gameobj); - } - } - } - - //process navigation mesh objects - for ( i=0; i<objectlist->GetCount();i++) - { - KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i)); - struct Object* blenderobject = gameobj->GetBlenderObject(); - if (blenderobject->type==OB_MESH && (blenderobject->gameflag & OB_NAVMESH)) - { - KX_NavMeshObject* navmesh = static_cast<KX_NavMeshObject*>(gameobj); - navmesh->SetVisible(0, true); - navmesh->BuildNavMesh(); - if (obssimulation) - obssimulation->AddObstaclesForNavMesh(navmesh); - } - } - for ( i=0; i<inactivelist->GetCount();i++) - { - KX_GameObject* gameobj = static_cast<KX_GameObject*>(inactivelist->GetValue(i)); - struct Object* blenderobject = gameobj->GetBlenderObject(); - if (blenderobject->type==OB_MESH && (blenderobject->gameflag & OB_NAVMESH)) - { - KX_NavMeshObject* navmesh = static_cast<KX_NavMeshObject*>(gameobj); - navmesh->SetVisible(0, true); - } - } - - // convert logic bricks, sensors, controllers and actuators - for (i=0;i<logicbrick_conversionlist->GetCount();i++) - { - KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); - struct Object* blenderobj = gameobj->GetBlenderObject(); - int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; - bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; - BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,layerMask,isInActiveLayer,converter); - } - for ( i=0;i<logicbrick_conversionlist->GetCount();i++) - { - KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); - struct Object* blenderobj = gameobj->GetBlenderObject(); - int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; - bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; - BL_ConvertControllers(blenderobj,gameobj,logicmgr, layerMask,isInActiveLayer,converter, libloading); - } - for ( i=0;i<logicbrick_conversionlist->GetCount();i++) - { - KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); - struct Object* blenderobj = gameobj->GetBlenderObject(); - int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; - bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; - BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,layerMask,isInActiveLayer,canvas,converter); - // set the init state to all objects - gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state); - } - // apply the initial state to controllers, only on the active objects as this registers the sensors - for ( i=0;i<objectlist->GetCount();i++) - { - KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i)); - gameobj->ResetState(); - } - - logicbrick_conversionlist->Release(); - - // Calculate the scene btree - - // too slow - commented out. - //kxscene->SetNodeTree(tf.MakeTree()); - - // instantiate dupli group, we will loop trough the object - // that are in active layers. Note that duplicating group - // has the effect of adding objects at the end of objectlist. - // Only loop through the first part of the list. - int objcount = objectlist->GetCount(); - for (i=0;i<objcount;i++) - { - KX_GameObject* gameobj = (KX_GameObject*) objectlist->GetValue(i); - if (gameobj->IsDupliGroup()) - { - kxscene->DupliGroupRecurse(gameobj, 0); - } - } - - KX_Camera *activecam = kxscene->GetActiveCamera(); - MT_Scalar distance = (activecam)? activecam->GetCameraFar() - activecam->GetCameraNear(): 100.0f; - RAS_BucketManager *bucketmanager = kxscene->GetBucketManager(); - bucketmanager->OptimizeBuckets(distance); -} - |