vkmEngine 1.0.0
A C++ game engine · vkmengine.com
Loading...
Searching...
No Matches
sample_track.h
1#pragma once
2
3#include <algorithm>
4#include <cstdint>
5
6#include <glm/glm.hpp>
7#include <glm/gtc/quaternion.hpp>
8
9namespace Vkm::Engine {
10
18template <size_t N>
20 struct Sample {
21 uint32_t tick = 0;
22 glm::vec3 position{0.0f};
23 glm::quat rotation{1.0f, 0.0f, 0.0f, 0.0f};
24 };
25
26 Sample samples[N];
27 size_t count = 0;
28
39 void record(uint32_t tick, const glm::vec3& position, const glm::quat& rotation) {
40 if (count > 0 && tick <= samples[count - 1].tick) return;
41
42 if (count == N) {
43 std::move(samples + 1, samples + N, samples);
44 --count;
45 }
46 samples[count++] = {tick, position, rotation};
47 }
48
61 bool poseAt(double tick, glm::vec3& position, glm::quat& rotation) const {
62 if (count == 0) return false;
63
64 if (tick <= static_cast<double>(samples[0].tick)) {
65 position = samples[0].position;
66 rotation = samples[0].rotation;
67 return true;
68 }
69 const Sample& newest = samples[count - 1];
70 if (tick >= static_cast<double>(newest.tick)) {
71 position = newest.position;
72 rotation = newest.rotation;
73 return true;
74 }
75
76 for (size_t i = 0; i + 1 < count; ++i) {
77 const Sample& from = samples[i];
78 const Sample& to = samples[i + 1];
79 if (tick < static_cast<double>(from.tick) || tick > static_cast<double>(to.tick)) continue;
80
81 const double span = static_cast<double>(to.tick - from.tick);
82 const float at = span > 0.0
83 ? static_cast<float>((tick - static_cast<double>(from.tick)) / span)
84 : 1.0f;
85 position = glm::mix(from.position, to.position, at);
86 // slerp: a linear blend speeds up through the middle of a turn.
87 rotation = glm::slerp(from.rotation, to.rotation, at);
88 return true;
89 }
90 return false;
91 }
92
94 uint32_t newest() const { return count > 0 ? samples[count - 1].tick : 0u; }
95};
96
97} // namespace Vkm::Engine
A short history of where one entity was, kept by tick.
Definition sample_track.h:19
void record(uint32_t tick, const glm::vec3 &position, const glm::quat &rotation)
Remember position and rotation as of tick.
Definition sample_track.h:39
Sample samples[N]
Oldest first, newest last; the first count are held.
Definition sample_track.h:26
bool poseAt(double tick, glm::vec3 &position, glm::quat &rotation) const
Where the entity was at tick, which may fall between two samples.
Definition sample_track.h:61
size_t count
Samples held.
Definition sample_track.h:27
uint32_t newest() const
The newest moment remembered, or zero when nothing is.
Definition sample_track.h:94