void Encoding() { if (EncodingData == null || string.IsNullOrEmpty(SavePath)) { Debug.LogError("Encoding Data Error"); return; } DracoMeshLoader dracoLoader = new DracoMeshLoader(); byte[] dracoData = dracoLoader.EncodeUnityMesh(EncodingData); try { if (dracoData != null && dracoData.Length > 0) { using (System.IO.FileStream saveFile = System.IO.File.Open(SavePath, System.IO.FileMode.Create)) { saveFile.Write(dracoData, 0, dracoData.Length); saveFile.Flush(); } } Debug.Log("Encode Finish"); return; } catch (System.Exception e) { Debug.LogError(e.ToString()); } Debug.LogError("Encode Faile"); }
// This function will be used when the GameObject is initialized. void Start() { // If the original mesh exceeds the limit of number of verices, the // loader will split it to a list of smaller meshes. List <Mesh> meshes = new List <Mesh>(); DracoMeshLoader dracoLoader = new DracoMeshLoader(); /* * Here we use the compressed Bunny model as example. * It's in unity/Resources/bunny.drc.bytes. * Please see README.md for details. */ int numFaces = dracoLoader.LoadMeshFromAsset(AssetName, ref meshes); /* Note: You need to add MeshFilter (and MeshRenderer) to your GameObject. * Or you can do something like the following in script: * AddComponent<MeshFilter>(); */ if (numFaces > 0) { MeshFilter filter = GetComponent <MeshFilter>(); if (filter == null) { filter = gameObject.AddComponent <MeshFilter>(); } filter.mesh = meshes[0]; } if (GetComponent <MeshRenderer>() == null) { MeshRenderer renderer = gameObject.AddComponent <MeshRenderer>(); renderer.material = new Material(Shader.Find("Legacy Shaders/Diffuse"));; } }
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach (string str in importedAssets) { // Compressed file must be renamed to ".drc.bytes". var extIndex = str.EndsWith(FILE_EXT, true, CultureInfo.InvariantCulture); var extBytesIndex = str.EndsWith(FILE_EXT_BYTES, true, CultureInfo.InvariantCulture); if (!(extIndex || extBytesIndex)) { return; } DracoMeshLoader dracoLoader = new DracoMeshLoader(); int length = str.Length - (extIndex?4:6) - str.LastIndexOf('/') - 1; string fileName = str.Substring(str.LastIndexOf('/') + 1, length); var data = File.ReadAllBytes(str); var nativeData = new NativeArray <byte>(data.Length, Allocator.TempJob); nativeData.CopyFrom(data); var mesh = dracoLoader.DecodeMeshSync(nativeData); nativeData.Dispose(); if (mesh != null) { mesh.name = fileName; // Create mesh assets. Combine the smaller meshes to a single asset. // TODO: Figure out how to combine to an unseen object as .obj files. var dir = Path.GetDirectoryName(str); AssetDatabase.CreateAsset(mesh, Path.Combine(dir, fileName + ".asset")); AssetDatabase.SaveAssets(); // Also create a Prefab for easy usage. GameObject newAsset = new GameObject(); newAsset.hideFlags = HideFlags.HideInHierarchy; var mf = newAsset.AddComponent <MeshFilter>(); mf.mesh = mesh; newAsset.AddComponent <MeshRenderer>(); bool success; PrefabUtility.SaveAsPrefabAsset(newAsset, Path.Combine(dir, fileName + ".prefab"), out success); Object.DestroyImmediate(newAsset); if (!success) { Debug.LogError("Creating Draco Prefab failed!"); } } else { // TODO: Throw exception? Debug.LogError("Decodeing Draco file failed."); } } }
public override async void OnImportAsset(AssetImportContext ctx) { var dracoData = File.ReadAllBytes(ctx.assetPath); var draco = new DracoMeshLoader(); var mesh = await draco.ConvertDracoMeshToUnity(dracoData, sync : true); ctx.AddObjectToAsset("mesh", mesh); ctx.SetMainObject(mesh); }
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach (string str in importedAssets) { // Compressed file must be renamed to ".drc.bytes". if (str.IndexOf(".drc.bytes") == -1) { return; } // If the original mesh exceeds the limit of number of verices, the // loader will split it to a list of smaller meshes. List <Mesh> meshes = new List <Mesh>(); DracoMeshLoader dracoLoader = new DracoMeshLoader(); // The decoded mesh will be named without ".drc.bytes" str.LastIndexOf('/'); int length = str.Length - ".drc.bytes".Length - str.LastIndexOf('/') - 1; string fileName = str.Substring(str.LastIndexOf('/') + 1, length); int numFaces = dracoLoader.LoadMeshFromAsset(fileName + ".drc", ref meshes); if (numFaces > 0) { // Create mesh assets. Combine the smaller meshes to a single asset. // TODO: Figure out how to combine to an unseen object as .obj files. AssetDatabase.CreateAsset(meshes [0], "Assets/Resources/" + fileName + ".asset"); AssetDatabase.SaveAssets(); for (int i = 1; i < meshes.Count; ++i) { AssetDatabase.AddObjectToAsset(meshes [i], meshes [0]); AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(meshes [i])); } // Also create a Prefab for easy usage. GameObject newAsset = new GameObject(); newAsset.hideFlags = HideFlags.HideInHierarchy; for (int i = 0; i < meshes.Count; ++i) { GameObject subObject = new GameObject(); subObject.hideFlags = HideFlags.HideInHierarchy; subObject.AddComponent <MeshFilter>(); subObject.AddComponent <MeshRenderer>(); subObject.GetComponent <MeshFilter>().mesh = UnityEngine.Object.Instantiate(meshes[i]); subObject.transform.parent = newAsset.transform; } PrefabUtility.CreatePrefab("Assets/Resources/" + fileName + ".prefab", newAsset); } else { // TODO: Throw exception? Debug.Log("Error: Decodeing Draco file failed."); } } }
public void StartDecode(NativeSlice <byte> data, int weightsAttributeId, int jointsAttributeId) { draco = new DracoMeshLoader(); dracoTask = draco.ConvertDracoMeshToUnity( data, needsNormals, needsTangents, weightsAttributeId, jointsAttributeId, morphTargetsContext != null ); }
void LoadBatch() { Profiler.BeginSample("LoadBatch"); for (int i = 0; i < count; i++) { Profiler.BeginSample("DecodeMesh"); DracoMeshLoader dracoLoader = new DracoMeshLoader(); dracoLoader.onMeshesLoaded += OnMeshesLoaded; StartCoroutine(dracoLoader.DecodeMesh(data)); Profiler.EndSample(); } Profiler.EndSample(); }
public override Primitive?CreatePrimitive() { jobHandle.Complete(); int result = dracoResult[0]; IntPtr dracoMesh = dracoPtr[0]; dracoResult.Dispose(); dracoPtr.Dispose(); if (result <= 0) { Debug.LogError("Failed: Decoding error."); return(null); } Profiler.BeginSample("DracoMeshLoader.CreateMesh"); bool hasTexcoords; bool hasNormals; var mesh = DracoMeshLoader.CreateMesh(dracoMesh, out hasNormals, out hasTexcoords); Profiler.EndSample(); if (needsNormals && !hasNormals) { Profiler.BeginSample("Draco.RecalculateNormals"); // TODO: Make optional. Only calculate if actually needed mesh.RecalculateNormals(); Profiler.EndSample(); } if (needsTangents && hasTexcoords) { Profiler.BeginSample("Draco.RecalculateTangents"); // TODO: Make optional. Only calculate if actually needed mesh.RecalculateTangents(); Profiler.EndSample(); } #if GLTFAST_KEEP_MESH_DATA Profiler.BeginSample("UploadMeshData"); mesh.UploadMeshData(false); Profiler.EndSample(); #else /// Don't upload explicitely. Unity takes care of upload on demand/deferred // Profiler.BeginSample("UploadMeshData"); // mesh.UploadMeshData(true); // Profiler.EndSample(); #endif return(new Primitive(mesh, materials)); }
public override async void OnImportAsset(AssetImportContext ctx) { var dracoData = File.ReadAllBytes(ctx.assetPath); var draco = new DracoMeshLoader(); var mesh = await draco.ConvertDracoMeshToUnity(dracoData, sync : true); if (mesh == null) { Debug.LogError("Import draco file failed"); return; } ctx.AddObjectToAsset("mesh", mesh); ctx.SetMainObject(mesh); }
void Decoding() { if (string.IsNullOrEmpty(SavePath) || !System.IO.File.Exists(SavePath)) { Debug.LogError("Decoding Data Error"); return; } DracoMeshLoader dracoLoader = new DracoMeshLoader(); byte[] dracoData = null; try { using (System.IO.FileStream saveFile = System.IO.File.Open(SavePath, System.IO.FileMode.Open)) { dracoData = new byte[saveFile.Length]; saveFile.Read(dracoData, 0, dracoData.Length); } if (dracoData != null) { List <Mesh> TestMeshList = new List <Mesh>(); dracoLoader.DecodeMesh(dracoData, ref TestMeshList); if (TestMeshList.Count > 0) { foreach (Mesh decMesh in TestMeshList) { MeshFilter showMeshCom = gameObject.AddComponent <MeshFilter>(); showMeshCom.mesh = decMesh; } } } Debug.Log("Decode Finish"); return; } catch (System.Exception e) { Debug.LogError(e.ToString()); } Debug.LogError("Decode Faile"); }
public override Primitive?CreatePrimitive() { jobHandle.Complete(); int result = dracoResult[0]; IntPtr dracoMesh = dracoPtr[0]; dracoResult.Dispose(); dracoPtr.Dispose(); if (result <= 0) { Debug.LogError("Failed: Decoding error."); return(null); } Profiler.BeginSample("DracoMeshLoader.CreateMesh"); bool hasTexcoords; bool hasNormals; var mesh = DracoMeshLoader.CreateMesh(dracoMesh, out hasNormals, out hasTexcoords); Profiler.EndSample(); if (needsNormals && !hasNormals) { Profiler.BeginSample("Draco.RecalculateNormals"); // TODO: Make optional. Only calculate if actually needed mesh.RecalculateNormals(); Profiler.EndSample(); } if (needsTangents && hasTexcoords) { Profiler.BeginSample("Draco.RecalculateTangents"); // TODO: Make optional. Only calculate if actually needed mesh.RecalculateTangents(); Profiler.EndSample(); } Profiler.BeginSample("UploadMeshData"); mesh.UploadMeshData(true); Profiler.EndSample(); return(new Primitive(mesh, materials)); }
public override Primitive?CreatePrimitive() { jobHandle.Complete(); int result = dracoResult[0]; IntPtr dracoMesh = dracoPtr[0]; dracoResult.Dispose(); dracoPtr.Dispose(); if (result <= 0) { Debug.LogError("Failed: Decoding error."); return(null); } var msh = DracoMeshLoader.CreateMesh(dracoMesh); return(new Primitive(msh, primitive.material)); }
// This function will be used when the GameObject is initialized. void Start() { List <Mesh> mesh = new List <Mesh>(); DracoMeshLoader dracoLoader = new DracoMeshLoader(); /* * Here we use the compressed Bunny model as example. * It's in unity/Resources/bunny.drc.bytes. * Please see README.md for details. */ int numFaces = dracoLoader.LoadMeshFromAsset("bunny.drc", ref mesh); /* Note: You need to add MeshFilter (and MeshRenderer) to your GameObject. * Or you can do something like the following in script: * AddComponent<MeshFilter>(); */ if (numFaces > 0) { GetComponent <MeshFilter>().mesh = mesh[0]; } }
void Start() { List <Mesh> meshes = new List <Mesh>(); DracoMeshLoader dracoLoader = new DracoMeshLoader(); int numFaces = dracoLoader.LoadMeshFromAsset(AssetName, ref meshes); if (numFaces > 0) { MeshFilter filter = GetComponent <MeshFilter>(); if (filter == null) { filter = gameObject.AddComponent <MeshFilter>(); } filter.mesh = meshes[0]; } if (GetComponent <MeshRenderer>() == null) { MeshRenderer renderer = gameObject.AddComponent <MeshRenderer>(); renderer.material = new Material(Shader.Find("Legacy Shaders/Diffuse"));; } }
// This function will be used when the GameObject is initialized. void Start() { // If the original mesh exceeds the limit of number of verices, the // loader will split it to a list of smaller meshes. List <Mesh> mesh = new List <Mesh>(); DracoMeshLoader dracoLoader = new DracoMeshLoader(); /* * Here we use the compressed Bunny model as example. * It's in unity/Resources/bunny.drc.bytes. * Please see README.md for details. */ int numFaces = dracoLoader.LoadMeshFromAsset("bunny", ref mesh); /* Note: You need to add MeshFilter (and MeshRenderer) to your GameObject. * Or you can do something like the following in script: * AddComponent<MeshFilter>(); */ if (numFaces > 0) { GetComponent <MeshFilter>().mesh = mesh[0]; } }
async Task LoadBatch(int quantity, NativeArray <byte> data, bool requireNormals = false, bool requireTangents = false) { var tasks = new List <Task <Mesh> >(quantity); for (var i = 0; i < quantity; i++) { DracoMeshLoader dracoLoader = new DracoMeshLoader(); var task = dracoLoader.ConvertDracoMeshToUnity(data, requireNormals, requireTangents); tasks.Add(task); } while (tasks.Count > 0) { var task = await Task.WhenAny(tasks); tasks.Remove(task); var mesh = await task; if (mesh == null) { Debug.LogError("Loading mesh failed"); } else { if (requireNormals) { var normals = mesh.normals; Assert.Greater(normals.Length, 0); } if (requireTangents) { var tangents = mesh.tangents; Assert.Greater(tangents.Length, 0); } } } await Task.Yield(); }
public static Mesh LoadMeshFromResources(string assetpath) { if (assetpath == null || assetpath.Equals("")) { Debug.Log("Assetpath is null or empty."); return(null); } Mesh mesh = null; string extension = System.IO.Path.GetExtension(assetpath); if (extension.Equals(".drc")) { List <Mesh> meshes = new List <Mesh>(); DracoMeshLoader dracoLoader = new DracoMeshLoader(); long startTicks = DateTime.Now.Ticks; int numFaces = dracoLoader.LoadMeshFromAsset(assetpath, ref meshes); long endTicks = DateTime.Now.Ticks; // Debug.Log("DracoMeshLoader - LoadMeshFromAsset: " + (endTicks - startTicks) * 100 + "[ns]"); Debug.Log("DracoMeshLoader - LoadMeshFromAsset: " + (endTicks - startTicks) / 10000 + "[ms]"); if (numFaces > 0) { mesh = meshes[0]; } } else { mesh = (Mesh)Resources.Load(assetpath, typeof(Mesh)); } return(mesh); }
async void LoadBatch(int quantity) { stopwatch.StartTime(); Profiler.BeginSample("LoadBatch"); var routines = new IEnumerator[quantity]; for (int i = 0; i < quantity; i++) { Profiler.BeginSample("DecodeMesh"); DracoMeshLoader dracoLoader = new DracoMeshLoader(); dracoLoader.onMeshesLoaded += OnMeshesLoaded; routines[i] = dracoLoader.DecodeMesh(data); Profiler.EndSample(); } Profiler.EndSample(); while (true) { var stillWorking = false; foreach (var routine in routines) { stillWorking |= routine.MoveNext(); } if (!stillWorking) { break; } await Task.Yield(); } await Task.Yield(); stopwatch.StopTime(); Debug.Log($"Loaded {filePath} {quantity} times in {stopwatch.GetTextReport()}"); }
public byte[] EncodeUnityMesh(Mesh meshData) { byte[] compresMeshBuffer = null; if (meshData == null) { return(compresMeshBuffer); } DracoMeshLoader.DracoToUnityMesh dracoMesh; UnityEngine.Vector3[] vertex = meshData.vertices; int[] face = meshData.triangles; UnityEngine.Vector2[] uv = meshData.uv; dracoMesh.numVertices = vertex.Length; dracoMesh.position = System.Runtime.InteropServices.Marshal.AllocHGlobal(vertex.Length * 3 * sizeof(float)); dracoMesh.numFaces = face.Length / 3; dracoMesh.indices = System.Runtime.InteropServices.Marshal.AllocHGlobal(face.Length * sizeof(int)); for (int vIndex = 0; vIndex < dracoMesh.numVertices; vIndex++) { byte *addr = (byte *)dracoMesh.position + vIndex * 3 * 4; *((float *)addr) = vertex[vIndex].x; *((float *)(addr + 4)) = vertex[vIndex].y; *((float *)(addr + 8)) = vertex[vIndex].z; } for (int faceIndex = 0; faceIndex < face.Length; faceIndex++) { byte *addr = (byte *)dracoMesh.indices + faceIndex * 4; *((int *)addr) = face[faceIndex]; } if (uv != null) { dracoMesh.hasTexcoord = true; dracoMesh.texcoord = System.Runtime.InteropServices.Marshal.AllocHGlobal(vertex.Length * 2 * sizeof(float)); for (int uvIndex = 0; uvIndex < dracoMesh.numVertices; uvIndex++) { byte *addr = (byte *)dracoMesh.texcoord + uvIndex * 2 * 4; *((float *)addr) = uv[uvIndex].x; *((float *)(addr + 4)) = uv[uvIndex].y; } } if (meshData.subMeshCount > 1) { dracoMesh.numSubmesh = meshData.subMeshCount; dracoMesh.submesh = System.Runtime.InteropServices.Marshal.AllocHGlobal(meshData.subMeshCount * sizeof(int *)); for (int submeshIndex = 0; submeshIndex < meshData.subMeshCount; submeshIndex++) { int[] submeshArray = meshData.GetTriangles(submeshIndex); ((IntPtr *)dracoMesh.submesh)[submeshIndex] = System.Runtime.InteropServices.Marshal.AllocHGlobal((submeshArray.Length + 1) * sizeof(int)); int *addr = (int *)((IntPtr *)dracoMesh.submesh)[submeshIndex]; addr[0] = submeshArray.Length; for (int i = 0; i < submeshArray.Length; i++) { addr[i + 1] = submeshArray[i]; } } } System.IntPtr dracoBuffer = new System.IntPtr(); DracoMeshLoader.DracoToUnityMesh *pMesh = &dracoMesh; int BuffSize = DracoMeshLoader.EncodeMeshForUnity(&dracoBuffer, &pMesh); if (BuffSize > 0) { compresMeshBuffer = new byte[BuffSize]; System.Runtime.InteropServices.Marshal.Copy(dracoBuffer, compresMeshBuffer, 0, BuffSize); } System.Runtime.InteropServices.Marshal.FreeHGlobal(dracoMesh.position); System.Runtime.InteropServices.Marshal.FreeHGlobal(dracoMesh.indices); System.Runtime.InteropServices.Marshal.FreeHGlobal(dracoMesh.texcoord); if (meshData.subMeshCount > 1) { for (int submeshIndex = 0; submeshIndex < meshData.subMeshCount; submeshIndex++) { System.Runtime.InteropServices.Marshal.FreeHGlobal(((IntPtr *)dracoMesh.submesh)[submeshIndex]); } System.Runtime.InteropServices.Marshal.FreeHGlobal(dracoMesh.submesh); } DracoMeshLoader.FreeDracoMesh(&dracoBuffer); return(compresMeshBuffer); }