using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Threading; using System.IO; namespace AIPagedLod { public class TileObjectInfo : IDisposable { public Vector3[] mVertices = null; public int[] mTriangles = null; public Vector2[] mTexCoords = null; public byte[] mImageData = null; public int mImageSize = 0; public int mImageResolutionS = 0; public int mImageResolutionT = 0; public int mTextureFormat = 0; public TextureFormat mUnityTextureFormat; public void Dispose() { mVertices = null; mTriangles = null; mTexCoords = null; mImageData = null; } } public class PagedLodFileLoader : IDisposable { public string mFileName = string.Empty; public string mTileName = string.Empty; public string mTileDirPath = string.Empty; public int mLevel = 0; public bool mIsFinished = false; public bool mIsLoaded = false; public ManualResetEvent mLoadedEvent = new ManualResetEvent(false); public bool mRequestResult = false; public bool mIsDaJiangData = false; public static Material mMatPrefab = null; public List mObjectInfoList = new List(); public void StartLoad() { mIsFinished = true; mRequestResult = true; } public virtual void LoadObjectMeshInfo() { } public virtual void LoadObjectBasicInfo() { } public void BuildObjectForThread(GameObject renderNode, int meshLayer = -1) { if (mMatPrefab == null) { mMatPrefab = Resources.Load("PagedLodMat") as Material; } if (mObjectInfoList.Count == 0) { Debug.Log(" ************* mObjectInfoList.Count == 0 " + renderNode.transform.parent.gameObject.name); } for (int i = 0; i < mObjectInfoList.Count; ++i) { TileObjectInfo info = mObjectInfoList[i]; GameObject meshGameObject = null; if (MeshPool.mInstance != null) { meshGameObject = MeshPool.mInstance.GetMeshObject(); } TextureFormat textureFormat = info.mUnityTextureFormat; if (meshGameObject == null) { meshGameObject = new GameObject("Mesh" + i.ToString()); meshGameObject.transform.parent = renderNode.transform; meshGameObject.transform.localPosition = Vector3.zero; meshGameObject.transform.localRotation = Quaternion.identity; meshGameObject.transform.localScale = Vector3.one; meshGameObject.SetActive(true); Mesh mesh = new Mesh(); if (info.mVertices.Length <= 65000) { mesh.vertices = info.mVertices; mesh.triangles = info.mTriangles; mesh.uv = info.mTexCoords; } else { Debug.Log(renderNode.transform.parent.name + " Mesh Vertex Count > 65000"); } Texture2D texture2D = new Texture2D(info.mImageResolutionS, info.mImageResolutionT, textureFormat, false); if (info.mImageData.Length > 0) { texture2D.LoadRawTextureData(info.mImageData); } else { meshGameObject.SetActive(false); } texture2D.Apply(); MeshFilter meshFilter = meshGameObject.AddComponent(); meshFilter.sharedMesh = mesh; MeshRenderer meshRenderer = meshGameObject.AddComponent(); Material material = new Material(mMatPrefab); material.SetTexture("_MainTex", texture2D); meshRenderer.sharedMaterial = material; //mesh.RecalculateNormals(); if (meshLayer == -1) { meshLayer = PagedLodConfig.mInstance == null ? 8 : PagedLodConfig.mInstance.mMeshLayer; } meshGameObject.layer = meshLayer; } else { meshGameObject.SetActive(true); meshGameObject.transform.parent = renderNode.transform; meshGameObject.transform.localPosition = Vector3.zero; meshGameObject.transform.localRotation = Quaternion.identity; meshGameObject.transform.localScale = Vector3.one; MeshFilter meshFilter = meshGameObject.GetComponent(); MeshRenderer meshRenderer = meshGameObject.GetComponent(); Mesh mesh = meshFilter.sharedMesh; mesh.Clear(); mesh.vertices = info.mVertices; mesh.triangles = info.mTriangles; mesh.uv = info.mTexCoords; Texture2D texture2D = meshRenderer.sharedMaterial.GetTexture("_MainTex") as Texture2D; if (textureFormat == TextureFormat.DXT5 || texture2D.format == TextureFormat.DXT5) { UnityEngine.Object.Destroy(texture2D); texture2D = new Texture2D(info.mImageResolutionS, info.mImageResolutionT, textureFormat, false); texture2D.LoadRawTextureData(info.mImageData); texture2D.Apply(); meshRenderer.sharedMaterial.SetTexture("_MainTex", texture2D); } else { if (info.mImageData.Length > 0) { #if (UNITY_2021_1_OR_NEWER) texture2D.Reinitialize(info.mImageResolutionS, info.mImageResolutionT, textureFormat, false); #else texture2D.Resize(info.mImageResolutionS, info.mImageResolutionT, textureFormat, false); #endif texture2D.LoadRawTextureData(info.mImageData); texture2D.Apply(); //meshFilter.sharedMesh.RecalculateNormals(); meshGameObject.SetActive(true); } else { meshGameObject.SetActive(false); } } } } } public void Dispose() { foreach (var info in mObjectInfoList) { info.Dispose(); } mLoadedEvent = null; } public virtual bool IsInvalidMesh() { return false; } public static PagedLodFileLoader GetFileLoader(string fileName) { if (PagedLodConfig.mInstance.mTileDataType == TileDataType.OSGB) return new OsgbFileLoader(fileName); else return new B3dmFileLoader(fileName); } public static PagedLodFileLoader GetPagedLodFileLoader(FileInfo fileInfo, int level, string TileDirPath, bool IsDaJiangData = false) { PagedLodFileLoader pagedLodLoader = GetFileLoader(fileInfo.FullName); pagedLodLoader.mIsDaJiangData = IsDaJiangData; pagedLodLoader.mTileName = fileInfo.Name.Replace(PagedLodConfig.mInstance.GetFileSufix(), ""); pagedLodLoader.mTileDirPath = TileDirPath; pagedLodLoader.mLevel = level; return pagedLodLoader; } } }