Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Converter/BL_BlenderDataConversion.cpp')
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp1227
1 files changed, 1227 insertions, 0 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
new file mode 100644
index 00000000000..68d45044fff
--- /dev/null
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -0,0 +1,1227 @@
+/**
+ * $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 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"
+
+#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();
+}