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