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 void normalise2();
73
74 void read(Stream &stream);
75
76 f32 x;
77 f32 y;
78
79 static const Vector2f zero;
80 static const Vector2f ex, ey;
81};
82
83inline constexpr Vector2f Vector2f::zero = Vector2f(0.0f, 0.0f);
84inline constexpr Vector2f Vector2f::ex = Vector2f(1.0f, 0.0f);
85inline constexpr Vector2f Vector2f::ey = Vector2f(0.0f, 1.0f);
86
88struct Vector3f {
89#ifdef BUILD_DEBUG
90 constexpr Vector3f()
91 : x(std::numeric_limits<f32>::signaling_NaN()),
92 y(std::numeric_limits<f32>::signaling_NaN()),
93 z(std::numeric_limits<f32>::signaling_NaN()) {}
94#else
95 constexpr Vector3f() = default;
96#endif
97 constexpr Vector3f(f32 x_, f32 y_, f32 z_) : x(x_), y(y_), z(z_) {}
98
99 // NOTE: Defining the destructor in the header ensures the struct is trivially destructible
100 ~Vector3f() = default;
101
102 inline void setZero() {
103 set(0.0f);
104 }
105
106 inline void set(f32 val) {
107 x = y = z = val;
108 }
109
110 [[nodiscard]] Vector3f operator-() const {
111 return Vector3f(-x, -y, -z);
112 }
113
114 [[nodiscard]] Vector3f operator-(const Vector3f &rhs) const {
115 return Vector3f(x - rhs.x, y - rhs.y, z - rhs.z);
116 }
117
118 Vector3f &operator-=(const Vector3f &rhs) {
119 return *this = *this - rhs;
120 }
121
122 [[nodiscard]] Vector3f operator+(const Vector3f &rhs) const {
123 return Vector3f(x + rhs.x, y + rhs.y, z + rhs.z);
124 }
125
126 Vector3f &operator+=(const Vector3f &rhs) {
127 return *this = *this + rhs;
128 }
129
130 [[nodiscard]] Vector3f operator+(f32 val) const {
131 return Vector3f(x + val, y + val, z + val);
132 }
133
134 Vector3f &operator+=(f32 val) {
135 return *this = *this + val;
136 }
137
138 [[nodiscard]] Vector3f operator*(const Vector3f &rhs) const {
139 return Vector3f(x * rhs.x, y * rhs.y, z * rhs.z);
140 }
141
142 [[nodiscard]] constexpr Vector3f operator*(f32 scalar) const {
143 return Vector3f(x * scalar, y * scalar, z * scalar);
144 }
145
146 [[nodiscard]] friend Vector3f operator*(f32 scalar, const Vector3f &rhs) {
147 return rhs * scalar;
148 }
149
150 Vector3f &operator*=(f32 scalar) {
151 return *this = *this * scalar;
152 }
153
154 [[nodiscard]] Vector3f operator/(f32 scalar) const {
155 return Vector3f(x / scalar, y / scalar, z / scalar);
156 }
157
158 Vector3f &operator/=(f32 scalar) {
159 return *this = *this / scalar;
160 }
161
162 bool operator==(const Vector3f &rhs) const {
163 return x == rhs.x && y == rhs.y && z == rhs.z;
164 }
165
166 bool operator!=(const Vector3f &rhs) const {
167 return !(*this == rhs);
168 }
169
171 explicit operator std::string() const {
172 return std::format("[0x{:08X}, 0x{:08X}, 0x{:08X}] | [{}, {}, {}]", f2u(x), f2u(y), f2u(z),
173 x, y, z);
174 }
175
177 [[nodiscard]] Vector3f cross(const Vector3f &rhs) const {
178 return Vector3f(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x);
179 }
180
182 [[nodiscard]] f32 squaredLength() const {
183 return x * x + y * y + z * z;
184 }
185
187 [[nodiscard]] f32 dot(const Vector3f &rhs) const {
188 return x * rhs.x + y * rhs.y + z * rhs.z;
189 }
190
192 [[nodiscard]] f32 length() const {
193 return Mathf::sqrt(squaredLength());
194 }
195
198 [[nodiscard]] Vector3f proj(const Vector3f &rhs) const {
199 return rhs * rhs.dot(*this);
200 }
201
204 [[nodiscard]] Vector3f rej(const Vector3f &rhs) const {
205 return *this - proj(rhs);
206 }
207
209 [[nodiscard]] std::pair<Vector3f, Vector3f> projAndRej(const Vector3f &rhs) const {
210 return std::pair(proj(rhs), rej(rhs));
211 }
212
214 [[nodiscard]] Vector3f abs() const {
215 return Vector3f(Mathf::abs(x), Mathf::abs(y), Mathf::abs(z));
216 }
217
219 [[nodiscard]] f32 sqDistance(const Vector3f &rhs) const {
220 const EGG::Vector3f diff = *this - rhs;
221 return diff.squaredLength();
222 }
223
226 [[nodiscard]] EGG::Vector3f multInv(f32 val) const {
227 return *this * (1.0f / val);
228 }
229
230 [[nodiscard]] f32 ps_dot() const;
231 [[nodiscard]] f32 ps_dot(const EGG::Vector3f &rhs) const;
232 [[nodiscard]] f32 ps_squareMag() const;
233 f32 normalise();
234 void normalise2();
235 [[nodiscard]] Vector3f maximize(const Vector3f &rhs) const;
236 [[nodiscard]] Vector3f minimize(const Vector3f &rhs) const;
237 [[nodiscard]] f32 ps_sqDistance(const Vector3f &rhs) const;
238 [[nodiscard]] Vector3f perpInPlane(const EGG::Vector3f &rhs, bool normalise) const;
239
240 void read(Stream &stream);
241
242 f32 x;
243 f32 y;
244 f32 z;
245
246 static const Vector3f zero;
247 static const Vector3f unit;
248 static const Vector3f ex, ey, ez;
249 static const Vector3f inf;
250};
251
252inline constexpr Vector3f Vector3f::zero = Vector3f(0.0f, 0.0f, 0.0f);
253inline constexpr Vector3f Vector3f::unit = Vector3f(1.0f, 1.0f, 1.0f);
254inline constexpr Vector3f Vector3f::ex = Vector3f(1.0f, 0.0f, 0.0f);
255inline constexpr Vector3f Vector3f::ey = Vector3f(0.0f, 1.0f, 0.0f);
256inline constexpr Vector3f Vector3f::ez = Vector3f(0.0f, 0.0f, 1.0f);
257
259inline constexpr Vector3f Vector3f::inf = Vector3f(std::numeric_limits<f32>::infinity(),
260 std::numeric_limits<f32>::infinity(), std::numeric_limits<f32>::infinity());
261
262} // 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:24
A 3D float vector.
Definition Vector.hh:88
f32 normalise()
Normalizes the vector and returns the original length.
Definition Vector.cc:52
Vector3f abs() const
Returns the absolute value of each element of the vector.
Definition Vector.hh:214
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.
Definition Vector.hh:187
f32 length() const
The square root of the vector's dot product.
Definition Vector.hh:192
f32 squaredLength() const
The dot product between the vector and itself.
Definition Vector.hh:182
Vector3f proj(const Vector3f &rhs) const
The projection of this vector onto rhs.
Definition Vector.hh:198
f32 ps_squareMag() const
Differs from ps_dot due to variation in which operands are fused.
Definition Vector.cc:43
void read(Stream &stream)
Initializes a Vector3f by reading 12 bytes from the stream.
Definition Vector.cc:123
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:104
EGG::Vector3f multInv(f32 val) const
Multiplies a vector by the inverse of val.
Definition Vector.hh:226
Vector3f rej(const Vector3f &rhs) const
The rejection of this vector onto rhs.
Definition Vector.hh:204
Vector3f maximize(const Vector3f &rhs) const
Returns a vector whose elements are the max of the elements of both vectors.
Definition Vector.cc:73
f32 sqDistance(const Vector3f &rhs) const
The square of the distance between two vectors.
Definition Vector.hh:219
f32 ps_sqDistance(const Vector3f &rhs) const
Paired-singles impl. of sqDistance.
Definition Vector.cc:97
f32 ps_dot() const
Paired-singles dot product implementation.
Definition Vector.cc:30
Vector3f minimize(const Vector3f &rhs) const
Returns a vector whose elements are the min of the elements of both vectors.
Definition Vector.cc:85