Implemented Animation Clip asset and animation controller #410

Merged
XiaoQiDigipen merged 66 commits from SP3-22-AnimationController into main 2023-03-09 16:19:40 +08:00
5 changed files with 36 additions and 12 deletions
Showing only changes of commit 7f170deb27 - Show all commits

View File

@ -1,4 +1,6 @@
namespace SHADE.Test
using System;
namespace SHADE.Test
{
public class AnimTest : Script
{
@ -25,21 +27,26 @@
protected override void update()
{
// Play loop if shift is held
Action<AnimationClipAsset> playFunc = Input.GetKey(Input.KeyCode.LeftShift) ? (x) => Animator.Play(x)
: (x) => Animator.PlayOneShot(x);
// Play animations
if (Input.GetKeyUp(Input.KeyCode.Equals))
{
Animator.Play(fullClip);
playFunc(fullClip);
}
else if (Input.GetKeyUp(Input.KeyCode.Alpha1))
{
Animator.Play(idleClip);
playFunc(idleClip);
}
else if (Input.GetKeyUp(Input.KeyCode.Alpha2))
{
Animator.Play(runClip);
playFunc(runClip);
}
else if (Input.GetKeyUp(Input.KeyCode.Alpha3))
{
Animator.Play(pickUpClip);
playFunc(pickUpClip);
}
}
#endregion

View File

@ -25,11 +25,14 @@ namespace SHADE
, startFrameIndex { firstFrame }
, endFrameIndex { lastFrame }
, duration { 0.0f }
, startTimeStamp { 0.0f }
{
if (!rawAnim)
return;
const float SECS_PER_TICK = 1.0f / static_cast<float>(rawAnim->GetTicksPerSecond());
const int ONE_PAST_LAST_FRAME = lastFrame + 1;
duration = (ONE_PAST_LAST_FRAME - firstFrame) / rawAnim->GetTicksPerSecond();
duration = static_cast<float>(ONE_PAST_LAST_FRAME - firstFrame) * SECS_PER_TICK;
startTimeStamp = static_cast<float>(firstFrame) * SECS_PER_TICK;
}
}

View File

@ -50,6 +50,7 @@ namespace SHADE
inline int GetStartFrameIndex() const noexcept { return startFrameIndex; }
inline int GetEndFrameIndex() const noexcept { return endFrameIndex; }
inline float GetTotalDuration() const noexcept { return duration; }
inline float GetStartTimeStamp() const noexcept { return startTimeStamp; }
private:
/*---------------------------------------------------------------------------------*/
@ -58,6 +59,7 @@ namespace SHADE
Handle<SHRawAnimation> rawAnim;
int startFrameIndex; // First Frame
int endFrameIndex; // Last Frame (inclusive)
float duration; // Total playback time
float duration; // Total playback time
float startTimeStamp; // Starting time stamp of the raw anim
};
}

View File

@ -65,18 +65,21 @@ namespace SHADE
instData.ClipPlaybackTime += dt;
// Check if we finished playing
if (instData.ClipPlaybackTime > instData.CurrentNode->Clip->GetTotalDuration())
const float CLIP_CURR_PLAYED_TIME = instData.ClipPlaybackTime - instData.CurrentNode->Clip->GetStartTimeStamp();
if (CLIP_CURR_PLAYED_TIME > instData.CurrentNode->Clip->GetTotalDuration())
{
// Clamp
instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetTotalDuration();
instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetStartTimeStamp() + instData.CurrentNode->Clip->GetTotalDuration();
// Go to next state
bool stateChanged = false;
for (const auto& transition : instData.CurrentNode->Transitions)
{
// Check for no condition special case
if (transition.Condition == Transition::ConditionType::None)
{
changeNode(instData, transition.Target);
stateChanged = true;
break;
}
else
@ -90,6 +93,7 @@ namespace SHADE
if (transition.EvaluateCondition(param))
{
changeNode(instData, transition.Target);
stateChanged = true;
// If trigger, we need to unset it
if (param.ParamType == AnimParam::Type::Trigger)
@ -101,6 +105,12 @@ namespace SHADE
}
}
}
// Handle if there is no next state, we repeat
if (!stateChanged)
{
instData.ClipPlaybackTime = instData.CurrentNode->Clip->GetStartTimeStamp();
}
}
}

View File

@ -62,6 +62,7 @@ namespace SHADE
{
// Calculate secs for the clip
secsPerTick = 1.0f / RAW_ANIM->GetTicksPerSecond();
currPlaybackTime = currClip->GetStartTimeStamp();
// Start playback
Play();
@ -232,17 +233,18 @@ namespace SHADE
void SHAnimatorComponent::updateManualClipState(float dt)
{
currPlaybackTime += dt;
if (currPlaybackTime > currClip->GetTotalDuration())
const float CLIP_CURR_PLAYED_TIME = currPlaybackTime - currClip->GetStartTimeStamp();
if (CLIP_CURR_PLAYED_TIME > currClip->GetTotalDuration())
{
if (playOnce)
{
playOnce = false;
isPlaying = false;
currPlaybackTime = currClip->GetTotalDuration();
currPlaybackTime = currClip->GetStartTimeStamp() + currClip->GetTotalDuration();
}
else
{
currPlaybackTime = currPlaybackTime - currClip->GetTotalDuration();
currPlaybackTime = currClip->GetStartTimeStamp();
}
}
}