Animation WIP merge #321
|
@ -19,6 +19,10 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
SHAnimationClip::SHAnimationClip(const SHAnimAsset& asset)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -19,15 +19,12 @@ of DigiPen Institute of Technology is prohibited.
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Forward Declarations */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/// <summary>
|
||||
/// Defines a single key frame in an animation.
|
||||
/// </summary>
|
||||
struct SHAnimationKeyFrame
|
||||
{
|
||||
float TimeStamp;
|
||||
|
@ -37,11 +34,19 @@ namespace SHADE
|
|||
SHMatrix TransformationMatrix;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Represents a animation clip of a 3D animation that is made for a specific model
|
||||
/// rig.
|
||||
/// </summary>
|
||||
class SHAnimationClip
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Defines the animations of a single bone in a rig.
|
||||
/// </summary>
|
||||
struct Channel
|
||||
{
|
||||
std::string Name;
|
||||
|
@ -56,12 +61,15 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
||||
float GetTotalTime() const noexcept { return totalTime; }
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
std::vector<Channel> Channels;
|
||||
std::vector<Channel> channels;
|
||||
float totalTime;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
|
|
|
@ -13,12 +13,50 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include "SHpch.h"
|
||||
// Primary Include
|
||||
#include "SHAnimatorComponent.h"
|
||||
// STL Includes
|
||||
#include <queue>
|
||||
// Project Includes
|
||||
#include "SHRig.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
#include "SHAnimationClip.h"
|
||||
#include "Graphics/SHVkUtil.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHAnimatorComponent::Play()
|
||||
{
|
||||
isPlaying = false;
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::Play(Handle<SHAnimationClip> clip)
|
||||
{
|
||||
currClip = clip;
|
||||
currPlaybackTime = 0.0f;
|
||||
Play();
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::PlayFromStart()
|
||||
{
|
||||
isPlaying = true;
|
||||
currPlaybackTime = 0.0f;
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::Pause()
|
||||
{
|
||||
isPlaying = false;
|
||||
}
|
||||
|
||||
void SHAnimatorComponent::Stop()
|
||||
{
|
||||
isPlaying = false;
|
||||
currPlaybackTime = 0.0f;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -31,14 +69,21 @@ namespace SHADE
|
|||
rig = newRig;
|
||||
|
||||
// Populate bone matrices based on new rig's default pose
|
||||
boneMatrices.clear();
|
||||
if (rig)
|
||||
{
|
||||
std::fill_n(std::back_inserter(boneMatrices), rig->GetNodeCount(), SHMatrix::Identity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
boneMatrices.clear();
|
||||
}
|
||||
void SHAnimatorComponent::SetClip(Handle<SHAnimationClip> newClip)
|
||||
{
|
||||
// No change
|
||||
if (currClip == newClip)
|
||||
return;
|
||||
|
||||
currClip = newClip;
|
||||
updatePoseWithClip(0.0f);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -46,10 +91,85 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHAnimatorComponent::Update(float dt)
|
||||
{
|
||||
// Set everything to identity
|
||||
// Nothing to animate
|
||||
if (!currClip || !isPlaying)
|
||||
return;
|
||||
|
||||
// Update time on the playback
|
||||
currPlaybackTime += dt;
|
||||
if (currPlaybackTime > currClip->GetTotalTime())
|
||||
{
|
||||
currPlaybackTime = currPlaybackTime - currClip->GetTotalTime();
|
||||
}
|
||||
|
||||
// Reset all matrices
|
||||
for (auto& mat : boneMatrices)
|
||||
{
|
||||
mat = SHMatrix::Identity;
|
||||
}
|
||||
|
||||
// Play the clip
|
||||
updatePoseWithClip(currPlaybackTime);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHAnimatorComponent::updatePoseWithClip(float poseTime)
|
||||
{
|
||||
for (const auto& channel : currClip->GetChannels())
|
||||
{
|
||||
// Get the bone
|
||||
std::queue<Handle<SHRig::Node>> bones;
|
||||
bones.push(rig->GetNode(channel.Name));
|
||||
while (!bones.empty())
|
||||
{
|
||||
// Select bone at front of the queue
|
||||
auto bone = bones.front(); bones.pop();
|
||||
if (!bone)
|
||||
continue;
|
||||
|
||||
// Add any children to the queue
|
||||
for (auto child : bone->Children)
|
||||
{
|
||||
bones.push(child);
|
||||
}
|
||||
|
||||
// Get interpolated frame
|
||||
auto firstKeyFrame = channel.KeyFrames.end();
|
||||
auto nextKeyFrame = channel.KeyFrames.end();
|
||||
for (auto iter = channel.KeyFrames.begin(); iter != channel.KeyFrames.end(); ++iter)
|
||||
{
|
||||
const auto& KEYFRAME = *iter;
|
||||
|
||||
if(KEYFRAME.TimeStamp <= poseTime)
|
||||
{
|
||||
firstKeyFrame = iter;
|
||||
}
|
||||
else if (KEYFRAME.TimeStamp > poseTime)
|
||||
{
|
||||
nextKeyFrame = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Calculate the matrix
|
||||
const int BONE_MTX_IDX = rig->GetNodeIndex(bone);
|
||||
const float T = (poseTime - firstKeyFrame->TimeStamp) / (nextKeyFrame->TimeStamp - firstKeyFrame->TimeStamp);
|
||||
boneMatrices[BONE_MTX_IDX] = boneMatrices[BONE_MTX_IDX] * SHMatrix::Transform
|
||||
(
|
||||
SHVec3::Lerp(firstKeyFrame->Position, nextKeyFrame->Position, T),
|
||||
SHQuaternion::Slerp(firstKeyFrame->Orientation, nextKeyFrame->Orientation, T),
|
||||
SHVec3::Lerp(firstKeyFrame->Scale, nextKeyFrame->Scale, T)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* RTTR Registration */
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
RTTR_REGISTRATION
|
||||
{
|
||||
using namespace SHADE;
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace SHADE
|
|||
/* Forward Declarations */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
class SHRig;
|
||||
class SHAnimationClip;
|
||||
class SHVkBuffer;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
|
@ -40,20 +42,61 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/*void Play();
|
||||
/// <summary>
|
||||
/// Plays the currently loaded animation from the last time.
|
||||
/// </summary>
|
||||
void Play();
|
||||
/// <summary>
|
||||
/// Plays the specified animation clip from the start.
|
||||
/// </summary>
|
||||
/// <param name="clip"></param>
|
||||
void Play(Handle<SHAnimationClip> clip);
|
||||
/// <summary>
|
||||
/// Plays the currently loaded animation clip from the start.
|
||||
/// </summary>
|
||||
void PlayFromStart();
|
||||
/// <summary>
|
||||
/// Pauses the animation at the current time.
|
||||
/// </summary>
|
||||
void Pause();
|
||||
void Stop();*/
|
||||
/// <summary>
|
||||
/// Stops the animation and resets the play time back to 0.
|
||||
/// </summary>
|
||||
void Stop();
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Sets the animation rig for this animator.
|
||||
/// </summary>
|
||||
/// <param name="newRig">Rig to use.</param>
|
||||
void SetRig(Handle<SHRig> newRig);
|
||||
/// <summary>
|
||||
/// Sets the animation clip of this animator without playing it.
|
||||
/// This will set the pose of the model to it's initial pose.
|
||||
/// If the clip is the same as the current clip, nothing happens.
|
||||
/// </summary>
|
||||
/// <param name="newClip">Clip to use.</param>
|
||||
void SetClip(Handle<SHAnimationClip> newClip);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Retrieves all the bone matrices of this animator.
|
||||
/// </summary>
|
||||
/// <returns>Reference to a vector of the bone matrices.</returns>
|
||||
const std::vector<SHMatrix>& GetBoneMatrices() const noexcept { return boneMatrices; }
|
||||
/// <summary>
|
||||
/// Retrieve the currently set animation clip.
|
||||
/// </summary>
|
||||
/// <returns>Handle to the currently set animation clip.</returns>
|
||||
Handle<SHAnimationClip> GetCurrentClip() const noexcept { return currClip; }
|
||||
/// <summary>
|
||||
/// Checks if an animation is currently playing.
|
||||
/// </summary>
|
||||
/// <returns>True if an animation clip is currently playing.</returns>
|
||||
bool IsPlaying() const { return isPlaying; }
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -70,10 +113,19 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
// Resources
|
||||
Handle<SHRig> rig;
|
||||
std::vector<SHMatrix> boneMatrices;
|
||||
Handle<SHAnimationClip> currClip;
|
||||
// Playback Tracking
|
||||
float currPlaybackTime = 0.0f;
|
||||
bool isPlaying = false;
|
||||
// Buffer
|
||||
std::vector<SHMatrix> boneMatrices;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void updatePoseWithClip(float poseTime);
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* RTTR */
|
||||
|
|
|
@ -60,6 +60,16 @@ namespace SHADE
|
|||
return nodeCount;
|
||||
}
|
||||
|
||||
int SHRig::GetNodeIndex(Handle<Node> node) const noexcept
|
||||
{
|
||||
if (nodeIndexMap.contains(node))
|
||||
{
|
||||
return nodeIndexMap.at(node);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -78,6 +88,8 @@ namespace SHADE
|
|||
{
|
||||
nodeNames.emplace(newNode, NODE_DATA.name);
|
||||
nodesByName.emplace(NODE_DATA.name, newNode);
|
||||
nodeIndexMap.emplace(newNode, nodes.size());
|
||||
nodes.emplace_back(newNode);
|
||||
}
|
||||
|
||||
// Fill child nodes
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
class SHRig
|
||||
{
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -78,6 +79,10 @@ namespace SHADE
|
|||
/// needed.
|
||||
/// </summary>
|
||||
int GetNodeCount() const noexcept;
|
||||
/// <summary>
|
||||
/// Retrieves the index in the node storage.
|
||||
/// </summary>
|
||||
int GetNodeIndex(Handle<Node> node) const noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -86,6 +91,8 @@ namespace SHADE
|
|||
Handle<Node> rootNode;
|
||||
std::unordered_map<Handle<Node>, std::string> nodeNames;
|
||||
std::unordered_map<std::string, Handle<Node>> nodesByName;
|
||||
std::vector<Handle<Node>> nodes;
|
||||
std::unordered_map<Handle<Node>, int> nodeIndexMap;
|
||||
int nodeCount = 0;
|
||||
SHResourceLibrary<Node> nodeStore;
|
||||
|
||||
|
|
|
@ -134,6 +134,7 @@ namespace SHADE
|
|||
TripleDescSet matPropsDescSet;
|
||||
TripleBuffer boneMatrixBuffer;
|
||||
TripleBuffer boneFirstIndexBuffer;
|
||||
TripleDescSet boneMatricesDescSet;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
|
|
Loading…
Reference in New Issue