Animation WIP merge #321
|
@ -19,6 +19,10 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Constructors */
|
/* Constructors */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
SHAnimationClip::SHAnimationClip(const SHAnimAsset& asset)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -19,15 +19,12 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Forward Declarations */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Defines a single key frame in an animation.
|
||||||
|
/// </summary>
|
||||||
struct SHAnimationKeyFrame
|
struct SHAnimationKeyFrame
|
||||||
{
|
{
|
||||||
float TimeStamp;
|
float TimeStamp;
|
||||||
|
@ -37,11 +34,19 @@ namespace SHADE
|
||||||
SHMatrix TransformationMatrix;
|
SHMatrix TransformationMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a animation clip of a 3D animation that is made for a specific model
|
||||||
|
/// rig.
|
||||||
|
/// </summary>
|
||||||
class SHAnimationClip
|
class SHAnimationClip
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the animations of a single bone in a rig.
|
||||||
|
/// </summary>
|
||||||
struct Channel
|
struct Channel
|
||||||
{
|
{
|
||||||
std::string Name;
|
std::string Name;
|
||||||
|
@ -56,12 +61,15 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
const std::vector<Channel>& GetChannels() const noexcept { return channels; }
|
||||||
|
float GetTotalTime() const noexcept { return totalTime; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
std::vector<Channel> Channels;
|
std::vector<Channel> channels;
|
||||||
|
float totalTime;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
|
@ -13,12 +13,50 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
// Primary Include
|
// Primary Include
|
||||||
#include "SHAnimatorComponent.h"
|
#include "SHAnimatorComponent.h"
|
||||||
|
// STL Includes
|
||||||
|
#include <queue>
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "SHRig.h"
|
#include "SHRig.h"
|
||||||
#include "Math/SHMatrix.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
|
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 */
|
/* Setter Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -31,14 +69,21 @@ namespace SHADE
|
||||||
rig = newRig;
|
rig = newRig;
|
||||||
|
|
||||||
// Populate bone matrices based on new rig's default pose
|
// Populate bone matrices based on new rig's default pose
|
||||||
|
boneMatrices.clear();
|
||||||
if (rig)
|
if (rig)
|
||||||
{
|
{
|
||||||
|
std::fill_n(std::back_inserter(boneMatrices), rig->GetNodeCount(), SHMatrix::Identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
void SHAnimatorComponent::SetClip(Handle<SHAnimationClip> newClip)
|
||||||
else
|
{
|
||||||
{
|
// No change
|
||||||
boneMatrices.clear();
|
if (currClip == newClip)
|
||||||
}
|
return;
|
||||||
|
|
||||||
|
currClip = newClip;
|
||||||
|
updatePoseWithClip(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -46,10 +91,85 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
void SHAnimatorComponent::Update(float dt)
|
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
|
RTTR_REGISTRATION
|
||||||
{
|
{
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
|
@ -26,6 +26,8 @@ namespace SHADE
|
||||||
/* Forward Declarations */
|
/* Forward Declarations */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
class SHRig;
|
class SHRig;
|
||||||
|
class SHAnimationClip;
|
||||||
|
class SHVkBuffer;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -40,20 +42,61 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Usage Functions */
|
/* 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();
|
void PlayFromStart();
|
||||||
|
/// <summary>
|
||||||
|
/// Pauses the animation at the current time.
|
||||||
|
/// </summary>
|
||||||
void Pause();
|
void Pause();
|
||||||
void Stop();*/
|
/// <summary>
|
||||||
|
/// Stops the animation and resets the play time back to 0.
|
||||||
|
/// </summary>
|
||||||
|
void Stop();
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the animation rig for this animator.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newRig">Rig to use.</param>
|
||||||
void SetRig(Handle<SHRig> newRig);
|
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 */
|
/* 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; }
|
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; }
|
bool IsPlaying() const { return isPlaying; }
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -70,10 +113,19 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
// Resources
|
||||||
Handle<SHRig> rig;
|
Handle<SHRig> rig;
|
||||||
std::vector<SHMatrix> boneMatrices;
|
Handle<SHAnimationClip> currClip;
|
||||||
|
// Playback Tracking
|
||||||
float currPlaybackTime = 0.0f;
|
float currPlaybackTime = 0.0f;
|
||||||
bool isPlaying = false;
|
bool isPlaying = false;
|
||||||
|
// Buffer
|
||||||
|
std::vector<SHMatrix> boneMatrices;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void updatePoseWithClip(float poseTime);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* RTTR */
|
/* RTTR */
|
||||||
|
|
|
@ -60,6 +60,16 @@ namespace SHADE
|
||||||
return nodeCount;
|
return nodeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SHRig::GetNodeIndex(Handle<Node> node) const noexcept
|
||||||
|
{
|
||||||
|
if (nodeIndexMap.contains(node))
|
||||||
|
{
|
||||||
|
return nodeIndexMap.at(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -78,6 +88,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
nodeNames.emplace(newNode, NODE_DATA.name);
|
nodeNames.emplace(newNode, NODE_DATA.name);
|
||||||
nodesByName.emplace(NODE_DATA.name, newNode);
|
nodesByName.emplace(NODE_DATA.name, newNode);
|
||||||
|
nodeIndexMap.emplace(newNode, nodes.size());
|
||||||
|
nodes.emplace_back(newNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill child nodes
|
// Fill child nodes
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
class SHRig
|
class SHRig
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -78,6 +79,10 @@ namespace SHADE
|
||||||
/// needed.
|
/// needed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int GetNodeCount() const noexcept;
|
int GetNodeCount() const noexcept;
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the index in the node storage.
|
||||||
|
/// </summary>
|
||||||
|
int GetNodeIndex(Handle<Node> node) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -86,6 +91,8 @@ namespace SHADE
|
||||||
Handle<Node> rootNode;
|
Handle<Node> rootNode;
|
||||||
std::unordered_map<Handle<Node>, std::string> nodeNames;
|
std::unordered_map<Handle<Node>, std::string> nodeNames;
|
||||||
std::unordered_map<std::string, Handle<Node>> nodesByName;
|
std::unordered_map<std::string, Handle<Node>> nodesByName;
|
||||||
|
std::vector<Handle<Node>> nodes;
|
||||||
|
std::unordered_map<Handle<Node>, int> nodeIndexMap;
|
||||||
int nodeCount = 0;
|
int nodeCount = 0;
|
||||||
SHResourceLibrary<Node> nodeStore;
|
SHResourceLibrary<Node> nodeStore;
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ namespace SHADE
|
||||||
TripleDescSet matPropsDescSet;
|
TripleDescSet matPropsDescSet;
|
||||||
TripleBuffer boneMatrixBuffer;
|
TripleBuffer boneMatrixBuffer;
|
||||||
TripleBuffer boneFirstIndexBuffer;
|
TripleBuffer boneFirstIndexBuffer;
|
||||||
|
TripleDescSet boneMatricesDescSet;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
|
|
Loading…
Reference in New Issue