A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
Vector.hh
1#pragma once
2
3#include "egg/math/Math.hh"
4
5#include "egg/util/Stream.hh"
6
7#include <format>
8
9namespace EGG {
10
12struct Vector2f {
13#ifdef BUILD_DEBUG
14 constexpr Vector2f()
15 : x(std::numeric_limits<f32>::signaling_NaN()),
16 y(std::numeric_limits<f32>::signaling_NaN()) {}
17#else
18 constexpr Vector2f() = default;
19#endif
20 constexpr Vector2f(f32 x_, f32 y_) : x(x_), y(y_) {}
21 ~Vector2f() = default;
22
23 inline void set(f32 val) {
24 x = y = val;
25 }
26
27 [[nodiscard]] Vector2f operator-() const {
28 return Vector2f(-x, -y);
29 }
30
31 [[nodiscard]] Vector2f operator-(const Vector2f &rhs) const {
32 return Vector2f(x - rhs.x, y - rhs.y);
33 }
34
35 [[nodiscard]] Vector2f operator+(const Vector2f &rhs) const {
36 return Vector2f(x + rhs.x, y + rhs.y);
37 }
38
39 Vector2f &operator+=(const Vector2f &rhs) {
40 return *this = *this + rhs;
41 }
42
43 [[nodiscard]] Vector2f operator*(const f32 scalar) const {
44 return Vector2f(x * scalar, y * scalar);
45 }
46
47 Vector2f &operator*=(const f32 scalar) {
48 return *this = *this * scalar;
49 }
50
51 friend Vector2f operator*(f32 scalar, const Vector2f &rhs) {
52 return Vector2f(scalar * rhs.x, scalar * rhs.y);
53 }
54
55 [[nodiscard]] f32 cross(const Vector2f &rhs) const {
56 return x * rhs.y - y * rhs.x;
57 }
58
59 [[nodiscard]] f32 dot(const Vector2f &rhs) const {
60 return x * rhs.x + y * rhs.y;
61 }
62
63 [[nodiscard]] f32 dot() const {
64 return x * x + y * y;
65 }
66
67 [[nodiscard]] f32 length() const {
68 return dot() > std::numeric_limits<f32>::epsilon() ? Mathf::sqrt(dot()) : 0.0f;
69 }
70
71 f32 normalise();
72
73 void read(Stream &stream);
74
75 f32 x;
76 f32 y;
77
78 static const Vector2f zero;
79 static const Vector2f ex, ey;
80};
81
82inline constexpr Vector2f Vector2f::zero = Vector2f(0.0f, 0.0f);
83inline constexpr Vector2f Vector2f::ex = Vector2f(1.0f, 0.0f);
84inline constexpr Vector2f Vector2f::ey = Vector2f(0.0f, 1.0f);
85
87struct Vector3f {
88#ifdef BUILD_DEBUG
89 constexpr Vector3f()
90 : x(std::numeric_limits<f32>::signaling_NaN()),
91 y(std::numeric_limits<f32>::signaling_NaN()),
92 z(std::numeric_limits<f32>::signaling_NaN()) {}
93#else
94 constexpr Vector3f() = default;
95#endif
96 constexpr Vector3f(f32 x_, f32 y_, f32 z_) : x(x_), y(y_), z(z_) {}
97
98 // NOTE: Defining the destructor in the header ensures the struct is trivially destructible
99 ~Vector3f() = default;
100
101 inline void setZero() {
102 set(0.0f);
103 }
104
105 inline void set(f32 val) {
106 x = y = z = val;
107 }
108
109 [[nodiscard]] Vector3f operator-() const {
110 return Vector3f(-x, -y, -z);
111 }
112
113 [[nodiscard]] Vector3f operator-(const Vector3f &rhs) const {
114 return Vector3f(x - rhs.x, y - rhs.y, z - rhs.z);
115 }
116
117 Vector3f &operator-=(const Vector3f &rhs) {
118 return *this = *this - rhs;
119 }
120
121 [[nodiscard]] Vector3f operator+(const Vector3f &rhs) const {
122 return Vector3f(x + rhs.x, y + rhs.y, z + rhs.z);
123 }
124
125 Vector3f &operator+=(const Vector3f &rhs) {
126 return *this = *this + rhs;
127 }
128
129 [[nodiscard]] Vector3f operator+(f32 val) const {
130 return Vector3f(x + val, y + val, z + val);
131 }
132
133 Vector3f &operator+=(f32 val) {
134 return *this = *this + val;
135 }
136
137 [[nodiscard]] Vector3f operator*(const Vector3f &rhs) const {
138 return Vector3f(x * rhs.x, y * rhs.y, z * rhs.z);
139 }
140
141 [[nodiscard]] Vector3f operator*(f32 scalar) const {
142 return Vector3f(x * scalar, y * scalar, z * scalar);
143 }
144
145 [[nodiscard]] friend Vector3f operator*(f32 scalar, const Vector3f &rhs) {
146 return rhs * scalar;
147 }
148
149 Vector3f &operator*=(f32 scalar) {
150 return *this = *this * scalar;
151 }
152
153 [[nodiscard]] Vector3f operator/(f32 scalar) const {
154 return Vector3f(x / scalar, y / scalar, z / scalar);
155 }
156
157 Vector3f &operator/=(f32 scalar) {
158 return *this = *this / scalar;
159 }
160
161 bool operator==(const Vector3f &rhs) const {
162 return x == rhs.x && y == rhs.y && z == rhs.z;
163 }
164
165 bool operator!=(const Vector3f &rhs) const {
166 return !(*this == rhs);
167 }
168
170 explicit operator std::string() const {
171 return std::format("[0x{:08X}, 0x{:08X}, 0x{:08X}] | [{}, {}, {}]", f2u(x), f2u(y), f2u(z),
172 x, y, z);
173 }
174
176 [[nodiscard]] Vector3f cross(const Vector3f &rhs) const {
177 return Vector3f(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x);
178 }
179
181 [[nodiscard]] f32 squaredLength() const {
182 return x * x + y * y + z * z;
183 }
184
186 [[nodiscard]] f32 dot(const Vector3f &rhs) const {
187 return x * rhs.x + y * rhs.y + z * rhs.z;
188 }
189
191 [[nodiscard]] f32 length() const {
192 return Mathf::sqrt(squaredLength());
193 }
194
197 [[nodiscard]] Vector3f proj(const Vector3f &rhs) const {
198 return rhs * rhs.dot(*this);
199 }
200
203 [[nodiscard]] Vector3f rej(const Vector3f &rhs) const {
204 return *this - proj(rhs);
205 }
206
208 [[nodiscard]] std::pair<Vector3f, Vector3f> projAndRej(const Vector3f &rhs) const {
209 return std::pair(proj(rhs), rej(rhs));
210 }
211
213 [[nodiscard]] Vector3f abs() const {
214 return Vector3f(Mathf::abs(x), Mathf::abs(y), Mathf::abs(z));
215 }
216
218 [[nodiscard]] f32 sqDistance(const Vector3f &rhs) const {
219 const EGG::Vector3f diff = *this - rhs;
220 return diff.squaredLength();
221 }
222
225 [[nodiscard]] EGG::Vector3f multInv(f32 val) const {
226 return *this * (1.0f / val);
227 }
228
229 [[nodiscard]] f32 ps_dot() const;
230 [[nodiscard]] f32 ps_dot(const EGG::Vector3f &rhs) const;
231 [[nodiscard]] f32 ps_squareMag() const;
232 f32 normalise();
233 void normalise2();
234 [[nodiscard]] Vector3f maximize(const Vector3f &rhs) const;
235 [[nodiscard]] Vector3f minimize(const Vector3f &rhs) const;
236 [[nodiscard]] f32 ps_sqDistance(const Vector3f &rhs) const;
237 [[nodiscard]] Vector3f perpInPlane(const EGG::Vector3f &rhs, bool normalise) const;
238
239 void read(Stream &stream);
240
241 f32 x;
242 f32 y;
243 f32 z;
244
245 static const Vector3f zero;
246 static const Vector3f unit;
247 static const Vector3f ex, ey, ez;
248 static const Vector3f inf;
249};
250
251inline constexpr Vector3f Vector3f::zero = Vector3f(0.0f, 0.0f, 0.0f);
252inline constexpr Vector3f Vector3f::unit = Vector3f(1.0f, 1.0f, 1.0f);
253inline constexpr Vector3f Vector3f::ex = Vector3f(1.0f, 0.0f, 0.0f);
254inline constexpr Vector3f Vector3f::ey = Vector3f(0.0f, 1.0f, 0.0f);
255inline constexpr Vector3f Vector3f::ez = Vector3f(0.0f, 0.0f, 1.0f);
256
258inline constexpr Vector3f Vector3f::inf = Vector3f(std::numeric_limits<f32>::infinity(),
259 std::numeric_limits<f32>::infinity(), std::numeric_limits<f32>::infinity());
260
261} // namespace EGG
A stream of data, abstracted to allow for continuous seeking.
Definition Stream.hh:10
EGG core library.
Definition Archive.cc:6
A 2D float vector.
Definition Vector.hh:12
void read(Stream &stream)
Initializes a Vector2f by reading 8 bytes from the stream.
Definition Vector.cc:16
A 3D float vector.
Definition Vector.hh:87
f32 normalise()
Normalizes the vector and returns the original length.
Definition Vector.cc:44
Vector3f abs() const
Returns the absolute value of each element of the vector.
Definition Vector.hh:213
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.
Definition Vector.hh:186
f32 length() const
The square root of the vector's dot product.
Definition Vector.hh:191
f32 squaredLength() const
The dot product between the vector and itself.
Definition Vector.hh:181
Vector3f proj(const Vector3f &rhs) const
The projection of this vector onto rhs.
Definition Vector.hh:197
f32 ps_squareMag() const
Differs from ps_dot due to variation in which operands are fused.
Definition Vector.cc:35
void read(Stream &stream)
Initializes a Vector3f by reading 12 bytes from the stream.
Definition Vector.cc:115
Vector3f perpInPlane(const EGG::Vector3f &rhs, bool normalise) const
Calculates the orthogonal vector, based on the plane defined by this vector and rhs.
Definition Vector.cc:96
EGG::Vector3f multInv(f32 val) const
Multiplies a vector by the inverse of val.
Definition Vector.hh:225
Vector3f rej(const Vector3f &rhs) const
The rejection of this vector onto rhs.
Definition Vector.hh:203
Vector3f maximize(const Vector3f &rhs) const
Returns a vector whose elements are the max of the elements of both vectors.
Definition Vector.cc:65
f32 sqDistance(const Vector3f &rhs) const
The square of the distance between two vectors.
Definition Vector.hh:218
f32 ps_sqDistance(const Vector3f &rhs) const
Paired-singles impl. of sqDistance.
Definition Vector.cc:89
f32 ps_dot() const
Paired-singles dot product implementation.
Definition Vector.cc:22
Vector3f minimize(const Vector3f &rhs) const
Returns a vector whose elements are the min of the elements of both vectors.
Definition Vector.cc:77