예제 #1
0
        /// <summary>
        /// Decodes a Draco mesh
        /// </summary>
        /// <param name="mesh">MeshData used to create the mesh</param>
        /// <param name="encodedData">Compressed Draco data</param>
        /// <param name="requireNormals">If draco does not contain normals and this is set to true, normals are calculated.</param>
        /// <param name="requireTangents">If draco does not contain tangents and this is set to true, tangents and normals are calculated.</param>
        /// <param name="weightsAttributeId">Draco attribute ID that contains bone weights (for skinning)</param>
        /// <param name="jointsAttributeId">Draco attribute ID that contains bone joint indices (for skinning)</param>
        /// <param name="forceUnityLayout">Enforces vertex buffer layout with highest compatibility. Enable this if you want to use blend shapes on the resulting mesh</param>
        /// <returns>A DecodeResult</returns>
        public async Task <DecodeResult> ConvertDracoMeshToUnity(
            Mesh.MeshData mesh,
            byte[] encodedData,
            bool requireNormals    = false,
            bool requireTangents   = false,
            int weightsAttributeId = -1,
            int jointsAttributeId  = -1,
            bool forceUnityLayout  = false
            )
        {
            var encodedDataPtr = PinGCArrayAndGetDataAddress(encodedData, out var gcHandle);
            var result         = await ConvertDracoMeshToUnity(
                mesh,
                encodedDataPtr,
                encodedData.Length,
                requireNormals,
                requireTangents,
                weightsAttributeId,
                jointsAttributeId,
                forceUnityLayout
                );

            UnsafeUtility.ReleaseGCObject(gcHandle);
            return(result);
        }
예제 #2
0
        /// <summary>
        /// Decodes a Draco mesh
        /// </summary>
        /// <param name="mesh">MeshData used to create the mesh</param>
        /// <param name="encodedData">Compressed Draco data</param>
        /// <param name="requireNormals">If draco does not contain normals and this is set to true, normals are calculated.</param>
        /// <param name="requireTangents">If draco does not contain tangents and this is set to true, tangents and normals are calculated.</param>
        /// <param name="weightsAttributeId">Draco attribute ID that contains bone weights (for skinning)</param>
        /// <param name="jointsAttributeId">Draco attribute ID that contains bone joint indices (for skinning)</param>
        /// <param name="forceUnityLayout">Enforces vertex buffer layout with highest compatibility. Enable this if you want to use blend shapes on the resulting mesh</param>
        /// <returns>A DecodeResult</returns>
        public async Task <DecodeResult> ConvertDracoMeshToUnity(
            Mesh.MeshData mesh,
            NativeArray <byte> encodedData,
            bool requireNormals    = false,
            bool requireTangents   = false,
            int weightsAttributeId = -1,
            int jointsAttributeId  = -1,
            bool forceUnityLayout  = false
#if UNITY_EDITOR
            , bool sync = false
#endif
            )
        {
            var encodedDataPtr = GetUnsafeReadOnlyIntPtr(encodedData);

            return(await ConvertDracoMeshToUnity(
                       mesh,
                       encodedDataPtr,
                       encodedData.Length,
                       requireNormals,
                       requireTangents,
                       weightsAttributeId,
                       jointsAttributeId,
                       forceUnityLayout
#if UNITY_EDITOR
                       , sync
#endif
                       ));
        }
 public void GenerateMeshes(GeneratedSurfaceList generatedMesh, Mesh.MeshData meshData)
 {
     for (int surfaceIndex = 0; surfaceIndex < generatedMesh.surfaceIndices.length; surfaceIndex++)
     {
         // get surface from surfaceGroup
         // write to meshData, based on surface specific information
     }
 }
예제 #4
0
        async Task <DecodeResult> ConvertDracoMeshToUnity(
            Mesh.MeshData mesh,
            IntPtr encodedData,
            int size,
            bool requireNormals,
            bool requireTangents,
            int weightsAttributeId = -1,
            int jointsAttributeId  = -1
#if UNITY_EDITOR
            , bool sync = false
#endif
            )
예제 #5
0
        public DracoNative(
#if DRACO_MESH_DATA
            Mesh.MeshData mesh,
#endif
            bool convertSpace = true
            )
        {
            this.convertSpace = convertSpace;
#if DRACO_MESH_DATA
            this.mesh = mesh;
#endif
        }
