diff options
Diffstat (limited to 'source/gameengine/Converter/BL_BlenderDataConversion.cpp')
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 183 |
1 files changed, 108 insertions, 75 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index d4b43cd7ac1..2c2fd052b5d 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -144,6 +144,8 @@ extern "C" { #include "BKE_cdderivedmesh.h" #include "BKE_DerivedMesh.h" #include "BKE_material.h" /* give_current_material */ +#include "BKE_image.h" +#include "IMB_imbuf_types.h" extern Material defmaterial; /* material.c */ } @@ -195,7 +197,7 @@ extern "C" { } #endif -static int default_face_mode = TF_DYNAMIC; +static bool default_light_mode = 0; static unsigned int KX_rgbaint2uint_new(unsigned int icol) { @@ -234,9 +236,9 @@ static unsigned int KX_Mcol2uint_new(MCol col) return out_color.integer; } -static void SetDefaultFaceType(Scene* scene) +static void SetDefaultLightMode(Scene* scene) { - default_face_mode = TF_DYNAMIC; + default_light_mode = false; Scene *sce_iter; Base *base; @@ -244,7 +246,7 @@ static void SetDefaultFaceType(Scene* scene) { if (base->object->type == OB_LAMP) { - default_face_mode = TF_DYNAMIC|TF_LIGHT; + default_light_mode = true; return; } } @@ -353,41 +355,41 @@ bool ConvertMaterial( // use lighting? material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT; + material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED; + // cast shadows? material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0; MTex *mttmp = 0; numchan = getNumTexChannels(mat); int valid_index = 0; - // use the face texture if - // 1) it is set in the buttons - // 2) we have a face texture and a material but no valid texture in slot 1 + /* In Multitexture use the face texture if and only if + * it is set in the buttons + * In GLSL is not working yet :/ 3.2011 */ bool facetex = false; if(validface && mat->mode &MA_FACETEXTURE) facetex = true; - if(validface && !mat->mtex[0]) - facetex = true; - if(validface && mat->mtex[0]) { - MTex *tmp = mat->mtex[0]; - if(!tmp->tex || (tmp->tex && !tmp->tex->ima)) - facetex = true; - } + numchan = numchan>MAXTEX?MAXTEX:numchan; + if (facetex && numchan == 0) numchan = 1; // foreach MTex for(int i=0; i<numchan; i++) { // use face tex if(i==0 && facetex ) { + facetex = false; 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->flag[i] |= MIPMAP; + material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ALPHA_SORT )?USEALPHA:0; + material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ALPHA )?USEALPHA:0; + material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ADD )?CALCALPHA:0; + if(material->img[i]->flag & IMA_REFLECT) material->mapping[i].mapping |= USEREFL; else @@ -405,11 +407,6 @@ bool ConvertMaterial( material->mapping[i].mapping |= USEUV; } - if(material->ras_mode & USE_LIGHT) - material->ras_mode &= ~USE_LIGHT; - if(tface->mode & TF_LIGHT) - material->ras_mode |= USE_LIGHT; - valid_index++; } else { @@ -567,25 +564,31 @@ bool ConvertMaterial( material->ras_mode |= (mat->material_type == MA_TYPE_WIRE)? WIRE: 0; } - else { + else { // No Material int valid = 0; // check for tface tex to fallback on if( validface ){ - - // no light bugfix - if(tface->mode) material->ras_mode |= USE_LIGHT; - material->img[0] = (Image*)(tface->tpage); // ------------------------ if(material->img[0]) { material->texname[0] = material->img[0]->id.name; material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0; - material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0; - material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0; + + /* see if depth of the image is 32bits */ + if(BKE_image_has_alpha(material->img[0])) { + material->flag[0] |= USEALPHA; + material->alphablend = GEMAT_ALPHA; + } + else + material->alphablend = GEMAT_SOLID; + valid++; } } + else + material->alphablend = GEMAT_SOLID; + material->SetUsers(-1); material->num_enabled = valid; material->IdMode = TEXFACE; @@ -598,6 +601,9 @@ bool ConvertMaterial( material->matcolor[2] = 0.5f; material->spec_f = 0.5f; material->ref = 0.8f; + + // No material - old default TexFace properties + material->ras_mode |= USE_LIGHT; } MT_Point2 uv[4]; MT_Point2 uv2[4]; @@ -606,13 +612,10 @@ bool ConvertMaterial( 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( validface ) { - - material->ras_mode |= (tface->mode & TF_INVISIBLE)?0:POLY_VIS; - - material->transp = tface->transp; material->tile = tface->tile; - material->mode = tface->mode; uv[0].setValue(tface->uv[0]); uv[1].setValue(tface->uv[1]); @@ -625,31 +628,26 @@ bool ConvertMaterial( } else { // nothing at all - material->ras_mode |= (POLY_VIS| (validmat?0:USE_LIGHT)); - material->mode = default_face_mode; - material->transp = TF_SOLID; + material->alphablend = GEMAT_SOLID; material->tile = 0; uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f); } + if (validmat && validface) { + material->alphablend = mat->game.alpha_blend; + } + // with ztransp enabled, enforce alpha blending mode - if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->transp == TF_SOLID)) - material->transp = TF_ALPHA; + if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->alphablend == GEMAT_SOLID)) + material->alphablend = GEMAT_ALPHA; // always zsort alpha + add - if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) && (material->transp != TF_CLIP)) { + if((ELEM3(material->alphablend, GEMAT_ALPHA, GEMAT_ALPHA_SORT, GEMAT_ADD) || texalpha) && (material->alphablend != GEMAT_CLIP )) { material->ras_mode |= ALPHA; - material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0; + material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0; } - // collider or not? - material->ras_mode |= (material->mode & TF_DYNAMIC)? COLLIDER: 0; - - // these flags are irrelevant at this point, remove so they - // don't hurt material bucketing - material->mode &= ~(TF_DYNAMIC|TF_ALPHASORT|TF_TEX); - // get uv sets if(validmat) { @@ -706,8 +704,8 @@ bool ConvertMaterial( unsigned int rgb[4]; GetRGB(type,mface,mmcol,mat,rgb[0],rgb[1],rgb[2], rgb[3]); - // swap the material color, so MCol on TF_BMFONT works - if (validmat && type==1 && (tface && tface->mode & TF_BMFONT)) + // swap the material color, so MCol on bitmap font works + if (validmat && type==1 && (mat->game.flag & GEMAT_TEXT)) { rgb[0] = KX_rgbaint2uint_new(rgb[0]); rgb[1] = KX_rgbaint2uint_new(rgb[1]); @@ -864,10 +862,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, layers, converter->GetGLSLMaterials()); - visible = ((bl_mat->ras_mode & POLY_VIS)!=0); - collider = ((bl_mat->ras_mode & COLLIDER)!=0); - twoside = ((bl_mat->mode & TF_TWOSIDE)!=0); - /* vertex colors and uv's were stored in bl_mat temporarily */ bl_mat->GetConversionRGB(rgb); rgb0 = rgb[0]; rgb1 = rgb[1]; @@ -885,7 +879,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, if (kx_blmat == NULL) kx_blmat = new KX_BlenderMaterial(); - kx_blmat->Initialize(scene, bl_mat); + kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL)); polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat); } else { @@ -893,37 +887,59 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, Image* bima = (tface)? (Image*)tface->tpage: NULL; imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; - char transp=0; - short mode=0, tile=0; + char alpha_blend=0; + short tile=0; int tilexrep=4,tileyrep = 4; - + + /* set material properties - old TexFace */ + if (ma) { + alpha_blend = ma->game.alpha_blend; + /* Commented out for now. If we ever get rid of + * "Texture Face/Singletexture" we can then think about it */ + + /* Texture Face mode ignores texture but requires "Face Textures to be True "*/ + /** + if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) { + bima = NULL; + imastr = ""; + alpha_blend = GEMAT_SOLID; + } + else + alpha_blend = ma->game.alpha_blend; + */ + } + /* check for tface tex to fallback on */ + else { + if (bima) { + /* see if depth of the image is 32 */ + if (BKE_image_has_alpha(bima)) + alpha_blend = GEMAT_ALPHA; + else + alpha_blend = GEMAT_SOLID; + } + else { + alpha_blend = GEMAT_SOLID; + } + } + if (bima) { tilexrep = bima->xrep; tileyrep = bima->yrep; } - /* get tface properties if available */ + /* set UV properties */ 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; - - visible = !(tface->mode & TF_INVISIBLE); - twoside = ((tface->mode & TF_TWOSIDE)!=0); - uv0.setValue(tface->uv[0]); uv1.setValue(tface->uv[1]); uv2.setValue(tface->uv[2]); if (mface->v4) uv3.setValue(tface->uv[3]); + + tile = tface->tile; } else { - /* no texfaces, set COLLSION true and everything else FALSE */ - mode = default_face_mode; - transp = TF_SOLID; + /* no texfaces */ tile = 0; } @@ -964,16 +980,20 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, if (mface->v4) rgb3 = KX_rgbaint2uint_new(color); } - + // only zsort alpha + add - bool alpha = (transp == TF_ALPHA || transp == TF_ADD); - bool zsort = (mode & TF_ALPHASORT)? alpha: 0; + bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT); + bool zsort = (alpha_blend == GEMAT_ALPHA_SORT); + bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode; + + // don't need zort anymore, deal as if it it's alpha blend + if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA; if (kx_polymat == NULL) kx_polymat = new KX_PolygonMaterial(); kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr, tile, tilexrep, tileyrep, - mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol); + alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol); polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat); if (ma) { @@ -987,6 +1007,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, } } + // set render flags + if (ma) + { + visible = ((ma->game.flag & GEMAT_INVISIBLE)==0); + twoside = ((ma->game.flag & GEMAT_BACKCULL)==0); + collider = ((ma->game.flag & GEMAT_NOPHYSICS)==0); + } + else{ + visible = true; + twoside = false; + collider = true; + } + /* mark face as flat, so vertices are split */ bool flat = (mface->flag & ME_SMOOTH) == 0; @@ -2035,7 +2068,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, logicmgr->RegisterActionName(curAct->id.name + 2, curAct); } - SetDefaultFaceType(blenderscene); + SetDefaultLightMode(blenderscene); // Let's support scene set. // Beware of name conflict in linked data, it will not crash but will create confusion // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have |