/// <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); }
/// <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 } }
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 )
public DracoNative( #if DRACO_MESH_DATA Mesh.MeshData mesh, #endif bool convertSpace = true ) { this.convertSpace = convertSpace; #if DRACO_MESH_DATA this.mesh = mesh; #endif }
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 }
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(); }
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); }
/// <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); }