From 83de5cb30831328548502126dff84ffdb72544f2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 11 Nov 2012 01:54:30 +0000 Subject: [PATCH] bge mesh conversion speedup, avoid calling ConvertMaterial() on every face. now do per material bucket. --- .../Converter/BL_BlenderDataConversion.cpp | 139 ++++++++++-------- source/gameengine/Ketsji/BL_Material.cpp | 34 +---- source/gameengine/Ketsji/BL_Material.h | 10 +- .../gameengine/Ketsji/KX_BlenderMaterial.cpp | 2 +- source/gameengine/Ketsji/KX_BlenderMaterial.h | 2 +- 5 files changed, 86 insertions(+), 101 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index b5ff11007de..eb695e624e4 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -480,6 +480,45 @@ typedef struct MTF_localLayer { const char *name; } MTF_localLayer; +static void tface_to_uv_bge(const MFace *mface, const MTFace *tface, MT_Point2 uv[4]) +{ + uv[0].setValue(tface->uv[0]); + uv[1].setValue(tface->uv[1]); + uv[2].setValue(tface->uv[2]); + if (mface->v4) { + uv[3].setValue(tface->uv[3]); + } +} + +static void GetUV( + MFace *mface, + MTFace *tface, + MTF_localLayer *layers, + const int layer_uv[2], + MT_Point2 uv[4], + MT_Point2 uv2[4]) +{ + bool validface = (tface != NULL); + + uv2[0] = uv2[1] = uv2[2] = uv2[3] = MT_Point2(0.0f, 0.0f); + + /* No material, what to do? let's see what is in the UV and set the material accordingly + * light and visible is always on */ + if (layer_uv[0] != -1) { + tface_to_uv_bge(mface, layers[layer_uv[0]].face, uv); + if (layer_uv[1] != -1) { + tface_to_uv_bge(mface, layers[layer_uv[1]].face, uv2); + } + } + else if (validface) { + tface_to_uv_bge(mface, tface, uv); + } + else { + // nothing at all + uv[0] = uv[1] = uv[2] = uv[3] = MT_Point2(0.0f, 0.0f); + } +} + // ------------------------------------ static bool ConvertMaterial( BL_Material *material, @@ -489,6 +528,7 @@ static bool ConvertMaterial( MFace* mface, MCol* mmcol, /* only for text, use first mcol, weak */ MTF_localLayer *layers, + int layer_uv[2], const bool glslmat) { material->Initialize(); @@ -500,6 +540,9 @@ static bool ConvertMaterial( material->glslmat = (validmat)? glslmat: false; material->materialindex = mface->mat_nr; + /* default value for being unset */ + layer_uv[0] = layer_uv[1] = -1; + // -------------------------------- if (validmat) { // use lighting? @@ -754,33 +797,19 @@ static bool ConvertMaterial( // No material - old default TexFace properties material->ras_mode |= USE_LIGHT; } - MT_Point2 uv[4]; - MT_Point2 uv2[4]; - const char *uvName = "", *uv2Name = ""; - - uv2[0] = uv2[1] = uv2[2] = uv2[3] = MT_Point2(0.0f, 0.0f); + const char *uvName = "", *uv2Name = ""; /* No material, what to do? let's see what is in the UV and set the material accordingly * light and visible is always on */ if ( validface ) { material->tile = tface->tile; - - uv[0].setValue(tface->uv[0]); - uv[1].setValue(tface->uv[1]); - uv[2].setValue(tface->uv[2]); - - if (mface->v4) - uv[3].setValue(tface->uv[3]); - uvName = tfaceName; } else { // nothing at all material->alphablend = GEMAT_SOLID; material->tile = 0; - - uv[0] = uv[1] = uv[2] = uv[3] = MT_Point2(0.0f, 0.0f); } if (validmat && validface) { @@ -798,49 +827,30 @@ static bool ConvertMaterial( } // get uv sets - if (validmat) - { + if (validmat) { bool isFirstSet = true; // only two sets implemented, but any of the eight // sets can make up the two layers - for (int vind = 0; vindnum_enabled; vind++) - { + for (int vind = 0; vindnum_enabled; vind++) { BL_Mapping &map = material->mapping[vind]; - if (map.uvCoName.IsEmpty()) + if (map.uvCoName.IsEmpty()) { isFirstSet = false; - else - { - for (int lay=0; layuv[0]); - uvSet[1].setValue(layer.face->uv[1]); - uvSet[2].setValue(layer.face->uv[2]); - - if (mface->v4) - uvSet[3].setValue(layer.face->uv[3]); - else - uvSet[3].setValue(0.0f, 0.0f); - - if (isFirstSet) - { - uv[0] = uvSet[0]; uv[1] = uvSet[1]; - uv[2] = uvSet[2]; uv[3] = uvSet[3]; + if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0) { + if (isFirstSet) { + layer_uv[0] = lay; isFirstSet = false; uvName = layer.name; } - else if (strcmp(layer.name, uvName) != 0) - { - uv2[0] = uvSet[0]; uv2[1] = uvSet[1]; - uv2[2] = uvSet[2]; uv2[3] = uvSet[3]; + else if (strcmp(layer.name, uvName) != 0) { + layer_uv[1] = lay; map.mapping |= USECUSTOMUV; uv2Name = layer.name; } @@ -853,8 +863,8 @@ static bool ConvertMaterial( if (validmat && mmcol) { /* color is only for text */ material->m_mcol = *(unsigned int *)mmcol; } - material->SetConversionUV(uvName, uv); - material->SetConversionUV2(uv2Name, uv2); + material->SetUVLayerName(uvName); + material->SetUVLayerName2(uv2Name); if (validmat) material->matname =(mat->id.name); @@ -900,6 +910,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, // Extract avaiable layers MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE]; + int layer_uv[2]; /* store uv1, uv2 layers */ for (int lay=0; layGetMaterials()) { + const bool is_bl_mat_new = (bl_mat == NULL); + //const bool is_kx_blmat_new = (kx_blmat == NULL); const bool glslmat = converter->GetGLSLMaterials(); const bool use_mcol = ma ? (ma->mode & MA_VERTEXCOLP || glslmat) : true; /* do Blender Multitexture and Blender GLSL materials */ - MT_Point2 uv[4]; + MT_Point2 uv_1[4]; + MT_Point2 uv_2[4]; /* first is the BL_Material */ - if (!bl_mat) + if (!bl_mat) { bl_mat = new BL_Material(); - ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, - layers, glslmat); + } - /* vertex colors and uv's were stored in bl_mat temporarily */ + /* only */ + if (is_bl_mat_new || (bl_mat->material != ma)) { + ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, + layers, layer_uv, glslmat); + } + + /* vertex colors and uv's from the faces */ GetRGB(use_mcol, mface, mcol, ma, rgb0, rgb1, rgb2, rgb3); + GetUV(mface, tface, layers, layer_uv, uv_1, uv_2); - bl_mat->GetConversionUV(uv); - uv0 = uv[0]; uv1 = uv[1]; - uv2 = uv[2]; uv3 = uv[3]; + uv0 = uv_1[0]; uv1 = uv_1[1]; + uv2 = uv_1[2]; uv3 = uv_1[3]; - bl_mat->GetConversionUV2(uv); - uv20 = uv[0]; uv21 = uv[1]; - uv22 = uv[2]; uv23 = uv[3]; + uv20 = uv_2[0]; uv21 = uv_2[1]; + uv22 = uv_2[2]; uv23 = uv_2[3]; /* then the KX_BlenderMaterial */ if (kx_blmat == NULL) kx_blmat = new KX_BlenderMaterial(); - kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL)); + //if (is_kx_blmat_new || !kx_blmat->IsMaterial(bl_mat)) { + kx_blmat->Initialize(scene, bl_mat, (ma ? &ma->game : NULL)); + //} + polymat = static_cast(kx_blmat); } else { diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index a7d89517a08..0954aa0f7ab 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -63,11 +63,6 @@ void BL_Material::Initialize() share = false; int i; - for (i=0; i<4; i++) - { - uv[i] = MT_Point2(0.f,1.f); - uv2[i] = MT_Point2(0.f, 1.f); - } for (i=0; i 1 ) diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index 082e265f387..ef180ed2126 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -89,17 +89,11 @@ public: EnvMap* cubemap[MAXTEX]; unsigned int m_mcol; /* for text color (only) */ - MT_Point2 uv[4]; - MT_Point2 uv2[4]; - STR_String uvName; STR_String uv2Name; - void SetConversionUV(const STR_String& name, MT_Point2 *uv); - void GetConversionUV(MT_Point2 *uv); - - void SetConversionUV2(const STR_String& name, MT_Point2 *uv); - void GetConversionUV2(MT_Point2 *uv); + void SetUVLayerName(const STR_String &name); + void SetUVLayerName2(const STR_String &name); void SetSharedMaterial(bool v); bool IsShared(); diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index cb995c3f738..88e26fd9a55 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -138,7 +138,7 @@ void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const RAS_IPolyMaterial::GetMaterialRGBAColor(rgba); } -bool KX_BlenderMaterial::IsMaterial(BL_Material *bl_mat) const +bool KX_BlenderMaterial::IsMaterial(const BL_Material *bl_mat) const { return (mMaterial == bl_mat); } diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index c38eb2a6fd0..7bc9c7c3863 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -77,7 +77,7 @@ public: )const; /* mMaterial is private, but need this for conversion */ - bool IsMaterial(BL_Material *bl_mat) const; + bool IsMaterial(const BL_Material *bl_mat) const; Material* GetBlenderMaterial() const; MTFace* GetMTFace(void) const; unsigned int* GetMCol(void) const;