ADD: AnimationSystem

This commit is contained in:
sebastian 2026-08-04 18:56:02 +02:00
parent a1936d666c
commit dedc37f6ac
7 changed files with 120 additions and 0 deletions

View File

@ -200,6 +200,9 @@ add_library(Engine STATIC
engine/src/core/audio/SoundSource.h engine/src/core/audio/SoundSource.h
engine/src/loader/sounds/SoundUploader.cpp engine/src/loader/sounds/SoundUploader.cpp
engine/src/loader/sounds/SoundUploader.h engine/src/loader/sounds/SoundUploader.h
engine/src/core/animation/components/TransformAnimationComponent.h
engine/src/core/animation/AnimationSystem.cpp
engine/src/core/animation/AnimationSystem.h
) )
target_include_directories(Engine PUBLIC engine/src ${dr_libs_SOURCE_DIR}) target_include_directories(Engine PUBLIC engine/src ${dr_libs_SOURCE_DIR})
target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image OpenAL::OpenAL) target_link_libraries(Engine PUBLIC OpenGL::GL glfw glad glm::glm imgui spdlog::spdlog tinyobjloader stb_image OpenAL::OpenAL)

Binary file not shown.

BIN
assets/sounds/pawn_step.wav Normal file

Binary file not shown.

View File

@ -0,0 +1,53 @@
//
// Created by sebastian on 04.08.26.
//
#include "AnimationSystem.h"
#include "components/TransformAnimationComponent.h"
#include "ecs/standardComponents/TransformComponent.h"
namespace engine::animation {
void animation::AnimationSystem::update(float deltaTime) {
for (auto& [entity, animation] : m_registry.getPool<TransformAnimationComponent>()) {
animation.time += deltaTime;
auto& transform = m_registry.getComponent<TransformComponent>(entity);
transform.m_position = evaluate(animation.position, animation.time);
transform.m_rotation = evaluate(animation.rotation, animation.time);
transform.m_scale = evaluate(animation.scale, animation.time);
if (animation.time >= animation.duration) {
if (animation.loop) {
animation.time = 0.f;
} else {
if (animation.onFinished) {
animation.onFinished();
}
animation.finished = true;
}
}
}
}
glm::vec3 AnimationSystem::evaluate(const AnimationTrack &track, float time) {
Keyframe a;
Keyframe b;
findSurroundingKeys(track, time, a, b);
float localT = (time - a.time) / (b.time - a.time);
float easedT = a.easingFunction(localT);
return glm::mix(a.value, b.value, easedT);
}
void AnimationSystem::findSurroundingKeys(const AnimationTrack &track, float time, Keyframe &a, Keyframe &b) {
for (int i = 1; i < track.keys.size(); i++) {
if (track.keys[i-1].time < 0.f && track.keys[i].time > 0.f) {
a = track.keys[i-1];
b = track.keys[i];
return;
}
}
}
} // engine

View File

@ -0,0 +1,23 @@
//
// Created by sebastian on 04.08.26.
//
#ifndef COLORRACE_ANIMATIONSYSTEM_H
#define COLORRACE_ANIMATIONSYSTEM_H
#include "components/TransformAnimationComponent.h"
#include "ecs/EntityRegistry.h"
#include "glm/glm.hpp"
namespace engine::animation {
class AnimationSystem {
public:
explicit AnimationSystem(EntityRegistry& registry) : m_registry(registry) {}
void update(float deltaTime);
private:
EntityRegistry& m_registry;
glm::vec3 evaluate(const AnimationTrack& track, float time);
void findSurroundingKeys(const AnimationTrack& track, float time, Keyframe& a, Keyframe& b);
};
} // engine
#endif //COLORRACE_ANIMATIONSYSTEM_H

View File

@ -0,0 +1,40 @@
//
// Created by sebastian on 04.08.26.
//
#ifndef COLORRACE_TRANSFORMANIMATIONCOMPONENT_H
#define COLORRACE_TRANSFORMANIMATIONCOMPONENT_H
#include <functional>
#include "glm/glm.hpp"
namespace engine::animation {
using EasingFunction = std::function<float(float)>;
struct Keyframe {
float time;
glm::vec3 value;
EasingFunction easingFunction = [](float t) {
return t;
};
};
struct AnimationTrack {
std::vector<Keyframe> keys;
};
struct TransformAnimationComponent {
float time = 0.0f;
float duration = 0.0f;
AnimationTrack position;
AnimationTrack rotation;
AnimationTrack scale;
std::function<void()> onFinished;
bool loop = false;
bool finished = false;
};
}
#endif //COLORRACE_TRANSFORMANIMATIONCOMPONENT_H

View File

@ -57,5 +57,6 @@ std::vector<engine::AssetRequest> GameScene::getRequiredAssets() const {
requests.emplace_back(engine::ModelRequest{"pawn_yellow", "assets/models/chess_yellow.obj", engine::ModelSplitPolicy::Combined}); requests.emplace_back(engine::ModelRequest{"pawn_yellow", "assets/models/chess_yellow.obj", engine::ModelSplitPolicy::Combined});
requests.emplace_back(engine::ModelRequest{ "gameboard", "assets/models/GameBoard.obj", engine::ModelSplitPolicy::Combined}); requests.emplace_back(engine::ModelRequest{ "gameboard", "assets/models/GameBoard.obj", engine::ModelSplitPolicy::Combined});
requests.emplace_back(engine::SoundRequest{ "rolling_dice", "assets/sounds/rolling_dice.wav"}); requests.emplace_back(engine::SoundRequest{ "rolling_dice", "assets/sounds/rolling_dice.wav"});
requests.emplace_back(engine::SoundRequest{ "pawn_step", "assets/sounds/pawn_step.wav"});
return requests; return requests;
} }