diff options
Diffstat (limited to 'source/gameengine/Converter')
-rw-r--r-- | source/gameengine/Converter/BL_ActionActuator.cpp | 24 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ArmatureObject.cpp | 9 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 904 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_DeformableGameObject.h | 1 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ShapeActionActuator.cpp | 59 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ShapeActionActuator.h | 18 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ShapeDeformer.cpp | 7 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_SkinDeformer.cpp | 48 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_SkinDeformer.h | 6 | ||||
-rw-r--r-- | source/gameengine/Converter/KX_ConvertActuators.cpp | 16 | ||||
-rw-r--r-- | source/gameengine/Converter/KX_ConvertSensors.cpp | 6 | ||||
-rw-r--r-- | source/gameengine/Converter/KX_IpoConvert.cpp | 59 | ||||
-rw-r--r-- | source/gameengine/Converter/KX_IpoConvert.h | 2 |
13 files changed, 654 insertions, 505 deletions
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index 5d6dd694765..2ee8b54a014 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -57,24 +57,12 @@ BL_ActionActuator::~BL_ActionActuator() { - - if (m_pose) { - free_pose_channels(m_pose); - MEM_freeN(m_pose); - m_pose = NULL; - }; - - if (m_userpose){ - free_pose_channels(m_userpose); - MEM_freeN(m_userpose); - m_userpose=NULL; - } - if (m_blendpose) { - free_pose_channels(m_blendpose); - MEM_freeN(m_blendpose); - m_blendpose = NULL; - }; - + if (m_pose) + free_pose(m_pose); + if (m_userpose) + free_pose(m_userpose); + if (m_blendpose) + free_pose(m_blendpose); } void BL_ActionActuator::ProcessReplica(){ diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index f73d5b42a01..09f1d9d4d87 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -82,10 +82,8 @@ void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica) BL_ArmatureObject::~BL_ArmatureObject() { - if (m_mrdPose){ - free_pose_channels(m_mrdPose); - MEM_freeN(m_mrdPose); - } + if (m_mrdPose) + free_pose(m_mrdPose); } /* note, you can only call this for exisiting Armature objects, and not mix it with other Armatures */ @@ -172,12 +170,13 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose) // copy_pose (&m_mrdPose, m_pose, 0); //} - if (!*pose) + if (!*pose) { // must duplicate the constraints too otherwise we have corruption in free_pose_channels() // because it will free the blender constraints. // Ideally, blender should rememeber that the constraints were not copied so that // free_pose_channels() would not free them. copy_pose(pose, m_objArma->pose, 1); + } else extract_pose_from_pose(*pose, m_objArma->pose); diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index f3e22cd297a..f44318120e8 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -136,8 +136,12 @@ #include "BKE_mesh.h" #include "MT_Point3.h" +#include "BLI_arithb.h" + extern "C" { - #include "BKE_customdata.h" +#include "BKE_customdata.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_DerivedMesh.h" } #include "BKE_material.h" /* give_current_material */ @@ -309,7 +313,6 @@ typedef struct MTF_localLayer // ------------------------------------ BL_Material* ConvertMaterial( - Mesh* mesh, Material *mat, MTFace* tface, const char *tfaceName, @@ -323,15 +326,16 @@ BL_Material* ConvertMaterial( //this needs some type of manager BL_Material *material = new BL_Material(); - int numchan = -1; + int numchan = -1, texalpha = 0; bool validmat = (mat!=0); - bool validface = (mesh->mtface && tface); + bool validface = (tface!=0); short type = 0; if( validmat ) type = 1; // material color material->IdMode = DEFAULT_BLENDER; + material->glslmat = (validmat)? glslmat: false; // -------------------------------- if(validmat) { @@ -367,12 +371,13 @@ BL_Material* ConvertMaterial( 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; + if(material->img[i]->flag & IMA_REFLECT) material->mapping[i].mapping |= USEREFL; else @@ -430,6 +435,8 @@ BL_Material* ConvertMaterial( material->flag[i] |= ( mttmp->mapto & MAP_ALPHA )?TEXALPHA:0; material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0; + if(!glslmat && (material->flag[i] & TEXALPHA)) + texalpha = 1; } } else if(mttmp->tex->type == TEX_ENVMAP) { @@ -546,17 +553,7 @@ BL_Material* ConvertMaterial( material->ref = mat->ref; material->amb = mat->amb; - // set alpha testing without z-sorting - if( ( validface && (!(tface->transp &~ TF_CLIP))) && mat->mode & MA_ZTRA) { - // sets the RAS_IPolyMaterial::m_flag |RAS_FORCEALPHA - // this is so we don't have the overhead of the z-sorting code - material->ras_mode|=ALPHA_TEST; - } - else{ - // use regular z-sorting - material->ras_mode |= ((mat->mode & MA_ZTRA) != 0)?ZSORT:0; - } - material->ras_mode |= ((mat->mode & MA_WIRE) != 0)?WIRE:0; + material->ras_mode |= (mat->mode & MA_WIRE)? WIRE: 0; } else { int valid = 0; @@ -574,7 +571,6 @@ BL_Material* ConvertMaterial( 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++; } } @@ -607,10 +603,6 @@ BL_Material* ConvertMaterial( material->ras_mode |= ( (tface->mode & TF_DYNAMIC)!= 0 )?COLLIDER:0; material->transp = tface->transp; - - if(tface->transp&~TF_CLIP) - material->ras_mode |= TRANSP; - material->tile = tface->tile; material->mode = tface->mode; @@ -631,7 +623,16 @@ BL_Material* ConvertMaterial( material->tile = 0; } + // with ztransp enabled, enforce alpha blending mode + if(validmat && (mat->mode & MA_ZTRA) && (material->transp == TF_SOLID)) + material->transp = TF_ALPHA; + // always zsort alpha + add + if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) + && (material->transp != TF_CLIP)) { + material->ras_mode |= ALPHA; + material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0; + } // get uv sets if(validmat) @@ -711,132 +712,54 @@ BL_Material* ConvertMaterial( } -static void BL_ComputeTriTangentSpace(const MT_Vector3 &v1, const MT_Vector3 &v2, const MT_Vector3 &v3, - const MT_Vector2 &uv1, const MT_Vector2 &uv2, const MT_Vector2 &uv3, - MFace* mface, MT_Vector3 *tan1, MT_Vector3 *tan2) -{ - MT_Vector3 dx1(v2 - v1), dx2(v3 - v1); - MT_Vector2 duv1(uv2 - uv1), duv2(uv3 - uv1); - - MT_Scalar r = 1.0 / (duv1.x() * duv2.y() - duv2.x() * duv1.y()); - duv1 *= r; - duv2 *= r; - MT_Vector3 sdir(duv2.y() * dx1 - duv1.y() * dx2); - MT_Vector3 tdir(duv1.x() * dx2 - duv2.x() * dx1); - - tan1[mface->v1] += sdir; - tan1[mface->v2] += sdir; - tan1[mface->v3] += sdir; - - tan2[mface->v1] += tdir; - tan2[mface->v2] += tdir; - tan2[mface->v3] += tdir; -} - -static MT_Vector4* BL_ComputeMeshTangentSpace(Mesh* mesh) -{ - MFace* mface = static_cast<MFace*>(mesh->mface); - MTFace* tface = static_cast<MTFace*>(mesh->mtface); - - MT_Vector3 *tan1 = new MT_Vector3[mesh->totvert]; - MT_Vector3 *tan2 = new MT_Vector3[mesh->totvert]; - - int v; - for (v = 0; v < mesh->totvert; v++) - { - tan1[v] = MT_Vector3(0.0, 0.0, 0.0); - tan2[v] = MT_Vector3(0.0, 0.0, 0.0); - } - - for (int p = 0; p < mesh->totface; p++, mface++, tface++) - { - MT_Vector3 v1(mesh->mvert[mface->v1].co), - v2(mesh->mvert[mface->v2].co), - v3(mesh->mvert[mface->v3].co); - - MT_Vector2 uv1(tface->uv[0]), - uv2(tface->uv[1]), - uv3(tface->uv[2]); - - BL_ComputeTriTangentSpace(v1, v2, v3, uv1, uv2, uv3, mface, tan1, tan2); - if (mface->v4) - { - MT_Vector3 v4(mesh->mvert[mface->v4].co); - MT_Vector2 uv4(tface->uv[3]); - - BL_ComputeTriTangentSpace(v1, v3, v4, uv1, uv3, uv4, mface, tan1, tan2); - } - } - - MT_Vector4 *tangent = new MT_Vector4[mesh->totvert]; - for (v = 0; v < mesh->totvert; v++) - { - const MT_Vector3 no(mesh->mvert[v].no[0]/32767.0, - mesh->mvert[v].no[1]/32767.0, - mesh->mvert[v].no[2]/32767.0); - // Gram-Schmidt orthogonalize - MT_Vector3 t(tan1[v] - no.cross(no.cross(tan1[v]))); - if (!MT_fuzzyZero(t)) - t /= t.length(); - - tangent[v].x() = t.x(); - tangent[v].y() = t.y(); - tangent[v].z() = t.z(); - // Calculate handedness - tangent[v].w() = no.dot(tan1[v].cross(tan2[v])) < 0.0 ? -1.0 : 1.0; - } - - delete [] tan1; - delete [] tan2; - - return tangent; -} - RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter) { RAS_MeshObject *meshobj; - bool skinMesh = false; - + bool skinMesh = false; int lightlayer = blenderobj->lay; - - MFace* mface = static_cast<MFace*>(mesh->mface); - MTFace* tface = static_cast<MTFace*>(mesh->mtface); + + // Get DerivedMesh data + DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj); + + MVert *mvert = dm->getVertArray(dm); + int totvert = dm->getNumVerts(dm); + + MFace *mface = dm->getFaceArray(dm); + MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE)); + MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL)); + float (*tangent)[3] = NULL; + int totface = dm->getNumFaces(dm); const char *tfaceName = ""; - MCol* mmcol = mesh->mcol; - MT_assert(mface || mesh->totface == 0); + if(tface) { + DM_add_tangent_layer(dm); + tangent = (float(*)[3])dm->getFaceDataArray(dm, CD_TANGENT); + } // Determine if we need to make a skinned mesh - if (mesh->dvert || mesh->key){ + if (mesh->dvert || mesh->key) { meshobj = new BL_SkinMeshObject(mesh, lightlayer); skinMesh = true; } - else { + else meshobj = new RAS_MeshObject(mesh, lightlayer); - } - MT_Vector4 *tangent = 0; - if (tface) - tangent = BL_ComputeMeshTangentSpace(mesh); - // Extract avaiable layers MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE]; - for (int lay=0; lay<MAX_MTFACE; lay++) - { + for (int lay=0; lay<MAX_MTFACE; lay++) { layers[lay].face = 0; layers[lay].name = ""; } - int validLayers = 0; - for (int i=0; i<mesh->fdata.totlayer; i++) + for (int i=0; i<dm->faceData.totlayer; i++) { - if (mesh->fdata.layers[i].type == CD_MTFACE) + if (dm->faceData.layers[i].type == CD_MTFACE) { assert(validLayers <= 8); - layers[validLayers].face = (MTFace*)mesh->fdata.layers[i].data;; - layers[validLayers].name = mesh->fdata.layers[i].name; + layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data); + layers[validLayers].name = dm->faceData.layers[i].name; if(tface == layers[validLayers].face) tfaceName = layers[validLayers].name; validLayers++; @@ -844,271 +767,269 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* } 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++) + meshobj->m_xyz_index_to_vertex_index_mapping.resize(totvert); + + for (int f=0;f<totface;f++,mface++) { - + Material* ma = 0; 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); - MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(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); - MT_Vector4 tan0(0.0, 0.0, 0.0, 0.0), - tan1(0.0, 0.0, 0.0, 0.0), - tan2(0.0, 0.0, 0.0, 0.0), - tan3(0.0, 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; + MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0); + MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0); + unsigned int rgb0,rgb1,rgb2,rgb3 = 0; + + MT_Vector3 no0, no1, no2, no3; + MT_Point3 pt0, pt1, pt2, pt3; + MT_Vector4 tan0, tan1, tan2, tan3; + + /* get coordinates, normals and tangents */ + pt0 = MT_Point3(mvert[mface->v1].co); + pt1 = MT_Point3(mvert[mface->v2].co); + pt2 = MT_Point3(mvert[mface->v3].co); + pt3 = (mface->v4)? MT_Point3(mvert[mface->v4].co): MT_Point3(0.0, 0.0, 0.0); + + if(mface->flag & ME_SMOOTH) { + float n0[3], n1[3], n2[3], n3[3]; + + NormalShortToFloat(n0, mvert[mface->v1].no); + NormalShortToFloat(n1, mvert[mface->v2].no); + NormalShortToFloat(n2, mvert[mface->v3].no); + no0 = n0; + no1 = n1; + no2 = n2; + + if(mface->v4) { + NormalShortToFloat(n3, mvert[mface->v4].no); + no3 = n3; } + else + no3 = MT_Vector3(0.0, 0.0, 0.0); + } + else { + float fno[3]; + + if(mface->v4) + CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co, + mvert[mface->v3].co, mvert[mface->v4].co, fno); + else + CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co, + mvert[mface->v3].co, fno); + + no0 = no1 = no2 = no3 = MT_Vector3(fno); + } + + if(tangent) { + tan0 = tangent[f*4 + 0]; + tan1 = tangent[f*4 + 1]; + tan2 = tangent[f*4 + 2]; + + if (mface->v4) + tan3 = tangent[f*4 + 3]; + } + + /* get material */ + ma = give_current_material(blenderobj, mface->mat_nr+1); - 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; - + { + bool polyvisible = true; + RAS_IPolyMaterial* polymat = NULL; + BL_Material *bl_mat = NULL; + + if(converter->GetMaterials()) { + /* do Blender Multitexture and Blender GLSL materials */ + unsigned int rgb[4]; + MT_Point2 uv[4]; + + /* first is the BL_Material */ + bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol, + lightlayer, blenderobj, layers, converter->GetGLSLMaterials()); + + bl_mat->material_index = (int)mface->mat_nr; + + polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0); + collider = ((bl_mat->ras_mode & COLLIDER)!=0); + + /* vertex colors and uv's were stored in bl_mat temporarily */ + bl_mat->GetConversionRGB(rgb); + rgb0 = rgb[0]; rgb1 = rgb[1]; + rgb2 = rgb[2]; rgb3 = rgb[3]; + + bl_mat->GetConversionUV(uv); + uv0 = uv[0]; uv1 = uv[1]; + uv2 = uv[2]; uv3 = uv[3]; + + bl_mat->GetConversionUV2(uv); + uv20 = uv[0]; uv21 = uv[1]; + uv22 = uv[2]; uv23 = uv[3]; + + /* then the KX_BlenderMaterial */ + polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj ); } + else { + /* do Texture Face materials */ + Image* bima = (tface)? (Image*)tface->tpage: NULL; + STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; - { - Material* ma = 0; - bool polyvisible = true; - RAS_IPolyMaterial* polymat = NULL; - BL_Material *bl_mat = NULL; - - if(converter->GetMaterials()) - { - if(mesh->totcol > 1) - ma = mesh->mat[mface->mat_nr]; - else - ma = give_current_material(blenderobj, 1); - - bl_mat = ConvertMaterial(mesh, ma, tface, tfaceName, mface, mmcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials()); - // 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); + char transp=0; + short mode=0, tile=0; + int tilexrep=4,tileyrep = 4; + + if (bima) { + tilexrep = bima->xrep; + tileyrep = bima->yrep; + } + + /* get tface properties if available */ + if(tface) { + /* TF_DYNAMIC means the polygon is a collision face */ + collider = ((tface->mode & TF_DYNAMIC) != 0); + transp = tface->transp; + tile = tface->tile; + mode = tface->mode; - polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj ); + polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE)); - 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]; - - bl_mat->GetConversionUV2(uv); - uv20 = uv[0]; uv21 = uv[1]; - uv22 = uv[2]; uv23 = uv[3]; - - if(tangent){ - tan0 = tangent[mface->v1]; - tan1 = tangent[mface->v2]; - tan2 = tangent[mface->v3]; - if (mface->v4) - tan3 = tangent[mface->v4]; - } + uv0 = MT_Point2(tface->uv[0]); + uv1 = MT_Point2(tface->uv[1]); + uv2 = MT_Point2(tface->uv[2]); + + if (mface->v4) + uv3 = MT_Point2(tface->uv[3]); + } + else { + /* no texfaces, set COLLSION true and everything else FALSE */ + mode = default_face_mode; + transp = TF_SOLID; + tile = 0; } - else - { - ma = give_current_material(blenderobj, 1); - Image* bima = ((mesh->mtface && tface) ? (Image*) tface->tpage : NULL); - - STR_String imastr = - ((mesh->mtface && tface) ? - (bima? (bima)->id.name : "" ) : "" ); - - char transp=0; - short mode=0, tile=0; - int tilexrep=4,tileyrep = 4; + /* get vertex colors */ + if (mcol) { + /* we have vertex colors */ + rgb0 = KX_Mcol2uint_new(mcol[0]); + rgb1 = KX_Mcol2uint_new(mcol[1]); + rgb2 = KX_Mcol2uint_new(mcol[2]); - if (bima) - { - tilexrep = bima->xrep; - tileyrep = bima->yrep; - - } + if (mface->v4) + rgb3 = KX_Mcol2uint_new(mcol[3]); + } + else { + /* no vertex colors, take from material, otherwise white */ + unsigned int color = 0xFFFFFFFFL; - if (mesh->mtface && tface) + if (ma) { - // Use texface colors if available - //TF_DYNAMIC means the polygon is a collision face - collider = ((tface->mode & TF_DYNAMIC) != 0); - transp = tface->transp &~ TF_CLIP; - tile = tface->tile; - mode = tface->mode; - - polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE)); + union + { + unsigned char cp[4]; + unsigned int integer; + } col_converter; - uv0 = MT_Point2(tface->uv[0]); - uv1 = MT_Point2(tface->uv[1]); - uv2 = MT_Point2(tface->uv[2]); - - if (mface->v4) - uv3 = MT_Point2(tface->uv[3]); - } - else - { - // no texfaces, set COLLSION true and everything else FALSE + 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); - mode = default_face_mode; - transp = TF_SOLID; - tile = 0; + color = col_converter.integer; } - if (mmcol) - { - // Use vertex colors - 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]); - } - else { - // no vertex colors: take from material if we have one, - // otherwise set to white - unsigned int color = 0xFFFFFFFFL; + rgb0 = KX_rgbaint2uint_new(color); + rgb1 = KX_rgbaint2uint_new(color); + rgb2 = KX_rgbaint2uint_new(color); + + if (mface->v4) + rgb3 = KX_rgbaint2uint_new(color); + } + + bool istriangle = (mface->v4==0); - if (ma) - { - 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); - - color = col_converter.integer; - } + // only zsort alpha + add + bool alpha = (transp == TF_ALPHA || transp == TF_ADD); + bool zsort = (mode & TF_ALPHASORT)? alpha: 0; + + polymat = new KX_PolygonMaterial(imastr, ma, + tile, tilexrep, tileyrep, + mode, transp, alpha, zsort, lightlayer, istriangle, blenderobj, tface, (unsigned int*)mcol); - rgb0 = KX_rgbaint2uint_new(color); - rgb1 = KX_rgbaint2uint_new(color); - rgb2 = KX_rgbaint2uint_new(color); - - if (mface->v4) - rgb3 = KX_rgbaint2uint_new(color); - } - - 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, (unsigned int*)mmcol); - - 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); + 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; + } + } - } else - { - polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f); - polymat->m_shininess = 35.0; - } + // see if a bucket was reused or a new one was created + // this way only one KX_BlenderMaterial object has to exist per bucket + bool bucketCreated; + RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated); + if (bucketCreated) { + // this is needed to free up memory afterwards + converter->RegisterPolyMaterial(polymat); + if(converter->GetMaterials()) { + converter->RegisterBlenderMaterial(bl_mat); } - - // see if a bucket was reused or a new one was created - // this way only one KX_BlenderMaterial object has to exist per bucket - bool bucketCreated; - RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated); - if (bucketCreated) { - // this is needed to free up memory afterwards - converter->RegisterPolyMaterial(polymat); - if(converter->GetMaterials()) { - converter->RegisterBlenderMaterial(bl_mat); - } - } else { - // delete the material objects since they are no longer needed - // from now on, use the polygon material from the material bucket - delete polymat; - if(converter->GetMaterials()) { - delete bl_mat; - } - polymat = bucket->GetPolyMaterial(); + } else { + // delete the material objects since they are no longer needed + // from now on, use the polygon material from the material bucket + delete polymat; + if(converter->GetMaterials()) { + delete bl_mat; } - - int nverts = mface->v4?4:3; - int vtxarray = meshobj->FindVertexArray(nverts,polymat); - RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray); + polymat = bucket->GetPolyMaterial(); + } + + int nverts = mface->v4?4:3; + int vtxarray = meshobj->FindVertexArray(nverts,polymat); + RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray); - bool flat; + bool flat; - if (skinMesh) { - /* If the face is set to solid, all fnors are the same */ - if (mface->flag & ME_SMOOTH) - flat = false; - else - flat = true; - } - else + if (skinMesh) { + /* If the face is set to solid, all fnors are the same */ + if (mface->flag & ME_SMOOTH) flat = false; + else + flat = true; + } + else + flat = false; - poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1)); - poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2)); - poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3)); - if (nverts==4) - poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4)); + poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1)); + poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2)); + poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3)); + if (nverts==4) + poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4)); - meshobj->AddPolygon(poly); - if (poly->IsCollider()) + 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) { - 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); - } + 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); } + +// poly->SetVisibleWireframeEdges(mface->edcode); + poly->SetCollider(collider); } + if (tface) tface++; - if (mmcol) - mmcol+=4; + if (mcol) + mcol+=4; for (int lay=0; lay<MAX_MTFACE; lay++) { @@ -1127,11 +1048,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* (*mit)->GetPolyMaterial()->OnConstruction(); } - if(tangent) - delete [] tangent; - if (layers) delete []layers; + + dm->release(dm); return meshobj; } @@ -1819,7 +1739,7 @@ KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){ return 0; } -#include "BLI_arithb.h" + // convert blender objects into ketsji gameobjects void BL_ConvertBlenderObjects(struct Main* maggie, const STR_String& scenename, @@ -1847,7 +1767,10 @@ void BL_ConvertBlenderObjects(struct Main* maggie, int aspect_width; int aspect_height; vector<MT_Vector3> inivel,iniang; - + set<Group*> grouplist; // list of groups to be converted + set<Object*> allblobj; // all objects converted + set<Object*> groupobj; // objects from groups (never in active layer) + if (alwaysUseExpandFraming) { frame_type = RAS_FrameSettings::e_frame_extend; aspect_width = canvas->GetWidth(); @@ -1919,6 +1842,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, for (SETLOOPER(blenderscene, base)) { Object* blenderobject = base->object; + allblobj.insert(blenderobject); + KX_GameObject* gameobj = gameobject_from_blenderobject( base->object, kxscene, @@ -1932,7 +1857,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if (converter->addInitFromFrame) if (!isInActiveLayer) addobj=false; - + if (gameobj&&addobj) { MT_Point3 posPrev; @@ -1984,10 +1909,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, 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); - + BL_ConvertMaterialIpos(blenderobject, gameobj, converter); + sumolist->Add(gameobj->AddRef()); BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); @@ -2024,8 +1947,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, // needed for python scripting logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); - // needed for dynamic object morphing - logicmgr->RegisterGameObj(gameobj, blenderobject); + // needed for group duplication + logicmgr->RegisterGameObj(blenderobject, gameobj); for (int i = 0; i < gameobj->GetMeshCount(); i++) logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject); @@ -2046,7 +1969,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, gameobj->NodeUpdateGS(0,true); gameobj->Bucketize(); - + } else { @@ -2054,6 +1977,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, //at the end of this function if it is not a root object inactivelist->Add(gameobj->AddRef()); } + if (gameobj->IsDupliGroup()) + grouplist.insert(blenderobject->dup_group); if (converter->addInitFromFrame){ gameobj->NodeSetLocalPosition(posPrev); gameobj->NodeSetLocalOrientation(angor); @@ -2073,7 +1998,188 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } - if (blenderscene->camera) { + if (!grouplist.empty()) + { + // now convert the group referenced by dupli group object + // keep track of all groups already converted + set<Group*> allgrouplist = grouplist; + set<Group*> tempglist; + // recurse + while (!grouplist.empty()) + { + set<Group*>::iterator git; + tempglist.clear(); + tempglist.swap(grouplist); + for (git=tempglist.begin(); git!=tempglist.end(); git++) + { + Group* group = *git; + GroupObject* go; + for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next) + { + Object* blenderobject = go->ob; + if (converter->FindGameObject(blenderobject) == NULL) + { + allblobj.insert(blenderobject); + groupobj.insert(blenderobject); + KX_GameObject* gameobj = gameobject_from_blenderobject( + blenderobject, + kxscene, + rendertools, + converter, + blenderscene); + + // this code is copied from above except that + // object from groups are never in active layer + bool isInActiveLayer = false; + bool addobj=true; + + if (converter->addInitFromFrame) + if (!isInActiveLayer) + addobj=false; + + if (gameobj&&addobj) + { + MT_Point3 posPrev; + MT_Matrix3x3 angor; + if (converter->addInitFromFrame) + blenderscene->r.cfra=blenderscene->r.sfra; + + 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] + ); + if (converter->addInitFromFrame){//rcruiz + float eulxyzPrev[3]; + blenderscene->r.cfra=blenderscene->r.sfra-1; + update_for_newframe(); + MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0], + blenderobject->loc[1]+blenderobject->dloc[1], + blenderobject->loc[2]+blenderobject->dloc[2] + ); + eulxyzPrev[0]=blenderobject->rot[0]; + eulxyzPrev[1]=blenderobject->rot[1]; + eulxyzPrev[2]=blenderobject->rot[2]; + + double fps = (double) blenderscene->r.frs_sec/ + (double) blenderscene->r.frs_sec_base; + + tmp.scale(fps, fps, fps); + inivel.push_back(tmp); + tmp=eulxyz-eulxyzPrev; + tmp.scale(fps, fps, fps); + iniang.push_back(tmp); + blenderscene->r.cfra=blenderscene->r.sfra; + update_for_newframe(); + } + + gameobj->NodeSetLocalPosition(pos); + gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); + gameobj->NodeSetLocalScale(scale); + gameobj->NodeUpdateGS(0,true); + + BL_ConvertIpos(blenderobject,gameobj,converter); + BL_ConvertMaterialIpos(blenderobject,gameobj, converter); + + 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)&&(!converter->addInitFromFrame)) + { + // 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 group duplication + logicmgr->RegisterGameObj(blenderobject, gameobj); + 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 (converter->addInitFromFrame){ + posPrev=gameobj->NodeGetWorldPosition(); + angor=gameobj->NodeGetWorldOrientation(); + } + if (isInActiveLayer) + { + objectlist->Add(gameobj->AddRef()); + //tf.Add(gameobj->GetSGNode()); + + gameobj->NodeUpdateGS(0,true); + gameobj->Bucketize(); + + } + else + { + //we must store this object otherwise it will be deleted + //at the end of this function if it is not a root object + inactivelist->Add(gameobj->AddRef()); + + } + if (gameobj->IsDupliGroup()) + { + // check that the group is not already converted + if (allgrouplist.insert(blenderobject->dup_group).second) + grouplist.insert(blenderobject->dup_group); + } + if (converter->addInitFromFrame){ + gameobj->NodeSetLocalPosition(posPrev); + gameobj->NodeSetLocalOrientation(angor); + } + + } + if (gameobj) + gameobj->Release(); + } + } + } + } + } + + // non-camera objects not supported as camera currently + if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) { KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera); if(gamecamera) @@ -2081,15 +2187,18 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } // Set up armatures - for(SETLOOPER(blenderscene, base)){ - if (base->object->type==OB_MESH){ - Mesh *me = (Mesh*)base->object->data; + set<Object*>::iterator oit; + for(oit=allblobj.begin(); oit!=allblobj.end(); oit++) + { + Object* blenderobj = *oit; + if (blenderobj->type==OB_MESH){ + Mesh *me = (Mesh*)blenderobj->data; if (me->dvert){ - KX_GameObject *obj = converter->FindGameObject(base->object); + KX_GameObject *obj = converter->FindGameObject(blenderobj); - if (base->object->parent && base->object->parent->type==OB_ARMATURE && base->object->partype==PARSKEL){ - KX_GameObject *par = converter->FindGameObject(base->object->parent); + if (obj && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE && blenderobj->partype==PARSKEL){ + KX_GameObject *par = converter->FindGameObject(blenderobj->parent); if (par) ((BL_SkinDeformer*)(((BL_DeformableGameObject*)obj)->m_pDeformer))->SetArmature((BL_ArmatureObject*) par); } @@ -2174,7 +2283,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, { meshobj = gameobj->GetMesh(0); } - BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter,processCompoundChildren); + int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0; + BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren); } processCompoundChildren = true; @@ -2189,7 +2299,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, { meshobj = gameobj->GetMesh(0); } - BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter,processCompoundChildren); + int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0; + BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren); } @@ -2311,29 +2422,32 @@ void BL_ConvertBlenderObjects(struct Main* maggie, { 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); + int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; + bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; + BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, layerMask,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); + int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; + bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; + BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,layerMask,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); + int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0; + bool isInActiveLayer = (blenderobj->lay & layerMask)!=0; + BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter); + // set the init state to all objects + gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state); } - // apply the initial state to controllers - for ( i=0;i<logicbrick_conversionlist->GetCount();i++) + // apply the initial state to controllers, only on the active objects as this registers the sensors + for ( i=0;i<objectlist->GetCount();i++) { - KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i)); - struct Object* blenderobj = converter->FindBlenderObject(gameobj); - gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state); + KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i)); gameobj->ResetState(); } @@ -2344,5 +2458,19 @@ void BL_ConvertBlenderObjects(struct Main* maggie, // Calculate the scene btree - // too slow - commented out. //kxscene->SetNodeTree(tf.MakeTree()); + + // instantiate dupli group, we will loop trough the object + // that are in active layers. Note that duplicating group + // has the effect of adding objects at the end of objectlist. + // Only loop through the first part of the list. + int objcount = objectlist->GetCount(); + for (i=0;i<objcount;i++) + { + KX_GameObject* gameobj = (KX_GameObject*) objectlist->GetValue(i); + if (gameobj->IsDupliGroup()) + { + kxscene->DupliGroupRecurse(gameobj, 0); + } + } } diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h index 57a404ad72b..315ad18c42c 100644 --- a/source/gameengine/Converter/BL_DeformableGameObject.h +++ b/source/gameengine/Converter/BL_DeformableGameObject.h @@ -60,6 +60,7 @@ public: { if (m_pDeformer) m_pDeformer->Relink (map); + KX_GameObject::Relink(map); }; void ProcessReplica(KX_GameObject* replica); diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp index 41bf565a4d8..7fb5d7ff829 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp +++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp @@ -442,15 +442,15 @@ PyMethodDef BL_ShapeActionActuator::Methods[] = { {"setProperty", (PyCFunction) BL_ShapeActionActuator::sPySetProperty, METH_VARARGS, SetProperty_doc}, {"setBlendtime", (PyCFunction) BL_ShapeActionActuator::sPySetBlendtime, METH_VARARGS, SetBlendtime_doc}, - {"getAction", (PyCFunction) BL_ShapeActionActuator::sPyGetAction, METH_VARARGS, GetAction_doc}, - {"getStart", (PyCFunction) BL_ShapeActionActuator::sPyGetStart, METH_VARARGS, GetStart_doc}, - {"getEnd", (PyCFunction) BL_ShapeActionActuator::sPyGetEnd, METH_VARARGS, GetEnd_doc}, - {"getBlendin", (PyCFunction) BL_ShapeActionActuator::sPyGetBlendin, METH_VARARGS, GetBlendin_doc}, - {"getPriority", (PyCFunction) BL_ShapeActionActuator::sPyGetPriority, METH_VARARGS, GetPriority_doc}, - {"getFrame", (PyCFunction) BL_ShapeActionActuator::sPyGetFrame, METH_VARARGS, GetFrame_doc}, - {"getProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc}, - {"getType", (PyCFunction) BL_ShapeActionActuator::sPyGetType, METH_VARARGS, GetType_doc}, - {"setType", (PyCFunction) BL_ShapeActionActuator::sPySetType, METH_VARARGS, SetType_doc}, + {"getAction", (PyCFunction) BL_ShapeActionActuator::sPyGetAction, METH_NOARGS, GetAction_doc}, + {"getStart", (PyCFunction) BL_ShapeActionActuator::sPyGetStart, METH_NOARGS, GetStart_doc}, + {"getEnd", (PyCFunction) BL_ShapeActionActuator::sPyGetEnd, METH_NOARGS, GetEnd_doc}, + {"getBlendin", (PyCFunction) BL_ShapeActionActuator::sPyGetBlendin, METH_NOARGS, GetBlendin_doc}, + {"getPriority", (PyCFunction) BL_ShapeActionActuator::sPyGetPriority, METH_NOARGS, GetPriority_doc}, + {"getFrame", (PyCFunction) BL_ShapeActionActuator::sPyGetFrame, METH_NOARGS, GetFrame_doc}, + {"getProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetProperty, METH_NOARGS, GetProperty_doc}, + {"getType", (PyCFunction) BL_ShapeActionActuator::sPyGetType, METH_NOARGS, GetType_doc}, + {"setType", (PyCFunction) BL_ShapeActionActuator::sPySetType, METH_NOARGS, SetType_doc}, {NULL,NULL} //Sentinel }; @@ -463,9 +463,7 @@ char BL_ShapeActionActuator::GetAction_doc[] = "getAction()\n" "\tReturns a string containing the name of the current action.\n"; -PyObject* BL_ShapeActionActuator::PyGetAction(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* BL_ShapeActionActuator::PyGetAction(PyObject* self) { PyObject *result; if (m_action){ @@ -484,9 +482,7 @@ char BL_ShapeActionActuator::GetProperty_doc[] = "getProperty()\n" "\tReturns the name of the property to be used in FromProp mode.\n"; -PyObject* BL_ShapeActionActuator::PyGetProperty(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* BL_ShapeActionActuator::PyGetProperty(PyObject* self) { PyObject *result; result = Py_BuildValue("s", (const char *)m_propname); @@ -499,9 +495,7 @@ char BL_ShapeActionActuator::GetFrame_doc[] = "getFrame()\n" "\tReturns the current frame number.\n"; -PyObject* BL_ShapeActionActuator::PyGetFrame(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* BL_ShapeActionActuator::PyGetFrame(PyObject* self) { PyObject *result; result = Py_BuildValue("f", m_localtime); @@ -514,9 +508,7 @@ char BL_ShapeActionActuator::GetEnd_doc[] = "getEnd()\n" "\tReturns the last frame of the action.\n"; -PyObject* BL_ShapeActionActuator::PyGetEnd(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* BL_ShapeActionActuator::PyGetEnd(PyObject* self) { PyObject *result; result = Py_BuildValue("f", m_endframe); @@ -529,9 +521,7 @@ char BL_ShapeActionActuator::GetStart_doc[] = "getStart()\n" "\tReturns the starting frame of the action.\n"; -PyObject* BL_ShapeActionActuator::PyGetStart(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* BL_ShapeActionActuator::PyGetStart(PyObject* self) { PyObject *result; result = Py_BuildValue("f", m_startframe); @@ -545,9 +535,7 @@ char BL_ShapeActionActuator::GetBlendin_doc[] = "\tReturns the number of interpolation animation frames to be\n" "\tgenerated when this actuator is triggered.\n"; -PyObject* BL_ShapeActionActuator::PyGetBlendin(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* BL_ShapeActionActuator::PyGetBlendin(PyObject* self) { PyObject *result; result = Py_BuildValue("f", m_blendin); @@ -561,9 +549,7 @@ char BL_ShapeActionActuator::GetPriority_doc[] = "\tReturns the priority for this actuator. Actuators with lower\n" "\tPriority numbers will override actuators with higher numbers.\n"; -PyObject* BL_ShapeActionActuator::PyGetPriority(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* BL_ShapeActionActuator::PyGetPriority(PyObject* self) { PyObject *result; result = Py_BuildValue("i", m_priority); @@ -605,6 +591,7 @@ PyObject* BL_ShapeActionActuator::PySetAction(PyObject* self, } } else { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } @@ -627,6 +614,7 @@ PyObject* BL_ShapeActionActuator::PySetStart(PyObject* self, m_startframe = start; } else { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } @@ -649,6 +637,7 @@ PyObject* BL_ShapeActionActuator::PySetEnd(PyObject* self, m_endframe = end; } else { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } @@ -672,6 +661,7 @@ PyObject* BL_ShapeActionActuator::PySetBlendin(PyObject* self, m_blendin = blendin; } else { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } @@ -700,6 +690,7 @@ PyObject* BL_ShapeActionActuator::PySetBlendtime(PyObject* self, m_blendframe = m_blendin; } else { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } @@ -724,6 +715,7 @@ PyObject* BL_ShapeActionActuator::PySetPriority(PyObject* self, m_priority = priority; } else { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } @@ -750,6 +742,7 @@ PyObject* BL_ShapeActionActuator::PySetFrame(PyObject* self, m_localtime=m_endframe; } else { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } @@ -773,6 +766,7 @@ PyObject* BL_ShapeActionActuator::PySetProperty(PyObject* self, m_propname = string; } else { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } @@ -784,9 +778,7 @@ PyObject* BL_ShapeActionActuator::PySetProperty(PyObject* self, char BL_ShapeActionActuator::GetType_doc[] = "getType()\n" "\tReturns the operation mode of the actuator.\n"; -PyObject* BL_ShapeActionActuator::PyGetType(PyObject* self, - PyObject* args, - PyObject* kwds) { +PyObject* BL_ShapeActionActuator::PyGetType(PyObject* self) { return Py_BuildValue("h", m_playtype); } @@ -801,6 +793,7 @@ PyObject* BL_ShapeActionActuator::PySetType(PyObject* self, short typeArg; if (!PyArg_ParseTuple(args, "h", &typeArg)) { + PyErr_SetString(PyExc_TypeError, "Invalid arguments"); return NULL; } diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index 434a62a1233..10cbe9f1ac3 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -1,5 +1,5 @@ /** - * $Id$ + * $Id:BL_ShapeActionActuator.h 15330 2008-06-23 16:37:51Z theeth $ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -87,15 +87,15 @@ public: KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetBlendtime); KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetChannel); - KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetAction); - KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetBlendin); - KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetPriority); - KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetStart); - KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetEnd); - KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetFrame); - KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetProperty); + KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetAction); + KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetBlendin); + KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetPriority); + KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetStart); + KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetEnd); + KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetFrame); + KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetProperty); // KX_PYMETHOD(BL_ActionActuator,GetChannel); - KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetType); + KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetType); KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetType); virtual PyObject* _getattr(const STR_String& attr); diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp index f2af0d9294e..d3fbb795b23 100644 --- a/source/gameengine/Converter/BL_ShapeDeformer.cpp +++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp @@ -109,6 +109,13 @@ bool BL_ShapeDeformer::ExecuteShapeDrivers(void) vector<IpoCurve*>::iterator it; void *poin; int type; + // the shape drivers use the bone matrix as input. Must + // update the matrix now + Object* par_arma = m_armobj->GetArmatureObject(); + m_armobj->ApplyPose(); + where_is_pose( par_arma ); + PoseApplied(true); + for (it=m_shapeDrivers.begin(); it!=m_shapeDrivers.end(); it++) { // no need to set a specific time: this curve has a driver IpoCurve *icu = *it; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index d3442fe5298..f96c40c098f 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -66,7 +66,8 @@ BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj, m_armobj(arma), m_lastArmaUpdate(-1), m_defbase(&bmeshobj->defbase), - m_releaseobject(false) + m_releaseobject(false), + m_poseApplied(false) { Mat4CpyMat4(m_obmat, bmeshobj->obmat); }; @@ -98,32 +99,28 @@ BL_SkinDeformer::~BL_SkinDeformer() m_armobj->Release(); } -bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *) +bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat) { size_t i, j; - if (!Update()) - // no need to update the cache - return false; + // update the vertex in m_transverts + Update(); - // Update all materials at once, so we can do the above update test - // without ending up with some materials not updated - for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial(); - mit != m_pMeshObject->GetLastMaterial(); ++ mit) { - RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial(); + // The vertex cache can only be updated for this deformer: + // Duplicated objects with more than one ploymaterial (=multiple mesh slot per object) + // share the same mesh (=the same cache). As the rendering is done per polymaterial + // cycling through the objects, the entire mesh cache cannot be updated in one shot. + vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); - vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat); + // For each array + for (i=0; i<vertexarrays.size(); i++) { + KX_VertexArray& vertexarray = (*vertexarrays[i]); - // For each array - for (i=0; i<vertexarrays.size(); i++) { - KX_VertexArray& vertexarray = (*vertexarrays[i]); - - // For each vertex - // copy the untransformed data from the original mvert - for (j=0; j<vertexarray.size(); j++) { - RAS_TexVert& v = vertexarray[j]; - v.SetXYZ(m_transverts[v.getOrigIndex()]); - } + // For each vertex + // copy the untransformed data from the original mvert + for (j=0; j<vertexarray.size(); j++) { + RAS_TexVert& v = vertexarray[j]; + v.SetXYZ(m_transverts[v.getOrigIndex()]); } } @@ -153,9 +150,11 @@ bool BL_SkinDeformer::Update(void) /* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */ /* but it requires the blender object pointer... */ - Object* par_arma = m_armobj->GetArmatureObject(); - where_is_pose( par_arma ); + if (!PoseApplied()){ + m_armobj->ApplyPose(); + where_is_pose( par_arma ); + } /* store verts locally */ VerifyStorage(); @@ -180,7 +179,8 @@ bool BL_SkinDeformer::Update(void) /* Update the current frame */ m_lastArmaUpdate=m_armobj->GetLastFrame(); - + /* reset for next frame */ + PoseApplied(false); /* indicate that the m_transverts and normals are up to date */ return true; } diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index f35db8273c4..d3fc5ae2a81 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -81,10 +81,13 @@ public: virtual ~BL_SkinDeformer(); bool Update (void); bool Apply (class RAS_IPolyMaterial *polymat); + bool PoseApplied() + { return m_poseApplied; } + void PoseApplied(bool applied) + { m_poseApplied = applied; } bool PoseUpdated(void) { if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()) { - m_armobj->ApplyPose(); return true; } return false; @@ -102,6 +105,7 @@ protected: ListBase* m_defbase; float m_obmat[4][4]; // the reference matrix for skeleton deform bool m_releaseobject; + bool m_poseApplied; }; diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 1cc1b2e27a3..53ac730d203 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -503,7 +503,7 @@ void BL_ConvertActuators(char* maggiename, case ACT_PROPERTY: { bPropertyActuator* propact = (bPropertyActuator*) bact->data; - CValue* destinationObj = NULL; + SCA_IObject* destinationObj = NULL; /* here the destinationobject is searched. problem with multiple scenes: other scenes @@ -628,6 +628,8 @@ void BL_ConvertActuators(char* maggiename, /* convert settings... degrees in the ui become radians */ /* internally */ if (conact->type == ACT_CONST_TYPE_ORI) { + min = (MT_2_PI * conact->minloc[0])/360.0; + max = (MT_2_PI * conact->maxloc[0])/360.0; switch (conact->mode) { case ACT_CONST_DIRPX: locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX; @@ -656,18 +658,18 @@ void BL_ConvertActuators(char* maggiename, min = conact->minloc[2]; max = conact->maxloc[2]; break; - case ACT_CONST_DIRMX: - locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMX; + case ACT_CONST_DIRNX: + locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNX; min = conact->minloc[0]; max = conact->maxloc[0]; break; - case ACT_CONST_DIRMY: - locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMY; + case ACT_CONST_DIRNY: + locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNY; min = conact->minloc[1]; max = conact->maxloc[1]; break; - case ACT_CONST_DIRMZ: - locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMZ; + case ACT_CONST_DIRNZ: + locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNZ; min = conact->minloc[2]; max = conact->maxloc[2]; break; diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index 7c9df688d45..5e433bb821b 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -733,9 +733,9 @@ void BL_ConvertSensors(struct Object* blenderobject, gameobj->AddSensor(gamesensor); // only register to manager if it's in an active layer - - if (isInActiveLayer) - gamesensor->RegisterToManager(); + // Make registration dynamic: only when sensor is activated + //if (isInActiveLayer) + // gamesensor->RegisterToManager(); for (int i=0;i<sens->totlinks;i++) diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp index 75ca59d01e7..7410beecaf4 100644 --- a/source/gameengine/Converter/KX_IpoConvert.cpp +++ b/source/gameengine/Converter/KX_IpoConvert.cpp @@ -36,6 +36,7 @@ #pragma warning (disable:4786) #endif +#include "BKE_material.h" /* give_current_material */ #include "KX_GameObject.h" #include "KX_IpoConvert.h" @@ -68,6 +69,8 @@ #include "SG_Node.h" +#include "STR_HashedString.h" + static BL_InterpolatorList *GetIpoList(struct Ipo *for_ipo, KX_BlenderSceneConverter *converter) { BL_InterpolatorList *ipoList= converter->FindInterpolatorList(for_ipo); @@ -560,16 +563,15 @@ void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *co } } - -void BL_ConvertMaterialIpos( - Material* blendermaterial, +static void ConvertMaterialIpos( + Material* blendermaterial, + dword matname_hash, KX_GameObject* gameobj, KX_BlenderSceneConverter *converter ) { if (blendermaterial->ipo) { - - KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController(); + KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); @@ -596,7 +598,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_COL_R); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -610,7 +612,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_COL_G); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -624,7 +626,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_COL_B); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -638,7 +640,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_ALPHA); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -653,7 +655,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_SPEC_R ); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -667,7 +669,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_SPEC_G); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -681,7 +683,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_SPEC_B); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -696,7 +698,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_HARD); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -710,7 +712,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_SPEC); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -725,7 +727,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_REF); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -739,7 +741,7 @@ void BL_ConvertMaterialIpos( ipo = ipoList->GetScalarInterpolator(MA_EMIT); if (ipo) { if (!ipocontr) { - ipocontr = new KX_MaterialIpoController(); + ipocontr = new KX_MaterialIpoController(matname_hash); gameobj->GetSGNode()->AddSGController(ipocontr); ipocontr->SetObject(gameobj->GetSGNode()); } @@ -752,3 +754,28 @@ void BL_ConvertMaterialIpos( } } +void BL_ConvertMaterialIpos( + struct Object* blenderobject, + KX_GameObject* gameobj, + KX_BlenderSceneConverter *converter + ) +{ + if (blenderobject->totcol==1) + { + Material *mat = give_current_material(blenderobject, 1); + // if there is only one material attached to the mesh then set material_index in BL_ConvertMaterialIpos to NULL + // --> this makes the UpdateMaterialData function in KX_GameObject.cpp use the old hack of using SetObjectColor + // because this yields a better performance as not all the vertex colors need to be edited + if(mat) ConvertMaterialIpos(mat, NULL, gameobj, converter); + } + else + { + for (int material_index=1; material_index <= blenderobject->totcol; material_index++) + { + Material *mat = give_current_material(blenderobject, material_index); + STR_HashedString matname = mat->id.name; + if(mat) ConvertMaterialIpos(mat, matname.hash(), gameobj, converter); + } + } +} + diff --git a/source/gameengine/Converter/KX_IpoConvert.h b/source/gameengine/Converter/KX_IpoConvert.h index afcb1b22821..4ec9bd31062 100644 --- a/source/gameengine/Converter/KX_IpoConvert.h +++ b/source/gameengine/Converter/KX_IpoConvert.h @@ -46,7 +46,7 @@ void BL_ConvertCameraIpos(struct Camera* blendercamera, class KX_GameObject* cameraobj, class KX_BlenderSceneConverter *converter); -void BL_ConvertMaterialIpos(struct Material* blendermaterial, +void BL_ConvertMaterialIpos(struct Object* blenderobject, class KX_GameObject* materialobj, class KX_BlenderSceneConverter *converter); |