#ifdef HAVE_CONFIG_H #include <config.h> #endif added to these files. Kent -- mein@cs.umn.edu
		
			
				
	
	
		
			1233 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1233 lines
		
	
	
		
			34 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 "BL_BlenderDataConversion.h"
 | 
						|
#include "KX_BlenderGL.h"
 | 
						|
#include "KX_BlenderScalarInterpolator.h"
 | 
						|
 | 
						|
#include "RAS_IPolygonMaterial.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 "KX_GameObject.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 "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 "DNA_action_types.h"
 | 
						|
#include "BKE_main.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_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_view3d_types.h"
 | 
						|
#include "DNA_world_types.h"
 | 
						|
#include "DNA_sound_types.h"
 | 
						|
#include "DNA_key_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"
 | 
						|
 | 
						|
// 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 "BL_ArmatureObject.h"
 | 
						|
#include "BL_DeformableGameObject.h"
 | 
						|
 | 
						|
static unsigned int KX_rgbaint2uint_new(unsigned int icol)
 | 
						|
{
 | 
						|
	unsigned int temp=0;
 | 
						|
	unsigned char *cp= (unsigned char *)&temp;
 | 
						|
	unsigned char *src= (unsigned char *)&icol;
 | 
						|
	cp[3]= src[0];//alpha
 | 
						|
	cp[2]= src[1];//blue
 | 
						|
	cp[1]= src[2];//green
 | 
						|
	cp[0]= src[3];//red
 | 
						|
	return temp;
 | 
						|
}
 | 
						|
 | 
						|
/* Now the real converting starts... */
 | 
						|
static unsigned int KX_Mcol2uint_new(MCol col)
 | 
						|
{
 | 
						|
	/* color has to be converted without endian sensitivity. So no shifting! */
 | 
						|
	unsigned int temp=0;
 | 
						|
	unsigned char *cp= (unsigned char *)&temp;
 | 
						|
	cp[3]=255;
 | 
						|
	cp[2]= col.r;
 | 
						|
	cp[1]= col.g;
 | 
						|
	cp[0]= col.b;
 | 
						|
	return temp;
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
	
 | 
						|
	// 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);
 | 
						|
	
 | 
						|
	
 | 
						|
	MFace* mface = static_cast<MFace*>(mesh->mface);
 | 
						|
	TFace* tface = static_cast<TFace*>(mesh->tface);
 | 
						|
	
 | 
						|
	
 | 
						|
	MCol* mmcol = mesh->mcol;
 | 
						|
	
 | 
						|
	
 | 
						|
	meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
 | 
						|
	
 | 
						|
	for (int f=0;f<mesh->totface;f++,mface++,tface++)
 | 
						|
	{
 | 
						|
		
 | 
						|
		bool collider = true;
 | 
						|
		
 | 
						|
		// only add valid polygons
 | 
						|
		if (mface->v3)
 | 
						|
		{
 | 
						|
			
 | 
						|
			MT_Vector3 no0(0.0,0.0,0.0),no1(0.0,0.0,0.0),no2(0.0,0.0,0.0),no3(0.0,0.0,0.0);
 | 
						|
			MT_Point3 pt0,pt1,pt2,pt3;
 | 
						|
			
 | 
						|
			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;
 | 
						|
			pt0 = MT_Point3(	mesh->mvert[mface->v1].co[0],
 | 
						|
								mesh->mvert[mface->v1].co[1],
 | 
						|
								mesh->mvert[mface->v1].co[2]);
 | 
						|
			no0 = MT_Vector3(
 | 
						|
				mesh->mvert[mface->v1].no[0]/32767.0,
 | 
						|
				mesh->mvert[mface->v1].no[1]/32767.0,
 | 
						|
				mesh->mvert[mface->v1].no[2]/32767.0
 | 
						|
				);
 | 
						|
						
 | 
						|
			pt1 = MT_Point3(	mesh->mvert[mface->v2].co[0],
 | 
						|
								mesh->mvert[mface->v2].co[1],
 | 
						|
								mesh->mvert[mface->v2].co[2]);
 | 
						|
			
 | 
						|
			no1 = MT_Vector3(
 | 
						|
				mesh->mvert[mface->v2].no[0]/32767.0,
 | 
						|
				mesh->mvert[mface->v2].no[1]/32767.0,
 | 
						|
				mesh->mvert[mface->v2].no[2]/32767.0
 | 
						|
				);
 | 
						|
			
 | 
						|
			pt2 = MT_Point3(	mesh->mvert[mface->v3].co[0],
 | 
						|
								mesh->mvert[mface->v3].co[1],
 | 
						|
								mesh->mvert[mface->v3].co[2]);
 | 
						|
	
 | 
						|
			no2 = MT_Vector3(
 | 
						|
				mesh->mvert[mface->v3].no[0]/32767.0,
 | 
						|
				mesh->mvert[mface->v3].no[1]/32767.0,
 | 
						|
				mesh->mvert[mface->v3].no[2]/32767.0
 | 
						|
				);
 | 
						|
			
 | 
						|
			if (mface->v4)
 | 
						|
			{
 | 
						|
				pt3 = MT_Point3(	mesh->mvert[mface->v4].co[0],
 | 
						|
									mesh->mvert[mface->v4].co[1],
 | 
						|
									mesh->mvert[mface->v4].co[2]);
 | 
						|
				no3 = MT_Vector3(
 | 
						|
					mesh->mvert[mface->v4].no[0]/32767.0,
 | 
						|
					mesh->mvert[mface->v4].no[1]/32767.0,
 | 
						|
					mesh->mvert[mface->v4].no[2]/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;
 | 
						|
	
 | 
						|
			}
 | 
						|
		
 | 
						|
			{
 | 
						|
				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;
 | 
						|
			
 | 
						|
				}
 | 
						|
	
 | 
						|
				
 | 
						|
				bool polyvisible = true;
 | 
						|
				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 {
 | 
						|
					}
 | 
						|
	
 | 
						|
	
 | 
						|
				} 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
 | 
						|
						rgb0 = KX_rgbaint2uint_new(0xFFFFFFFF);
 | 
						|
						rgb1 = KX_rgbaint2uint_new(0xFFFFFFFF);
 | 
						|
						rgb2 = KX_rgbaint2uint_new(0xFFFFFFFF);
 | 
						|
						
 | 
						|
						if (mface->v4)
 | 
						|
							rgb3 = KX_rgbaint2uint_new(0xFFFFFFFF);
 | 
						|
	
 | 
						|
						mode = TF_DYNAMIC;	
 | 
						|
						transp = TF_SOLID;
 | 
						|
						tile = 0;
 | 
						|
					}
 | 
						|
				}
 | 
						|
					
 | 
						|
				
 | 
						|
				Material* ma = give_current_material(blenderobj, 1);
 | 
						|
				const char* matnameptr = (ma ? ma->id.name : "");
 | 
						|
				
 | 
						|
	
 | 
						|
				bool istriangle = (mface->v4==0);
 | 
						|
				
 | 
						|
				RAS_IPolyMaterial* polymat = rendertools->CreateBlenderPolyMaterial(imastr,false,matnameptr,tile,tilexrep,tileyrep,mode,transp, lightlayer,istriangle,blenderobj,tface);
 | 
						|
	
 | 
						|
				if (ma)
 | 
						|
				{
 | 
						|
					polymat->m_specular = MT_Vector3(ma->spec * ma->specr,ma->spec * ma->specg,ma->spec * ma->specb);
 | 
						|
					polymat->m_shininess = (float)ma->har;
 | 
						|
 | 
						|
				} 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;
 | 
						|
					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);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	meshobj->UpdateMaterialList();
 | 
						|
	
 | 
						|
	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;
 | 
						|
	
 | 
						|
	assert(materialProps);
 | 
						|
		
 | 
						|
	Material* blendermat = give_current_material(blenderobject, 0);
 | 
						|
		
 | 
						|
	if (blendermat)
 | 
						|
	{
 | 
						|
		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;
 | 
						|
	
 | 
						|
	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 * blenderobject->mass * blenderobject->inertia * blenderobject->inertia;
 | 
						|
	
 | 
						|
	assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
 | 
						|
	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;
 | 
						|
}
 | 
						|
 | 
						|
	
 | 
						|
	
 | 
						|
	
 | 
						|
		
 | 
						|
