123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- using UnityEngine;
- using System.IO;
- using System.Text;
- using System.Collections.Generic;
- using System.Threading;
- namespace Nxr.Internal
- {
- public class ObjModelLoader : MonoBehaviour
- {
- public enum FileType
- {
- OBJ, MTL, PNG
- }
- private Vector3 modelScaleSize = Vector3.one;
- private Transform parentTransform;
- private string objFilePath;
- public void LoadObjFile(string objPath, Transform parent) {
- LoadObjFile(objPath, Vector3.one, parent);
- }
- public void LoadObjFile(string objPath, Vector3 scaleSize, Transform parent)
- {
- FileDict.Clear();
- loaded = false;
- IsObjModelLoaded = false;
- parentTransform = parent;
- modelScaleSize = scaleSize;
- objFilePath = objPath;
- Thread readFileThread = new Thread(new ParameterizedThreadStart(ReadFiles));
- readFileThread.Start(objPath);
- }
- private Dictionary<FileType, byte[]> FileDict = new Dictionary<FileType, byte[]>();
- private bool loaded = false;
- private void Update()
- {
- if (FileDict.Count == 3 && !loaded)
- {
- CreateModelObject(/*objFilePath*/ null, "OBJ_Model");
- loaded = true;
- }
- }
- public GameObject GetObjModel()
- {
- return ObjModel;
- }
- ObjMesh objInstace = null;
- void ReadFiles(object objPath)
- {
- ReadFileCore(FileType.OBJ, (string)objPath);
- string objtext = System.Text.Encoding.Default.GetString(FileDict[FileType.OBJ]);
- objInstace = Nxr.Internal.NxrSDKApi.Instance.GetObjMesh((string)objPath);
- if(objInstace == null)
- {
- objInstace = new ObjMesh();
- objInstace = objInstace.LoadFromObj(objtext);
- Nxr.Internal.NxrSDKApi.Instance.AddObjMesh((string)objPath, objInstace);
- Debug.Log("Create ObjMesh : " + (string)objPath);
- } else
- {
- Debug.Log("Use Cache ObjMesh : " + (string)objPath);
- }
- FileDict[FileType.OBJ] = null;
- ReadFileCore(FileType.MTL, ((string)objPath).Replace("obj", "mtl"));
- ReadFileCore(FileType.PNG, ((string)objPath).Replace("obj", "png"));
- }
- void ReadFileCore(FileType fileType, string filePath)
- {
- FileStream fileStream = new FileStream(filePath, FileMode.Open, System.IO.FileAccess.Read);
- fileStream.Seek(0, SeekOrigin.Begin);
- byte[] binary = new byte[fileStream.Length];
- fileStream.Read(binary, 0, (int)fileStream.Length);
- if (!FileDict.ContainsKey(fileType))
- {
- FileDict.Add(fileType, binary);
- }
- else
- {
- FileDict[fileType] = binary;
- }
- fileStream.Close();
- fileStream.Dispose();
- fileStream = null;
- }
- GameObject ObjModel = null;
- public bool IsObjModelLoaded = false;
- void CreateModelObject(string objFilePath, string objName)
- {
- Debug.Log("CreateModelObject=" + objName + "," + objFilePath + ".");
- //解析内容
- //计算网格
- Mesh mesh = new Mesh();
- mesh.Clear();
- mesh.name = "ObjMesh";
- mesh.vertices = objInstace.VertexArray;
- mesh.triangles = objInstace.TriangleArray;
- if (objInstace.UVArray.Length > 0)
- mesh.uv = objInstace.UVArray;
- if (objInstace.NormalArray.Length > 0)
- mesh.normals = objInstace.NormalArray;
- mesh.RecalculateBounds();
- //生成物体
- ObjModel = new GameObject(objName);
- if (parentTransform != null)
- {
- ObjModel.transform.SetParent(parentTransform);
- }
- ObjModel.transform.localScale = modelScaleSize;
- ObjModel.transform.localPosition = Vector3.zero;
- ObjModel.transform.localRotation = Quaternion.identity;
- MeshFilter meshFilter = ObjModel.AddComponent<MeshFilter>();
- meshFilter.mesh = mesh;
- MeshRenderer meshRenderer = ObjModel.AddComponent<MeshRenderer>();
- string directory = objFilePath == null ? null : Path.GetDirectoryName(objFilePath);
- string mtltext = System.Text.Encoding.Default.GetString(FileDict[FileType.MTL]);
- Material[] materials = ObjMaterial.Instance.LoadFormMtl(mtltext, directory, FileDict[FileType.PNG]);
- meshRenderer.materials = materials;
- IsObjModelLoaded = true;
- }
- //public void LoadFormFile(string objName, string modelFilePath, string texturePath)
- //{
- // if (!File.Exists(modelFilePath))
- // Debug.Log("请确认obj模型文件是否存在!");
- // if (!modelFilePath.EndsWith(".obj"))
- // Debug.Log("请确认这是一个obj模型文件");
- // //读取内容
- // StreamReader reader = new StreamReader(modelFilePath, Encoding.Default);
- // string content = reader.ReadToEnd();
- // reader.Close();
- // //解析内容
- // ObjMesh objInstace = new ObjMesh();
- // objInstace = objInstace.LoadFromObj(content);
- // //计算网格
- // Mesh mesh = new Mesh();
- // mesh.vertices = objInstace.VertexArray;
- // mesh.triangles = objInstace.TriangleArray;
- // if (objInstace.UVArray.Length > 0)
- // mesh.uv = objInstace.UVArray;
- // if (objInstace.NormalArray.Length > 0)
- // mesh.normals = objInstace.NormalArray;
- // mesh.RecalculateBounds();
- // //生成物体
- // GameObject go = new GameObject(objName);
- // MeshFilter meshFilter = go.AddComponent<MeshFilter>();
- // meshFilter.mesh = mesh;
- // MeshRenderer meshRenderer = go.AddComponent<MeshRenderer>();
- // //获取mtl文件路径
- // string mtlFilePath = modelFilePath.Replace(".obj", ".mtl");
- // StreamReader mtlReader = new StreamReader(mtlFilePath, Encoding.Default);
- // string mtlContent = mtlReader.ReadToEnd();
- // mtlReader.Close();
- // //从mtl文件中加载材质
- // Material[] materials = ObjMaterial.Instance.LoadFormMtl(mtlContent, texturePath, null);
- // meshRenderer.materials = materials;
- //}
- //IEnumerator LoadFileAsync(FileType fileType, string filePath)
- //{
- // WWW www = new WWW(filePath);
- // yield return null;
- // yield return www;
- // Debug.Log("Load." + filePath + ",isDone=" + www.isDone);
- // if ((www.error == null || www.error.Length == 0) && www.isDone)
- // {
- // // 保持顺序
- // if (!FileDict.ContainsKey(fileType))
- // {
- // FileDict.Add(fileType, Encoding.Default.GetBytes((www.text)));
- // }
- // else
- // {
- // FileDict[fileType] = Encoding.Default.GetBytes(www.text);
- // }
- // www.Dispose();
- // switch (fileType)
- // {
- // case FileType.OBJ:
- // StartCoroutine(LoadFileAsync(FileType.MTL, filePath.Replace("obj", "mtl")));
- // break;
- // case FileType.MTL:
- // StartCoroutine(LoadFileAsync(FileType.PNG, filePath.Replace("mtl", "png")));
- // break;
- // case FileType.PNG:
- // StartCoroutine(CreateModelObject(filePath, "Model"));
- // break;
- // default: break;
- // }
- // }
- // else
- // {
- // Debug.LogError("Load Error :" + www.error + "," + www.text);
- // }
- // Debug.Log("LoadFileAsync finish " + fileType);
- //}
- }
- }
|