using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace Nxr.Internal
{
public class ObjMaterial : MonoBehaviour
{
///
/// 全局变量
///
private Texture2D globalTexture;
///
/// 材质名称列表
///
private ArrayList materialNames;
///
/// 漫反射颜色列表
///
private List diffuseColors;
///
/// 漫反射贴图列表
///
private ArrayList diffuseTextures;
///
/// 当前实例
///
private static ObjMaterial instance;
public static ObjMaterial Instance
{
get
{
if (instance == null)
instance = GameObject.FindObjectOfType();
if (instance == null)
instance = new GameObject("ObjMatrial").AddComponent();
return instance;
}
}
void Awake()
{
this.diffuseColors = new List();
this.diffuseTextures = new ArrayList();
this.materialNames = new ArrayList();
}
///
/// 从一个文本化后的mtl文件加载一组材质
///
/// 文本化的mtl文件
/// 贴图文件夹路径
public Material[] LoadFormMtl(string mtlText, string texturePath, byte[] textureContent)
{
Debug.Log("LoadFormMtl="+ texturePath + ".");
if (mtlText == "")
return null;
materialNames.Clear();
//将文本化后的内容按行分割
string[] allLines = mtlText.Split('\n');
foreach (string line in allLines)
{
//按照空格分割每一行的内容
string[] chars = line.Split(' ');
switch (chars[0])
{
case "newmtl":
//处理材质名
materialNames.Add(chars[1]);
break;
case "Ka":
//暂时仅考虑漫反射
break;
case "Kd":
//处理漫反射
diffuseColors.Add(new Vector3(
ConvertToFloat(chars[1]),
ConvertToFloat(chars[2]),
ConvertToFloat(chars[3])
));
break;
case "Ks":
//暂时仅考虑漫反射
break;
case "Ke":
//Todo
break;
case "Ni":
//Todo
break;
case "e":
//Todo
break;
case "illum":
//Todo
break;
case "map_Ka":
//暂时仅考虑漫反射
break;
case "map_Kd":
//处理漫反射贴图
//因为mtl文件中的贴图使用的是绝对路径
//所以这里需要截取它的文件名来和材质相对应起来
string textureName = chars[1].Substring(chars[1].LastIndexOf("\\") + 1, chars[1].Length - chars[1].LastIndexOf("\\") - 1);
//默认贴图格式为.png
textureName = textureName.Replace(".dds", ".png").Replace("\r", ""); ;
diffuseTextures.Add(textureName);
break;
case "map_Ks":
//暂时仅考虑漫反射
break;
default: continue;
}
}
//准备一个数组来存储材质
Material[] materials = new Material[materialNames.Count];
for (int i = 0; i < materialNames.Count; i++)
{
//创建一个内置的Diffuse材质
Material mat = new Material(Shader.Find("Unlit/Texture"));
//设置材质名称
mat.name = materialNames[i].ToString();
//加载贴图
if (textureContent == null)
{
StartCoroutine(LoadTexture(mat, texturePath + "/" + diffuseTextures[i]));
}
else
{
globalTexture = new Texture2D(1, 1);
#if UNITY_2017_1
ImageConversion.LoadImage(globalTexture, textureContent);
#else
globalTexture.LoadImage(textureContent);
#endif
}
//设置贴图
mat.mainTexture = globalTexture;
if (diffuseColors.Count > 0) mat.color = new Color(
diffuseColors[0].x, diffuseColors[0].y, diffuseColors[0].z
);
materials[i] = mat;
}
return materials;
}
///
/// 将一个字符串转换为浮点类型
///
/// 待转换的字符串
///
private float ConvertToFloat(string s)
{
return System.Convert.ToSingle(s, CultureInfo.InvariantCulture);
}
///
/// 加载指定路径的贴图
///
/// The texture.
/// 贴图路径
IEnumerator LoadTexture(Material mat, string fileName)
{
Debug.Log("LoadTexture=" + fileName + ".");
//使用WWW下载贴图
WWW www = new WWW(fileName);
yield return www;
if (www != null && string.IsNullOrEmpty(www.error))
{
if (www.isDone)
{
globalTexture = www.texture;
mat.mainTexture = globalTexture;
}
}
else
{
globalTexture = null;
}
}
}
}