예제 #1
0
bool sMaterial::ConvertMTL(Mtl *mtl)
{
	char filename[64];
	char file_ext[16];
	char filename_with_ext[128];

	m_EmissiveColor = mtl->GetSelfIllumColor();
	m_AmbientColor = mtl->GetAmbient();
	m_DiffuseColor = mtl->GetDiffuse();
	m_SpecularColor = mtl->GetSpecular();
	m_fShininess = mtl->GetShininess();

	m_iNumTextures = 0;

	m_BlendMode = "replace";

	if ( mtl->ClassID()==Class_ID(DMTL_CLASS_ID, 0) ) 
	{
		StdMat* std = (StdMat*)mtl;

		float fOpacity = std->GetOpacity(0);
		if ( fOpacity < 1.0f )
		{
			switch (std->GetTransparencyType()) 
			{
			case TRANSP_FILTER: 
				m_BlendMode = "blend";
				break;
			case TRANSP_SUBTRACTIVE: 
				m_BlendMode = "subtract";
				break;
			case TRANSP_ADDITIVE: 
				m_BlendMode = "add";
				break;
			default: 
				m_BlendMode = "replace";
				break;
			}	
		}

		m_bCullFace = !std->GetTwoSided();
	}

	for (int i=0; i<mtl->NumSubTexmaps(); i++) 
	{
		Texmap *tex = mtl->GetSubTexmap(i);
		if ( tex && tex->ClassID() == Class_ID(BMTEX_CLASS_ID, 0x00) ) 
		{
			bool valid_channel = false;
			int texture_type = -1;

			switch(i)
			{
			case 0: // ambientmap/lightmap
				texture_type = TEXTURE_LIGHTMAP;
				break;
			case 1: // diffusemap
				texture_type = TEXTURE_DIFFUSE;
				break;
			case 9: // environment
				texture_type = TEXTURE_ENVIRONMENT;
				break;
			default:
				// not supported by fixed pipeline 3D rendering
				break;
			}

			if ( texture_type >= 0 )
			{
				TSTR mapName = ((BitmapTex *)tex)->GetMapName();
				_splitpath(mapName, NULL, NULL, filename, file_ext);
				sprintf(filename_with_ext, "%s%s", filename, file_ext);
				m_Textures[texture_type] = filename_with_ext;
				m_MapChannel[texture_type] = tex->GetMapChannel()-1;
			}
		}
	}

	return true;
}
예제 #2
0
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;
			}
		}
	}
}
예제 #3
0
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;
}