예제 #6
0
        public void CreateMesh(
            out bool calculateNormals,
            bool requireNormals    = false,
            bool requireTangents   = false,
            int weightsAttributeId = -1,
            int jointsAttributeId  = -1
            )
        {
            Profiler.BeginSample("CreateMesh");

            var dracoMesh = (DracoMesh *)dracoTempResources[meshPtrIndex];

            allocator = dracoMesh->numVertices > persistentDataThreshold ? Allocator.Persistent : Allocator.TempJob;

            CalculateVertexParams(dracoMesh, requireNormals, requireTangents, weightsAttributeId, jointsAttributeId, out calculateNormals);

            Profiler.BeginSample("SetParameters");
#if DRACO_MESH_DATA
            indicesCount = dracoMesh->numFaces * 3;
#else
            mesh = new Mesh();
#endif
            mesh.SetIndexBufferParams(dracoMesh->numFaces * 3, IndexFormat.UInt32);
            var vertexParams = new List <VertexAttributeDescriptor>(attributes.Count);
            foreach (var map in attributes)
            {
                vertexParams.Add(map.GetVertexAttributeDescriptor());
            }
            mesh.SetVertexBufferParams(dracoMesh->numVertices, vertexParams.ToArray());
#if !DRACO_MESH_DATA
            AllocateIndices(dracoMesh);
            AllocateVertexBuffers(dracoMesh);
#endif
            Profiler.EndSample(); // SetParameters
            Profiler.EndSample(); // CreateMesh
        }
예제 #7
0
    public void CombineMesh(ChunkMeshData chunkMeshData)
    {
        //获取输出meshData
        Mesh.MeshDataArray outMeshDataArray = Mesh.AllocateWritableMeshData(1);
        Mesh.MeshData      outMesh          = outMeshDataArray[0];

        Mesh.MeshDataArray outMeshDataArrayCollider = Mesh.AllocateWritableMeshData(1);
        Mesh.MeshData      outMeshCollider          = outMeshDataArrayCollider[0];

        Mesh.MeshDataArray outMeshDataArrayTrigger = Mesh.AllocateWritableMeshData(1);
        Mesh.MeshData      outMeshTrigger          = outMeshDataArrayTrigger[0];

        int subMeshCount      = 0;
        int subMeshIndexCount = 0;

        List <int> trisDataAll = new List <int>();
        List <SubMeshDescriptor> listSubMeshDescriptor = new List <SubMeshDescriptor>();

        for (int i = 0; i < chunkMeshData.dicTris.Length; i++)
        {
            List <int> trisData = chunkMeshData.dicTris[i];
            if (trisData.IsNull())
            {
                continue;
            }
            trisDataAll.AddRange(trisData);
            SubMeshDescriptor subMeshDesc = new SubMeshDescriptor
            {
                indexStart = subMeshIndexCount,
                indexCount = trisData.Count
            };
            listSubMeshDescriptor.Add(subMeshDesc);
            subMeshCount++;
            subMeshIndexCount += trisData.Count;
        }

        VertexStruct[] listVertex = chunkMeshData.GetVertexStruct();
        outMesh.SetVertexBufferParams(listVertex.Length, vertexAttributeDescriptors);

        VertexStruct[] listVertexCollider = chunkMeshData.GetVertexStructCollider();
        outMeshCollider.SetVertexBufferParams(listVertexCollider.Length, vertexAttributeDescriptors);

        VertexStruct[] listVertexTrigger = chunkMeshData.GetVertexStructTrigger();
        outMeshTrigger.SetVertexBufferParams(listVertexTrigger.Length, vertexAttributeDescriptors);

        //获取点信息
        NativeArray <VertexStruct> vertexData         = outMesh.GetVertexData <VertexStruct>();
        NativeArray <VertexStruct> vertexDataCollider = outMeshCollider.GetVertexData <VertexStruct>();
        NativeArray <VertexStruct> vertexDataTrigger  = outMeshTrigger.GetVertexData <VertexStruct>();

        //设置点信息
        NativeArray <VertexStruct> .Copy(listVertex, vertexData);

        NativeArray <VertexStruct> .Copy(listVertexCollider, vertexDataCollider);

        NativeArray <VertexStruct> .Copy(listVertexTrigger, vertexDataTrigger);

        //设置三角数量
        outMesh.SetIndexBufferParams(trisDataAll.Count, IndexFormat.UInt32);
        outMeshCollider.SetIndexBufferParams(chunkMeshData.trisCollider.Count, IndexFormat.UInt32);
        outMeshTrigger.SetIndexBufferParams(chunkMeshData.trisTrigger.Count, IndexFormat.UInt32);
        //获取三角下标
        NativeArray <int> triangelData         = outMesh.GetIndexData <int>();
        NativeArray <int> triangelDataCollider = outMeshCollider.GetIndexData <int>();
        NativeArray <int> triangelDataTrigger  = outMeshTrigger.GetIndexData <int>();

        NativeArray <int> .Copy(trisDataAll.ToArray(), triangelData);

        NativeArray <int> .Copy(chunkMeshData.trisCollider.ToArray(), triangelDataCollider);

        NativeArray <int> .Copy(chunkMeshData.trisTrigger.ToArray(), triangelDataTrigger);

        outMesh.subMeshCount         = subMeshCount;
        outMeshCollider.subMeshCount = 1;
        outMeshTrigger.subMeshCount  = 1;

        for (int i = 0; i < listSubMeshDescriptor.Count; i++)
        {
            outMesh.SetSubMesh(i, listSubMeshDescriptor[i]);
        }
        outMeshCollider.SetSubMesh(0, new SubMeshDescriptor
        {
            indexStart = 0,
            indexCount = chunkMeshData.trisCollider.Count
        });
        outMeshTrigger.SetSubMesh(0, new SubMeshDescriptor
        {
            indexStart = 0,
            indexCount = chunkMeshData.trisTrigger.Count
        });

        Mesh.ApplyAndDisposeWritableMeshData(outMeshDataArray, chunkMesh);
        Mesh.ApplyAndDisposeWritableMeshData(outMeshDataArrayCollider, chunkMeshCollider);
        Mesh.ApplyAndDisposeWritableMeshData(outMeshDataArrayTrigger, chunkMeshTrigger);

        chunkMesh.RecalculateNormals();
        chunkMesh.RecalculateBounds();

        //chunkMeshCollider.RecalculateNormals();
        //chunkMeshCollider.RecalculateBounds();

        //chunkMeshTrigger.RecalculateNormals();
        //chunkMeshTrigger.RecalculateBounds();

        vertexData.Dispose();
        triangelData.Dispose();

        vertexDataCollider.Dispose();
        triangelDataCollider.Dispose();

        vertexDataTrigger.Dispose();
        triangelDataTrigger.Dispose();
    }
