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 void setPerPointVelocities(bool isSet) {
34 m_usePerPointVelocities = isSet;
35 }
36
38 void setT(f32 t) {
39 m_segmentT = t;
40 }
41
42 [[nodiscard]] const EGG::Vector3f &floorNrm(size_t idx) const;
43 [[nodiscard]] f32 railLength() const;
44
45 [[nodiscard]] const System::MapdataPointInfo::Point &curPoint() const {
46 ASSERT(static_cast<size_t>(m_currPointIdx) < m_points.size());
47 return m_points[m_currPointIdx];
48 }
49
50 [[nodiscard]] const EGG::Vector3f &curPos() const {
51 return m_curPos;
52 }
53
54 [[nodiscard]] const EGG::Vector3f &curTangentDir() const {
55 return m_curTangentDir;
56 }
57
58 [[nodiscard]] bool isMovementDirectionForward() const {
59 return m_movementDirectionForward;
60 }
61
62protected:
63 void updateVel();
64 void calcVelocities();
65 [[nodiscard]] bool shouldChangeDirection() const;
66 void calcDirectionChange();
67 void calcNextIndices();
68
69 s16 m_railIdx;
70 u16 m_pointCount;
71 std::span<System::MapdataPointInfo::Point> m_points;
72 bool m_isOscillating;
73 f32 m_speed;
74 bool m_usePerPointVelocities;
75 EGG::Vector3f m_curPos;
76 EGG::Vector3f m_curTangentDir;
77 f32 m_currVel;
78 f32 m_prevPointVel;
79 f32 m_nextPointVel;
80 f32 m_currSegmentVel;
81 f32 m_segmentT;
82 bool m_movementDirectionForward;
83 s16 m_currPointIdx;
84 s16 m_nextPointIdx;
85 bool m_4a;
86};
87
89public:
90 RailLinearInterpolator(f32 speed, u32 idx);
91 ~RailLinearInterpolator() override;
92
93 void init(f32 t, u32 idx) override;
94 Status calc() override;
95 void setCurrVel(f32 speed) override;
96
98 [[nodiscard]] f32 getCurrVel() override {
99 return m_currVel;
100 }
101
102 void evalCubicBezierOnPath(f32 t, EGG::Vector3f &currDir,
103 EGG::Vector3f &curTangentDir) override;
104 void getPathLocation(f32 t, s16 &idx, f32 &len) override;
105
106private:
107 void calcNextSegment();
108 EGG::Vector3f lerp(f32 t, u32 currIdx, u32 nextIdx) const;
109
110 EGG::Vector3f m_currentDirection;
111 std::span<RailLineTransition> m_transitions;
112};
113
115public:
116 RailSmoothInterpolator(f32 speed, u32 idx);
117 ~RailSmoothInterpolator() override;
118
119 void init(f32 t, u32 idx) override;
120 Status calc() override;
121 void setCurrVel(f32 speed) override;
122
124 [[nodiscard]] f32 getCurrVel() override {
125 return m_velocity;
126 }
127
128 void evalCubicBezierOnPath(f32 t, EGG::Vector3f &currDir,
129 EGG::Vector3f &curTangentDir) override;
130 void getPathLocation(f32 t, s16 &idx, f32 &len) override;
131
132private:
133 void calcCubicBezier(f32 t, u32 currIdx, u32 nextIdx, EGG::Vector3f &pos,
134 EGG::Vector3f &dir) const;
135 [[nodiscard]] EGG::Vector3f calcCubicBezierPos(f32 t, const RailSplineTransition &trans) const;
136 [[nodiscard]] EGG::Vector3f calcCubicBezierTangentDir(f32 t,
137 const RailSplineTransition &trans) const;
138 [[nodiscard]] f32 calcT(f32 t) const;
139 void calcNextSegment();
140
141 std::span<RailSplineTransition> m_transitions;
142 u32 m_estimatorSampleCount;
143 f32 m_estimatorStep;
144 std::span<f32> m_pathPercentages;
145 EGG::Vector3f m_prevPos;
146 f32 m_velocity;
147};
148
149} // 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