Added basic blending and refactored some files

This commit is contained in:
Maximilian Winter
2022-12-10 15:02:53 +01:00
parent ee0fa7a5fa
commit 9f8a7fb7d8
43 changed files with 13583 additions and 345 deletions

View File

@ -33,9 +33,9 @@ public class AnimatedPrefabSpawner : MonoBehaviour
}
currentPosition = new Vector3( startPosition.x , currentPosition.y, currentPosition.z + Distance );
}
VA_AnimationLibraryComponentAuthoring[] vaAnimationLibraryComponentAuthorings = Parent.GetComponentsInChildren < VA_AnimationLibraryComponentAuthoring >();
AnimationLibraryComponentAuthoring[] vaAnimationLibraryComponentAuthorings = Parent.GetComponentsInChildren < AnimationLibraryComponentAuthoring >();
foreach ( VA_AnimationLibraryComponentAuthoring authoring in vaAnimationLibraryComponentAuthorings )
foreach ( AnimationLibraryComponentAuthoring authoring in vaAnimationLibraryComponentAuthorings )
{
var test = Guid.NewGuid().GetHashCode().ToString();
Debug.Log( test );

View File

@ -3,7 +3,7 @@ using UnityEngine;
namespace TAO.VertexAnimation
{
public class VA_Animation : ScriptableObject
public class Animation : ScriptableObject
{
public VA_AnimationData Data;

View File

@ -4,14 +4,14 @@ using UnityEngine;
namespace TAO.VertexAnimation
{
[CreateAssetMenu(fileName = "new AnimationBook", menuName = "TAO/VertexAnimation/AnimationBook", order = 400)]
public class VA_AnimationBook : ScriptableObject
public class AnimationBook : ScriptableObject
{
public VA_AnimationBook(Texture2DArray a_positionMap)
public AnimationBook(Texture2DArray a_positionMap)
{
positionMap = a_positionMap;
}
public VA_AnimationBook(Texture2DArray a_positionMap, List<VA_Animation> a_animations)
public AnimationBook(Texture2DArray a_positionMap, List<Animation> a_animations)
{
positionMap = a_positionMap;
@ -24,10 +24,10 @@ namespace TAO.VertexAnimation
public int MaxFrames { get; private set; } = 0;
public Texture2DArray positionMap = null;
public List<VA_Animation> animations = new List<VA_Animation>();
public List<Animation> animations = new List<Animation>();
public List<Material> materials = new List<Material>();
public bool TryAddAnimation(VA_Animation animation)
public bool TryAddAnimation(Animation animation)
{
if (animations != null && animations.Count != 0)
{

View File

@ -0,0 +1,25 @@
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
namespace TAO.VertexAnimation
{
public class AnimationDataComponentAuthoring : MonoBehaviour
{
public float4 AnimationDataOne;
public float4 AnimationDataTwo;
public float BlendFactor;
}
public class AnimationDataComponentBaker : Baker < AnimationDataComponentAuthoring >
{
public override void Bake( AnimationDataComponentAuthoring authoring )
{
//Entity parent = GetEntity( authoring.RootParent );
AddComponent( new FirstAnimationDataComponent{ Value = authoring.AnimationDataOne} );
AddComponent( new SecondAnimationDataComponent{ Value = authoring.AnimationDataTwo} );
AddComponent( new BlendingAnimationDataComponent{ Value = authoring.BlendFactor} );
}
}
}

View File

@ -5,30 +5,30 @@ using UnityEngine;
namespace TAO.VertexAnimation
{
[CreateAssetMenu(fileName = "new AnimationLibrary", menuName = "TAO/VertexAnimation/AnimationLibrary", order = 400)]
public class VA_AnimationLibrary : ScriptableObject
public class AnimationLibrary : ScriptableObject
{
[SerializeField]
private List<VA_AnimationBook> animationBooks = new List<VA_AnimationBook>();
private List<AnimationBook> animationBooks = new List<AnimationBook>();
[HideInInspector]
public List<VA_AnimationData> animationData = null;
#if UNITY_EDITOR
[SerializeField]
private List<VA_Animation> loadedAnimationsPreview = null;
private List<Animation> loadedAnimationsPreview = null;
#endif
public void Init()
{
animationData = new List<VA_AnimationData>();
foreach (VA_AnimationBook book in animationBooks)
foreach (AnimationBook book in animationBooks)
{
book.UpdateMaterials();
if (book != null)
{
foreach (VA_Animation animation in book.animations)
foreach (Animation animation in book.animations)
{
// TODO: Fix data name, FixedString32 doesn't transfer from editor?
//animation.Data.name = new FixedString32(animation.name);
@ -40,13 +40,13 @@ namespace TAO.VertexAnimation
public void OnValidate()
{
Dictionary<string, VA_Animation> usedNames = new Dictionary<string, VA_Animation>();
Dictionary<string, Animation> usedNames = new Dictionary<string, Animation>();
foreach (VA_AnimationBook book in animationBooks)
foreach (AnimationBook book in animationBooks)
{
if (book != null)
{
foreach (VA_Animation animation in book.animations)
foreach (Animation animation in book.animations)
{
if (!usedNames.ContainsKey(animation.name))
{
@ -61,7 +61,7 @@ namespace TAO.VertexAnimation
}
#if UNITY_EDITOR
loadedAnimationsPreview = new List<VA_Animation>();
loadedAnimationsPreview = new List<Animation>();
foreach (var un in usedNames)
{
loadedAnimationsPreview.Add(un.Value);

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Unity.Entities;
using Unity.Collections;
using Unity.Mathematics;
@ -9,9 +10,9 @@ using Random = Unity.Mathematics.Random;
namespace TAO.VertexAnimation
{
[UnityEngine.DisallowMultipleComponent]
public class VA_AnimationLibraryComponentAuthoring : UnityEngine.MonoBehaviour
public class AnimationLibraryComponentAuthoring : UnityEngine.MonoBehaviour
{
public VA_AnimationLibrary AnimationLibrary;
public AnimationLibrary AnimationLibrary;
public bool DebugMode = false;
public uint Seed;
}
@ -21,18 +22,18 @@ internal struct SkinnedMeshEntity : IBufferElementData
public Entity Value;
}
public struct VA_AnimationLibraryComponent : IComponentData
public struct AnimationLibraryComponent : IComponentData
{
public BlobAssetReference<VA_AnimationLibraryData> AnimLibAssetRef;
public BlobAssetStore BlobAssetStore;
}
public class VA_AnimationLibraryComponentBaker : Baker < VA_AnimationLibraryComponentAuthoring >
public class AnimationLibraryComponentBaker : Baker < AnimationLibraryComponentAuthoring >
{
public override void Bake( VA_AnimationLibraryComponentAuthoring authoring )
public override void Bake( AnimationLibraryComponentAuthoring authoring )
{
authoring.AnimationLibrary.Init();
VA_AnimationLibraryComponent animationLibrary = new VA_AnimationLibraryComponent();
AnimationLibraryComponent animationLibrary = new AnimationLibraryComponent();
using (BlobBuilder blobBuilder = new BlobBuilder(Allocator.Temp))
{
// Construct the root.
@ -71,60 +72,59 @@ public class VA_AnimationLibraryComponentBaker : Baker < VA_AnimationLibraryComp
BlobAssetReference<VA_AnimationLibraryData> animLib = animationLibrary.AnimLibAssetRef;
// Get the animation lib data.
ref VA_AnimationLibraryData animationsRef = ref animLib.Value;
Random random = new Random( authoring.Seed );
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
{
Enabled = true,
AnimationName = animationsRef.animations[index].name,
animationIndex = index,
animationIndexNext = -1,
animationTime = 0,
animationLibrary = animLib
AnimationIndex = 2,
AnimationIndexNext = -1,
AnimationTime = 0,
AnimationLibrary = animLib
};
AddComponent(animatorComponent);
VA_AnimatorStateComponent animatorStateComponent = new VA_AnimatorStateComponent
VA_AnimatorBlendStateComponent animatorStateComponent = new VA_AnimatorBlendStateComponent
{
Enabled = true,
CurrentAnimationName = animationsRef.animations[index].name,
AnimationIndex = index,
BlendingEnabled = true,
AnimationIndex = 1,
AnimationIndexNext = -1,
AnimationTime = 0
};
AddComponent( animatorStateComponent );
var boneEntityArray = AddBuffer<SkinnedMeshEntity>();
MeshRenderer[] skinnedMeshRenderers =
MeshRenderer[] meshRenderers =
authoring.transform.GetComponentsInChildren < MeshRenderer >();
boneEntityArray.ResizeUninitialized(skinnedMeshRenderers.Length);
for (int boneIndex = 0; boneIndex < skinnedMeshRenderers.Length; ++boneIndex)
boneEntityArray.ResizeUninitialized(meshRenderers.Length);
for (int meshIndex = 0; meshIndex < meshRenderers.Length; ++meshIndex)
{
var boneEntity = GetEntity(skinnedMeshRenderers[boneIndex]);
boneEntityArray[boneIndex] = new SkinnedMeshEntity {Value = boneEntity};
var meshEntity = GetEntity(meshRenderers[meshIndex]);
boneEntityArray[meshIndex] = new SkinnedMeshEntity {Value = meshEntity};
}
}
}
//[GenerateAuthoringComponent]
public struct VA_AnimatorComponent : IComponentData
{
public FixedString64Bytes AnimationName;
public int animationIndex;
public int animationIndexNext;
public float animationTime;
public BlobAssetReference<VA_AnimationLibraryData> animationLibrary;
}
public struct VA_AnimatorStateComponent : IComponentData
{
public bool Enabled;
public FixedString64Bytes CurrentAnimationName;
public FixedString64Bytes AnimationName;
public int AnimationIndex;
public int AnimationIndexNext;
public Random Rand;
public float AnimationTime;
public BlobAssetReference<VA_AnimationLibraryData> AnimationLibrary;
}
public struct VA_AnimatorBlendStateComponent : IComponentData
{
public bool BlendingEnabled;
public int AnimationIndex;
public int AnimationIndexNext;
public float AnimationTime;
}
}

View File

@ -0,0 +1,155 @@
using Unity.Entities;
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;
}
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 116de67f78e741cb93a39dc3de9449a3
timeCreated: 1670678206

View File

@ -0,0 +1,36 @@
using System.Collections.Generic;
using Unity.Collections;
using Unity.Entities;
using Unity.Transforms;
using Unity.Mathematics;
namespace TAO.VertexAnimation
{
// System to update all the animations.
public partial struct AnimatorSystem : ISystem
{
public void OnCreate( ref SystemState state )
{
}
public void OnDestroy( ref SystemState state )
{
}
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 >() )
{
animatorAspect.UpdateAnimator( deltaTime, ecb.AsParallelWriter(), ref i );
}
ecb.Playback( state.EntityManager );
}
}
}

View File

@ -0,0 +1,28 @@
using Unity.Entities;
using Unity.Mathematics;
using Unity.Rendering;
namespace TAO.VertexAnimation
{
[MaterialProperty("_AnimationDataOne")] //, MaterialPropertyFormat.Float4
public struct FirstAnimationDataComponent : IComponentData
{
// animationTime, animationIndex, colorIndex, nan.
public float4 Value;
}
[MaterialProperty("_AnimationDataTwo")] //, MaterialPropertyFormat.Float4
public struct SecondAnimationDataComponent : IComponentData
{
// animationTime, animationIndex, colorIndex, nan.
public float4 Value;
}
[MaterialProperty("_AnimationDataBlend")] //, MaterialPropertyFormat.Float4
public struct BlendingAnimationDataComponent : IComponentData
{
// animationTime, animationIndex, colorIndex, nan.
public float Value;
}
}

View File

@ -128,7 +128,7 @@ namespace TAO.VertexAnimation
// Bake mesh for a copy and to apply the new UV's to.
SkinnedMeshRenderer skinnedMeshRenderer = model.GetComponent<SkinnedMeshRenderer>();
skinnedMeshRenderer.BakeMesh(mesh);
mesh = model.GetComponent<SkinnedMeshRenderer>().sharedMesh.Copy();
mesh.RecalculateBounds();
mesh.uv3 = mesh.BakePositionUVs(animationInfo);

View File

@ -7,11 +7,10 @@ namespace TAO.VertexAnimation
public static Mesh[] GenerateLOD(this Mesh mesh, int lods, float[] quality)
{
Mesh[] lodMeshes = new Mesh[lods];
for (int lm = 0; lm < lodMeshes.Length; lm++)
{
lodMeshes[lm] = mesh.Copy();
// Only simplify when needed.
if (quality[lm] < 1.0f)
{

View File

@ -24,7 +24,7 @@ namespace TAO.VertexAnimation
uv5 = mesh.uv5,
uv6 = mesh.uv6,
uv7 = mesh.uv7,
uv8 = mesh.uv8
uv8 = mesh.uv8,
};
return copy;
@ -35,6 +35,7 @@ namespace TAO.VertexAnimation
{
mesh.Optimize();
mesh.UploadMeshData(true);
}
}
}

View File

@ -2,7 +2,7 @@
namespace TAO.VertexAnimation
{
public static class VA_Texture2DArrayUtils
public static class Texture2DArrayUtils
{
public static Texture2DArray CreateTextureArray(Texture2D[] a_textures, bool a_useMipChain, bool a_isLinear,
TextureWrapMode a_wrapMode = TextureWrapMode.Repeat, FilterMode a_filterMode = FilterMode.Bilinear, int a_anisoLevel = 1, string a_name = "", bool a_makeNoLongerReadable = true)

View File

@ -1,21 +0,0 @@
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
namespace TAO.VertexAnimation
{
public class VA_AnimationDataComponentAuthoring : MonoBehaviour
{
public float4 Color;
}
public class VA_AnimationDataBaker : Baker < VA_AnimationDataComponentAuthoring >
{
public override void Bake( VA_AnimationDataComponentAuthoring authoring )
{
//Entity parent = GetEntity( authoring.RootParent );
AddComponent( new VaAnimationDataComponent{ Value = authoring.Color} );
}
}
}

View File

@ -1,9 +0,0 @@
using Unity.Entities;
using Unity.Transforms;
using Unity.Collections;
using UnityEngine;
namespace TAO.VertexAnimation
{
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 29deecb09ead9e74aa32f9d265f1e7ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,74 +0,0 @@
using System.Collections.Generic;
using Unity.Entities;
using Unity.Transforms;
using Unity.Mathematics;
namespace TAO.VertexAnimation
{
// System to update all the animations.
public partial class VA_AnimatorSystem : SystemBase
{
protected override void OnUpdate()
{
float deltaTime = SystemAPI.Time.DeltaTime;
// This is only executed if we have a valid skinning setup
Entities
.ForEach((ref VA_AnimatorComponent animator, in VA_AnimatorStateComponent vaAnimatorStateComponent, in DynamicBuffer<SkinnedMeshEntity> bones) =>
{
if ( vaAnimatorStateComponent.Enabled )
{
// 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.animationIndex = 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;
}
// Lerp animations.
// Set animation for lerp.
int animationIndexNext = animator.animationIndexNext;
if (animator.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;
}
for ( int i = 0; i < bones.Length; i++ )
{
VaAnimationDataComponent vaAnimationDataComponent = new VaAnimationDataComponent();
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<VaAnimationDataComponent>( bones[i].Value, vaAnimationDataComponent );
}
}
}).Run();
}
}
}

View File

@ -1,15 +0,0 @@
using Unity.Entities;
using Unity.Mathematics;
using Unity.Rendering;
namespace TAO.VertexAnimation
{
[MaterialProperty("_AnimationData")] //, MaterialPropertyFormat.Float4
public struct VaAnimationDataComponent : IComponentData
{
// animationTime, animationIndex, colorIndex, nan.
public float4 Value;
}
}