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