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
44 [[nodiscard]] const EGG::Vector3f &floorNrm(size_t idx) const;
45 [[nodiscard]] f32 railLength() const;
46
47 [[nodiscard]] const System::MapdataPointInfo::Point &curPoint() const {
48 ASSERT(static_cast<size_t>(m_currPointIdx) < m_points.size());
49 return m_points[m_currPointIdx];
50 }
51
52 [[nodiscard]] const System::MapdataPointInfo::Point &nextPoint() const {
53 ASSERT(static_cast<size_t>(m_nextPointIdx) < m_points.size());
54 return m_points[m_nextPointIdx];
55 }
56
57 [[nodiscard]] s16 railIdx() const {
58 return m_railIdx;
59 }
60
61 [[nodiscard]] u16 pointCount() const {
62 return m_pointCount;
63 }
64
65 [[nodiscard]] f32 speed() const {
66 return m_speed;
67 }
68
69 [[nodiscard]] const EGG::Vector3f &curPos() const {
70 return m_curPos;
71 }
72
73 [[nodiscard]] const EGG::Vector3f &curTangentDir() const {
74 return m_curTangentDir;
75 }
76
77 [[nodiscard]] f32 currVel() const {
78 return m_currVel;
79 }
80
81 [[nodiscard]] f32 segmentT() const {
82 return m_segmentT;
83 }
84
85 [[nodiscard]] bool isMovementDirectionForward() const {
86 return m_movementDirectionForward;
87 }
88
89 [[nodiscard]] s16 curPointIdx() const {
90 return m_currPointIdx;
91 }
92
93 [[nodiscard]] s16 nextPointIdx() const {
94 return m_nextPointIdx;
95 }
96
97protected:
98 void updateVel();
99 void calcVelocities();
100 [[nodiscard]] bool shouldChangeDirection() const;
101 void calcDirectionChange();
102 void calcNextIndices();
103
104 s16 m_railIdx;
105 u16 m_pointCount;
106 std::span<System::MapdataPointInfo::Point> m_points;
107 bool m_isOscillating;
108 f32 m_speed;
109 bool m_usePerPointVelocities;
110 EGG::Vector3f m_curPos;
111 EGG::Vector3f m_curTangentDir;
112 f32 m_currVel;
113 f32 m_prevPointVel;
114 f32 m_nextPointVel;
115 f32 m_currSegmentVel;
116 f32 m_segmentT;
117 bool m_movementDirectionForward;
118 s16 m_currPointIdx;
119 s16 m_nextPointIdx;
120 bool m_4a;
121};
122
124public:
125 RailLinearInterpolator(f32 speed, u32 idx);
126 ~RailLinearInterpolator() override;
127
128 void init(f32 t, u32 idx) override;
129 Status calc() override;
130 void setCurrVel(f32 speed) override;
131
133 [[nodiscard]] f32 getCurrVel() override {
134 return m_currVel;
135 }
136
137 void evalCubicBezierOnPath(f32 t, EGG::Vector3f &currDir,
138 EGG::Vector3f &curTangentDir) override;
139 void getPathLocation(f32 t, s16 &idx, f32 &len) override;
140
142 [[nodiscard]] f32 getCurrSegmentLength() const override {
143 s16 idx = m_movementDirectionForward ? m_currPointIdx : m_nextPointIdx;
144 return m_transitions[idx].m_length;
145 }
146
147private:
148 void calcNextSegment();
149 EGG::Vector3f lerp(f32 t, u32 currIdx, u32 nextIdx) const;
150
151 EGG::Vector3f m_currentDirection;
152 std::span<RailLineTransition> m_transitions;
153};
154
156public:
157 RailSmoothInterpolator(f32 speed, u32 idx);
158 ~RailSmoothInterpolator() override;
159
160 void init(f32 t, u32 idx) override;
161 Status calc() override;
162 void setCurrVel(f32 speed) override;
163
165 [[nodiscard]] f32 getCurrVel() override {
166 return m_velocity;
167 }
168
169 void evalCubicBezierOnPath(f32 t, EGG::Vector3f &currDir,
170 EGG::Vector3f &curTangentDir) override;
171 void getPathLocation(f32 t, s16 &idx, f32 &len) override;
172
174 [[nodiscard]] f32 getCurrSegmentLength() const override {
175 s16 idx = m_movementDirectionForward ? m_currPointIdx : m_nextPointIdx;
176 return m_transitions[idx].m_length;
177 }
178
179private:
180 void calcCubicBezier(f32 t, u32 currIdx, u32 nextIdx, EGG::Vector3f &pos,
181 EGG::Vector3f &dir) const;
182 [[nodiscard]] EGG::Vector3f calcCubicBezierPos(f32 t, const RailSplineTransition &trans) const;
183 [[nodiscard]] EGG::Vector3f calcCubicBezierTangentDir(f32 t,
184 const RailSplineTransition &trans) const;
185 [[nodiscard]] f32 calcT(f32 t) const;
186 void calcNextSegment();
187
188 std::span<RailSplineTransition> m_transitions;
189 u32 m_estimatorSampleCount;
190 f32 m_estimatorStep;
191 std::span<f32> m_pathPercentages;
192 EGG::Vector3f m_prevPos;
193 f32 m_velocity;
194};
195
196} // 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