A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
Rail.hh
1#pragma once
2
3#include "game/system/map/MapdataPointInfo.hh"
4
5namespace Kinoko::Field {
6
8 f32 m_length;
9 f32 m_lengthInv;
10 EGG::Vector3f m_dir;
11};
12
14 EGG::Vector3f m_p0;
15 EGG::Vector3f m_p1;
16 EGG::Vector3f m_p2;
17 EGG::Vector3f m_p3;
18 f32 m_length;
19 f32 m_lengthInv;
20};
21
22class Rail {
23public:
24 Rail(u16 idx, System::MapdataPointInfo *info);
25 virtual ~Rail();
26
27 virtual f32 getPathLength() const = 0;
28 virtual std::span<const RailLineTransition> getLinearTransitions() const = 0;
29 virtual std::span<const RailSplineTransition> getSplineTransitions() const = 0;
30 virtual std::span<const f32> getPathPercentages() const = 0;
31
32 void addPoint(f32 scale, const EGG::Vector3f &point);
33 void checkSphereFull();
34
35 [[nodiscard]] u16 pointCount() const {
36 return m_pointCount;
37 }
38
39 [[nodiscard]] bool isOscillating() const {
40 return m_isOscillating;
41 }
42
43 [[nodiscard]] std::span<const System::MapdataPointInfo::Point> points() const {
44 return m_points.view();
45 }
46
48 [[nodiscard]] const EGG::Vector3f &pointPos(u16 idx) const {
49 ASSERT(idx < m_pointCount);
50 return m_points[idx].pos;
51 }
52
53 [[nodiscard]] const EGG::Vector3f &floorNrm(u16 idx) const {
54 ASSERT(!m_floorNrms.empty() && idx < m_floorNrms.size());
55 return m_floorNrms[idx];
56 }
57
58protected:
59 virtual void onPointsChanged() = 0;
60 virtual void onPointAdded() = 0;
61
62 u16 m_pointCount;
63 bool m_isOscillating;
64 owning_span<System::MapdataPointInfo::Point> m_points;
65 f32 m_someScale;
66
67private:
68 u16 m_idx;
69 u16 m_pointCapacity;
70 bool m_hasCheckedCol;
71 owning_span<EGG::Vector3f> m_floorNrms;
72};
73
74class RailLine : public Rail {
75public:
76 RailLine(u16 idx, System::MapdataPointInfo *info);
77 ~RailLine() override;
78
81 [[nodiscard]] std::span<const f32> getPathPercentages() const override {
82 static owning_span<f32> EMPTY_PERCENTAGES;
83 return EMPTY_PERCENTAGES.view();
84 }
85
86private:
88 [[nodiscard]] f32 getPathLength() const override {
89 return m_pathLength;
90 }
91
93 [[nodiscard]] std::span<const RailLineTransition> getLinearTransitions() const override {
94 return m_transitions.view();
95 }
96
99 [[nodiscard]] std::span<const RailSplineTransition> getSplineTransitions() const override {
100 static owning_span<RailSplineTransition> EMPTY_TRANSITIONS;
101 return EMPTY_TRANSITIONS.view();
102 }
103
104 void onPointsChanged() override {}
105 void onPointAdded() override {}
106
107 u16 m_dirCount;
108 owning_span<RailLineTransition> m_transitions;
109 f32 m_pathLength;
110};
111
112class RailSpline : public Rail {
113public:
114 RailSpline(u16 idx, System::MapdataPointInfo *info);
115 ~RailSpline() override;
116
118 [[nodiscard]] std::span<const f32> getPathPercentages() const override {
119 return m_pathPercentages.view();
120 }
121
122 [[nodiscard]] static consteval u32 getEstimatorSampleCount() {
123 return ESTIMATOR_SAMPLE_COUNT;
124 }
125
127 [[nodiscard]] static consteval f32 getEstimatorStep() {
128 return ESTIMATOR_STEP;
129 }
130
131private:
133 [[nodiscard]] f32 getPathLength() const override {
134 return m_pathLength;
135 }
136
138 [[nodiscard]] std::span<const RailLineTransition> getLinearTransitions() const override {
139 static owning_span<RailLineTransition> EMPTY_TRANSITIONS;
140 return EMPTY_TRANSITIONS.view();
141 }
142
144 [[nodiscard]] std::span<const RailSplineTransition> getSplineTransitions() const override {
145 return m_transitions.view();
146 }
147
148 void onPointsChanged() override;
149 void onPointAdded() override;
150
151 void invalidateTransitions(bool lastOnly);
152 void calcCubicBezierControlPoints(const EGG::Vector3f &p0, const EGG::Vector3f &p1,
153 const EGG::Vector3f &p2, const EGG::Vector3f &p3, s32 count,
154 RailSplineTransition &transition);
155 [[nodiscard]] f32 estimateLength(const RailSplineTransition &transition, s32 count);
156 [[nodiscard]] EGG::Vector3f calcCubicBezierP1(const EGG::Vector3f &p0, const EGG::Vector3f &p1,
157 const EGG::Vector3f &p2) const;
158 [[nodiscard]] EGG::Vector3f calcCubicBezierP2(const EGG::Vector3f &p0, const EGG::Vector3f &p1,
159 const EGG::Vector3f &p2) const;
160 [[nodiscard]] EGG::Vector3f cubicBezier(f32 t, const RailSplineTransition &transition) const;
161
162 u16 m_transitionCount;
164 owning_span<f32> m_pathPercentages;
165 s32 m_segmentCount;
166 f32 m_pathLength;
167 bool m_doNotAllocatePathPercentages;
168
169 static constexpr u32 ESTIMATOR_SAMPLE_COUNT = 10;
170 static constexpr f32 ESTIMATOR_STEP = 1.0f / static_cast<f32>(ESTIMATOR_SAMPLE_COUNT);
171};
172
173} // namespace Kinoko::Field
std::span< const f32 > getPathPercentages() const override
In the base game we return a nullptr. To mimic this, return an empty vector.
Definition Rail.hh:81
std::span< const RailSplineTransition > getSplineTransitions() const override
In the base game we return a nullptr. To mimic this, return an empty vector.
Definition Rail.hh:99
A contiguous storage container that manages the lifecycle of a buffer of a given size.
Definition Types.hh:32
std::span< const T > view() const
Returns a read-only view of the entire buffer.
Definition Types.hh:161
Pertains to collision.
A 3D float vector.
Definition Vector.hh:107