mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Animations now component based
This commit is contained in:
@@ -29,6 +29,9 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
private Skeleton _skeleton ~ _.ReleaseRef();
|
private Skeleton _skeleton ~ _.ReleaseRef();
|
||||||
public JointPose[] LocalPose ~ delete _;
|
public JointPose[] LocalPose ~ delete _;
|
||||||
public Matrix[] GlobalPose ~ delete _;
|
public Matrix[] GlobalPose ~ delete _;
|
||||||
|
|
||||||
|
public Matrix[] SkinningMatricies ~ delete _;
|
||||||
|
public Matrix3x3[] InvTransSkinningMatricies ~ delete _;
|
||||||
|
|
||||||
public Skeleton Skeleton => _skeleton;
|
public Skeleton Skeleton => _skeleton;
|
||||||
|
|
||||||
@@ -40,6 +43,9 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
|
|
||||||
LocalPose = new JointPose[jointCount];
|
LocalPose = new JointPose[jointCount];
|
||||||
GlobalPose = new Matrix[jointCount];
|
GlobalPose = new Matrix[jointCount];
|
||||||
|
|
||||||
|
SkinningMatricies = new Matrix[jointCount];
|
||||||
|
InvTransSkinningMatricies = new Matrix3x3[jointCount];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ namespace GlitchyEngine.World
|
|||||||
{
|
{
|
||||||
private AnimationClip _animationClip;
|
private AnimationClip _animationClip;
|
||||||
|
|
||||||
|
private SkeletonPose _pose;
|
||||||
|
|
||||||
public AnimationClip AnimationClip
|
public AnimationClip AnimationClip
|
||||||
{
|
{
|
||||||
get => _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)
|
public static void DisposeComponent(void* component)
|
||||||
{
|
{
|
||||||
Self* animationComponent = (Self*)component;
|
Self* animationComponent = (Self*)component;
|
||||||
|
|
||||||
animationComponent._animationClip?.ReleaseRef();
|
animationComponent._animationClip?.ReleaseRef();
|
||||||
|
delete animationComponent._pose;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+81
-55
@@ -222,7 +222,6 @@ namespace Sandbox
|
|||||||
Skeleton Skeleton;
|
Skeleton Skeleton;
|
||||||
List<AnimationClip> Clips ~ delete _;
|
List<AnimationClip> Clips ~ delete _;
|
||||||
|
|
||||||
AnimationPlayer AnimationPlayer ~ delete _;
|
|
||||||
Material animationMat;
|
Material animationMat;
|
||||||
|
|
||||||
mixin UnloadModelTest()
|
mixin UnloadModelTest()
|
||||||
@@ -267,14 +266,14 @@ namespace Sandbox
|
|||||||
materialTestMaterial.ReleaseRef();
|
materialTestMaterial.ReleaseRef();
|
||||||
testEffect.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>())
|
for(var (entity, transform, mesh, meshRenderer) in _world.Enumerate<TransformComponent, MeshComponent, SkinnedMeshRendererComponent>())
|
||||||
{
|
{
|
||||||
var animation = _world.AssignComponent<AnimationComponent>(entity);
|
var animation = _world.AssignComponent<AnimationComponent>(entity);
|
||||||
|
|
||||||
animation.AnimationClip = Clips[0];
|
animation.AnimationClip = Clips[0];
|
||||||
|
animation.TimeScale = 1.0f;
|
||||||
|
animation.IsPlaying = true;
|
||||||
|
animation.[Friend]_pose = new SkeletonPose(meshRenderer.Skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -417,65 +416,92 @@ namespace Sandbox
|
|||||||
{
|
{
|
||||||
var material = meshRenderer.Material;
|
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)
|
ref JointPose localPose = ref pose.LocalPose[i];
|
||||||
AnimationPlayer.Update(gameTime);
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
GameTime gt = new GameTime();
|
globalPose = pose.GlobalPose[parentIndex] * jointToParent;
|
||||||
AnimationPlayer.Update(gt);
|
|
||||||
delete gt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//_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)
|
|
||||||
{
|
|
||||||
Joint currentJoint = AnimationPlayer.Skeleton.Joints[i];
|
|
||||||
|
|
||||||
Matrix bindPose = currentJoint.InverseBindPose.Invert();
|
|
||||||
|
|
||||||
// Draw skeleton
|
|
||||||
Matrix mat = AnimationPlayer.SkinningMatricies[i] * bindPose;
|
|
||||||
|
|
||||||
uint8 parentId = currentJoint.ParentID;
|
|
||||||
|
|
||||||
if(parentId != uint8.MaxValue)
|
|
||||||
{
|
|
||||||
Vector3 start = mat.Translation;
|
|
||||||
|
|
||||||
Joint parent = AnimationPlayer.Skeleton.Joints[parentId];
|
|
||||||
|
|
||||||
Matrix parentBindPose = parent.InverseBindPose.Invert();
|
|
||||||
|
|
||||||
Matrix parentMatrix = AnimationPlayer.SkinningMatricies[parentId] * parentBindPose;
|
|
||||||
|
|
||||||
Vector3 end = parentMatrix.Translation;
|
|
||||||
|
|
||||||
Renderer.DrawLine(start, end, .Black, transform.WorldTransform);
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugRenderer.DrawCoordinateCross(transform.WorldTransform * mat, 2.0f);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
material.SetVariable("SkinningMatrices", AnimationPlayer.SkinningMatricies);
|
|
||||||
material.SetVariable("InvTransSkinningMatrices", AnimationPlayer.InvTransSkinningMatricies);
|
|
||||||
|
|
||||||
// TODO: non engine
|
|
||||||
material.SetVariable("BaseColor", Color.White);
|
|
||||||
material.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for(var globalPose in pose.GlobalPose)
|
||||||
|
{
|
||||||
|
Joint currentJoint = meshRenderer.Skeleton.Joints[i];
|
||||||
|
|
||||||
|
Matrix bindPose = currentJoint.InverseBindPose.Invert();
|
||||||
|
|
||||||
|
// Draw skeleton
|
||||||
|
Matrix mat = pose.SkinningMatricies[i] * bindPose;
|
||||||
|
|
||||||
|
uint8 parentId = currentJoint.ParentID;
|
||||||
|
|
||||||
|
if(parentId != uint8.MaxValue)
|
||||||
|
{
|
||||||
|
Vector3 start = mat.Translation;
|
||||||
|
|
||||||
|
Joint parent = meshRenderer.Skeleton.Joints[parentId];
|
||||||
|
|
||||||
|
Matrix parentBindPose = parent.InverseBindPose.Invert();
|
||||||
|
|
||||||
|
Matrix parentMatrix = pose.SkinningMatricies[parentId] * parentBindPose;
|
||||||
|
|
||||||
|
Vector3 end = parentMatrix.Translation;
|
||||||
|
|
||||||
|
Renderer.DrawLine(start, end, .Black, transform.WorldTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugRenderer.DrawCoordinateCross(transform.WorldTransform * mat, 0.5f);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
material.SetVariable("SkinningMatrices", pose.SkinningMatricies);
|
||||||
|
material.SetVariable("InvTransSkinningMatrices", pose.InvTransSkinningMatricies);
|
||||||
|
|
||||||
|
// non engine
|
||||||
|
material.SetVariable("BaseColor", Color.White);
|
||||||
|
material.SetVariable("LightDir", Vector3(1, 1, -0.5f).Normalized());
|
||||||
|
|
||||||
Renderer.Submit(mesh.Mesh, material, transform.WorldTransform);
|
Renderer.Submit(mesh.Mesh, material, transform.WorldTransform);
|
||||||
}
|
}
|
||||||
@@ -515,7 +541,7 @@ namespace Sandbox
|
|||||||
private bool OnImGuiRender(ImGuiRenderEvent e)
|
private bool OnImGuiRender(ImGuiRenderEvent e)
|
||||||
{
|
{
|
||||||
ImGui.Begin("Animation");
|
ImGui.Begin("Animation");
|
||||||
|
/*
|
||||||
if(AnimationPlayer != null)
|
if(AnimationPlayer != null)
|
||||||
{
|
{
|
||||||
ImGui.DragFloat("Timestamp", &AnimationPlayer.TimeStamp, 0.01f, -AnimationPlayer.CurrentClip.Duration, AnimationPlayer.CurrentClip.Duration);
|
ImGui.DragFloat("Timestamp", &AnimationPlayer.TimeStamp, 0.01f, -AnimationPlayer.CurrentClip.Duration, AnimationPlayer.CurrentClip.Duration);
|
||||||
@@ -527,7 +553,7 @@ namespace Sandbox
|
|||||||
|
|
||||||
ImGui.Checkbox("Play", &playAnimation);
|
ImGui.Checkbox("Play", &playAnimation);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
ImGui.End();
|
ImGui.End();
|
||||||
|
|
||||||
ImGui.Begin("Test");
|
ImGui.Begin("Test");
|
||||||
|
|||||||
Reference in New Issue
Block a user