From 9dca839eaf1cf6aaaf6c6c4a3000ca4f580a7569 Mon Sep 17 00:00:00 2001 From: Maximilian Winter Date: Sat, 10 Dec 2022 22:33:36 +0100 Subject: [PATCH] Rewrote Animator to ISystem --- .../AnimationLibraryComponentAuthoring.cs | 13 +- Runtime/Scripts/AnimatorAspect.cs | 146 ------------- Runtime/Scripts/AnimatorSystem.cs | 191 +++++++++++++++++- 3 files changed, 190 insertions(+), 160 deletions(-) diff --git a/Runtime/Scripts/AnimationLibraryComponentAuthoring.cs b/Runtime/Scripts/AnimationLibraryComponentAuthoring.cs index 63bac65..b8d221b 100644 --- a/Runtime/Scripts/AnimationLibraryComponentAuthoring.cs +++ b/Runtime/Scripts/AnimationLibraryComponentAuthoring.cs @@ -17,7 +17,7 @@ namespace TAO.VertexAnimation public uint Seed; } -internal struct SkinnedMeshEntity : IBufferElementData +public struct SkinnedMeshEntity : IBufferElementData { public Entity Value; } @@ -75,7 +75,7 @@ public class AnimationLibraryComponentBaker : Baker < AnimationLibraryComponentA Random random = new Random( authoring.Seed != 0 ? authoring.Seed : 42 ); int index = random.NextInt( 20 ); // Add animator to 'parent'. - VA_AnimatorComponent animatorComponent = new VA_AnimatorComponent + AnimatorComponent animatorComponent = new AnimatorComponent { Enabled = true, AnimationName = animationsRef.animations[index].name, @@ -87,7 +87,7 @@ public class AnimationLibraryComponentBaker : Baker < AnimationLibraryComponentA AddComponent(animatorComponent); - VA_AnimatorBlendStateComponent animatorStateComponent = new VA_AnimatorBlendStateComponent + AnimatorBlendStateComponent animatorStateComponent = new AnimatorBlendStateComponent { BlendingEnabled = true, AnimationIndex = 1, @@ -110,21 +110,24 @@ public class AnimationLibraryComponentBaker : Baker < AnimationLibraryComponentA } //[GenerateAuthoringComponent] -public struct VA_AnimatorComponent : IComponentData +public struct AnimatorComponent : IComponentData { public bool Enabled; public FixedString64Bytes AnimationName; public int AnimationIndex; public int AnimationIndexNext; public float AnimationTime; + public float AnimationTimeNext; public BlobAssetReference AnimationLibrary; } -public struct VA_AnimatorBlendStateComponent : IComponentData +public struct AnimatorBlendStateComponent : IComponentData { public bool BlendingEnabled; public int AnimationIndex; public int AnimationIndexNext; public float AnimationTime; + public float AnimationTimeNext; + } } \ No newline at end of file diff --git a/Runtime/Scripts/AnimatorAspect.cs b/Runtime/Scripts/AnimatorAspect.cs index 1bddd0f..a43460b 100644 --- a/Runtime/Scripts/AnimatorAspect.cs +++ b/Runtime/Scripts/AnimatorAspect.cs @@ -4,152 +4,6 @@ using Unity.Mathematics; namespace TAO.VertexAnimation { -public readonly partial struct AnimatorAspect : IAspect -{ - private readonly RefRW < VA_AnimatorComponent > m_Animator; - private readonly RefRW < VA_AnimatorBlendStateComponent > m_AnimatorBlendState; - private readonly DynamicBuffer < SkinnedMeshEntity > m_SkinnedMeshEntities; - public void UpdateAnimator(float deltaTime, EntityCommandBuffer.ParallelWriter ecb, ref int startIndex) - { - if ( m_Animator.ValueRO.Enabled ) - { - // Get the animation lib data. - ref VA_AnimationLibraryData animationsRef = ref m_Animator.ValueRO.AnimationLibrary.Value; - - //if ( m_Animator.ValueRO.AnimationName != vaAnimatorStateComponent.CurrentAnimationName ) - //{ - // // Set the animation index on the AnimatorComponent to play this animation. - // m_Animator.ValueRO.AnimationIndexNext = VA_AnimationLibraryUtils.GetAnimation(ref animationsRef, vaAnimatorStateComponent.CurrentAnimationName); - // m_Animator.ValueRO.AnimationName = vaAnimatorStateComponent.CurrentAnimationName; - //} - - // 'Play' the actual animation. - m_Animator.ValueRW.AnimationTime += deltaTime * animationsRef.animations[m_Animator.ValueRO.AnimationIndex].frameTime; - - if ( m_Animator.ValueRO.AnimationTime > animationsRef.animations[m_Animator.ValueRO.AnimationIndex].duration ) - { - // Set time. Using the difference to smoothen out animations when looping. - m_Animator.ValueRW.AnimationTime -= animationsRef.animations[m_Animator.ValueRO.AnimationIndex].duration; - - //m_Animator.ValueRW.animationIndexNext = vaAnimatorStateComponent.Rand.NextInt( 20 ); - } - - // Lerp animations. - // Set animation for lerp. - int animationIndexNext = m_Animator.ValueRO.AnimationIndexNext; - - if ( animationIndexNext < 0 ) - { - animationIndexNext = m_Animator.ValueRO.AnimationIndex; - - //m_Animator.ValueRO.animationIndexNext = animationIndexNext + 1; - } - - // Calculate next frame time for lerp. - float animationTimeNext = m_Animator.ValueRO.AnimationTime + - ( 1.0f / animationsRef.animations[animationIndexNext].maxFrames ); - - if ( animationTimeNext > animationsRef.animations[animationIndexNext].duration ) - { - // Set time. Using the difference to smooth out animations when looping. - animationTimeNext -= m_Animator.ValueRO.AnimationTime; - } - - int animationIndexNextBlend = 0; - float animationTimeNextBlend = 0.0f; - - if ( m_AnimatorBlendState.ValueRO.BlendingEnabled ) - { - // 'Play' the actual animation. - m_AnimatorBlendState.ValueRW.AnimationTime += deltaTime * - animationsRef. - animations[m_AnimatorBlendState.ValueRO.AnimationIndex]. - frameTime; - - if ( m_AnimatorBlendState.ValueRO.AnimationTime > - animationsRef.animations[m_AnimatorBlendState.ValueRO.AnimationIndex].duration ) - { - // Set time. Using the difference to smoothen out animations when looping. - m_AnimatorBlendState.ValueRW.AnimationTime -= - animationsRef.animations[m_AnimatorBlendState.ValueRO.AnimationIndex].duration; - - //m_Animator.ValueRO.animationIndexNext = vaAnimatorStateComponent.Rand.NextInt( 20 ); - } - - // Lerp animations. - // Set animation for lerp. - animationIndexNextBlend = m_AnimatorBlendState.ValueRO.AnimationIndexNext; - - if ( animationIndexNextBlend < 0 ) - { - animationIndexNextBlend = m_AnimatorBlendState.ValueRO.AnimationIndex; - - //m_Animator.ValueRO.animationIndexNext = animationIndexNext + 1; - } - - // Calculate next frame time for lerp. - animationTimeNextBlend = m_AnimatorBlendState.ValueRO.AnimationTime + - ( 1.0f / animationsRef.animations[animationIndexNextBlend].maxFrames ); - - if ( animationTimeNextBlend > animationsRef.animations[animationIndexNextBlend].duration ) - { - // Set time. Using the difference to smooth out animations when looping. - animationTimeNextBlend -= m_AnimatorBlendState.ValueRO.AnimationTime; - } - } - - for ( int i = 0; i < m_SkinnedMeshEntities.Length; i++ ) - { - FirstAnimationDataComponent animationDataComponent = new FirstAnimationDataComponent(); - - animationDataComponent.Value = new float4 - { - x = m_Animator.ValueRO.AnimationTime, - y = VA_AnimationLibraryUtils.GetAnimationMapIndex( - ref animationsRef, - m_Animator.ValueRO.AnimationIndex ), - z = animationTimeNext, - w = VA_AnimationLibraryUtils.GetAnimationMapIndex( ref animationsRef, animationIndexNext ) - }; - - ecb.SetComponent < FirstAnimationDataComponent >(startIndex, - m_SkinnedMeshEntities[i].Value, - animationDataComponent ); - - startIndex++; - - if ( m_AnimatorBlendState.ValueRO.BlendingEnabled ) - { - SecondAnimationDataComponent animationDataComponent2 = new SecondAnimationDataComponent(); - - animationDataComponent2.Value = new float4 - { - x = m_AnimatorBlendState.ValueRO.AnimationTime, - y = VA_AnimationLibraryUtils.GetAnimationMapIndex( - ref animationsRef, - m_AnimatorBlendState.ValueRO.AnimationIndex ), - z = animationTimeNextBlend, - w = VA_AnimationLibraryUtils.GetAnimationMapIndex( - ref animationsRef, - animationIndexNextBlend ) - }; - - ecb.SetComponent < SecondAnimationDataComponent >(startIndex, - m_SkinnedMeshEntities[i].Value, - animationDataComponent2 ); - - startIndex++; - } - } - - if ( m_Animator.ValueRO.AnimationIndexNext >= 0 ) - { - m_Animator.ValueRW.AnimationIndex = animationIndexNext; - m_Animator.ValueRW.AnimationIndexNext = -1; - } - } - } -} } diff --git a/Runtime/Scripts/AnimatorSystem.cs b/Runtime/Scripts/AnimatorSystem.cs index 7fb1667..7ddffa1 100644 --- a/Runtime/Scripts/AnimatorSystem.cs +++ b/Runtime/Scripts/AnimatorSystem.cs @@ -1,35 +1,208 @@ -using System.Collections.Generic; +using Unity.Burst; using Unity.Collections; using Unity.Entities; -using Unity.Transforms; +using Unity.Jobs; using Unity.Mathematics; namespace TAO.VertexAnimation { // System to update all the animations. + +[BurstCompile] +[UpdateInGroup( typeof( SimulationSystemGroup ) )] +[UpdateAfter( typeof( BeginSimulationEntityCommandBufferSystem ) )] public partial struct AnimatorSystem : ISystem { + //private EntityQuery m_Group; + [BurstCompile] public void OnCreate( ref SystemState state ) { + //NativeArray < ComponentType > componentTypes = new NativeArray < ComponentType >( 2, Allocator.Persistent ); + //componentTypes[0] = ComponentType.ReadWrite < AnimatorComponent >(); + //componentTypes[1] = ComponentType.ReadWrite(); + //m_Group = state.GetEntityQuery(componentTypes); } + [BurstCompile] public void OnDestroy( ref SystemState state ) { } + [BurstCompile] public void OnUpdate( ref SystemState state ) { float deltaTime = SystemAPI.Time.DeltaTime; - EntityCommandBuffer ecb = new EntityCommandBuffer( Allocator.Temp ); - int i = 0; - foreach ( var animatorAspect in SystemAPI. - Query < AnimatorAspect >() ) + + EntityCommandBuffer ecb = SystemAPI.GetSingleton < BeginSimulationEntityCommandBufferSystem.Singleton >(). + CreateCommandBuffer( state.WorldUnmanaged ); + + UpdateAnimatorJob job = + new UpdateAnimatorJob { DeltaTime = deltaTime, StartIndex = 0, Ecb = ecb.AsParallelWriter() }; + + job.Run(); + + //handle.Complete(); + // state.Dependency = JobHandle.CombineDependencies( ecb., state.Dependency ); + //state.Dependency.Complete(); + + // int i = 0; + // for ( int j = 0; j < jobHandles.Length; j++ ) + // { + // jobHandles2.Add(new UpdateAnimatedMeshMaterialParametersJob { Ecb = ecb.AsParallelWriter(), StartIndex = i }.ScheduleParallel(jobHandles[j] )); + // i += 2; + // } + // + // for ( int j = 0; j < jobHandles2.Length; j++ ) + // { + // jobHandles2[j].Complete(); + // } + // //ecb.Playback( state.EntityManager ); + } +} + +[BurstCompile] +public partial struct UpdateAnimatorJob : IJobEntity +{ + public float DeltaTime; + public int StartIndex; + public EntityCommandBuffer.ParallelWriter Ecb; + + [BurstCompile] + public void Execute( + ref AnimatorComponent animator, + ref AnimatorBlendStateComponent animatorBlendState, + in DynamicBuffer < SkinnedMeshEntity > buffer ) + { + if ( animator.Enabled ) { - animatorAspect.UpdateAnimator( deltaTime, ecb.AsParallelWriter(), ref i ); + // Get the animation lib data. + ref VA_AnimationLibraryData animationsRef = ref animator.AnimationLibrary.Value; + + //if ( animator.AnimationName != vaAnimatorStateComponent.CurrentAnimationName ) + //{ + // // Set the animation index on the AnimatorComponent to play this animation. + // animator.AnimationIndexNext = VA_AnimationLibraryUtils.GetAnimation(ref animationsRef, vaAnimatorStateComponent.CurrentAnimationName); + // animator.AnimationName = vaAnimatorStateComponent.CurrentAnimationName; + //} + + // 'Play' the actual animation. + animator.AnimationTime += DeltaTime * animationsRef.animations[animator.AnimationIndex].frameTime; + + if ( animator.AnimationTime > animationsRef.animations[animator.AnimationIndex].duration ) + { + // Set time. Using the difference to smoothen out animations when looping. + animator.AnimationTime -= animationsRef.animations[animator.AnimationIndex].duration; + + //animator.animationIndexNext = vaAnimatorStateComponent.Rand.NextInt( 20 ); + } + + // Lerp animations. + // Set animation for lerp. + int animationIndexNext = animator.AnimationIndexNext; + + if ( animationIndexNext < 0 ) + { + animationIndexNext = animator.AnimationIndex; + + //animator.animationIndexNext = animationIndexNext + 1; + } + + // Calculate next frame time for lerp. + float animationTimeNext = animator.AnimationTime + + ( 1.0f / animationsRef.animations[animationIndexNext].maxFrames ); + + if ( animationTimeNext > animationsRef.animations[animationIndexNext].duration ) + { + // Set time. Using the difference to smooth out animations when looping. + animationTimeNext -= animator.AnimationTime; + } + + int animationIndexNextBlend = 0; + float animationTimeNextBlend = 0.0f; + + if ( animatorBlendState.BlendingEnabled ) + { + // 'Play' the actual animation. + animatorBlendState.AnimationTime += DeltaTime * + animationsRef. + animations[animatorBlendState.AnimationIndex]. + frameTime; + + if ( animatorBlendState.AnimationTime > + animationsRef.animations[animatorBlendState.AnimationIndex].duration ) + { + // Set time. Using the difference to smoothen out animations when looping. + animatorBlendState.AnimationTime -= + animationsRef.animations[animatorBlendState.AnimationIndex].duration; + + //animator.animationIndexNext = vaAnimatorStateComponent.Rand.NextInt( 20 ); + } + + // Lerp animations. + // Set animation for lerp. + animationIndexNextBlend = animatorBlendState.AnimationIndexNext; + + if ( animationIndexNextBlend < 0 ) + { + animationIndexNextBlend = animatorBlendState.AnimationIndex; + + //animator.animationIndexNext = animationIndexNext + 1; + } + + // Calculate next frame time for lerp. + animationTimeNextBlend = animatorBlendState.AnimationTime + + ( 1.0f / animationsRef.animations[animationIndexNextBlend].maxFrames ); + + if ( animationTimeNextBlend > animationsRef.animations[animationIndexNextBlend].duration ) + { + // Set time. Using the difference to smooth out animations when looping. + animationTimeNextBlend -= animatorBlendState.AnimationTime; + } + } + + for ( int i = 0; i < buffer.Length; i++ ) + { + FirstAnimationDataComponent vaAnimationDataComponent = new FirstAnimationDataComponent(); + + vaAnimationDataComponent.Value = new float4 + { + x = animator.AnimationTime, + y = VA_AnimationLibraryUtils.GetAnimationMapIndex( ref animationsRef, animator.AnimationIndex ), + z = animationTimeNext, + w = VA_AnimationLibraryUtils.GetAnimationMapIndex( ref animationsRef, animationIndexNext ) + }; + + SystemAPI.SetComponent < FirstAnimationDataComponent >( buffer[i].Value, vaAnimationDataComponent ); + + if ( animatorBlendState.BlendingEnabled ) + { + SecondAnimationDataComponent vaAnimationDataComponent2 = new SecondAnimationDataComponent(); + + vaAnimationDataComponent2.Value = new float4 + { + x = animatorBlendState.AnimationTime, + y = VA_AnimationLibraryUtils.GetAnimationMapIndex( + ref animationsRef, + animatorBlendState.AnimationIndex ), + z = animationTimeNextBlend, + w = VA_AnimationLibraryUtils.GetAnimationMapIndex( + ref animationsRef, + animationIndexNextBlend ) + }; + + SystemAPI.SetComponent < SecondAnimationDataComponent >( + buffer[i].Value, + vaAnimationDataComponent2 ); + } + } + + if ( animator.AnimationIndexNext >= 0 ) + { + animator.AnimationIndex = animationIndexNext; + animator.AnimationIndexNext = -1; + } } - - ecb.Playback( state.EntityManager ); } }