#if ENABLE_ENTITIES using System.Collections.Generic; using Unity.Entities; using Unity.Mathematics; using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine.Scripting; namespace UnityEngine.U2D.Animation { [Preserve] [UnityEngine.ExecuteAlways] [UpdateInGroup(typeof(PresentationSystemGroup))] [UpdateAfter(typeof(PrepareSkinningSystem))] class DeformSpriteSystem : JobComponentSystem { List m_UniqueSpriteComponents = new List(16); EntityQuery m_ComponentGroup; protected override void OnCreateManager() { m_ComponentGroup = GetEntityQuery(typeof(WorldToLocal), typeof(SpriteComponent), typeof(Vertex), typeof(BoneTransform)); } [BurstCompile] public struct SkinJob : IJobParallelFor { // these are readonly per sprite and shared [ReadOnly] [DeallocateOnJobCompletion] public NativeArray entities; [ReadOnly] public NativeSlice vertices; [ReadOnly] public NativeSlice boneWeights; [ReadOnly] public NativeSlice bindPoses; [ReadOnly] [DeallocateOnJobCompletion] public NativeArray localToWorldArray; // these are calculated per renderer and per instance [NativeDisableParallelForRestriction] public BufferFromEntity boneTransformArray; [NativeDisableParallelForRestriction] public BufferFromEntity deformedArray; public void Execute(int i) { var rootTransformId = localToWorldArray[i].Value; var boneTransforms = boneTransformArray[entities[i]].Reinterpret().AsNativeArray(); var deformableVertices = deformedArray[entities[i]].Reinterpret().AsNativeArray(); SpriteSkinUtility.Deform(rootTransformId, vertices, boneWeights, boneTransforms, bindPoses, deformableVertices); } } protected override JobHandle OnUpdate(JobHandle inputDeps) { m_UniqueSpriteComponents.Clear(); EntityManager.GetAllUniqueSharedComponentData(m_UniqueSpriteComponents); var spriteComponentCount = m_UniqueSpriteComponents.Count; var returnHandle = inputDeps; for (var i = 0; i < spriteComponentCount; i++) { var spriteComponent = m_UniqueSpriteComponents[i]; var sprite = spriteComponent.Value; var entityCount = 0; if (sprite != null) { m_ComponentGroup.SetFilter(spriteComponent); var filteredEntities = m_ComponentGroup.ToEntityArray(Allocator.TempJob); entityCount = filteredEntities.Length; if (entityCount > 0) { var skinJob = new SkinJob { entities = filteredEntities, vertices = sprite.GetVertexAttribute(UnityEngine.Rendering.VertexAttribute.Position).SliceWithStride(), boneWeights = sprite.GetVertexAttribute(UnityEngine.Rendering.VertexAttribute.BlendWeight), bindPoses = new NativeSlice(sprite.GetBindPoses()).SliceWithStride(), localToWorldArray = m_ComponentGroup.ToComponentDataArray(Allocator.TempJob), boneTransformArray = GetBufferFromEntity(), deformedArray = GetBufferFromEntity() }; returnHandle = skinJob.Schedule(entityCount, 4, returnHandle); } else filteredEntities.Dispose(); } } var system = World.GetOrCreateSystem(); system.AddJobHandleForProducer(returnHandle); return returnHandle; } } } #endif