예제 #8
0
        public JobHandle DecodeVertexData(
#if UNITY_EDITOR
            bool sync = false
#endif
            )
        {
            var decodeVerticesJob = new DecodeVerticesJob()
            {
                result             = dracoDecodeResult,
                dracoTempResources = dracoTempResources
            };
            var decodeVerticesJobHandle = decodeVerticesJob.Schedule();

#if UNITY_EDITOR
            if (sync)
            {
                decodeVerticesJobHandle.Complete();
            }
#endif

            var indicesJob = new GetDracoIndicesJob()
            {
                result             = dracoDecodeResult,
                dracoTempResources = dracoTempResources,
                flip = convertSpace,
#if DRACO_MESH_DATA
                mesh = mesh
#else
                indices = indices
#endif
            };

            NativeArray <JobHandle> jobHandles = new NativeArray <JobHandle>(attributes.Count + 1, allocator);

            jobHandles[0] = indicesJob.Schedule(decodeVerticesJobHandle);
#if UNITY_EDITOR
            if (sync)
            {
                jobHandles[0].Complete();
            }
#endif

            int jobIndex = 1;
            foreach (var mapBase in attributes)
            {
                var map = mapBase as AttributeMap;
                if (map == null)
                {
                    continue;
                }
                if (streamMemberCount[map.stream] > 1)
                {
                    var job = new GetDracoDataInterleavedJob()
                    {
                        result             = dracoDecodeResult,
                        dracoTempResources = dracoTempResources,
                        attribute          = map.dracoAttribute,
                        stride             = streamStrides[map.stream],
                        flip = map.convertSpace,
#if DRACO_MESH_DATA
                        mesh        = mesh,
                        streamIndex = map.stream,
                        offset      = map.offset
#else
                        dstPtr = vDataPtr[map.stream] + map.offset
#endif
                    };
                    jobHandles[jobIndex] = job.Schedule(decodeVerticesJobHandle);
                }
                else
                {
                    var job = new GetDracoDataJob()
                    {
                        result             = dracoDecodeResult,
                        dracoTempResources = dracoTempResources,
                        attribute          = map.dracoAttribute,
                        flip = map.convertSpace,
#if DRACO_MESH_DATA
                        mesh        = mesh,
                        streamIndex = map.stream
#else
                        dstPtr = vDataPtr[map.stream] + map.offset
#endif
                    };
                    jobHandles[jobIndex] = job.Schedule(decodeVerticesJobHandle);
                }
#if UNITY_EDITOR
                if (sync)
                {
                    jobHandles[jobIndex].Complete();
                }
#endif
                jobIndex++;
            }
            var jobHandle = JobHandle.CombineDependencies(jobHandles);
            jobHandles.Dispose();

            var releaseDracoMeshJob = new ReleaseDracoMeshJob {
                dracoTempResources = dracoTempResources
            };
            var releaseDreacoMeshJobHandle = releaseDracoMeshJob.Schedule(jobHandle);

#if UNITY_EDITOR
            if (sync)
            {
                releaseDreacoMeshJobHandle.Complete();
            }
#endif
            return(releaseDreacoMeshJobHandle);
        }
예제 #9
0
 /// <summary>
 /// Get the actual index count of a <see cref="Mesh.MeshData"/> object.
 /// </summary>
 public static int GetIndexCount(this Mesh.MeshData md)
 {
     return(md.indexFormat == IndexFormat.UInt16
             ? md.GetIndexData <ushort>().Length
             : md.GetIndexData <uint>().Length);
 }