Animations now component based

This commit is contained in:
Simon Lübeß
2021-09-13 20:52:41 +02:00
parent 44374a84a7
commit b0b5f76423
3 changed files with 98 additions and 55 deletions
@@ -30,6 +30,9 @@ namespace GlitchyEngine.Renderer.Animation
public JointPose[] LocalPose ~ delete _;
public Matrix[] GlobalPose ~ delete _;
public Matrix[] SkinningMatricies ~ delete _;
public Matrix3x3[] InvTransSkinningMatricies ~ delete _;
public Skeleton Skeleton => _skeleton;
public this(Skeleton skeleton)
@@ -40,6 +43,9 @@ namespace GlitchyEngine.Renderer.Animation
LocalPose = new JointPose[jointCount];
GlobalPose = new Matrix[jointCount];
SkinningMatricies = new Matrix[jointCount];
InvTransSkinningMatricies = new Matrix3x3[jointCount];
}
}
}
@@ -6,6 +6,8 @@ namespace GlitchyEngine.World
{
private AnimationClip _animationClip;
private SkeletonPose _pose;
public AnimationClip AnimationClip
{
get => _animationClip;
@@ -20,11 +22,20 @@ namespace GlitchyEngine.World
}
}
public float TimeIndex;
public float TimeScale;
public bool IsPlaying;
public SkeletonPose Pose => _pose;
public static void DisposeComponent(void* component)
{
Self* animationComponent = (Self*)component;
animationComponent._animationClip?.ReleaseRef();
delete animationComponent._pose;
}
}
}
+52 -26
View File
@@ -222,7 +222,6 @@ namespace Sandbox
Skeleton Skeleton;
List<AnimationClip> Clips ~ delete _;
AnimationPlayer AnimationPlayer ~ delete _;
Material animationMat;
mixin UnloadModelTest()
@@ -267,14 +266,14 @@ namespace Sandbox
materialTestMaterial.ReleaseRef();
testEffect.ReleaseRef();
if(Clips != null && Clips.Count > 0)
AnimationPlayer = new AnimationPlayer(Skeleton, Clips.Back);
for(var (entity, transform, mesh, meshRenderer) in _world.Enumerate<TransformComponent, MeshComponent, SkinnedMeshRendererComponent>())
{
var animation = _world.AssignComponent<AnimationComponent>(entity);
animation.AnimationClip = Clips[0];
animation.TimeScale = 1.0f;
animation.IsPlaying = true;
animation.[Friend]_pose = new SkeletonPose(meshRenderer.Skeleton);
}
/*
@@ -417,35 +416,63 @@ namespace Sandbox
{
var material = meshRenderer.Material;
//var testEffect = Application.Get().EffectLibrary.Get("testShader");
var timeIndex = ref animation.TimeIndex;
var currentClip = animation.AnimationClip;
var pose = animation.Pose;
if(AnimationPlayer == null)
// Only advance time index if animation is playing
if(animation.IsPlaying)
{
AnimationPlayer = new AnimationPlayer(meshRenderer.Skeleton, Clips[0]);
timeIndex += (float)gameTime.FrameTime.TotalSeconds * animation.TimeScale;
if(currentClip.IsLooping && currentClip.Duration != 0)
{
timeIndex %= currentClip.Duration;
// modulo can result in negative numbers
if(timeIndex < 0)
timeIndex += currentClip.Duration;
}
}
if(AnimationPlayer != null)
// Update joints
for(int i < Skeleton.Joints.Count)
{
if(playAnimation)
AnimationPlayer.Update(gameTime);
ref JointPose localPose = ref pose.LocalPose[i];
localPose = currentClip.JointAnimations[i].GetCurrentPose(timeIndex);
Matrix jointToParent =
Matrix.Translation(localPose.Translation) *
Matrix.RotationQuaternion(localPose.Rotation) *
Matrix.Scaling(localPose.Scale);
uint8 parentIndex = Skeleton.Joints[i].ParentID;
ref Matrix globalPose = ref pose.GlobalPose[i];
if(parentIndex == uint8.MaxValue)
{
globalPose = jointToParent;
}
else
{
GameTime gt = new GameTime();
AnimationPlayer.Update(gt);
delete gt;
globalPose = pose.GlobalPose[parentIndex] * jointToParent;
}
//_context.SetRasterizerState(_rasterizerStateClockWise);
pose.SkinningMatricies[i] = globalPose * Skeleton.Joints[i].InverseBindPose;
pose.InvTransSkinningMatricies[i] = ((Matrix3x3)pose.SkinningMatricies[i]).Inverse().Transpose();
}
int i = 0;
for(var globalPose in AnimationPlayer.Pose.GlobalPose)
for(var globalPose in pose.GlobalPose)
{
Joint currentJoint = AnimationPlayer.Skeleton.Joints[i];
Joint currentJoint = meshRenderer.Skeleton.Joints[i];
Matrix bindPose = currentJoint.InverseBindPose.Invert();
// Draw skeleton
Matrix mat = AnimationPlayer.SkinningMatricies[i] * bindPose;
Matrix mat = pose.SkinningMatricies[i] * bindPose;
uint8 parentId = currentJoint.ParentID;
@@ -453,29 +480,28 @@ namespace Sandbox
{
Vector3 start = mat.Translation;
Joint parent = AnimationPlayer.Skeleton.Joints[parentId];
Joint parent = meshRenderer.Skeleton.Joints[parentId];
Matrix parentBindPose = parent.InverseBindPose.Invert();
Matrix parentMatrix = AnimationPlayer.SkinningMatricies[parentId] * parentBindPose;
Matrix parentMatrix = pose.SkinningMatricies[parentId] * parentBindPose;
Vector3 end = parentMatrix.Translation;
Renderer.DrawLine(start, end, .Black, transform.WorldTransform);
}
DebugRenderer.DrawCoordinateCross(transform.WorldTransform * mat, 2.0f);
DebugRenderer.DrawCoordinateCross(transform.WorldTransform * mat, 0.5f);
i++;
}
material.SetVariable("SkinningMatrices", AnimationPlayer.SkinningMatricies);
material.SetVariable("InvTransSkinningMatrices", AnimationPlayer.InvTransSkinningMatricies);
material.SetVariable("SkinningMatrices", pose.SkinningMatricies);
material.SetVariable("InvTransSkinningMatrices", pose.InvTransSkinningMatricies);
// TODO: non engine
// non engine
material.SetVariable("BaseColor", Color.White);
material.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
}
Renderer.Submit(mesh.Mesh, material, transform.WorldTransform);
}
@@ -515,7 +541,7 @@ namespace Sandbox
private bool OnImGuiRender(ImGuiRenderEvent e)
{
ImGui.Begin("Animation");
/*
if(AnimationPlayer != null)
{
ImGui.DragFloat("Timestamp", &AnimationPlayer.TimeStamp, 0.01f, -AnimationPlayer.CurrentClip.Duration, AnimationPlayer.CurrentClip.Duration);
@@ -527,7 +553,7 @@ namespace Sandbox
ImGui.Checkbox("Play", &playAnimation);
}
*/
ImGui.End();
ImGui.Begin("Test");