A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
RailInterpolator.hh
1#pragma once
2
3#include <Common.hh>
4
5#include "game/field/Rail.hh"
6
7#include "game/system/map/MapdataPointInfo.hh"
8
9#include <egg/math/Vector.hh>
10
11namespace Field {
12
14public:
15 enum class Status {
16 InProgress = 0,
17 SegmentEnd = 1,
18 ChangingDirection = 2,
19 };
20
21 RailInterpolator(f32 speed, u32 idx);
22 virtual ~RailInterpolator();
23
24 virtual void init(f32 t, u32 idx) = 0;
25 virtual Status calc() = 0;
26 virtual void setCurrVel(f32 speed) = 0;
27
28 virtual f32 getCurrVel() = 0;
29 virtual void evalCubicBezierOnPath(f32 t, EGG::Vector3f &currDir,
30 EGG::Vector3f &curTangentDir) = 0;
31 virtual void getPathLocation(f32 t, s16 &idx, f32 &len) = 0;
32
33 [[nodiscard]] virtual f32 getCurrSegmentLength() const = 0;
34
35 void setPerPointVelocities(bool isSet) {
36 m_usePerPointVelocities = isSet;
37 }
38
40 void setT(f32 t) {
41 m_segmentT = t;
42 }
43
45 void reverseDirection() {
46 m_movementDirectionForward = !m_movementDirectionForward;
47 std::swap(m_currPointIdx, m_nextPointIdx);
48 m_segmentT = 1.0f - m_segmentT;
49 }
50
51 [[nodiscard]] const EGG::Vector3f &floorNrm(size_t idx) const;
52 [[nodiscard]] f32 railLength() const;
53
54 [[nodiscard]] const System::MapdataPointInfo::Point &curPoint() const {
55 ASSERT(static_cast<size_t>(m_currPointIdx) < m_points.size());
56 return m_points[m_currPointIdx];
57 }
58
59 [[nodiscard]] const System::MapdataPointInfo::Point &nextPoint() const {
60 ASSERT(static_cast<size_t>(m_nextPointIdx) < m_points.size());
61 return m_points[m_nextPointIdx];
62 }
63
64 [[nodiscard]] s16 railIdx() const {
65 return m_railIdx;
66 }
67
68 [[nodiscard]] u16 pointCount() const {
69 return m_pointCount;
70 }
71
72 [[nodiscard]] f32 speed() const {
73 return m_speed;
74 }
75
76 [[nodiscard]] const EGG::Vector3f &curPos() const {
77 return m_curPos;
78 }
79
80 [[nodiscard]] const EGG::Vector3f &curTangentDir() const {
81 return m_curTangentDir;
82 }
83
84 [[nodiscard]] f32 currVel() const {
85 return m_currVel;
86 }
87
88 [[nodiscard]] f32 segmentT() const {
89 return m_segmentT;
90 }
91
92 [[nodiscard]] bool isMovementDirectionForward() const {
93 return m_movementDirectionForward;
94 }
95
96 [[nodiscard]] s16 curPointIdx() const {
97 return m_currPointIdx;
98 }
99
100 [[nodiscard]] s16 nextPointIdx() const {
101 return m_nextPointIdx;
102 }
103
104protected:
105 void updateVel();
106 void calcVelocities();
107 [[nodiscard]] bool shouldChangeDirection() const;
108 void calcDirectionChange();
109 void calcNextIndices();
110
111 s16 m_railIdx;
112 u16 m_pointCount;
113 std::span<System::MapdataPointInfo::Point> m_points;
114 bool m_isOscillating;
115 f32 m_speed;
116 bool m_usePerPointVelocities;
117 EGG::Vector3f m_curPos;
118 EGG::Vector3f m_curTangentDir;
119 f32 m_currVel;
120 f32 m_prevPointVel;
121 f32 m_nextPointVel;
122 f32 m_currSegmentVel;
123 f32 m_segmentT;
124 bool m_movementDirectionForward;
125 s16 m_currPointIdx;
126 s16 m_nextPointIdx;
127 bool m_4a;
128};
129
131public:
132 RailLinearInterpolator(f32 speed, u32 idx);
133 ~RailLinearInterpolator() override;
134
135 void init(f32 t, u32 idx) override;
136 Status calc() override;
137 void setCurrVel(f32 speed) override;
138
140 [[nodiscard]] f32 getCurrVel() override {
141 return m_currVel;
142 }
143
144 void evalCubicBezierOnPath(f32 t, EGG::Vector3f &currDir,
145 EGG::Vector3f &curTangentDir) override;
146 void getPathLocation(f32 t, s16 &idx, f32 &len) override;
147
149 [[nodiscard]] f32 getCurrSegmentLength() const override {
150 s16 idx = m_movementDirectionForward ? m_currPointIdx : m_nextPointIdx;
151 return m_transitions[idx].m_length;
152 }
153
154private:
155 void calcNextSegment();
156 EGG::Vector3f lerp(f32 t, u32 currIdx, u32 nextIdx) const;
157
158 EGG::Vector3f m_currentDirection;
159 std::span<RailLineTransition> m_transitions;
160};
161
163public:
164 RailSmoothInterpolator(f32 speed, u32 idx);
165 ~RailSmoothInterpolator() override;
166
167 void init(f32 t, u32 idx) override;
168 Status calc() override;
169 void setCurrVel(f32 speed) override;
170
172 [[nodiscard]] f32 getCurrVel() override {
173 return m_velocity;
174 }
175
176 void evalCubicBezierOnPath(f32 t, EGG::Vector3f &currDir,
177 EGG::Vector3f &curTangentDir) override;
178 void getPathLocation(f32 t, s16 &idx, f32 &len) override;
179
181 [[nodiscard]] f32 getCurrSegmentLength() const override {
182 s16 idx = m_movementDirectionForward ? m_currPointIdx : m_nextPointIdx;
183 return m_transitions[idx].m_length;
184 }
185
186private:
187 void calcCubicBezier(f32 t, u32 currIdx, u32 nextIdx, EGG::Vector3f &pos,
188 EGG::Vector3f &dir) const;
189 [[nodiscard]] EGG::Vector3f calcCubicBezierPos(f32 t, const RailSplineTransition &trans) const;
190 [[nodiscard]] EGG::Vector3f calcCubicBezierTangentDir(f32 t,
191 const RailSplineTransition &trans) const;
192 [[nodiscard]] f32 calcT(f32 t) const;
193 void calcNextSegment();
194
195 std::span<RailSplineTransition> m_transitions;
196 u32 m_estimatorSampleCount;
197 f32 m_estimatorStep;
198 std::span<f32> m_pathPercentages;
199 EGG::Vector3f m_prevPos;
200 f32 m_velocity;
201};
202
203} // namespace Field
This header houses common data types such as our integral types and enums.
Pertains to collision.
A 3D float vector.
Definition Vector.hh:88