//////////////////////////////////////////////////////////
 | 
						|
	
 | 
						|
 | 
						|
 | 
						|
 | 
						|
void my_boundbox_mesh(Mesh *me, float *loc, float *size)
 | 
						|
		{
 | 
						|
	MVert *mvert;
 | 
						|
	BoundBox *bb;
 | 
						|
	float min[3], max[3];
 | 
						|
	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];
 | 
						|
			}
 | 
						|
		
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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;
 | 
						|
	}
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
void my_get_local_bounds(Object *ob, float *centre, float *size)
 | 
						|
						{
 | 
						|
	BoundBox *bb= NULL;
 | 
						|
	/* uses boundbox, function used by Ketsji */
 | 
						|
	
 | 
						|
	if(ob->type==OB_MESH) {
 | 
						|
		bb= ( (Mesh *)ob->data )->bb;
 | 
						|
		if(bb==0) {
 | 
						|
			my_tex_space_mesh((struct Mesh *)ob->data);
 | 
						|
			bb= ( (Mesh *)ob->data )->bb;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
 | 
						|
		centre[0]= centre[1]= centre[2]= 0.0;
 | 
						|
		size[0]  = size[1]=size[2]=0.0;
 | 
						|
	}
 | 
						|
	else if(ob->type==OB_MBALL) {
 | 
						|
		bb= ob->bb;
 | 
						|
						}
 | 
						|
	if(bb==NULL) {
 | 
						|
		centre[0]= centre[1]= centre[2]= 0.0;
 | 
						|
		size[0] = size[1]=size[2]=0.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]= (bb->vec[0][0] + bb->vec[4][0])/2.0;
 | 
						|
		centre[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0;
 | 
						|
		centre[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0;
 | 
						|
					}
 | 
						|
}
 | 
						|
	
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//////////////////////////////////////////////////////
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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();
 | 
						|
	//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;
 | 
						|
	objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
 | 
						|
	//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_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
 | 
						|
	objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
 | 
						|
	objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
 | 
						|
	objprop.m_dynamic_parent=NULL;
 | 
						|
	objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
 | 
						|
	objprop.m_implicitsphere = false;
 | 
						|
	objprop.m_implicitbox = false;
 | 
						|
	
 | 
						|
	if (blenderobject->dtx & OB_BOUNDBOX)
 | 
						|
	{
 | 
						|
		objprop.m_implicitsphere = (blenderobject->boundtype == OB_BOUND_SPHERE);
 | 
						|
		objprop.m_implicitbox = (blenderobject->boundtype == OB_BOUND_BOX);
 | 
						|
	}
 | 
						|
 | 
						|
	// 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_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
 | 
						|
	objprop.m_concave = (blenderobject->boundtype & 4) != 0;
 | 
						|
	
 | 
						|
	
 | 
						|
	my_get_local_bounds(blenderobject,objprop.m_boundingbox.m_center,objprop.m_boundingbox.m_extends);
 | 
						|
	//mmm, has to be divided by 2 to be proper extends
 | 
						|
	objprop.m_boundingbox.m_extends[0]*=2.f;
 | 
						|
	objprop.m_boundingbox.m_extends[1]*=2.f;
 | 
						|
	objprop.m_boundingbox.m_extends[2]*=2.f;
 | 
						|
	
 | 
						|
	switch (physics_engine)
 | 
						|
		{
 | 
						|
			case UseSumo:
 | 
						|
				{
 | 
						|
 | 
						|
#ifdef USE_SUMO_SOLID
 | 
						|
					KX_ConvertSumoObject(	gameobj,meshobj,kxscene,shapeprops,	smmaterial,	&objprop);
 | 
						|
#endif
 | 
						|
					break;
 | 
						|
				}
 | 
						|
			case UseODE:
 | 
						|
			{
 | 
						|
 | 
						|
#ifdef USE_ODE
 | 
						|
				KX_ConvertODEEngineObject(gameobj,meshobj,kxscene,shapeprops,	smmaterial,	&objprop);
 | 
						|
#endif //USE_ODE
 | 
						|
 | 
						|
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case UseDynamo:
 | 
						|
			{
 | 
						|
				//KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops,	smmaterial,	&objprop);
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case UseNone:
 | 
						|
			default:
 | 
						|
	{
 | 
						|
	}
 | 
						|
	
 | 
						|
}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
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_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;
 | 
						|
	
 | 
						|
	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;
 | 
						|
	KX_Camera *gamecamera;
 | 
						|
	
 | 
						|
	camdata.m_lens= ca->lens;
 | 
						|
	camdata.m_clipend= ca->clipend;
 | 
						|
	camdata.m_clipstart= ca->clipsta;
 | 
						|
	
 | 
						|
	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);
 | 
						|
		
 | 
						|
		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;
 | 
						|
		}
 | 
						|
	
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	
 | 
						|
	case OB_ARMATURE:
 | 
						|
	{
 | 
						|
		gameobj = new BL_ArmatureObject (kxscene, KX_Scene::m_callbacks,
 | 
						|
			(bArmature*)ob->data,
 | 
						|
			ob->pose);
 | 
						|
	
 | 
						|
		/* 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();
 | 
						|
	
 | 
						|
	// Convert actions to actionmap
 | 
						|
	bAction *curAct;
 | 
						|
	for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
 | 
						|
	{
 | 
						|
		logicmgr->RegisterActionName(curAct->id.name, curAct);
 | 
						|
	}
 | 
						|
	
 | 
						|
	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);
 | 
						|
	
 | 
						|
			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);
 | 
						|
	
 | 
						|
			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());
 | 
						|
				
 | 
						|
				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;
 | 
						|
		if (blenderchild->partype == 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);
 | 
						|
		} else 
 | 
						|
		if (blenderchild->partype == 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);
 | 
						|
		}	
 | 
						|
	
 | 
						|
		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 0
 | 
						|
	SND_Scene* soundscene = kxscene->GetSoundScene();
 | 
						|
	SND_SoundListener* listener = soundscene->GetListener();
 | 
						|
	if (listener && glob->listener)
 | 
						|
	{
 | 
						|
		listener->SetDopplerFactor(glob->listener->dopplerfactor);
 | 
						|
		listener->SetDopplerVelocity(glob->listener->dopplervelocity);
 | 
						|
		listener->SetGain(glob->listener->gain);
 | 
						|
	}
 | 
						|
#endif
 | 
						|
 | 
						|
	// convert world
 | 
						|
	KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene->world);
 | 
						|
	converter->RegisterWorldInfo(worldinfo);
 | 
						|
	kxscene->SetWorldInfo(worldinfo);
 | 
						|
	
 | 
						|
	// 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);
 | 
						|
	}
 | 
						|
	logicbrick_conversionlist->Release();
 | 
						|
}
 |