P(GmMaterial) GmUtil::createGmMaterial( Mtl* material, Mtl* bakedmaterial ) { require( material ); P(GmMaterial) s = new GmMaterial; // get name static int unnamedCount = 0; if ( material->GetName().data() ) s->name = material->GetName().data(); else s->name = "noname #"+String::valueOf( ++unnamedCount ); // Standard material (+Diffuse) (+ Reflection) if ( material->ClassID() == Class_ID(DMTL_CLASS_ID,0) ) { StdMat* stdmat = static_cast<StdMat*>(material); StdMat* bakedmat = static_cast<StdMat*>(bakedmaterial); // StdMat2? StdMat2* stdmat2 = 0; if ( stdmat->SupportsShaders() ) stdmat2 = static_cast<StdMat2*>( stdmat ); // uniform transparency s->opacity = stdmat->GetOpacity(0); // self illumination s->selfIllum = stdmat->GetSelfIllum(0); // two-sided material? s->twosided = ( 0 != stdmat->GetTwoSided() ); // blending mode s->blend = GmMaterial::BLEND_COPY; if ( s->opacity < 1.f ) s->blend = GmMaterial::BLEND_MULTIPLY; if ( stdmat->GetTransparencyType() == TRANSP_ADDITIVE ) s->blend = GmMaterial::BLEND_ADD; // diffuse color s->diffuseColor = toColorf( stdmat->GetDiffuse(0) ); // specular highlights float shinStr = stdmat->GetShinStr(0); s->specular = (shinStr > 0.f); if ( s->specular ) { float shininess = stdmat->GetShininess(0); s->specularExponent = Math::pow( 2.f, shininess*10.f + 2.f ); s->specularColor = toColorf( stdmat->GetSpecular(0) ) * shinStr; } if ( bakedmat ) { shinStr = bakedmat->GetShinStr(0); s->specular = (shinStr > 0.f); if ( s->specular ) { float shininess = bakedmat->GetShininess(0); s->specularExponent = Math::pow( 2.f, shininess*10.f + 2.f ); s->specularColor = toColorf( bakedmat->GetSpecular(0) ) * shinStr; } } // diffuse texture layer BitmapTex* tex = SceneExportUtil::getStdMatBitmapTex( stdmat, ID_DI ); if ( tex ) { GmMaterial::TextureLayer& layer = s->diffuseLayer; setLayerTex( layer, tex, s->name ); } // opacity texture layer tex = SceneExportUtil::getStdMatBitmapTex( stdmat, ID_OP ); if ( tex ) { GmMaterial::TextureLayer& layer = s->opacityLayer; setLayerTex( layer, tex, s->name ); // check alpha channel validity Bitmap* bmp = tex->GetBitmap(0); if ( bmp && !bmp->HasAlpha() ) Debug::printlnError( "Material \"{0}\" opacity map \"{1}\" must have image alpha channel.", s->name, tex->GetMapName() ); //throw IOException( Format("Material \"{0}\" opacity map \"{1}\" must have image alpha channel.", s->name, tex->GetMapName()) ); s->blend = GmMaterial::BLEND_MULTIPLY; // check that opacity map is the same as diffuse map if ( s->opacityLayer.filename != s->diffuseLayer.filename ) throw IOException( Format("Material \"{0}\" diffuse bitmap needs to be the same in opacity map.(diffuse map is \"{1}\" and opacity map is \"{2}\")", s->name, s->diffuseLayer.filename, s->opacityLayer.filename) ); if ( s->opacityLayer.coordset != s->diffuseLayer.coordset ) throw IOException( Format("Material \"{0}\" diffuse map texture coordinate set needs to be the same in opacity map.", s->name) ); if ( s->opacityLayer.env != s->diffuseLayer.env ) throw IOException( Format("Material \"{0}\" diffuse map texture coordinate generator needs to be the same in opacity map.", s->name) ); } // reflection texture layer tex = SceneExportUtil::getStdMatBitmapTex( stdmat, ID_RL ); if ( tex ) { GmMaterial::TextureLayer& layer = s->reflectionLayer; setLayerTex( layer, tex, s->name ); } // glossiness (shininess strength, SS) texture layer tex = SceneExportUtil::getStdMatBitmapTex( stdmat, ID_SS ); if ( tex ) { GmMaterial::TextureLayer& layer = s->glossinessLayer; setLayerTex( layer, tex, s->name ); // check alpha channel validity Bitmap* bmp = tex->GetBitmap(0); //if ( bmp && !bmp->HasAlpha() ) // throw IOException( Format("Material \"{0}\" glossiness map \"{1}\" must have image alpha channel.", s->name, tex->GetMapName()) ); if ( bmp && !bmp->HasAlpha() ) Debug::printlnError("Material \"{0}\" glossiness map \"{1}\" must have image alpha channel.", s->name, tex->GetMapName() ); // check that glossiness map is the same as diffuse map if ( s->glossinessLayer.filename != s->diffuseLayer.filename ) throw IOException( Format("Material \"{0}\" diffuse bitmap needs to be the same in glossiness map.(diffuse map is \"{1}\" and glossiness map is \"{2}\")", s->name, s->diffuseLayer.filename, s->glossinessLayer.filename) ); if ( s->glossinessLayer.coordset != s->diffuseLayer.coordset ) throw IOException( Format("Material \"{0}\" diffuse map texture coordinate set needs to be the same in glossiness map.", s->name) ); if ( s->glossinessLayer.env != s->diffuseLayer.env ) throw IOException( Format("Material \"{0}\" diffuse map texture coordinate generator needs to be the same in glossiness map.", s->name) ); // check that reflection map has been set if ( s->reflectionLayer.filename.length() == 0 ) throw IOException( Format("Material \"{0}\" glossiness map requires reflection map to be set.", s->name) ); } // bump texture layer tex = SceneExportUtil::getStdMatBitmapTex( stdmat, ID_BU ); if ( tex ) { GmMaterial::TextureLayer& layer = s->bumpLayer; setLayerTex( layer, tex, s->name ); } // specular color texture layer tex = SceneExportUtil::getStdMatBitmapTex( stdmat, ID_SP ); if ( tex ) { GmMaterial::TextureLayer& layer = s->specularColorLayer; setLayerTex( layer, tex, s->name ); } // specular level texture layer tex = SceneExportUtil::getStdMatBitmapTex( stdmat, ID_SH ); if ( tex ) { GmMaterial::TextureLayer& layer = s->specularLevelLayer; setLayerTex( layer, tex, s->name ); } // lightmap texture layer ( from self-illumination map of baked material ) tex = SceneExportUtil::getStdMatBitmapTex( stdmat, ID_SI ); BitmapTex* tex2 = 0; if ( bakedmat ) tex2 = SceneExportUtil::getStdMatBitmapTex( bakedmat, ID_SI ); if ( tex || tex2 ) { GmMaterial::TextureLayer& layer = s->lightMapLayer; if ( tex && !tex2 ) setLayerTex( layer, tex, s->name ); else if ( tex2 ) setLayerTex( layer, tex2, s->name ); } } return s; }