153 lines
5.1 KiB
C++
153 lines
5.1 KiB
C++
#include "AnimationComponent.h"
|
|
|
|
AnimationComponent::AnimationComponent(Object *owner)
|
|
: Component(owner) {}
|
|
|
|
void AnimationComponent::SetTextureAtlasPath(const std::string &path, int texelWidth, int texelHeight, float duration, int start, int end)
|
|
{
|
|
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
|
const auto *asset = AssetManager::GetAssetByPath(path);
|
|
if (asset)
|
|
SetTextureAtlas(asset->uaid, texelWidth, texelHeight, duration, start, end);
|
|
}
|
|
|
|
void AnimationComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texelHeight, float duration, int start, int end)
|
|
{
|
|
textureUAID = uaid;
|
|
|
|
const auto *asset = AssetManager::GetAssetByID(uaid);
|
|
if (!asset || !asset->loaded)
|
|
{
|
|
Logger::LogError("SetTextureAtlas: Asset not found or not loaded (UAID: %llu)", uaid);
|
|
return;
|
|
}
|
|
|
|
int texWidth = static_cast<int>(asset->size.x);
|
|
int texHeight = static_cast<int>(asset->size.y);
|
|
|
|
if (texelWidth <= 0 || texelHeight <= 0 || texWidth < texelWidth || texHeight < texelHeight)
|
|
{
|
|
Logger::LogError("SetTextureAtlas: Invalid texel size %dx%d for image size %dx%d (UAID: %llu)",
|
|
texelWidth, texelHeight, texWidth, texHeight, uaid);
|
|
return;
|
|
}
|
|
|
|
if (texWidth % texelWidth != 0 || texHeight % texelHeight != 0)
|
|
{
|
|
Logger::LogWarning("SetTextureAtlas: Texture size is not cleanly divisible by texel size (UAID: %llu)", uaid);
|
|
}
|
|
|
|
texture = std::make_shared<Texture>(asset->uaid);
|
|
|
|
atlas.texture = texture;
|
|
atlas.SetTexelSize(texelWidth, texelHeight);
|
|
|
|
columns = texWidth / texelWidth;
|
|
rows = texHeight / texelHeight;
|
|
totalFrames = columns * rows;
|
|
|
|
startFrame = 0;
|
|
endFrame = totalFrames > 0 ? totalFrames - 1 : 0;
|
|
|
|
if (start != 0)
|
|
{
|
|
startFrame = start;
|
|
}
|
|
|
|
if (end != 0)
|
|
{
|
|
endFrame = end;
|
|
}
|
|
|
|
frameDuration = duration;
|
|
currentFrame = startFrame;
|
|
|
|
renderType = RenderType::Unlit;
|
|
}
|
|
|
|
void AnimationComponent::Play() { playing = true; }
|
|
void AnimationComponent::Stop() { playing = false; }
|
|
void AnimationComponent::SetLooping(bool loop_) { loop = loop_; }
|
|
|
|
bool AnimationComponent::IsPlaying() const { return playing; }
|
|
|
|
void AnimationComponent::SetPlaying(bool play) { playing = play; }
|
|
|
|
uint64_t AnimationComponent::GetTextureUAID() const { return textureUAID; }
|
|
|
|
void AnimationComponent::SetTextureUAID(uint64_t uaid) { textureUAID = uaid; }
|
|
|
|
bool AnimationComponent::IsLooping() const { return loop; }
|
|
void AnimationComponent::SetSpeed(float speed_) { speed = speed_; }
|
|
float AnimationComponent::GetSpeed() const { return speed; }
|
|
|
|
void AnimationComponent::SetFrame(int frame)
|
|
{
|
|
currentFrame = std::clamp(frame, startFrame, endFrame);
|
|
time = 0.0f;
|
|
}
|
|
int AnimationComponent::GetCurrentFrame() const { return currentFrame; }
|
|
int AnimationComponent::GetStartFrame() const { return startFrame; }
|
|
void AnimationComponent::SetStartFrame(int start) { startFrame = std::clamp(start, 0, totalFrames - 1); }
|
|
int AnimationComponent::GetEndFrame() const { return endFrame; }
|
|
void AnimationComponent::SetEndFrame(int end) { endFrame = std::clamp(end, 0, totalFrames - 1); }
|
|
int AnimationComponent::GetTotalFrames() const { return totalFrames; }
|
|
|
|
float AnimationComponent::GetFrameDuration() const { return frameDuration; }
|
|
void AnimationComponent::SetFrameDuration(float duration) { frameDuration = duration; }
|
|
|
|
TextureAtlas *AnimationComponent::GetAtlas() { return &atlas; }
|
|
const TextureAtlas *AnimationComponent::GetAtlas() const { return &atlas; }
|
|
|
|
void AnimationComponent::Update(float dt)
|
|
{
|
|
if (!playing || totalFrames <= 1)
|
|
return;
|
|
|
|
time += dt * speed;
|
|
if (time >= frameDuration)
|
|
{
|
|
time -= frameDuration;
|
|
currentFrame++;
|
|
|
|
if (currentFrame > endFrame)
|
|
{
|
|
if (loop)
|
|
currentFrame = startFrame;
|
|
else
|
|
{
|
|
currentFrame = startFrame;
|
|
playing = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string AnimationComponent::GetName() const { return "AnimationComponent"; }
|
|
|
|
void AnimationComponent::Save(YAML::Emitter &out) const
|
|
{
|
|
out << YAML::BeginMap;
|
|
out << YAML::Key << "type" << YAML::Value << GetName();
|
|
out << YAML::Key << "TextureUAID" << YAML::Value << textureUAID;
|
|
out << YAML::Key << "TexelWidth" << YAML::Value << atlas.frameWidth;
|
|
out << YAML::Key << "TexelHeight" << YAML::Value << atlas.frameHeight;
|
|
out << YAML::Key << "FrameDuration" << YAML::Value << frameDuration;
|
|
out << YAML::Key << "StartFrame" << YAML::Value << startFrame;
|
|
out << YAML::Key << "EndFrame" << YAML::Value << endFrame;
|
|
out << YAML::EndMap;
|
|
}
|
|
|
|
void AnimationComponent::Load(const YAML::Node &node)
|
|
{
|
|
|
|
uint64_t uaid = node["TextureUAID"].as<uint64_t>();
|
|
int texelWidth = node["TexelWidth"].as<int>();
|
|
int texelHeight = node["TexelHeight"].as<int>();
|
|
float duration = node["FrameDuration"].as<float>();
|
|
int start = node["StartFrame"] ? node["StartFrame"].as<int>() : 0;
|
|
int end = node["EndFrame"] ? node["EndFrame"].as<int>() : 0;
|
|
|
|
SetTextureAtlas(uaid, texelWidth, texelHeight, duration, start, end);
|
|
}
|