Blender V2.61 - r43446

BL_BlenderDataConversion.cpp

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