void Exporter::DumpMaterial(MaxMaterial *maxm,Mtl* mtl, int mtlID, int subNo, int indentLevel) { int i; TimeValue t = GetStaticFrame(); if (!mtl) return; // for(i=0;i<indentLevel;i++) { log(" "); } // log("material %s adding. type : ",mtl->GetName()); // We know the Standard material, so we can get some extra info if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { // top level & standard material // log("standard \n"); StdMat* std = (StdMat*)mtl; MaxStdMaterial *stdm=new MaxStdMaterial; strcpy(stdm->name,mtl->GetName()); stdm->Ambient=rvector(std->GetAmbient(t)); stdm->Ambient.x=-stdm->Ambient.x; stdm->Diffuse=rvector(std->GetDiffuse(t)); stdm->Diffuse.x=-stdm->Diffuse.x; stdm->Specular=rvector(std->GetSpecular(t)); stdm->Specular.x=-stdm->Specular.x; // 축의 바뀜때문에 만들어 놓은.. 으흑.. stdm->TwoSide=std->GetTwoSided(); if(std->GetTransparencyType()==TRANSP_ADDITIVE) stdm->ShadeMode=RSSHADEMODE_ADD; else stdm->ShadeMode=RSSHADEMODE_NORMAL; if(rsm->MaxStdMaterialList.GetByName(stdm->name)==-1) // 이미 있는 standard material 이면 더하지 않음. { rsm->MaxStdMaterialList.Add(stdm); stdm->RMLIndex=rsm->MaxStdMaterialList.GetCount()-1; for (i=0; i<mtl->NumSubTexmaps(); i++) { Texmap* subTex = mtl->GetSubTexmap(i); float amt = 1.0f; if (subTex) { // If it is a standard material we can see if the map is enabled. if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { if (!((StdMat*)mtl)->MapEnabled(i)) continue; amt = ((StdMat*)mtl)->GetTexmapAmt(i, 0); } DumpTexture(stdm, subTex, mtl->ClassID(), i, amt, indentLevel+1); } } } else { delete stdm; } maxm->nSubMaterial=1; maxm->SubMaterials=new int[1]; maxm->SubMaterials[0]=rsm->MaxStdMaterialList.GetByName(mtl->GetName()); } if (mtl->NumSubMtls() > 0) { // log("multi/sub ( count : %d )\n",mtl->NumSubMtls()); maxm->nSubMaterial=mtl->NumSubMtls(); maxm->SubMaterials=new int[maxm->nSubMaterial]; maxm->pSubMaterials=new MaxMaterial*[maxm->nSubMaterial]; for (i=0; i<mtl->NumSubMtls(); i++) { Mtl* subMtl = mtl->GetSubMtl(i); if (subMtl) { maxm->pSubMaterials[i]=new MaxMaterial; DumpMaterial(maxm->pSubMaterials[i],subMtl, 0, i, indentLevel+1); if(subMtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { maxm->SubMaterials[i]= rsm->MaxStdMaterialList.GetByName(subMtl->GetName()); } else maxm->SubMaterials[i]= maxm->pSubMaterials[i]->SubMaterials[0]; } else { maxm->pSubMaterials[i]=NULL; maxm->SubMaterials[i]=-1; } } } }
void AWDExporter::ExportMaterial( AWD *awd, awd_ncache *ncache, Mtl* mtl, int mtlID, int subNo) { TimeValue t = GetStaticFrame(); int i; BOOL usediffusemap = FALSE; const char *name = mtl->GetName(); int namelen = strlen( name ); AWDMaterial *material = new AWDMaterial( AWD_MATTYPE_COLOR, name, namelen ); AWDTexture *tex; for (i=0; i<mtl->NumSubTexmaps(); i++) { Texmap* subTex = mtl->GetSubTexmap(i); float amt = 1.0f; if (subTex) { // If it is a standard material we can see if the map is enabled. if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { if (!((StdMat*)mtl)->MapEnabled(i)) continue; amt = ((StdMat*)mtl)->GetTexmapAmt(i, 0); } tex = ExportTexture(awd, ncache, subTex, mtl->ClassID(), i, material ); if( tex && i == ID_DI ) { usediffusemap = true; } } } if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { StdMat* std = (StdMat*)mtl; material->color = get_awd_color( std->GetDiffuse(t), 1.0f ); } else { material->color = get_awd_color( mtl->GetDiffuse(), 1.0f ); } AWD_mat_type mattype; if( usediffusemap ) mattype = AWD_MATTYPE_BITMAP; else mattype = AWD_MATTYPE_COLOR; material->set_type( mattype ); awd_ncache_add(ncache, (InterfaceServer*)mtl, material); awd->add_material( material ); if (mtl->NumSubMtls() > 0) { for (i=0; i<mtl->NumSubMtls(); i++) { Mtl* subMtl = mtl->GetSubMtl(i); if (subMtl && mtlList.GetMtlID( subMtl ) == -1 ) { ExportMaterial(awd, ncache, subMtl, 0, i); } } } }
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; }
//---------------------------------------------------------------------------------- void DumpMaterial(IGameMaterial *pGMaxMat) { m_material *pMat = NULL; if (!pGMaxMat->IsMultiType()) // check not a mix material { pMat = new m_material; // set the name of the material... pMat->name = pGMaxMat->GetMaterialName(); // add the new material to the TOC(Table Of Contants) and set its id... pMat->id = ExporterMAX::GetExporter()->AddMaterial(pGMaxMat, pMat); Mtl *pMaxMaterial = pGMaxMat->GetMaxMaterial(); if (pMaxMaterial->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { StdMat *pStandardMaterial = (StdMat*)pMaxMaterial; Color col; // diffuse color... col = pStandardMaterial->GetDiffuse(ExporterMAX::GetExporter()->GetStaticFrame()); pMat->diffuse = Vector4f(col.r, col.g, col.b, 1.f); // ambient color... col = pStandardMaterial->GetAmbient(ExporterMAX::GetExporter()->GetStaticFrame()); pMat->ambient = Vector4f(col.r, col.g, col.b, 1.f); // specular color... col = pStandardMaterial->GetSpecular(ExporterMAX::GetExporter()->GetStaticFrame()); pMat->specular = Vector4f(col.r, col.g, col.b, 1.f); // emissive color... pMat->emission = Vector4f(0.f, 0.f, 0.f, 1.f); // level of transparency pMat->transparent = pStandardMaterial->GetOpacity(ExporterMAX::GetExporter()->GetStaticFrame()); // specular exponent... pMat->shininess = pStandardMaterial->GetShininess(ExporterMAX::GetExporter()->GetStaticFrame()); // transparency if (pMat->transparent < 1.f){ pMat->diffuse.z = pMat->transparent; } }// 3dsmax6 HLSL Material support. (IDxMaterial) else if (IsDynamicDxMaterial((MtlBase*)pMaxMaterial)) { IDxMaterial *idxm = (IDxMaterial*)pMaxMaterial->GetInterface(IDXMATERIAL_INTERFACE); int lightParams = idxm->GetNumberOfLightParams(); for (int i = 0; i < lightParams; ++i) { INode *pNode = idxm->GetLightNode(i); if (pNode){ TCHAR *paramName = idxm->GetLightParameterName(i); } } // Other attributes are located in paramblk 0... IParamBlock2 *pParamBlk2 = (IParamBlock2*)(pMaxMaterial->GetParamBlock(0)); TimeValue t0 = ExporterMAX::GetExporter()->GetIGame()->GetSceneStartTime(); TimeValue t1 = ExporterMAX::GetExporter()->GetIGame()->GetSceneEndTime(); TimeValue DeltaTime = ExporterMAX::GetExporter()->GetIGame()->GetSceneTicks(); const int SamplingRate = 1; int numkeys = (t1 - t0) / (DeltaTime * SamplingRate) + 1; for (int i = 0; i < pParamBlk2->NumParams(); ++i) { ParamID id = pParamBlk2->IndextoID(i); ParamDef paramDef = pParamBlk2->GetParamDef(id); // we want the variable name not the UI Name... OutputDebugString(paramDef.int_name); } } //do the textures if they are there DumpTexture(pMat, pGMaxMat); } }