From d09fd6b8e8dbca7acfe007c9b2c1ca18398bef8f Mon Sep 17 00:00:00 2001
From: OusmBlueNinja <89956790+OusmBlueNinja@users.noreply.github.com>
Date: Mon, 21 Apr 2025 21:48:26 -0500
Subject: [PATCH] started on Animations

---
 src/src/Components/AnimationComponent.cpp | 60 +++++++++++++++++++++++
 src/src/Components/AnimationComponent.h   | 39 +++++++++++++++
 src/src/core/utils/TextureAtlas.h         | 31 ++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 src/src/Components/AnimationComponent.cpp
 create mode 100644 src/src/Components/AnimationComponent.h
 create mode 100644 src/src/core/utils/TextureAtlas.h

diff --git a/src/src/Components/AnimationComponent.cpp b/src/src/Components/AnimationComponent.cpp
new file mode 100644
index 0000000..1c91809
--- /dev/null
+++ b/src/src/Components/AnimationComponent.cpp
@@ -0,0 +1,60 @@
+#include "AnimationComponent.h"
+#include "Renderer.h"
+
+AnimationComponent::AnimationComponent(Object* owner): Component(owner) {}
+
+void AnimationComponent::SetTextureAtlas(const std::string& path, int cols, int rows, float duration) {
+    texture = std::make_shared<Texture>(path);
+    columns = cols;
+    rows = rows;
+    totalFrames = cols * rows;
+    frameDuration = duration;
+    GenerateUVs();
+}
+
+void AnimationComponent::GenerateUVs() {
+    uvOffsets.clear();
+    float frameW = 1.0f / float(columns);
+    float frameH = 1.0f / float(rows);
+
+    for (int y = 0; y < rows; ++y) {
+        for (int x = 0; x < columns; ++x) {
+            uvOffsets.emplace_back(core::types::Vec2(x * frameW, y * frameH));
+        }
+    }
+}
+
+void AnimationComponent::Play() { playing = true; }
+void AnimationComponent::Stop() { playing = false; }
+void AnimationComponent::SetLooping(bool l) { loop = l; }
+void AnimationComponent::SetSpeed(float s) { speed = s; }
+void AnimationComponent::SetFrame(int f) { currentFrame = f % totalFrames; }
+
+void AnimationComponent::Update(float dt) {
+    if (!playing || totalFrames <= 1) return;
+
+    time += dt * speed;
+    if (time >= frameDuration) {
+        time -= frameDuration;
+        currentFrame++;
+
+        if (currentFrame >= totalFrames) {
+            if (loop)
+                currentFrame = 0;
+            else {
+                currentFrame = totalFrames - 1;
+                playing = false;
+            }
+        }
+    }
+}
+
+void AnimationComponent::Draw() {
+    if (!texture) return;
+
+    float frameW = 1.0f / float(columns);
+    float frameH = 1.0f / float(rows);
+    core::types::Vec2 uv = uvOffsets[currentFrame];
+
+    //Renderer::Draw(*texture, GetOwner()->GetWorldPosition(), uv, core::types::Vec2(frameW, frameH));
+}
diff --git a/src/src/Components/AnimationComponent.h b/src/src/Components/AnimationComponent.h
new file mode 100644
index 0000000..3355645
--- /dev/null
+++ b/src/src/Components/AnimationComponent.h
@@ -0,0 +1,39 @@
+#pragma once
+#include "Component.h"
+#include "core/types/Vec2.h"
+#include <string>
+#include <vector>
+#include <memory>
+
+class Texture;
+
+class AnimationComponent : public Component {
+public:
+    AnimationComponent(Object* owner);;
+
+    void SetTextureAtlas(const std::string& path, int cols, int rows, float frameDuration);
+    void Play();
+    void Stop();
+    void SetLooping(bool loop);
+    void SetSpeed(float speed);
+    void SetFrame(int frame);
+
+    void Update(float dt);
+    void Draw();
+
+private:
+    std::shared_ptr<Texture> texture;
+    std::vector<core::types::Vec2> uvOffsets;
+    int columns = 1;
+    int rows = 1;
+    int totalFrames = 1;
+
+    float frameDuration = 0.1f;
+    float time = 0.0f;
+    int currentFrame = 0;
+    bool playing = true;
+    bool loop = true;
+    float speed = 1.0f;
+
+    void GenerateUVs();
+};
diff --git a/src/src/core/utils/TextureAtlas.h b/src/src/core/utils/TextureAtlas.h
new file mode 100644
index 0000000..a87e750
--- /dev/null
+++ b/src/src/core/utils/TextureAtlas.h
@@ -0,0 +1,31 @@
+#pragma once
+#include <memory>
+#include "core/types/Vec2.h"
+
+class Texture;
+
+struct TextureAtlas {
+    std::shared_ptr<Texture> texture;
+    int columns = 1;
+    int rows = 1;
+
+    TextureAtlas() = default;
+    TextureAtlas(std::shared_ptr<Texture> tex, int cols, int rows)
+        : texture(std::move(tex)), columns(cols), rows(rows) {}
+
+    core::types::Vec2 GetFrameUV(int index) const {
+        float w = 1.0f / float(columns);
+        float h = 1.0f / float(rows);
+        int x = index % columns;
+        int y = index / columns;
+        return core::types::Vec2(x * w, y * h);
+    }
+
+    core::types::Vec2 GetFrameSizeUV() const {
+        return core::types::Vec2(1.0f / float(columns), 1.0f / float(rows));
+    }
+
+    int GetTotalFrames() const {
+        return columns * rows;
+    }
+};