118 lines
2.7 KiB
C++
118 lines
2.7 KiB
C++
#ifndef AnimationController_h__
|
|||
|
|
#define AnimationController_h__
|
||
|
|
|
||
|
|
#include <map>
|
||
|
|
#include <vector>
|
||
|
|
#include "AnimationTrack.h"
|
||
|
|
#include "Skeleton.h"
|
||
|
|
#include "LString.h"
|
||
|
|
namespace LifeGraphics
|
||
|
|
{
|
||
|
|
class AnimationController
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
float fadeSpeed;
|
||
|
|
std::map<String, AnimationTrack*> tracks;
|
||
|
|
int trackCount;
|
||
|
|
Skeleton* skeleton;
|
||
|
|
int lastId;
|
||
|
|
std::vector<AnimationTrack*> plainList;
|
||
|
|
|
||
|
|
void CrossFade(String name)
|
||
|
|
{
|
||
|
|
AnimationTrack* t = tracks[name];
|
||
|
|
t->Weight += fadeSpeed;
|
||
|
|
if (t->Weight > 1.0f) t->Weight = 1.0f;
|
||
|
|
|
||
|
|
for(std::map<String, AnimationTrack*>::iterator it = tracks.begin(); it != tracks.end(); it++)
|
||
|
|
{
|
||
|
|
AnimationTrack* t2 = it->second;
|
||
|
|
if (t2->Layer == t->Layer && t2->Name != t->Name)
|
||
|
|
{
|
||
|
|
t2->Weight -= fadeSpeed;
|
||
|
|
if (t2->Weight < 0) t2->Weight = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
AnimationController()
|
||
|
|
:fadeSpeed(1.0f/20.0f), trackCount(0),lastId(0)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void SetState(const String& stateName)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Add animatrion track to the current animation controller.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="track">Animation track to add.</param>
|
||
|
|
void AddTrack(AnimationTrack* track)
|
||
|
|
{
|
||
|
|
track->ID = lastId++;
|
||
|
|
tracks[track->Name] = track;
|
||
|
|
trackCount++;
|
||
|
|
}
|
||
|
|
|
||
|
|
void SetTrackWeight(String track, float weight)
|
||
|
|
{
|
||
|
|
tracks[track]->Weight = weight;
|
||
|
|
}
|
||
|
|
|
||
|
|
void LerpTransform(BoneTransform* left, const BoneTransform* right, float amount, BoneTransform* result)
|
||
|
|
{
|
||
|
|
if (amount == 0)
|
||
|
|
{
|
||
|
|
result->Rotation = left->Rotation;
|
||
|
|
result->Translation = left->Translation;
|
||
|
|
result->boneId = left->boneId;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
else if (amount == 1.0f)
|
||
|
|
{
|
||
|
|
result->Rotation = right->Rotation;
|
||
|
|
result->Translation = right->Translation;
|
||
|
|
result->boneId = right->boneId;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
QuatLerp(left->Rotation, right->Rotation, amount, result->Rotation);
|
||
|
|
Vec3Lerp(left->Translation, right->Translation, amount, result->Translation);
|
||
|
|
result->boneId = left->boneId;
|
||
|
|
}
|
||
|
|
|
||
|
|
void AdvanceTime(float dt)
|
||
|
|
{
|
||
|
|
for(std::map<String, AnimationTrack*>::iterator it = tracks.begin(); it != tracks.end(); it++)
|
||
|
|
{
|
||
|
|
AnimationTrack* track = it->second;
|
||
|
|
track->AdvanceTime(dt);
|
||
|
|
|
||
|
|
const BoneTransform* transform = track->GetTransform();
|
||
|
|
|
||
|
|
for (int i = 0; i < skeleton->BonesCount; i++)
|
||
|
|
{
|
||
|
|
for (int j = 0; j < track->Frames[0].boneCount; j++)
|
||
|
|
{
|
||
|
|
if (transform[j].boneId == i)
|
||
|
|
{
|
||
|
|
Bone* bone = skeleton->GetBone(i);
|
||
|
|
BoneTransform lt = bone->LocalTransform;
|
||
|
|
LerpTransform(<, &transform[j], track->Weight, &bone->LocalTransform);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
skeleton->UpdateTransform();
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Use to set up mesh into initial pose
|
||
|
|
/// </summary>
|
||
|
|
void Reset()
|
||
|
|
{
|
||
|
|
tracks[0]->Reset();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|
||
|
|
#endif // AnimationController_h__
|