Exemplo n.º 1
0
    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");
    }
Exemplo n.º 2
0
    // 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"));;
        }
    }
Exemplo n.º 3
0
    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.");
            }
        }
    }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
    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.");
            }
        }
    }
Exemplo n.º 6
0
 public void StartDecode(NativeSlice <byte> data, int weightsAttributeId, int jointsAttributeId)
 {
     draco     = new DracoMeshLoader();
     dracoTask = draco.ConvertDracoMeshToUnity(
         data,
         needsNormals,
         needsTangents,
         weightsAttributeId,
         jointsAttributeId,
         morphTargetsContext != null
         );
 }
Exemplo n.º 7
0
 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));
        }
Exemplo n.º 9
0
        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);
        }
Exemplo n.º 10
0
    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");
    }
Exemplo n.º 11
0
        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));
        }
Exemplo n.º 12
0
        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));
        }
Exemplo n.º 13
0
    // 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];
        }
    }
Exemplo n.º 14
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"));;
        }
    }
Exemplo n.º 15
0
    // 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];
        }
    }
Exemplo n.º 16
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();
        }
Exemplo n.º 17
0
    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);
    }
Exemplo n.º 18
0
    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()}");
    }
Exemplo n.º 19
0
    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);
    }