using System; using System.Collections.Generic; using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine; namespace NGS.MeshFusionPro; public class JobsMeshMoverLW : IAsyncCombinedMeshMover, ICombinedMeshMover, IDisposable { [BurstCompile] private struct MovePartsJob : IJobParallelFor { [NativeDisableParallelForRestriction] public NativeArray vertices; [ReadOnly] public NativeArray localVertices; [WriteOnly] [NativeDisableParallelForRestriction] public NativeArray bounds; [ReadOnly] [NativeDisableParallelForRestriction] public NativeArray localBounds; [ReadOnly] public NativeList moveInfos; public void Execute(int idx) { PartMoveInfo partMoveInfo = moveInfos[idx]; int partIndex = partMoveInfo.partIndex; int vertexStart = partMoveInfo.vertexStart; int num = vertexStart + partMoveInfo.vertexCount; Matrix4x4 targetTransform = partMoveInfo.targetTransform; for (int i = vertexStart; i < num; i++) { LightweightVertex lightweightVertex = localVertices[i]; float w = lightweightVertex.tanW; Vector3 normalized = targetTransform.MultiplyVector(lightweightVertex.Normal).normalized; Vector4 tangent = targetTransform.MultiplyVector(lightweightVertex.Tangent).normalized; tangent.w = w; LightweightVertex lightweightVertex2 = default(LightweightVertex); lightweightVertex2.Position = targetTransform.MultiplyPoint3x4(lightweightVertex.Position); lightweightVertex2.Normal = normalized; lightweightVertex2.Tangent = tangent; lightweightVertex2.uv = lightweightVertex.uv; lightweightVertex2.uv2 = lightweightVertex.uv2; LightweightVertex value = lightweightVertex2; vertices[i] = value; } bounds[partIndex] = localBounds[partIndex].Transform(targetTransform); } } [BurstCompile] private struct RecalculateBoundsJob : IJob { public NativeArray bounds; public NativeArray boundingBox; public void Execute() { Bounds value = boundingBox[0]; value.size = Vector3.zero; for (int i = 0; i < bounds.Length; i++) { value.Encapsulate(bounds[i]); } boundingBox[0] = value; } } private MeshDataNativeArraysLW _meshData; private NativeList _moveInfos; private JobHandle _handle; public JobsMeshMoverLW(MeshDataNativeArraysLW meshData) { _meshData = meshData; _moveInfos = new NativeList(Allocator.Persistent); } public void MoveParts(IList moveInfos) { MovePartsAsync(moveInfos); FinishAsyncMoving(); } public void MovePartsAsync(IList moveInfos) { NativeArray bounds = _meshData.Bounds; bounds[0] = new Bounds(_meshData.GetBounds().center, Vector3.zero); _moveInfos.Clear(); for (int i = 0; i < moveInfos.Count; i++) { ref NativeList moveInfos2 = ref _moveInfos; PartMoveInfo value = moveInfos[i]; moveInfos2.Add(in value); } MovePartsJob movePartsJob = default(MovePartsJob); movePartsJob.vertices = _meshData.Vertices; movePartsJob.bounds = _meshData.PartsBounds; movePartsJob.localVertices = _meshData.VerticesLocal; movePartsJob.localBounds = _meshData.PartsBoundsLocal; movePartsJob.moveInfos = _moveInfos; MovePartsJob jobData = movePartsJob; RecalculateBoundsJob recalculateBoundsJob = default(RecalculateBoundsJob); recalculateBoundsJob.bounds = _meshData.PartsBounds; recalculateBoundsJob.boundingBox = bounds; RecalculateBoundsJob jobData2 = recalculateBoundsJob; _handle = jobData2.Schedule(IJobParallelForExtensions.Schedule(jobData, _moveInfos.Length, 4)); } public void FinishAsyncMoving() { _handle.Complete(); } public void ApplyData() { if (!_handle.IsCompleted) { FinishAsyncMoving(); } _meshData.ApplyDataToMesh(); } public void Dispose() { _moveInfos.Dispose(); } }