forked from bartvdbraak/blender
6f3e593105
remove constraint fixed, Bullet timestep now subdivides Blender game engine timestep, so it runs 60 hertz, SphereShape reverted to old style, so no support for non-uniform scaled spheres for now,
1765 lines
49 KiB
C++
1765 lines
49 KiB
C++
/**
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
* Convert blender data to ketsji
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
#pragma warning (disable : 4786)
|
|
#endif
|
|
|
|
#include <math.h>
|
|
|
|
#include "BL_BlenderDataConversion.h"
|
|
#include "KX_BlenderGL.h"
|
|
#include "KX_BlenderScalarInterpolator.h"
|
|
|
|
#include "RAS_IPolygonMaterial.h"
|
|
#include "KX_PolygonMaterial.h"
|
|
|
|
// Expressions
|
|
#include "ListValue.h"
|
|
#include "IntValue.h"
|
|
// Collision & Fuzzics LTD
|
|
|
|
#include "PHY_Pro.h"
|
|
|
|
|
|
#include "KX_Scene.h"
|
|
#include "KX_GameObject.h"
|
|
#include "RAS_FramingManager.h"
|
|
#include "RAS_MeshObject.h"
|
|
|
|
#include "KX_ConvertActuators.h"
|
|
#include "KX_ConvertControllers.h"
|
|
#include "KX_ConvertSensors.h"
|
|
|
|
#include "SCA_LogicManager.h"
|
|
#include "SCA_EventManager.h"
|
|
#include "SCA_TimeEventManager.h"
|
|
#include "KX_Light.h"
|
|
#include "KX_Camera.h"
|
|
#include "KX_EmptyObject.h"
|
|
#include "MT_Point3.h"
|
|
#include "MT_Transform.h"
|
|
#include "MT_MinMax.h"
|
|
#include "SCA_IInputDevice.h"
|
|
#include "RAS_TexMatrix.h"
|
|
#include "RAS_ICanvas.h"
|
|
#include "RAS_MaterialBucket.h"
|
|
//#include "KX_BlenderPolyMaterial.h"
|
|
#include "RAS_Polygon.h"
|
|
#include "RAS_TexVert.h"
|
|
#include "RAS_BucketManager.h"
|
|
#include "RAS_IRenderTools.h"
|
|
#include "BL_Material.h"
|
|
#include "KX_BlenderMaterial.h"
|
|
#include "BL_Texture.h"
|
|
|
|
#include "DNA_action_types.h"
|
|
#include "BKE_main.h"
|
|
#include "BKE_global.h"
|
|
#include "BL_SkinMeshObject.h"
|
|
#include "BL_SkinDeformer.h"
|
|
#include "BL_MeshDeformer.h"
|
|
//#include "BL_ArmatureController.h"
|
|
|
|
#include "BlenderWorldInfo.h"
|
|
|
|
#include "KX_KetsjiEngine.h"
|
|
#include "KX_BlenderSceneConverter.h"
|
|
|
|
#include"SND_Scene.h"
|
|
#include "SND_SoundListener.h"
|
|
|
|
/* This little block needed for linking to Blender... */
|
|
#ifdef WIN32
|
|
#include "BLI_winstuff.h"
|
|
#endif
|
|
|
|
/* This list includes only data type definitions */
|
|
#include "DNA_object_types.h"
|
|
#include "DNA_material_types.h"
|
|
#include "DNA_texture_types.h"
|
|
#include "DNA_image_types.h"
|
|
#include "DNA_lamp_types.h"
|
|
#include "DNA_group_types.h"
|
|
#include "DNA_scene_types.h"
|
|
#include "DNA_camera_types.h"
|
|
#include "DNA_property_types.h"
|
|
#include "DNA_text_types.h"
|
|
#include "DNA_sensor_types.h"
|
|
#include "DNA_controller_types.h"
|
|
#include "DNA_actuator_types.h"
|
|
#include "DNA_mesh_types.h"
|
|
#include "DNA_meshdata_types.h"
|
|
#include "DNA_view3d_types.h"
|
|
#include "DNA_world_types.h"
|
|
#include "DNA_sound_types.h"
|
|
#include "DNA_key_types.h"
|
|
#include "DNA_armature_types.h"
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
#include "BKE_utildefines.h"
|
|
#include "BKE_key.h"
|
|
#include "BKE_mesh.h"
|
|
#include "MT_Point3.h"
|
|
|
|
|
|
#include "BKE_material.h" /* give_current_material */
|
|
/* end of blender include block */
|
|
|
|
#include "KX_BlenderInputDevice.h"
|
|
#include "KX_ConvertProperties.h"
|
|
#include "KX_HashedPtr.h"
|
|
|
|
|
|
#include "KX_ScalarInterpolator.h"
|
|
|
|
#include "KX_IpoConvert.h"
|
|
#include "SYS_System.h"
|
|
|
|
#include "SG_Node.h"
|
|
#include "SG_BBox.h"
|
|
#include "SG_Tree.h"
|
|
|
|
// defines USE_ODE to choose physics engine
|
|
#include "KX_ConvertPhysicsObject.h"
|
|
|
|
|
|
// This file defines relationships between parents and children
|
|
// in the game engine.
|
|
|
|
#include "KX_SG_NodeRelationships.h"
|
|
#include "KX_SG_BoneParentNodeRelationship.h"
|
|
|
|
#include "BL_ArmatureObject.h"
|
|
#include "BL_DeformableGameObject.h"
|
|
|
|
static int default_face_mode = TF_DYNAMIC;
|
|
|
|
static unsigned int KX_rgbaint2uint_new(unsigned int icol)
|
|
{
|
|
union
|
|
{
|
|
unsigned int integer;
|
|
unsigned char cp[4];
|
|
} out_colour, in_colour;
|
|
|
|
in_colour.integer = icol;
|
|
out_colour.cp[0] = in_colour.cp[3]; // red
|
|
out_colour.cp[1] = in_colour.cp[2]; // green
|
|
out_colour.cp[2] = in_colour.cp[1]; // blue
|
|
out_colour.cp[3] = in_colour.cp[0]; // alpha
|
|
|
|
return out_colour.integer;
|
|
}
|
|
|
|
/* Now the real converting starts... */
|
|
static unsigned int KX_Mcol2uint_new(MCol col)
|
|
{
|
|
/* color has to be converted without endian sensitivity. So no shifting! */
|
|
union
|
|
{
|
|
MCol col;
|
|
unsigned int integer;
|
|
unsigned char cp[4];
|
|
} out_colour, in_colour;
|
|
|
|
in_colour.col = col;
|
|
out_colour.cp[0] = in_colour.cp[3]; // red
|
|
out_colour.cp[1] = in_colour.cp[2]; // green
|
|
out_colour.cp[2] = in_colour.cp[1]; // blue
|
|
out_colour.cp[3] = in_colour.cp[0]; // alpha
|
|
|
|
return out_colour.integer;
|
|
}
|
|
|
|
static void SetDefaultFaceType(Scene* scene)
|
|
{
|
|
default_face_mode = TF_DYNAMIC;
|
|
Base *base = static_cast<Base*>(scene->base.first);
|
|
while(base)
|
|
{
|
|
if (base->object->type == OB_LAMP)
|
|
{
|
|
default_face_mode = TF_DYNAMIC|TF_LIGHT;
|
|
return;
|
|
}
|
|
base = base->next;
|
|
}
|
|
}
|
|
|
|
|
|
// --
|
|
static void GetRGB(short type,
|
|
MFace* mface,
|
|
MCol* mmcol,
|
|
Material *mat,
|
|
TFace *tface,
|
|
unsigned int &c0,
|
|
unsigned int &c1,
|
|
unsigned int &c2,
|
|
unsigned int &c3)
|
|
{
|
|
unsigned int colour = 0xFFFFFFFFL;
|
|
switch(type)
|
|
{
|
|
case 0: // vertex colors?
|
|
{
|
|
if(mmcol) {
|
|
c0 = KX_Mcol2uint_new(mmcol[0]);
|
|
c1 = KX_Mcol2uint_new(mmcol[1]);
|
|
c2 = KX_Mcol2uint_new(mmcol[2]);
|
|
if (mface->v4)
|
|
c3 = KX_Mcol2uint_new(mmcol[3]);
|
|
mmcol += 4;
|
|
}else // backup white
|
|
{
|
|
c0 = KX_rgbaint2uint_new(colour);
|
|
c1 = KX_rgbaint2uint_new(colour);
|
|
c2 = KX_rgbaint2uint_new(colour);
|
|
if (mface->v4)
|
|
c3 = KX_rgbaint2uint_new( colour );
|
|
}
|
|
} break;
|
|
|
|
|
|
case 1: // material rgba
|
|
{
|
|
if (mat) {
|
|
union {
|
|
unsigned char cp[4];
|
|
unsigned int integer;
|
|
} col_converter;
|
|
col_converter.cp[3] = (unsigned char) (mat->r*255.0);
|
|
col_converter.cp[2] = (unsigned char) (mat->g*255.0);
|
|
col_converter.cp[1] = (unsigned char) (mat->b*255.0);
|
|
col_converter.cp[0] = (unsigned char) (mat->alpha*255.0);
|
|
colour = col_converter.integer;
|
|
}
|
|
c0 = KX_rgbaint2uint_new(colour);
|
|
c1 = KX_rgbaint2uint_new(colour);
|
|
c2 = KX_rgbaint2uint_new(colour);
|
|
if (mface->v4)
|
|
c3 = KX_rgbaint2uint_new(colour);
|
|
} break;
|
|
|
|
case 2: // vertex colors
|
|
{
|
|
if(tface ) {
|
|
c0 = KX_rgbaint2uint_new(tface->col[0]);
|
|
c1 = KX_rgbaint2uint_new(tface->col[1]);
|
|
c2 = KX_rgbaint2uint_new(tface->col[2]);
|
|
|
|
if (mface->v4) {
|
|
c3 = KX_rgbaint2uint_new(tface->col[3]);
|
|
}
|
|
}else {
|
|
c0 = KX_rgbaint2uint_new(colour);
|
|
c1 = KX_rgbaint2uint_new(colour);
|
|
c2 = KX_rgbaint2uint_new(colour);
|
|
if (mface->v4)
|
|
c3 = KX_rgbaint2uint_new( colour );
|
|
}
|
|
} break;
|
|
|
|
case 3: // white
|
|
{
|
|
c0 = KX_rgbaint2uint_new(colour);
|
|
c1 = KX_rgbaint2uint_new(colour);
|
|
c2 = KX_rgbaint2uint_new(colour);
|
|
if (mface->v4)
|
|
c3 = KX_rgbaint2uint_new(colour);
|
|
} break;
|
|
}
|
|
}
|
|
|
|
// ------------------------------------
|
|
BL_Material* ConvertMaterial( Mesh* mesh, Material *mat, TFace* tface, MFace* mface, MCol* mmcol, int lightlayer, Object* blenderobj )
|
|
{
|
|
BL_Material *material = new BL_Material();
|
|
//initBL_Material(material);
|
|
int numchan = -1;
|
|
bool validmat = (mat!=0);
|
|
bool using_facetexture = false;
|
|
|
|
short type = 0;
|
|
if( validmat )
|
|
type = 1; // material color
|
|
else if(mesh->tface && tface)
|
|
type = 2; // vertex colors
|
|
|
|
material->IdMode = DEFAULT_BLENDER;
|
|
|
|
// --------------------------------
|
|
if(validmat) {
|
|
|
|
// use vertex colors by explicitly setting
|
|
if(mat->mode &MA_VERTEXCOLP)
|
|
type = 2;
|
|
|
|
// use lighting?
|
|
material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT;
|
|
MTex *mttmp = 0;
|
|
numchan = getNumTexChannels(mat);
|
|
int valid_index = 0;
|
|
|
|
bool facetex = ((mat->mode & MA_FACETEXTURE) && (mesh->tface && tface) );
|
|
|
|
numchan = numchan>MAXTEX?MAXTEX:(numchan>=0&& facetex)?numchan+1:numchan;
|
|
|
|
// foreach MTex
|
|
for(int i=0; i<numchan; i++) {
|
|
// use face tex
|
|
if(i==0 && facetex ) {
|
|
Image*tmp = (Image*)(tface->tpage);
|
|
if(tmp) {
|
|
material->img[i] = tmp;
|
|
material->texname[i] = material->img[i]->id.name;
|
|
material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
|
|
material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
|
|
material->ras_mode|= ( tface->transp &(TF_ADD | TF_ALPHA))?TRANSP:0;
|
|
material->mapping[i].mapping |= ( (material->img[i]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
|
|
//material->blend_mode[i] = BLEND_MUL;
|
|
i++;// skip to the next image
|
|
valid_index++;
|
|
}
|
|
}
|
|
|
|
mttmp = getImageFromMaterial( mat, i );
|
|
if( mttmp ) {
|
|
if( mttmp->tex ) {
|
|
if( mttmp->tex->type == TEX_IMAGE ) {
|
|
material->mtexname[i] = mttmp->tex->id.name;
|
|
material->img[i] = mttmp->tex->ima;
|
|
if( material->img[i] ) {
|
|
|
|
material->texname[i] = material->img[i]->id.name;
|
|
material->flag[i] |= ( mttmp->tex->imaflag &TEX_MIPMAP )?MIPMAP:0;
|
|
// -----------------------
|
|
if( mttmp->tex->imaflag &TEX_USEALPHA ) {
|
|
material->flag[i] |= USEALPHA;
|
|
}
|
|
// -----------------------
|
|
else if( mttmp->tex->imaflag &TEX_CALCALPHA ) {
|
|
material->flag[i] |= CALCALPHA;
|
|
}
|
|
else if(mttmp->tex->flag &TEX_NEGALPHA) {
|
|
material->flag[i] |= USENEGALPHA;
|
|
}
|
|
|
|
material->color_blend[i] = mttmp->colfac;
|
|
material->flag[i] |= ( mttmp->mapto & MAP_ALPHA )?TEXALPHA:0;
|
|
material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0;
|
|
|
|
}
|
|
}
|
|
else if(mttmp->tex->type == TEX_ENVMAP) {
|
|
if( mttmp->tex->env->stype == ENV_LOAD ) {
|
|
|
|
material->mtexname[i]= mttmp->tex->id.name;
|
|
material->cubemap[i] = mttmp->tex->env;
|
|
if(material->cubemap[i]->ima) {
|
|
material->texname[i] = material->cubemap[i]->ima->id.name;
|
|
material->mapping[i].mapping |= USEENV;
|
|
}
|
|
else {
|
|
// in the player, we need to split it our self
|
|
material->cubemap[i]->ima = mttmp->tex->ima;
|
|
if(material->cubemap[i]->ima) {
|
|
material->texname[i] = material->cubemap[i]->ima->id.name;
|
|
material->mapping[i].mapping |= USEENV;
|
|
}
|
|
//
|
|
}
|
|
}
|
|
}
|
|
material->flag[i] |= (mat->ipo!=0)?HASIPO:0;
|
|
/// --------------------------------
|
|
// mapping methods
|
|
material->mapping[i].mapping |= ( mttmp->texco & TEXCO_REFL )?USEREFL:0;
|
|
|
|
if(mttmp->texco & TEXCO_OBJECT) {
|
|
material->mapping[i].mapping |= USEOBJ;
|
|
if(mttmp->object)
|
|
material->mapping[i].objconame = mttmp->object->id.name;
|
|
}
|
|
|
|
material->mapping[i].scale[0] = mttmp->size[0];
|
|
material->mapping[i].scale[1] = mttmp->size[1];
|
|
material->mapping[i].scale[2] = mttmp->size[2];
|
|
material->mapping[i].offsets[0] = mttmp->ofs[0];
|
|
material->mapping[i].offsets[1] = mttmp->ofs[1];
|
|
material->mapping[i].offsets[2] = mttmp->ofs[2];
|
|
|
|
material->mapping[i].projplane[0] = mttmp->projx;
|
|
material->mapping[i].projplane[1] = mttmp->projy;
|
|
material->mapping[i].projplane[2] = mttmp->projz;
|
|
/// --------------------------------
|
|
|
|
switch( mttmp->blendtype ) {
|
|
case MTEX_BLEND:
|
|
material->blend_mode[i] = BLEND_MIX;
|
|
break;
|
|
case MTEX_MUL:
|
|
material->blend_mode[i] = BLEND_MUL;
|
|
break;
|
|
case MTEX_ADD:
|
|
material->blend_mode[i] = BLEND_ADD;
|
|
break;
|
|
case MTEX_SUB:
|
|
material->blend_mode[i] = BLEND_SUB;
|
|
break;
|
|
case MTEX_SCREEN:
|
|
material->blend_mode[i] = BLEND_SCR;
|
|
break;
|
|
}
|
|
valid_index++;
|
|
}
|
|
}
|
|
}
|
|
// above one tex the switches here
|
|
// are not used
|
|
switch(valid_index) {
|
|
case 0:
|
|
material->IdMode = DEFAULT_BLENDER;
|
|
break;
|
|
case 1:
|
|
material->IdMode = ONETEX;
|
|
break;
|
|
default:
|
|
material->IdMode = GREATERTHAN2;
|
|
break;
|
|
}
|
|
|
|
material->num_enabled = valid_index;
|
|
|
|
material->speccolor[0] = mat->specr;
|
|
material->speccolor[1] = mat->specg;
|
|
material->speccolor[2] = mat->specb;
|
|
material->hard = (float)mat->har/4.0f;
|
|
material->matcolor[0] = mat->r;
|
|
material->matcolor[1] = mat->g;
|
|
material->matcolor[2] = mat->b;
|
|
material->matcolor[3] = mat->alpha;
|
|
material->alpha = mat->alpha;
|
|
material->emit = mat->emit;
|
|
material->spec_f = mat->spec;
|
|
material->ref = mat->ref;
|
|
material->amb = mat->amb;
|
|
material->ras_mode |= ((mat->mode & MA_ZTRA) != 0)?ZSORT:0;
|
|
material->ras_mode |= ((mat->mode & MA_WIRE) != 0)?WIRE:0;
|
|
}
|
|
else {
|
|
int valid = 0;
|
|
// check for tface tex to fallback on
|
|
if( mesh->tface && tface ){
|
|
material->img[0] = (Image*)(tface->tpage);
|
|
// ------------------------
|
|
if(material->img[0]) {
|
|
material->texname[0] = material->img[0]->id.name;
|
|
material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
|
|
material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
|
|
material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
|
|
material->ras_mode|= ( tface->transp & (TF_ADD|TF_ALPHA))?TRANSP:0;
|
|
valid++;
|
|
}
|
|
}
|
|
material->num_enabled = valid;
|
|
material->IdMode = TEXFACE;
|
|
material->speccolor[0] = 1.f;
|
|
material->speccolor[1] = 1.f;
|
|
material->speccolor[2] = 1.f;
|
|
material->hard = 35.f;
|
|
material->matcolor[0] = 0.5f;
|
|
material->matcolor[1] = 0.5f;
|
|
material->matcolor[2] = 0.5f;
|
|
material->spec_f = 0.5f;
|
|
material->ref = 0.8f;
|
|
}
|
|
MT_Point2 uv[4];
|
|
|
|
if( mesh->tface && tface ) {
|
|
|
|
material->ras_mode |= !(
|
|
(tface->flag & TF_HIDE) ||
|
|
(tface->mode & TF_INVISIBLE)
|
|
)?POLY_VIS:0;
|
|
|
|
material->ras_mode |= ( (tface->mode & TF_DYNAMIC)!= 0 )?COLLIDER:0;
|
|
material->transp = tface->transp;
|
|
|
|
if(tface->transp)
|
|
material->ras_mode |= TRANSP;
|
|
|
|
material->tile = tface->tile;
|
|
material->mode = tface->mode;
|
|
|
|
uv[0] = MT_Point2(tface->uv[0]);
|
|
uv[1] = MT_Point2(tface->uv[1]);
|
|
uv[2] = MT_Point2(tface->uv[2]);
|
|
|
|
if (mface->v4)
|
|
uv[3] = MT_Point2(tface->uv[3]);
|
|
}
|
|
else {
|
|
// nothing at all
|
|
material->ras_mode |= (COLLIDER|POLY_VIS| (validmat?0:USE_LIGHT));
|
|
material->mode = default_face_mode;
|
|
material->transp = TF_SOLID;
|
|
material->tile = 0;
|
|
}
|
|
unsigned int rgb[4];
|
|
GetRGB(type,mface,mmcol,mat,tface,rgb[0],rgb[1],rgb[2], rgb[3]);
|
|
material->SetConversionRGB(rgb);
|
|
material->SetConversionUV(uv);
|
|
|
|
material->ras_mode |= (mface->v4==0)?TRIANGLE:0;
|
|
if(validmat)
|
|
material->matname =(mat->id.name);
|
|
|
|
material->tface = tface;
|
|
material->material = mat;
|
|
return material;
|
|
}
|
|
|
|
|
|
RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter)
|
|
{
|
|
RAS_MeshObject *meshobj;
|
|
bool skinMesh = false;
|
|
|
|
int lightlayer = blenderobj->lay;
|
|
|
|
MFace* mface = static_cast<MFace*>(mesh->mface);
|
|
TFace* tface = static_cast<TFace*>(mesh->tface);
|
|
MCol* mmcol = mesh->mcol;
|
|
MT_assert(mface || mesh->totface == 0);
|
|
|
|
// Determine if we need to make a skinned mesh
|
|
if (mesh->dvert){
|
|
meshobj = new BL_SkinMeshObject(lightlayer);
|
|
skinMesh = true;
|
|
}
|
|
else {
|
|
meshobj = new RAS_MeshObject(lightlayer);
|
|
}
|
|
|
|
meshobj->SetName(mesh->id.name);
|
|
|
|
meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
|
|
|
|
for (int f=0;f<mesh->totface;f++,mface++)
|
|
{
|
|
|
|
bool collider = true;
|
|
|
|
// only add valid polygons
|
|
if (mface->v3)
|
|
{
|
|
MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
|
|
// rgb3 is set from the adjoint face in a square
|
|
unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
|
|
MT_Vector3 no0(mesh->mvert[mface->v1].no[0], mesh->mvert[mface->v1].no[1], mesh->mvert[mface->v1].no[2]),
|
|
no1(mesh->mvert[mface->v2].no[0], mesh->mvert[mface->v2].no[1], mesh->mvert[mface->v2].no[2]),
|
|
no2(mesh->mvert[mface->v3].no[0], mesh->mvert[mface->v3].no[1], mesh->mvert[mface->v3].no[2]),
|
|
no3(0.0, 0.0, 0.0);
|
|
MT_Point3 pt0(mesh->mvert[mface->v1].co),
|
|
pt1(mesh->mvert[mface->v2].co),
|
|
pt2(mesh->mvert[mface->v3].co),
|
|
pt3(0.0, 0.0, 0.0);
|
|
|
|
no0 /= 32767.0;
|
|
no1 /= 32767.0;
|
|
no2 /= 32767.0;
|
|
if (mface->v4)
|
|
{
|
|
pt3 = MT_Point3(mesh->mvert[mface->v4].co);
|
|
no3 = MT_Vector3(mesh->mvert[mface->v4].no[0], mesh->mvert[mface->v4].no[1], mesh->mvert[mface->v4].no[2]);
|
|
no3 /= 32767.0;
|
|
}
|
|
|
|
if(!(mface->flag & ME_SMOOTH))
|
|
{
|
|
MT_Vector3 norm = ((pt1-pt0).cross(pt2-pt0)).safe_normalized();
|
|
norm[0] = ((int) (10*norm[0]))/10.0;
|
|
norm[1] = ((int) (10*norm[1]))/10.0;
|
|
norm[2] = ((int) (10*norm[2]))/10.0;
|
|
no0=no1=no2=no3= norm;
|
|
|
|
}
|
|
|
|
{
|
|
Material* ma = 0;
|
|
bool polyvisible = true;
|
|
RAS_IPolyMaterial* polymat = NULL;
|
|
|
|
if(converter->GetMaterials())
|
|
{
|
|
if(mesh->totcol > 1)
|
|
ma = mesh->mat[mface->mat_nr];
|
|
else
|
|
ma = give_current_material(blenderobj, 1);
|
|
|
|
BL_Material *bl_mat = ConvertMaterial(mesh, ma, tface, mface, mmcol, lightlayer, blenderobj);
|
|
// set the index were dealing with
|
|
bl_mat->material_index = (int)mface->mat_nr;
|
|
|
|
polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
|
|
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
|
|
|
|
polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
|
|
converter->RegisterBlenderMaterial(bl_mat);
|
|
|
|
unsigned int rgb[4];
|
|
bl_mat->GetConversionRGB(rgb);
|
|
rgb0 = rgb[0];
|
|
rgb1 = rgb[1];
|
|
rgb2 = rgb[2];
|
|
rgb3 = rgb[3];
|
|
MT_Point2 uv[4];
|
|
bl_mat->GetConversionUV(uv);
|
|
uv0 = uv[0];
|
|
uv1 = uv[1];
|
|
uv2 = uv[2];
|
|
uv3 = uv[3];
|
|
// this is needed to free up memory afterwards
|
|
converter->RegisterPolyMaterial(polymat);
|
|
}
|
|
else
|
|
{
|
|
ma = give_current_material(blenderobj, 1);
|
|
|
|
Image* bima = ((mesh->tface && tface) ? (Image*) tface->tpage : NULL);
|
|
|
|
STR_String imastr =
|
|
((mesh->tface && tface) ?
|
|
(bima? (bima)->id.name : "" ) : "" );
|
|
|
|
char transp=0;
|
|
short mode=0, tile=0;
|
|
int tilexrep=4,tileyrep = 4;
|
|
|
|
if (bima)
|
|
{
|
|
tilexrep = bima->xrep;
|
|
tileyrep = bima->yrep;
|
|
|
|
}
|
|
|
|
if (mesh->tface && tface)
|
|
{
|
|
// Use texface colors if available
|
|
//TF_DYNAMIC means the polygon is a collision face
|
|
collider = ((tface->mode & TF_DYNAMIC) != 0);
|
|
transp = tface->transp;
|
|
tile = tface->tile;
|
|
mode = tface->mode;
|
|
|
|
polyvisible = !((tface->flag & TF_HIDE)||(tface->mode & TF_INVISIBLE));
|
|
|
|
uv0 = MT_Point2(tface->uv[0]);
|
|
uv1 = MT_Point2(tface->uv[1]);
|
|
uv2 = MT_Point2(tface->uv[2]);
|
|
rgb0 = KX_rgbaint2uint_new(tface->col[0]);
|
|
rgb1 = KX_rgbaint2uint_new(tface->col[1]);
|
|
rgb2 = KX_rgbaint2uint_new(tface->col[2]);
|
|
|
|
if (mface->v4)
|
|
{
|
|
uv3 = MT_Point2(tface->uv[3]);
|
|
rgb3 = KX_rgbaint2uint_new(tface->col[3]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
if (mmcol)
|
|
{
|
|
// Use vertex colours
|
|
rgb0 = KX_Mcol2uint_new(mmcol[0]);
|
|
rgb1 = KX_Mcol2uint_new(mmcol[1]);
|
|
rgb2 = KX_Mcol2uint_new(mmcol[2]);
|
|
|
|
|
|
if (mface->v4)
|
|
{
|
|
rgb3 = KX_Mcol2uint_new(mmcol[3]);
|
|
|
|
}
|
|
|
|
mmcol += 4;
|
|
}
|
|
else
|
|
{
|
|
// If there are no vertex colors OR texfaces,
|
|
// Initialize face to white and set COLLSION true and everything else FALSE
|
|
unsigned int colour = 0xFFFFFFFFL;
|
|
mode = default_face_mode;
|
|
transp = TF_SOLID;
|
|
tile = 0;
|
|
if (ma)
|
|
{
|
|
// If we have a material, take the default colour from the material.
|
|
union
|
|
{
|
|
unsigned char cp[4];
|
|
unsigned int integer;
|
|
} col_converter;
|
|
|
|
col_converter.cp[3] = (unsigned char) (ma->r*255.0);
|
|
col_converter.cp[2] = (unsigned char) (ma->g*255.0);
|
|
col_converter.cp[1] = (unsigned char) (ma->b*255.0);
|
|
col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
|
|
|
|
colour = col_converter.integer;
|
|
}
|
|
|
|
rgb0 = KX_rgbaint2uint_new(colour);
|
|
rgb1 = KX_rgbaint2uint_new(colour);
|
|
rgb2 = KX_rgbaint2uint_new(colour);
|
|
|
|
if (mface->v4)
|
|
rgb3 = KX_rgbaint2uint_new(colour);
|
|
}
|
|
}
|
|
|
|
|
|
bool istriangle = (mface->v4==0);
|
|
bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false;
|
|
|
|
polymat = new KX_PolygonMaterial(imastr, ma,
|
|
tile, tilexrep, tileyrep,
|
|
mode, transp, zsort, lightlayer, istriangle, blenderobj, tface);
|
|
|
|
if (ma)
|
|
{
|
|
polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
|
|
polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
|
|
polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
|
|
|
|
} else
|
|
{
|
|
polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
|
|
polymat->m_shininess = 35.0;
|
|
}
|
|
// this is needed to free up memory afterwards
|
|
converter->RegisterPolyMaterial(polymat);
|
|
|
|
}
|
|
|
|
RAS_MaterialBucket* bucket = scene->FindBucket(polymat);
|
|
|
|
int nverts = mface->v4?4:3;
|
|
int vtxarray = meshobj->FindVertexArray(nverts,polymat);
|
|
RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
|
|
if (skinMesh) {
|
|
int d1, d2, d3, d4=0;
|
|
bool flat;
|
|
|
|
/* If the face is set to solid, all fnors are the same */
|
|
if (mface->flag & ME_SMOOTH)
|
|
flat = false;
|
|
else
|
|
flat = true;
|
|
|
|
d1=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v1, &mesh->dvert[mface->v1], polymat);
|
|
d2=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v2, &mesh->dvert[mface->v2], polymat);
|
|
d3=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v3, &mesh->dvert[mface->v3], polymat);
|
|
if (nverts==4)
|
|
d4=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v4, &mesh->dvert[mface->v4], polymat);
|
|
poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,d1,flat, polymat));
|
|
poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,d2,flat, polymat));
|
|
poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,d3,flat, polymat));
|
|
if (nverts==4)
|
|
poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,d4, flat,polymat));
|
|
}
|
|
else
|
|
{
|
|
poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,polymat,mface->v1));
|
|
poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,polymat,mface->v2));
|
|
poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,polymat,mface->v3));
|
|
if (nverts==4)
|
|
poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,polymat,mface->v4));
|
|
}
|
|
meshobj->AddPolygon(poly);
|
|
if (poly->IsCollider())
|
|
{
|
|
RAS_TriangleIndex idx;
|
|
idx.m_index[0] = mface->v1;
|
|
idx.m_index[1] = mface->v2;
|
|
idx.m_index[2] = mface->v3;
|
|
idx.m_collider = collider;
|
|
meshobj->m_triangle_indices.push_back(idx);
|
|
if (nverts==4)
|
|
{
|
|
idx.m_index[0] = mface->v1;
|
|
idx.m_index[1] = mface->v3;
|
|
idx.m_index[2] = mface->v4;
|
|
idx.m_collider = collider;
|
|
meshobj->m_triangle_indices.push_back(idx);
|
|
}
|
|
}
|
|
|
|
// poly->SetVisibleWireframeEdges(mface->edcode);
|
|
poly->SetCollider(collider);
|
|
}
|
|
}
|
|
if (tface)
|
|
tface++;
|
|
}
|
|
meshobj->UpdateMaterialList();
|
|
|
|
|
|
|
|
// -----------------------------------
|
|
// pre calculate texture generation
|
|
for(RAS_MaterialBucket::Set::iterator mit = meshobj->GetFirstMaterial();
|
|
mit != meshobj->GetLastMaterial(); ++ mit) {
|
|
(*mit)->GetPolyMaterial()->OnConstruction();
|
|
}
|
|
// -----------------------------------
|
|
|
|
|
|
return meshobj;
|
|
}
|
|
|
|
static PHY_MaterialProps g_materialProps = {
|
|
1.0, // restitution
|
|
2.0, // friction
|
|
0.0, // fh spring constant
|
|
0.0, // fh damping
|
|
0.0, // fh distance
|
|
false // sliding material?
|
|
};
|
|
|
|
|
|
|
|
static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject,
|
|
KX_Scene *kxscene)
|
|
{
|
|
PHY_MaterialProps *materialProps = new PHY_MaterialProps;
|
|
|
|
MT_assert(materialProps && "Create physics material properties failed");
|
|
|
|
Material* blendermat = give_current_material(blenderobject, 0);
|
|
|
|
if (blendermat)
|
|
{
|
|
MT_assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f);
|
|
|
|
materialProps->m_restitution = blendermat->reflect;
|
|
materialProps->m_friction = blendermat->friction;
|
|
materialProps->m_fh_spring = blendermat->fh;
|
|
materialProps->m_fh_damping = blendermat->xyfrict;
|
|
materialProps->m_fh_distance = blendermat->fhdist;
|
|
materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
|
|
}
|
|
else {
|
|
*materialProps = g_materialProps;
|
|
}
|
|
|
|
return materialProps;
|
|
}
|
|
|
|
static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject,
|
|
KX_Scene *kxscene)
|
|
{
|
|
PHY_ShapeProps *shapeProps = new PHY_ShapeProps;
|
|
|
|
MT_assert(shapeProps);
|
|
|
|
shapeProps->m_mass = blenderobject->mass;
|
|
|
|
// This needs to be fixed in blender. For now, we use:
|
|
|
|
// in Blender, inertia stands for the size value which is equivalent to
|
|
// the sphere radius
|
|
shapeProps->m_inertia = blenderobject->formfactor;
|
|
|
|
MT_assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
|
|
MT_assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
|
|
|
|
shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
|
|
shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
|
|
|
|
shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0];
|
|
shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
|
|
shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2];
|
|
shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0);
|
|
|
|
shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0;
|
|
shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
|
|
|
|
return shapeProps;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
static float my_boundbox_mesh(Mesh *me, float *loc, float *size)
|
|
{
|
|
MVert *mvert;
|
|
BoundBox *bb;
|
|
MT_Point3 min, max;
|
|
float mloc[3], msize[3];
|
|
int a;
|
|
|
|
if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
|
|
bb= me->bb;
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
if (!loc) loc= mloc;
|
|
if (!size) size= msize;
|
|
|
|
mvert= me->mvert;
|
|
for(a=0; a<me->totvert; a++, mvert++) {
|
|
DO_MINMAX(mvert->co, min, max);
|
|
}
|
|
|
|
if(me->totvert) {
|
|
loc[0]= (min[0]+max[0])/2.0;
|
|
loc[1]= (min[1]+max[1])/2.0;
|
|
loc[2]= (min[2]+max[2])/2.0;
|
|
|
|
size[0]= (max[0]-min[0])/2.0;
|
|
size[1]= (max[1]-min[1])/2.0;
|
|
size[2]= (max[2]-min[2])/2.0;
|
|
}
|
|
else {
|
|
loc[0]= loc[1]= loc[2]= 0.0;
|
|
size[0]= size[1]= size[2]= 0.0;
|
|
}
|
|
|
|
bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
|
|
bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
|
|
|
|
bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
|
|
bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
|
|
|
|
bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
|
|
bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
|
|
|
|
float radius = 0;
|
|
for (a=0, mvert = me->mvert; a < me->totvert; a++, mvert++)
|
|
{
|
|
float vert_radius = MT_Vector3(mvert->co).length2();
|
|
if (vert_radius > radius)
|
|
radius = vert_radius;
|
|
}
|
|
return sqrt(radius);
|
|
}
|
|
|
|
|
|
|
|
|
|
static void my_tex_space_mesh(Mesh *me)
|
|
{
|
|
KeyBlock *kb;
|
|
float *fp, loc[3], size[3], min[3], max[3];
|
|
int a;
|
|
|
|
my_boundbox_mesh(me, loc, size);
|
|
|
|
if(me->texflag & AUTOSPACE) {
|
|
if(me->key) {
|
|
kb= me->key->refkey;
|
|
if (kb) {
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
fp= (float *)kb->data;
|
|
for(a=0; a<kb->totelem; a++, fp+=3) {
|
|
DO_MINMAX(fp, min, max);
|
|
}
|
|
if(kb->totelem) {
|
|
loc[0]= (min[0]+max[0])/2.0; loc[1]= (min[1]+max[1])/2.0; loc[2]= (min[2]+max[2])/2.0;
|
|
size[0]= (max[0]-min[0])/2.0; size[1]= (max[1]-min[1])/2.0; size[2]= (max[2]-min[2])/2.0;
|
|
}
|
|
else {
|
|
loc[0]= loc[1]= loc[2]= 0.0;
|
|
size[0]= size[1]= size[2]= 0.0;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
VECCOPY(me->loc, loc);
|
|
VECCOPY(me->size, size);
|
|
me->rot[0]= me->rot[1]= me->rot[2]= 0.0;
|
|
|
|
if(me->size[0]==0.0) me->size[0]= 1.0;
|
|
else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001;
|
|
else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001;
|
|
|
|
if(me->size[1]==0.0) me->size[1]= 1.0;
|
|
else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001;
|
|
else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001;
|
|
|
|
if(me->size[2]==0.0) me->size[2]= 1.0;
|
|
else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001;
|
|
else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001;
|
|
}
|
|
|
|
}
|
|
|
|
static void my_get_local_bounds(Object *ob, float *centre, float *size)
|
|
{
|
|
BoundBox *bb= NULL;
|
|
/* uses boundbox, function used by Ketsji */
|
|
switch (ob->type)
|
|
{
|
|
case OB_MESH:
|
|
bb= ( (Mesh *)ob->data )->bb;
|
|
if(bb==0)
|
|
{
|
|
my_tex_space_mesh((struct Mesh *)ob->data);
|
|
bb= ( (Mesh *)ob->data )->bb;
|
|
}
|
|
break;
|
|
case OB_CURVE:
|
|
case OB_SURF:
|
|
case OB_FONT:
|
|
centre[0]= centre[1]= centre[2]= 0.0;
|
|
size[0] = size[1]=size[2]=0.0;
|
|
break;
|
|
case OB_MBALL:
|
|
bb= ob->bb;
|
|
break;
|
|
}
|
|
|
|
if(bb==NULL)
|
|
{
|
|
centre[0]= centre[1]= centre[2]= 0.0;
|
|
size[0] = size[1]=size[2]=1.0;
|
|
}
|
|
else
|
|
{
|
|
size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
|
|
size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
|
|
size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
|
|
|
|
centre[0]= 0.5*(bb->vec[0][0] + bb->vec[4][0]);
|
|
centre[1]= 0.5*(bb->vec[0][1] + bb->vec[2][1]);
|
|
centre[2]= 0.5*(bb->vec[0][2] + bb->vec[1][2]);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
|
|
struct Object* blenderobject,
|
|
RAS_MeshObject* meshobj,
|
|
KX_Scene* kxscene,
|
|
int activeLayerBitInfo,
|
|
e_PhysicsEngine physics_engine,
|
|
KX_BlenderSceneConverter *converter
|
|
)
|
|
|
|
{
|
|
//SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
|
|
//int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
|
|
//bool bRigidBody = (userigidbody == 0);
|
|
|
|
PHY_ShapeProps* shapeprops =
|
|
CreateShapePropsFromBlenderObject(blenderobject,
|
|
kxscene);
|
|
|
|
|
|
PHY_MaterialProps* smmaterial =
|
|
CreateMaterialFromBlenderObject(blenderobject, kxscene);
|
|
|
|
KX_ObjectProperties objprop;
|
|
if ((objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0))
|
|
{
|
|
objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
|
|
objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
|
|
objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
|
|
} else {
|
|
objprop.m_dyna = false;
|
|
objprop.m_angular_rigidbody = false;
|
|
objprop.m_ghost = false;
|
|
}
|
|
//mmm, for now, taks this for the size of the dynamicobject
|
|
// Blender uses inertia for radius of dynamic object
|
|
objprop.m_radius = blenderobject->inertia;
|
|
objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
|
|
objprop.m_dynamic_parent=NULL;
|
|
objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
|
|
objprop.m_boundclass = objprop.m_dyna?KX_BOUNDSPHERE:KX_BOUNDMESH;
|
|
|
|
KX_BoxBounds bb;
|
|
my_get_local_bounds(blenderobject,objprop.m_boundobject.box.m_center,bb.m_extends);
|
|
if (blenderobject->gameflag & OB_BOUNDS)
|
|
{
|
|
switch (blenderobject->boundtype)
|
|
{
|
|
case OB_BOUND_BOX:
|
|
objprop.m_boundclass = KX_BOUNDBOX;
|
|
//mmm, has to be divided by 2 to be proper extends
|
|
objprop.m_boundobject.box.m_extends[0]=2.f*bb.m_extends[0];
|
|
objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1];
|
|
objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2];
|
|
break;
|
|
case OB_BOUND_POLYT:
|
|
if (blenderobject->type == OB_MESH)
|
|
{
|
|
objprop.m_boundclass = KX_BOUNDPOLYTOPE;
|
|
break;
|
|
}
|
|
// Object is not a mesh... fall through OB_BOUND_POLYH to
|
|
// OB_BOUND_SPHERE
|
|
case OB_BOUND_POLYH:
|
|
if (blenderobject->type == OB_MESH)
|
|
{
|
|
objprop.m_boundclass = KX_BOUNDMESH;
|
|
break;
|
|
}
|
|
// Object is not a mesh... can't use polyheder.
|
|
// Fall through and become a sphere.
|
|
case OB_BOUND_SPHERE:
|
|
{
|
|
objprop.m_boundclass = KX_BOUNDSPHERE;
|
|
objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2]));
|
|
break;
|
|
}
|
|
case OB_BOUND_CYLINDER:
|
|
{
|
|
objprop.m_boundclass = KX_BOUNDCYLINDER;
|
|
objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
|
|
objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
|
|
break;
|
|
}
|
|
case OB_BOUND_CONE:
|
|
{
|
|
objprop.m_boundclass = KX_BOUNDCONE;
|
|
objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], bb.m_extends[1]);
|
|
objprop.m_boundobject.c.m_height = 2.f*bb.m_extends[2];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// get Root Parent of blenderobject
|
|
struct Object* parent= blenderobject->parent;
|
|
while(parent && parent->parent) {
|
|
parent= parent->parent;
|
|
}
|
|
|
|
if (parent && (parent->gameflag & OB_DYNAMIC)) {
|
|
|
|
KX_GameObject *parentgameobject = converter->FindGameObject(parent);
|
|
objprop.m_dynamic_parent = parentgameobject;
|
|
|
|
}
|
|
|
|
objprop.m_concave = (blenderobject->boundtype & 4) != 0;
|
|
|
|
switch (physics_engine)
|
|
{
|
|
#ifdef USE_BULLET
|
|
case UseBullet:
|
|
KX_ConvertBulletObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
|
|
break;
|
|
|
|
#endif
|
|
#ifdef USE_SUMO_SOLID
|
|
case UseSumo:
|
|
KX_ConvertSumoObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
|
|
break;
|
|
#endif
|
|
|
|
#ifdef USE_ODE
|
|
case UseODE:
|
|
KX_ConvertODEEngineObject(gameobj, meshobj, kxscene, shapeprops, smmaterial, &objprop);
|
|
break;
|
|
#endif //USE_ODE
|
|
|
|
case UseDynamo:
|
|
//KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
|
|
break;
|
|
|
|
case UseNone:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
|
|
RAS_LightObject lightobj;
|
|
KX_LightObject *gamelight;
|
|
|
|
lightobj.m_att1 = la->att1;
|
|
lightobj.m_att2 = (la->mode & LA_QUAD)?la->att2:0.0;
|
|
lightobj.m_red = la->r;
|
|
lightobj.m_green = la->g;
|
|
lightobj.m_blue = la->b;
|
|
lightobj.m_distance = la->dist;
|
|
lightobj.m_energy = la->energy;
|
|
lightobj.m_layer = layerflag;
|
|
lightobj.m_spotblend = la->spotblend;
|
|
lightobj.m_spotsize = la->spotsize;
|
|
|
|
lightobj.m_nodiffuse = (la->mode & LA_NO_DIFF) != 0;
|
|
lightobj.m_nospecular = (la->mode & LA_NO_SPEC) != 0;
|
|
|
|
if (la->mode & LA_NEG)
|
|
{
|
|
lightobj.m_red = -lightobj.m_red;
|
|
lightobj.m_green = -lightobj.m_green;
|
|
lightobj.m_blue = -lightobj.m_blue;
|
|
}
|
|
|
|
if (la->type==LA_SUN) {
|
|
lightobj.m_type = RAS_LightObject::LIGHT_SUN;
|
|
} else if (la->type==LA_SPOT) {
|
|
lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
|
|
} else {
|
|
lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
|
|
}
|
|
|
|
gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj);
|
|
BL_ConvertLampIpos(la, gamelight, converter);
|
|
|
|
return gamelight;
|
|
}
|
|
|
|
static KX_Camera *gamecamera_from_bcamera(Camera *ca, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
|
|
RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP);
|
|
KX_Camera *gamecamera;
|
|
|
|
gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
|
|
gamecamera->SetName(ca->id.name + 2);
|
|
|
|
BL_ConvertCameraIpos(ca, gamecamera, converter);
|
|
|
|
return gamecamera;
|
|
}
|
|
|
|
static KX_GameObject *gameobject_from_blenderobject(
|
|
Object *ob,
|
|
KX_Scene *kxscene,
|
|
RAS_IRenderTools *rendertools,
|
|
KX_BlenderSceneConverter *converter,
|
|
Scene *blenderscene)
|
|
{
|
|
KX_GameObject *gameobj = NULL;
|
|
|
|
switch(ob->type)
|
|
{
|
|
case OB_LAMP:
|
|
{
|
|
KX_LightObject* gamelight= gamelight_from_blamp(static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
|
|
gameobj = gamelight;
|
|
|
|
gamelight->AddRef();
|
|
kxscene->GetLightList()->Add(gamelight);
|
|
|
|
break;
|
|
}
|
|
|
|
case OB_CAMERA:
|
|
{
|
|
KX_Camera* gamecamera = gamecamera_from_bcamera(static_cast<Camera*>(ob->data), kxscene, converter);
|
|
gameobj = gamecamera;
|
|
|
|
gamecamera->AddRef();
|
|
kxscene->AddCamera(gamecamera);
|
|
|
|
break;
|
|
}
|
|
|
|
case OB_MESH:
|
|
{
|
|
Mesh* mesh = static_cast<Mesh*>(ob->data);
|
|
RAS_MeshObject* meshobj = converter->FindGameMesh(mesh, ob->lay);
|
|
float centre[3], extents[3];
|
|
float radius = my_boundbox_mesh((Mesh*) ob->data, centre, extents);
|
|
|
|
if (!meshobj) {
|
|
meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter);
|
|
converter->RegisterGameMesh(meshobj, mesh);
|
|
}
|
|
|
|
// needed for python scripting
|
|
kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
|
|
|
|
gameobj = new BL_DeformableGameObject(kxscene,KX_Scene::m_callbacks);
|
|
|
|
// set transformation
|
|
gameobj->AddMesh(meshobj);
|
|
|
|
// for all objects: check whether they want to
|
|
// respond to updates
|
|
bool ignoreActivityCulling =
|
|
((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
|
|
gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
|
|
|
|
// If this is a skin object, make Skin Controller
|
|
if (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && ((Mesh*)ob->data)->dvert){
|
|
BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj );
|
|
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
|
|
}
|
|
else if (((Mesh*)ob->data)->dvert){
|
|
BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj );
|
|
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
|
|
}
|
|
|
|
MT_Point3 min = MT_Point3(centre) - MT_Vector3(extents);
|
|
MT_Point3 max = MT_Point3(centre) + MT_Vector3(extents);
|
|
SG_BBox bbox = SG_BBox(min, max);
|
|
gameobj->GetSGNode()->SetBBox(bbox);
|
|
gameobj->GetSGNode()->SetRadius(radius);
|
|
|
|
break;
|
|
}
|
|
|
|
case OB_ARMATURE:
|
|
{
|
|
gameobj = new BL_ArmatureObject(
|
|
kxscene,
|
|
KX_Scene::m_callbacks,
|
|
ob // handle
|
|
);
|
|
/* Get the current pose from the armature object and apply it as the rest pose */
|
|
break;
|
|
}
|
|
|
|
case OB_EMPTY:
|
|
{
|
|
gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks);
|
|
// set transformation
|
|
break;
|
|
}
|
|
}
|
|
|
|
return gameobj;
|
|
}
|
|
|
|
struct parentChildLink {
|
|
struct Object* m_blenderchild;
|
|
SG_Node* m_gamechildnode;
|
|
};
|
|
|
|
/**
|
|
* Find the specified scene by name, or the first
|
|
* scene if nothing matches (shouldn't happen).
|
|
*/
|
|
static struct Scene *GetSceneForName(struct Main *maggie, const STR_String& scenename) {
|
|
Scene *sce;
|
|
|
|
for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
|
|
if (scenename == (sce->id.name+2))
|
|
return sce;
|
|
|
|
return (Scene*) maggie->scene.first;
|
|
}
|
|
|
|
|
|
// convert blender objects into ketsji gameobjects
|
|
void BL_ConvertBlenderObjects(struct Main* maggie,
|
|
const STR_String& scenename,
|
|
KX_Scene* kxscene,
|
|
KX_KetsjiEngine* ketsjiEngine,
|
|
e_PhysicsEngine physics_engine,
|
|
PyObject* pythondictionary,
|
|
SCA_IInputDevice* keydev,
|
|
RAS_IRenderTools* rendertools,
|
|
RAS_ICanvas* canvas,
|
|
KX_BlenderSceneConverter* converter,
|
|
bool alwaysUseExpandFraming
|
|
)
|
|
{
|
|
|
|
Scene *blenderscene = GetSceneForName(maggie, scenename);
|
|
|
|
// Get the frame settings of the canvas.
|
|
// Get the aspect ratio of the canvas as designed by the user.
|
|
|
|
RAS_FrameSettings::RAS_FrameType frame_type;
|
|
int aspect_width;
|
|
int aspect_height;
|
|
|
|
if (alwaysUseExpandFraming) {
|
|
frame_type = RAS_FrameSettings::e_frame_extend;
|
|
aspect_width = canvas->GetWidth();
|
|
aspect_height = canvas->GetHeight();
|
|
} else {
|
|
if (blenderscene->framing.type == SCE_GAMEFRAMING_BARS) {
|
|
frame_type = RAS_FrameSettings::e_frame_bars;
|
|
} else if (blenderscene->framing.type == SCE_GAMEFRAMING_EXTEND) {
|
|
frame_type = RAS_FrameSettings::e_frame_extend;
|
|
} else {
|
|
frame_type = RAS_FrameSettings::e_frame_scale;
|
|
}
|
|
|
|
aspect_width = blenderscene->r.xsch;
|
|
aspect_height = blenderscene->r.ysch;
|
|
}
|
|
|
|
RAS_FrameSettings frame_settings(
|
|
frame_type,
|
|
blenderscene->framing.col[0],
|
|
blenderscene->framing.col[1],
|
|
blenderscene->framing.col[2],
|
|
aspect_width,
|
|
aspect_height
|
|
);
|
|
kxscene->SetFramingType(frame_settings);
|
|
|
|
kxscene->SetGravity(MT_Vector3(0,0,(blenderscene->world != NULL) ? -blenderscene->world->gravity : -9.8));
|
|
|
|
/* set activity culling parameters */
|
|
if (blenderscene->world) {
|
|
kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
|
|
kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
|
|
} else {
|
|
kxscene->SetActivityCulling(false);
|
|
}
|
|
|
|
int activeLayerBitInfo = blenderscene->lay;
|
|
|
|
// templist to find Root Parents (object with no parents)
|
|
CListValue* templist = new CListValue();
|
|
CListValue* sumolist = new CListValue();
|
|
|
|
vector<parentChildLink> vec_parent_child;
|
|
|
|
CListValue* objectlist = kxscene->GetObjectList();
|
|
CListValue* parentlist = kxscene->GetRootParentList();
|
|
|
|
SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
|
|
SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
|
|
|
|
CListValue* logicbrick_conversionlist = new CListValue();
|
|
|
|
SG_TreeFactory tf;
|
|
|
|
// Convert actions to actionmap
|
|
bAction *curAct;
|
|
for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
|
|
{
|
|
logicmgr->RegisterActionName(curAct->id.name, curAct);
|
|
}
|
|
|
|
SetDefaultFaceType(blenderscene);
|
|
|
|
Base *base = static_cast<Base*>(blenderscene->base.first);
|
|
while(base)
|
|
{
|
|
Object* blenderobject = base->object;
|
|
KX_GameObject* gameobj = gameobject_from_blenderobject(
|
|
base->object,
|
|
kxscene,
|
|
rendertools,
|
|
converter,
|
|
blenderscene);
|
|
|
|
if (gameobj)
|
|
{
|
|
MT_Point3 pos = MT_Point3(
|
|
blenderobject->loc[0]+blenderobject->dloc[0],
|
|
blenderobject->loc[1]+blenderobject->dloc[1],
|
|
blenderobject->loc[2]+blenderobject->dloc[2]
|
|
);
|
|
MT_Vector3 eulxyz = MT_Vector3(
|
|
blenderobject->rot[0],
|
|
blenderobject->rot[1],
|
|
blenderobject->rot[2]
|
|
);
|
|
MT_Vector3 scale = MT_Vector3(
|
|
blenderobject->size[0],
|
|
blenderobject->size[1],
|
|
blenderobject->size[2]
|
|
);
|
|
|
|
gameobj->NodeSetLocalPosition(pos);
|
|
gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
|
|
gameobj->NodeSetLocalScale(scale);
|
|
gameobj->NodeUpdateGS(0,true);
|
|
|
|
BL_ConvertIpos(blenderobject,gameobj,converter);
|
|
// TODO: expand to multiple ipos per mesh
|
|
Material *mat = give_current_material(blenderobject, 1);
|
|
if(mat) BL_ConvertMaterialIpos(mat, gameobj, converter);
|
|
|
|
bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
|
|
|
|
sumolist->Add(gameobj->AddRef());
|
|
|
|
BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
|
|
|
|
|
|
gameobj->SetName(blenderobject->id.name);
|
|
|
|
// templist to find Root Parents (object with no parents)
|
|
templist->Add(gameobj->AddRef());
|
|
|
|
// update children/parent hierarchy
|
|
if (blenderobject->parent != 0)
|
|
{
|
|
// blender has an additional 'parentinverse' offset in each object
|
|
SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
|
|
|
|
// define a normal parent relationship for this node.
|
|
KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
|
|
parentinversenode->SetParentRelation(parent_relation);
|
|
|
|
parentChildLink pclink;
|
|
pclink.m_blenderchild = blenderobject;
|
|
pclink.m_gamechildnode = parentinversenode;
|
|
vec_parent_child.push_back(pclink);
|
|
|
|
float* fl = (float*) blenderobject->parentinv;
|
|
MT_Transform parinvtrans(fl);
|
|
parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
|
|
parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
|
|
|
|
parentinversenode->AddChild(gameobj->GetSGNode());
|
|
}
|
|
|
|
// needed for python scripting
|
|
logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
|
|
|
|
// needed for dynamic object morphing
|
|
logicmgr->RegisterGameObj(gameobj, blenderobject);
|
|
for (int i = 0; i < gameobj->GetMeshCount(); i++)
|
|
logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
|
|
|
|
converter->RegisterGameObject(gameobj, blenderobject);
|
|
|
|
// this was put in rapidly, needs to be looked at more closely
|
|
// only draw/use objects in active 'blender' layers
|
|
|
|
logicbrick_conversionlist->Add(gameobj->AddRef());
|
|
|
|
if (isInActiveLayer)
|
|
{
|
|
objectlist->Add(gameobj->AddRef());
|
|
tf.Add(gameobj->GetSGNode());
|
|
|
|
gameobj->NodeUpdateGS(0,true);
|
|
gameobj->Bucketize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
base = base->next;
|
|
}
|
|
|
|
if (blenderscene->camera) {
|
|
KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
|
|
|
|
kxscene->SetActiveCamera(gamecamera);
|
|
}
|
|
|
|
// Set up armatures
|
|
for (base = static_cast<Base*>(blenderscene->base.first); base; base=base->next){
|
|
if (base->object->type==OB_MESH){
|
|
Mesh *me = (Mesh*)base->object->data;
|
|
|
|
if (me->dvert){
|
|
KX_GameObject *obj = converter->FindGameObject(base->object);
|
|
|
|
if (base->object->parent && base->object->parent->type==OB_ARMATURE && base->object->partype==PARSKEL){
|
|
KX_GameObject *par = converter->FindGameObject(base->object->parent);
|
|
if (par)
|
|
((BL_SkinDeformer*)(((BL_DeformableGameObject*)obj)->m_pDeformer))->SetArmature((BL_ArmatureObject*) par);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// create hierarchy information
|
|
int i;
|
|
vector<parentChildLink>::iterator pcit;
|
|
|
|
for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
|
|
{
|
|
|
|
struct Object* blenderchild = pcit->m_blenderchild;
|
|
switch (blenderchild->partype)
|
|
{
|
|
case PARVERT1:
|
|
{
|
|
// creat a new vertex parent relationship for this node.
|
|
KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
|
|
pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
|
|
break;
|
|
}
|
|
case PARSLOW:
|
|
{
|
|
// creat a new slow parent relationship for this node.
|
|
KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
|
|
pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
|
|
break;
|
|
}
|
|
case PARBONE:
|
|
{
|
|
// parent this to a bone
|
|
Bone *parent_bone = get_named_bone(get_armature(blenderchild->parent), blenderchild->parsubstr);
|
|
KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone);
|
|
pcit->m_gamechildnode->SetParentRelation(bone_parent_relation);
|
|
|
|
break;
|
|
}
|
|
case PARSKEL: // skinned - ignore
|
|
break;
|
|
case PAROBJECT:
|
|
case PARCURVE:
|
|
case PARKEY:
|
|
case PARVERT3:
|
|
default:
|
|
// unhandled
|
|
break;
|
|
}
|
|
|
|
struct Object* blenderparent = blenderchild->parent;
|
|
KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
|
|
if (parentobj)
|
|
{
|
|
parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode);
|
|
}
|
|
}
|
|
vec_parent_child.clear();
|
|
|
|
// find 'root' parents (object that has not parents in SceneGraph)
|
|
for (i=0;i<templist->GetCount();++i)
|
|
{
|
|
KX_GameObject* gameobj = (KX_GameObject*) templist->GetValue(i);
|
|
if (gameobj->GetSGNode()->GetSGParent() == 0)
|
|
{
|
|
parentlist->Add(gameobj->AddRef());
|
|
gameobj->NodeUpdateGS(0,true);
|
|
}
|
|
}
|
|
|
|
// create physics information
|
|
for (i=0;i<sumolist->GetCount();i++)
|
|
{
|
|
KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
|
|
struct Object* blenderobject = converter->FindBlenderObject(gameobj);
|
|
int nummeshes = gameobj->GetMeshCount();
|
|
RAS_MeshObject* meshobj = 0;
|
|
|
|
if (nummeshes > 0)
|
|
{
|
|
meshobj = gameobj->GetMesh(0);
|
|
}
|
|
|
|
BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter);
|
|
|
|
}
|
|
|
|
templist->Release();
|
|
sumolist->Release();
|
|
|
|
|
|
int executePriority=0; /* incremented by converter routines */
|
|
|
|
// convert global sound stuff
|
|
|
|
/* XXX, glob is the very very wrong place for this
|
|
* to be, re-enable once the listener has been moved into
|
|
* the scene. */
|
|
#if 1
|
|
SND_Scene* soundscene = kxscene->GetSoundScene();
|
|
SND_SoundListener* listener = soundscene->GetListener();
|
|
if (listener && G.listener)
|
|
{
|
|
listener->SetDopplerFactor(G.listener->dopplerfactor);
|
|
listener->SetDopplerVelocity(G.listener->dopplervelocity);
|
|
listener->SetGain(G.listener->gain);
|
|
}
|
|
#endif
|
|
|
|
// convert world
|
|
KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene->world);
|
|
converter->RegisterWorldInfo(worldinfo);
|
|
kxscene->SetWorldInfo(worldinfo);
|
|
|
|
#define CONVERT_LOGIC
|
|
#ifdef CONVERT_LOGIC
|
|
// convert logic bricks, sensors, controllers and actuators
|
|
for (i=0;i<logicbrick_conversionlist->GetCount();i++)
|
|
{
|
|
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
|
|
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
|
|
bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
|
|
BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, activeLayerBitInfo,isInActiveLayer,rendertools,converter);
|
|
}
|
|
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
|
|
{
|
|
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
|
|
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
|
|
bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
|
|
BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,activeLayerBitInfo,isInActiveLayer,converter);
|
|
}
|
|
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
|
|
{
|
|
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
|
|
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
|
|
bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
|
|
BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter);
|
|
}
|
|
#endif //CONVERT_LOGIC
|
|
|
|
logicbrick_conversionlist->Release();
|
|
|
|
// Calculate the scene btree -
|
|
// too slow - commented out.
|
|
//kxscene->SetNodeTree(tf.MakeTree());
|
|
}
|
|
|