-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbezierAnimation.hpp
83 lines (74 loc) · 2.44 KB
/
bezierAnimation.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#pragma once
#include <functional>
#include <glm/glm.hpp>
#include <vector>
#include "game/component.hpp"
#include "game/gameObject.hpp"
#include "transform.hpp"
class BezierAnimation final : public Component {
public:
BezierAnimation(const std::vector<glm::vec3> &points, float duration, bool loop = true) :
controlPoints(points), totalTime(duration), currentTime(0.0f), isLooping(loop), isForward(true) {}
void initialize() override {
transform = gameObject->getComponent<Transform>();
if (!transform) {
std::cerr << "BezierAnimation requires a Transform component.\n";
return;
}
initialPosition = transform->getPosition();
}
void update(float deltaTime) override {
if (isLooping) {
currentTime += (isForward ? 1 : -1) * deltaTime;
if (currentTime > totalTime) {
isForward = false;
currentTime = totalTime;
if (onEndCallback)
onEndCallback();
} else if (currentTime < 0) {
isForward = true;
currentTime = 0;
if (onEndCallback)
onEndCallback();
}
} else {
currentTime += deltaTime;
if (currentTime > totalTime) {
currentTime = totalTime;
if (onEndCallback) {
onEndCallback();
return;
}
}
}
float t = currentTime / totalTime;
glm::vec3 position = calculateBezierPoint(t);
transform->setPosition(initialPosition + position);
}
void setOnEndCallback(std::function<void()> callback) { onEndCallback = callback; }
private:
std::shared_ptr<Transform> transform;
glm::vec3 initialPosition;
std::vector<glm::vec3> controlPoints;
std::function<void()> onEndCallback;
float totalTime;
float currentTime;
bool isLooping;
bool isForward;
glm::vec3 calculateBezierPoint(float t) {
glm::vec3 p0 = controlPoints[0];
glm::vec3 p1 = controlPoints[1];
glm::vec3 p2 = controlPoints[2];
glm::vec3 p3 = controlPoints[3];
float u = 1 - t;
float tt = t * t;
float uu = u * u;
float uuu = uu * u;
float ttt = tt * t;
glm::vec3 p = uuu * p0;
p += 3 * uu * t * p1;
p += 3 * u * tt * p2;
p += ttt * p3;
return p;
}
};