ObjMaterial.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. 
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Globalization;
  6. using System.Text;
  7. namespace Nxr.Internal
  8. {
  9. public class ObjMaterial : MonoBehaviour
  10. {
  11. /// <summary>
  12. /// 全局变量
  13. /// </summary>
  14. private Texture2D globalTexture;
  15. /// <summary>
  16. /// 材质名称列表
  17. /// </summary>
  18. private ArrayList materialNames;
  19. /// <summary>
  20. /// 漫反射颜色列表
  21. /// </summary>
  22. private List<Vector3> diffuseColors;
  23. /// <summary>
  24. /// 漫反射贴图列表
  25. /// </summary>
  26. private ArrayList diffuseTextures;
  27. /// <summary>
  28. /// 当前实例
  29. /// </summary>
  30. private static ObjMaterial instance;
  31. public static ObjMaterial Instance
  32. {
  33. get
  34. {
  35. if (instance == null)
  36. instance = GameObject.FindObjectOfType<ObjMaterial>();
  37. if (instance == null)
  38. instance = new GameObject("ObjMatrial").AddComponent<ObjMaterial>();
  39. return instance;
  40. }
  41. }
  42. void Awake()
  43. {
  44. this.diffuseColors = new List<Vector3>();
  45. this.diffuseTextures = new ArrayList();
  46. this.materialNames = new ArrayList();
  47. }
  48. /// <summary>
  49. /// 从一个文本化后的mtl文件加载一组材质
  50. /// </summary>
  51. /// <param name="mtlText">文本化的mtl文件</param>
  52. /// <param name="texturePath">贴图文件夹路径</param>
  53. public Material[] LoadFormMtl(string mtlText, string texturePath, byte[] textureContent)
  54. {
  55. Debug.Log("LoadFormMtl="+ texturePath + ".");
  56. if (mtlText == "")
  57. return null;
  58. materialNames.Clear();
  59. //将文本化后的内容按行分割
  60. string[] allLines = mtlText.Split('\n');
  61. foreach (string line in allLines)
  62. {
  63. //按照空格分割每一行的内容
  64. string[] chars = line.Split(' ');
  65. switch (chars[0])
  66. {
  67. case "newmtl":
  68. //处理材质名
  69. materialNames.Add(chars[1]);
  70. break;
  71. case "Ka":
  72. //暂时仅考虑漫反射
  73. break;
  74. case "Kd":
  75. //处理漫反射
  76. diffuseColors.Add(new Vector3(
  77. ConvertToFloat(chars[1]),
  78. ConvertToFloat(chars[2]),
  79. ConvertToFloat(chars[3])
  80. ));
  81. break;
  82. case "Ks":
  83. //暂时仅考虑漫反射
  84. break;
  85. case "Ke":
  86. //Todo
  87. break;
  88. case "Ni":
  89. //Todo
  90. break;
  91. case "e":
  92. //Todo
  93. break;
  94. case "illum":
  95. //Todo
  96. break;
  97. case "map_Ka":
  98. //暂时仅考虑漫反射
  99. break;
  100. case "map_Kd":
  101. //处理漫反射贴图
  102. //因为mtl文件中的贴图使用的是绝对路径
  103. //所以这里需要截取它的文件名来和材质相对应起来
  104. string textureName = chars[1].Substring(chars[1].LastIndexOf("\\") + 1, chars[1].Length - chars[1].LastIndexOf("\\") - 1);
  105. //默认贴图格式为.png
  106. textureName = textureName.Replace(".dds", ".png").Replace("\r", ""); ;
  107. diffuseTextures.Add(textureName);
  108. break;
  109. case "map_Ks":
  110. //暂时仅考虑漫反射
  111. break;
  112. default: continue;
  113. }
  114. }
  115. //准备一个数组来存储材质
  116. Material[] materials = new Material[materialNames.Count];
  117. for (int i = 0; i < materialNames.Count; i++)
  118. {
  119. //创建一个内置的Diffuse材质
  120. Material mat = new Material(Shader.Find("Unlit/Texture"));
  121. //设置材质名称
  122. mat.name = materialNames[i].ToString();
  123. //加载贴图
  124. if (textureContent == null)
  125. {
  126. StartCoroutine(LoadTexture(mat, texturePath + "/" + diffuseTextures[i]));
  127. }
  128. else
  129. {
  130. globalTexture = new Texture2D(1, 1);
  131. #if UNITY_2017_1
  132. ImageConversion.LoadImage(globalTexture, textureContent);
  133. #else
  134. globalTexture.LoadImage(textureContent);
  135. #endif
  136. }
  137. //设置贴图
  138. mat.mainTexture = globalTexture;
  139. if (diffuseColors.Count > 0) mat.color = new Color(
  140. diffuseColors[0].x, diffuseColors[0].y, diffuseColors[0].z
  141. );
  142. materials[i] = mat;
  143. }
  144. return materials;
  145. }
  146. /// <summary>
  147. /// 将一个字符串转换为浮点类型
  148. /// </summary>
  149. /// <param name="s">待转换的字符串</param>
  150. /// <returns></returns>
  151. private float ConvertToFloat(string s)
  152. {
  153. return System.Convert.ToSingle(s, CultureInfo.InvariantCulture);
  154. }
  155. /// <summary>
  156. /// 加载指定路径的贴图
  157. /// </summary>
  158. /// <returns>The texture.</returns>
  159. /// <param name="fileName">贴图路径</param>
  160. IEnumerator LoadTexture(Material mat, string fileName)
  161. {
  162. Debug.Log("LoadTexture=" + fileName + ".");
  163. //使用WWW下载贴图
  164. WWW www = new WWW(fileName);
  165. yield return www;
  166. if (www != null && string.IsNullOrEmpty(www.error))
  167. {
  168. if (www.isDone)
  169. {
  170. globalTexture = www.texture;
  171. mat.mainTexture = globalTexture;
  172. }
  173. }
  174. else
  175. {
  176. globalTexture = null;
  177. }
  178. }
  179. }
  180. }