SH4ZAM! 0.1.0
Fast math library for the Sega Dreamcast's SH4 CPU
Loading...
Searching...
No Matches
shz_vector.hpp
Go to the documentation of this file.
1/*! \file
2 * \brief C++ Vector types and operations.
3 * \ingroup vector
4 *
5 * This file provides types and mathematical functions for representing and
6 * operating on vectors within C++.
7 *
8 * \author 2025 Falco Girgis
9 * \copyright MIT License
10 *
11 * \todo
12 * - C++ proxy class equivalent for shz_vecN_deref().
13 * - C++ better swizzling mechanism
14 */
15
16#ifndef SHZ_VECTOR_HPP
17#define SHZ_VECTOR_HPP
18
19#include <compare>
20#include <concepts>
21
22#include "shz_vector.h"
23#include "shz_scalar.hpp"
24#include "shz_trig.hpp"
25
26namespace shz {
27
28struct vec2;
29struct vec3;
30struct vec4;
31
32/*! Common C++ base structure inherited by all vector types.
33
34 This struct template serves as the base class for all
35 concrete vector types, providing:
36 - Common API routines
37 - Adaptor between C and C++ types
38 - Convenience overloaded operators and STL iterators.
39
40 \sa shz::vec2, shz::vec3, shz::vec4
41*/
42template<typename CRTP, typename C, size_t R>
43struct vecN: C {
44 using CppType = CRTP; //!< Cpp derived type
45 using CType = C; //!< C base type
46
47 static constexpr size_t Rows = R; //!< Number of rows
48 static constexpr size_t Cols = 1; //!< Number of columns
49
50 //! Default constructor, does nothing.
51 vecN() noexcept = default;
52
53 //! Default copy constructor.
54 vecN(const vecN& other) noexcept = default;
55
56 //! Converting constructor from existing C instance.
57 SHZ_FORCE_INLINE vecN(const CType& other) noexcept:
58 CType(other) {}
59
60 //! Converting constructor from existing volatile C instance.
61 SHZ_FORCE_INLINE vecN(const volatile CType& other) noexcept:
62 CType(const_cast<const CType&>(other)) {}
63
64 //! Conversion operator for going from a layout-compatible vector type to a SH4ZAM vector type.
65 SHZ_FORCE_INLINE static CppType from(const auto& raw) noexcept {
66 return *reinterpret_cast<const CppType*>(&raw);
67 }
68
69 //! Conversion operator for going from a SH4ZAM vector type to another layout-compatible type.
70 template<typename T>
71 SHZ_FORCE_INLINE T to() const noexcept {
72 return *reinterpret_cast<const T*>(this);
73 }
74
75 //! Conversion operator for accessing an existing pointer type as though it were a refrence to a SH4ZAM type.
76 SHZ_FORCE_INLINE CppType& deref(const auto* raw) noexcept {
77 return *const_cast<CppType*>(reinterpret_cast<const CppType*>(raw));
78 }
79
80 //! Returns the vector that is linearly interpolated between the two given vectors by the `0.0f-1.0f` factor, \p t.
81 SHZ_FORCE_INLINE static CppType lerp(CppType start, CppType end, float t) noexcept {
82 return shz_vec_lerp(start, end, t);
83 }
84
85 //! Compares each component of the vector to the edge. 0 returned in that component if x[i] < edge. Otherwise the component is 1.
86 template<typename T>
87 SHZ_FORCE_INLINE static CppType step(CppType vec, T edge) noexcept {
88 return shz_vec_step(vec, edge);
89 }
90
91 //! Returns a vector where each component is smoothly interpolated from 0 to 1 between edge0 and edge1.
92 template<typename T>
93 SHZ_FORCE_INLINE static CppType smoothstep(CppType vec, T edge0, T edge1) noexcept {
94 return shz_vec_smoothstep(vec, edge0, edge1);
95 }
96
97 //! Returns a vector where each component is smoothly interpolated from 0 to 1 between edge0 and edge1.
98 template<typename T>
99 SHZ_FORCE_INLINE static CppType smoothstep_safe(CppType vec, T edge0, T edge1) noexcept {
100 return shz_vec_smoothstep_safe(vec, edge0, edge1);
101 }
102
103#ifdef SHZ_CPP23
104 //! Overloaded subscript operator -- allows for indexing vectors like an array.
105 SHZ_FORCE_INLINE auto&& operator[](this auto&& self, size_t index) noexcept {
106 return std::forward<decltype(self)>(self).e[index];
107 }
108
109 //! Overloaded space-ship operator, for generic lexicographical comparison of vectors.
110 friend auto operator<=>(CppType lhs, CppType rhs) noexcept {
112 }
113
114 //! Returns an iterator to the beginning of the vector -- For STL support.
115 SHZ_FORCE_INLINE auto begin(this auto&& self) noexcept {
116 return &self[0];
117 }
118
119 //! Returns an iterator to the end of the vector -- For STL support.
120 SHZ_FORCE_INLINE auto end(this auto&& self) noexcept {
121 return &self[Rows];
122 }
123
124 //! Overloaded "less-than" operator, for comparing vectors.
125 friend auto operator<(CppType lhs, CppType rhs) noexcept {
127 }
128#endif
129
130 //! Overloaded equality operator, for comparing vectors.
131 friend bool operator==(CppType lhs, CppType rhs) noexcept {
132 return shz_vec_equal(lhs, rhs);
133 }
134
135 //! Overloaded unary negation operator, returns the negated vector.
136 friend CppType operator-(CppType vec) noexcept {
137 return vec.neg();
138 }
139
140 //! Overloaded operator for assigning to volatile reference to base C type.
141 volatile CppType& operator=(volatile CType other) volatile noexcept {
142 *static_cast<CppType*>(const_cast<vecN*>(this)) = CppType(const_cast<CType&>(other));
143 return *static_cast<volatile CppType*>(this);
144 }
145
146 //! Overloaded operator for adding and accumulating a vector onto another.
147 SHZ_FORCE_INLINE CppType& operator+=(CppType other) noexcept {
148 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) + other;
149 return *static_cast<CppType*>(this);
150 }
151
152 //! Overloaded subtraction assignment operator, subtracts a vector from the left-hand vector.
153 SHZ_FORCE_INLINE CppType& operator-=(CppType other) noexcept {
154 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) - other;
155 return *static_cast<CppType*>(this);
156 }
157
158 //! Overloaded multiplication assignment operator, multiplies and accumulates a vector onto the left-hand vector.
159 SHZ_FORCE_INLINE CppType& operator*=(CppType other) noexcept {
160 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) * other;
161 return *static_cast<CppType*>(this);
162 }
163
164 //! Overloaded division assignment operator, divides the left vector by the right, assigning the left to the result.
165 SHZ_FORCE_INLINE CppType& operator/=(CppType other) noexcept {
166 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) / other;
167 return *static_cast<CppType*>(this);
168 }
169
170 //! Overloaded multiplication assignment operator, multiplies and accumulates each vector component by the given scalar.
171 SHZ_FORCE_INLINE CppType& operator*=(float other) noexcept {
172 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) * other;
173 return *static_cast<CppType*>(this);
174 }
175
176 //! Overloaded division assignment operator, dividing and assigning each vector component by the given scalar value.
177 SHZ_FORCE_INLINE CppType& operator/=(float other) noexcept {
178 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) / other;
179 return *static_cast<CppType*>(this);
180 }
181
182 //! Swizzle oeprator which takes a compile-time list of indices as non-type template arguments for the index each element should use as its new value.
183 template<unsigned... Indices>
184 SHZ_FORCE_INLINE CppType swizzle() const noexcept {
185 return shz_vec_swizzle(*static_cast<const CppType*>(this), Indices...);
186 }
187
188 //! Returns a new vector whose components are the absolute value of the given vector.
189 SHZ_FORCE_INLINE CppType abs() const noexcept {
190 return shz_vec_abs(*static_cast<const CppType*>(this));
191 }
192
193 //! Returns a new vector whose components are the negative values of the given vector.
194 SHZ_FORCE_INLINE CppType neg() const noexcept {
195 return shz_vec_neg(*static_cast<const CppType*>(this));
196 }
197
198 //! Returns a new vector whose components are the reciprocal values of the given vector.
199 SHZ_FORCE_INLINE CppType inv() const noexcept {
200 return shz_vec_inv(*static_cast<const CppType*>(this));
201 }
202
203 //! Returns the maximum value of every element within the vector.
204 SHZ_FORCE_INLINE float max() const noexcept {
205 return shz_vec_max(*static_cast<const CppType*>(this));
206 }
207
208 //! Returns the minimum value of every element within the vector.
209 SHZ_FORCE_INLINE float min() const noexcept {
210 return shz_vec_min(*static_cast<const CppType*>(this));
211 }
212
213 //! Returns a new vector whose values are the clamped components of the given vector.
214 SHZ_FORCE_INLINE CppType clamp(float min, float max) const noexcept {
215 return shz_vec_clamp(*static_cast<const CppType*>(this), min, max);
216 }
217
218 //! Returns a new vector with the component-wise floor of the given vector.
219 SHZ_FORCE_INLINE CppType floor() const noexcept {
220 return shz_vec_floor(*static_cast<const CppType*>(this));
221 }
222
223 //! Returns a new vector with the component-wise ceil of the given vector.
224 SHZ_FORCE_INLINE CppType ceil() const noexcept {
225 return shz_vec_ceil(*static_cast<const CppType*>(this));
226 }
227
228 //! Returns a new vector with the component-wise rounding of the given vector.
229 SHZ_FORCE_INLINE CppType round() const noexcept {
230 return shz_vec_round(*static_cast<const CppType*>(this));
231 }
232
233 //! Returns a new vector with the fractional part of each component.
234 SHZ_FORCE_INLINE CppType fract() const noexcept {
235 return shz_vec_fract(*static_cast<const CppType*>(this));
236 }
237
238 //! Returns a new vector with the sign of each component (-1, 0, or 1).
239 SHZ_FORCE_INLINE CppType sign() const noexcept {
240 return shz_vec_sign(*static_cast<const CppType*>(this));
241 }
242
243 //! Returns a new vector with each component clamped to [0, 1].
244 SHZ_FORCE_INLINE CppType saturate() const noexcept {
245 return shz_vec_saturate(*static_cast<const CppType*>(this));
246 }
247
248 //! Returns a new vector with the component-wise minimum of two vectors.
249 SHZ_FORCE_INLINE CppType minv(CppType other) const noexcept {
250 return shz_vec_minv(*static_cast<const CppType*>(this), other);
251 }
252
253 //! Returns a new vector with the component-wise maximum of two vectors.
254 SHZ_FORCE_INLINE CppType maxv(CppType other) const noexcept {
255 return shz_vec_maxv(*static_cast<const CppType*>(this), other);
256 }
257
258 //! Returns the dot product of the given vector and another.
259 SHZ_FORCE_INLINE float dot(CppType other) const noexcept {
260 return shz_vec_dot(*static_cast<const CppType*>(this), other);
261 }
262
263 //! Returns the dot product of the given vector against two others.
264 SHZ_FORCE_INLINE vec2 dot(CppType v1, CppType v2) const noexcept;
265
266 //! Returns the dot product of the given vector against three others.
267 SHZ_FORCE_INLINE vec3 dot(CppType v1, CppType v2, CppType v3) const noexcept;
268
269 //! Returns the magnitude of the given vector.
270 SHZ_FORCE_INLINE float magnitude() const noexcept {
271 return shz_vec_magnitude(*static_cast<const CppType*>(this));
272 }
273
274 //! Returns the squared magnitude of the given vector.
275 SHZ_FORCE_INLINE float magnitude_sqr() const noexcept {
276 return shz_vec_magnitude_sqr(*static_cast<const CppType*>(this));
277 }
278
279 //! Returns the inverse magnitude of the given vector.
280 SHZ_FORCE_INLINE float magnitude_inv() const noexcept {
281 return shz_vec_magnitude_inv(*static_cast<const CppType*>(this));
282 }
283
284 //! Returns the direction vector resulting from normalizing the given vector.
285 SHZ_FORCE_INLINE CppType direction() const noexcept {
286 return shz_vec_normalize(*static_cast<const CppType*>(this));
287 }
288
289 //! Normalizes the given vector.
290 SHZ_FORCE_INLINE void normalize() noexcept {
291 *static_cast<CppType*>(this) = shz_vec_normalize(*static_cast<const CppType*>(this));
292 }
293
294 //! Returns the direction vector of a given vector, safely protecting against division-by-zero.
295 SHZ_FORCE_INLINE CppType direction_safe() const noexcept {
296 return shz_vec_normalize_safe(*static_cast<const CppType*>(this));
297 }
298
299 //! Normalizes the given vector, safely protecting against division-by-zero.
300 SHZ_FORCE_INLINE void normalize_safe() noexcept {
301 *static_cast<CppType*>(this) = shz_vec_normalize_safe(*static_cast<const CppType*>(this));
302 }
303
304 //! Returns the magnitude of the difference between two vectors as their distance.
305 SHZ_FORCE_INLINE float distance(const CppType& other) const noexcept {
306 return shz_vec_distance(*static_cast<const CppType*>(this), other);
307 }
308
309 //! Returns the value of the distance between two vectors squared (faster than actual distance)
310 SHZ_FORCE_INLINE float distance_sqr(const CppType& other) const noexcept {
311 return shz_vec_distance_sqr(*static_cast<const CppType*>(this), other);
312 }
313
314 //! Moves the given vector towards the target by the given \p maxdist.
315 SHZ_FORCE_INLINE CppType move(CppType target, float maxdist) const noexcept {
316 return shz_vec_move(*static_cast<const CppType*>(this), target, maxdist);
317 }
318
319 //! Returns the vector created from reflecting the given vector over the normal of a surface.
320 SHZ_FORCE_INLINE CppType reflect(CppType normal) const noexcept {
321 return shz_vec_reflect(*static_cast<const CppType*>(this), normal);
322 }
323
324 //! Returns the vector create from refracting the given incidence vector over the normal of a surface, using the given refraction ratio index.
325 SHZ_FORCE_INLINE CppType refract(CppType normal, float eta) const noexcept {
326 return shz_vec_refract(*static_cast<const CppType*>(this), normal, eta);
327 }
328
329 //! Returns the vector created from projecting the given vector onto another.
330 SHZ_FORCE_INLINE CppType project(CppType onto) const noexcept {
331 return shz_vec_project(*static_cast<const CppType*>(this), onto);
332 }
333
334 //! Returns the vector created from projecting the given vector onto another, safely protecting against division-by-zero.
335 SHZ_FORCE_INLINE CppType project_safe(CppType onto) const noexcept {
336 return shz_vec_project_safe(*static_cast<const CppType*>(this), onto);
337 }
338
339 //! Returns the angle between the given vector and another, in radians.
340 SHZ_FORCE_INLINE float angle_between(CppType other) const noexcept {
341 return shz_vec_angle_between(*static_cast<const CppType*>(this), other);
342 }
343
344 //! Returns the angle(s) created between the given vector axis and the +X axis, in radians.
345 SHZ_FORCE_INLINE auto angles() const noexcept {
346 return shz_vec_angles(*static_cast<const CppType*>(this));
347 }
348};
349
350//! Overloaded addition operator, adding two vectors together and returning the result.
351template<typename CRTP, typename C, size_t R>
352SHZ_FORCE_INLINE CRTP operator+(vecN<CRTP, C, R> lhs, vecN<CRTP, C, R> rhs) noexcept {
353 return shz_vec_add(lhs, rhs);
354}
355
356//! Overloaded subtraction operator, subtracting one vector from another, returning the result.
357template<typename CRTP, typename C, size_t R>
358SHZ_FORCE_INLINE CRTP operator-(vecN<CRTP, C, R> lhs, vecN<CRTP, C, R> rhs) noexcept {
359 return shz_vec_sub(lhs, rhs);
360}
361
362//! Overloaded multiplication operator, performing element-wise multiplication between two vectors, returning the resultant vector.
363template<typename CRTP, typename C, size_t R>
364SHZ_FORCE_INLINE CRTP operator*(vecN<CRTP, C, R> lhs, vecN<CRTP, C, R> rhs) noexcept {
365 return shz_vec_mul(lhs, rhs);
366}
367
368//! Overloaded division operator, returning the resulting vector from component-wise dividing the elements of \p lhs by \p rhs.
369template<typename CRTP, typename C, size_t R>
370SHZ_FORCE_INLINE CRTP operator/(vecN<CRTP, C, R> lhs, vecN<CRTP, C, R> rhs) noexcept {
371 return shz_vec_div(lhs, rhs);
372}
373
374//! Overloaded multiplication operator for scaling a vector by a scalar and returning the resulting vector.
375template<typename CRTP, typename C, size_t R>
376SHZ_FORCE_INLINE CRTP operator*(vecN<CRTP, C, R> lhs, float rhs) noexcept {
377 return shz_vec_scale(lhs, rhs);
378}
379
380//! Reverse overloaded multiplication operator for scaling a vector by a scalar and returning the resulting vector.
381template<typename CRTP, typename C, size_t R>
382SHZ_FORCE_INLINE CRTP operator*(float lhs, vecN<CRTP, C, R> rhs) noexcept {
383 return shz_vec_scale(rhs, lhs);
384}
385
386//! Overloaded division operator for component-wise dividing each element of the given vector by the given scalar.
387template<typename CRTP, typename C, size_t R>
388SHZ_FORCE_INLINE CRTP operator/(vecN<CRTP, C, R> lhs, float rhs) noexcept {
389 return shz_vec_scale(lhs, shz::invf(rhs));
390}
391
392//! Reverse overloaded division operator for component-wise dividing a vector whose elements have all been initialized to the scalar by the given vector.
393template<typename CRTP, typename C, size_t R>
394SHZ_FORCE_INLINE CRTP operator/(float lhs, vecN<CRTP, C, R> rhs) noexcept {
395 return shz_vec_div(CRTP(lhs), rhs);
396}
397
398/*! 2D Vector type
399 *
400 * C++ structure for representing a 2-dimensional vector.
401 *
402 * \sa shz::vecN, shz_vec2_t, shz::vec3, shz::vec4
403 */
404struct vec2: vecN<vec2, shz_vec2_t, 2> {
405 // Inherit parent constructors and operators.
406 using vecN::vecN;
407
408 // Unhide inherited overloaded dot product methods.
409 using vecN::dot;
410
411 //! Default constructor: does nothing.
412 vec2() = default;
413
414 //! Single-value constructor: sets both components equal to \p v.
415 SHZ_FORCE_INLINE vec2(float v) noexcept:
416 vecN(shz_vec2_fill(v)) {}
417
418 //! Constructs a vec2 with the given values as components.
419 SHZ_FORCE_INLINE vec2(float x, float y) noexcept:
420 vecN(shz_vec2_init(x, y)) {}
421
422 //! Constructs a vec2 from the given angle of rotation from the +X axis.
423 SHZ_FORCE_INLINE vec2(sincos pair) noexcept:
425
426 //! Constructs a vec2 from the given angle of rotation from the +X axis, in radians.
427 SHZ_FORCE_INLINE static vec2 from_angle(float rads) noexcept {
428 return shz_vec2_from_angle(rads);
429 }
430
431 //! Constructs a vec2 from the given angle of rotation from the +X axis, in degrees.
432 SHZ_FORCE_INLINE static vec2 from_angle_deg(float deg) noexcept {
434 }
435
436 //! C++ wrapper for shz_vec2_cross().
437 SHZ_FORCE_INLINE float cross(vec2 other) const noexcept {
438 return shz_vec2_cross(*this, other);
439 }
440
441 //! C++ wrapper for shz_vec2_rotate().
442 SHZ_FORCE_INLINE vec2 rotate(float radians) const noexcept {
443 return shz_vec2_rotate(*this, radians);
444 }
445};
446
447//! C++ alias for vec2 for those who like POSIX-style.
448using vec2_t = vec2;
449
450/*! 3D Vector type
451 *
452 * C++ structure for representing a 3-dimensional vector.
453 *
454 * \sa shz::vecN, shz_vec2_t, shz::vec2, shz::vec4
455 */
456struct vec3: vecN<vec3, shz_vec3_t, 3> {
457 // Inherit parent constructors and operators.
458 using vecN::vecN;
459
460 // Unhide inherited overloaded dot product methods.
461 using vecN::dot;
462
463 // Unhide inherited overloaded assignment operators.
464 using vecN::operator=;
465
466 //! Default constructor: does nothing
467 vec3() = default;
468
469 //! C constructor: constructs a C++ vec3 from a C shz_vec3_t.
470 SHZ_FORCE_INLINE vec3(const shz_vec3_t& other) noexcept:
471 vecN(other) {}
472
473 //! Single-value constructor: initializes all components to \p v.
474 SHZ_FORCE_INLINE vec3(float v) noexcept:
475 vecN(shz_vec3_fill(v)) {}
476
477 //! Value constructor: initializes each component to its given value.
478 SHZ_FORCE_INLINE vec3(float x, float y, float z) noexcept:
479 vecN(shz_vec3_init(x, y, z)) {}
480
481 //! Constructs a vec3 from a shz::vec2 and a scalar value for its z component.
482 SHZ_FORCE_INLINE vec3(shz::vec2 xy, float z) noexcept:
483 vecN(shz_vec2_vec3(xy, z)) {}
484
485 //! Constructs a vec3 from a scalar as its x component and a shz::vec2 as its Y and Z components.
486 SHZ_FORCE_INLINE vec3(float x, shz::vec2 yz) noexcept:
487 vecN(shz_vec3_init(x, yz.x, yz.y)) {}
488
489 //! Returns a 3D vector which forms the given angles with the +X axis.
490 SHZ_FORCE_INLINE vec3(sincos azimuth, sincos elevation) noexcept:
492
493 //! Returns 2 3D vectors which are normalized and orthogonal to the two input vectors as a std::pair<>.
494 SHZ_FORCE_INLINE static auto orthonormalize(vec3 in1, vec3 in2) noexcept {
495 vec3 out1, out2;
496 shz_vec3_orthonormalize(in1, in2, &out1, &out2);
497 return std::make_pair(out1, out2);
498 }
499
500 //! Returns 2 3D vectors which are normalized and orthogonal to the two input vectors via output pointers.
501 SHZ_FORCE_INLINE static void orthonormalize(vec3 in1, vec3 in2, vec3* out1, vec3* out2) noexcept {
502 shz_vec3_orthonormalize(in1, in2, out1, out2);
503 }
504
505 //! Calculates the cubic hermite interpolation between two vectors and their tangents.
506 SHZ_FORCE_INLINE static vec3 cubic_hermite(vec3 v1, vec3 tangent1, vec3 v2, vec3 tangent2, float amount) noexcept {
507 return shz_vec3_cubic_hermite(v1, tangent1, v2, tangent2, amount);
508 }
509
510 // Returns the inner 2D vector, <X, Y>, as a C++ vector.
511 SHZ_FORCE_INLINE vec2 xy() const noexcept {
512 return shz_vec3_t::xy;
513 }
514
515 //! Returns a 3D vector which forms the given angles with the +X axis, in radians.
516 SHZ_FORCE_INLINE static vec3 from_angles(float azimuth_rads, float elevation_rads) noexcept {
517 return shz_vec3_from_angles(azimuth_rads, elevation_rads);
518 }
519
520 //! Returns a 3D vector which forms the given angles with the +X axis, in degrees.
521 SHZ_FORCE_INLINE static vec3 from_angles_deg(float azimuth_deg, float elevation_deg) noexcept {
522 return shz_vec3_from_angles_deg(azimuth_deg, elevation_deg);
523 }
524
525 //! Returns a 3D vector which forms the given angles with the +X axis.
526 SHZ_FORCE_INLINE vec3 cross(vec3 other) const noexcept {
527 return shz_vec3_cross(*this, other);
528 }
529
530 //! Returns the 3D vector "triple product" between the given vector and vectors \p a and \p b.
531 SHZ_FORCE_INLINE float triple(vec3 b, vec3 c) const noexcept {
532 return shz_vec3_triple(*this, b, c);
533 }
534
535 //! Returns a 3D vector which is perpendicular to this vector.
536 SHZ_FORCE_INLINE vec3 perp() const noexcept {
537 return shz_vec3_perp(*this);
538 }
539
540 //! Returns the 3D reject vector of the given vector and another.
541 SHZ_FORCE_INLINE vec3 reject(vec3 onto) const noexcept {
542 return shz_vec3_reject(*this, onto);
543 }
544
545 //! Computes the barycentric coordinates `<u, v, w>` for the given 3D vector, within the plane of the triangle formed by the given vertices, \p a, \p b, and \p c.
546 SHZ_FORCE_INLINE vec3 barycenter(vec3 a, vec3 b, vec3 c) const noexcept {
547 return shz_vec3_barycenter(*this, a, b, c);
548 }
549};
550
551//! C++ alias for vec3 for those who like POSIX-style.
552using vec3_t = vec3;
553
554/*! 4D Vector type
555 *
556 * C++ structure for representing a 4-dimensional vector.
557 *
558 * \sa shz::vecN, shz_vec4_t, shz::vec2, shz::vec3
559 */
560struct vec4: vecN<vec4, shz_vec4_t, 4> {
561 // Inherit parent constructors and operators.
562 using vecN::vecN;
563
564 // Unhide inherited overloaded dot product methods.
565 using vecN::dot;
566
567 //! Default constructor: does nothing.
568 vec4() = default;
569
570 //! C Constructor: initializes a C++ shz::vec4 from a C shz_vec4_t.
571 SHZ_FORCE_INLINE vec4(const shz_vec4_t& other) noexcept:
572 vecN(other) {}
573
574 //! Single-value constructor: initializes each element to the given value.
575 SHZ_FORCE_INLINE vec4(float v) noexcept:
576 vecN(shz_vec4_fill(v)) {}
577
578 //! Value constructor: initializes each element to its corresponding parameter value.
579 SHZ_FORCE_INLINE vec4(float x, float y, float z, float w) noexcept:
580 vecN(shz_vec4_init(x, y, z, w)) {}
581
582 //! Constructs a 4D vector with a 2D vector providing the X and Y coordinates and scalars providing Z and W.
583 SHZ_FORCE_INLINE vec4(shz::vec2 xy, float z, float w) noexcept:
584 vecN(shz_vec2_vec4(xy, z, w)) {}
585
586 //! Constructs a 4D vector with scalars providing X and W coordinates and a 2D vector providing Y and Z.
587 SHZ_FORCE_INLINE vec4(float x, shz::vec2 yz, float w) noexcept:
588 vecN(shz_vec4_init(x, yz.x, yz.y, w)) {}
589
590 //! Constructs a 4D vector with scalars providing X and Y coordinaets and a 2D vector providing Z and W.
591 SHZ_FORCE_INLINE vec4(float x, float y, shz::vec2 zw) noexcept:
592 vecN(shz_vec4_init(x, y, zw.x, zw.y )) {}
593
594 //! Constructs a 4D vector from the components provided by the given pair of 2D vectors.
595 SHZ_FORCE_INLINE vec4(shz::vec2 xy, shz::vec2 zw) noexcept:
596 vecN(shz_vec4_init(xy.x, xy.y, zw.x, zw.y)) {}
597
598 //! Constructs a 4D vector with the X, Y, and Z components given by a 3D vector and W given by a scalar.
599 SHZ_FORCE_INLINE vec4(shz::vec3 xyz, float w) noexcept:
600 vecN(shz_vec3_vec4(xyz, w)) {}
601
602 //! Constructs a 4D vector with the X component given by a scalar and the Y, Z, and W components given by a 3D vector.
603 SHZ_FORCE_INLINE vec4(float x, shz::vec3 yzw) noexcept:
604 vecN(shz_vec4_init(x, yzw.x, yzw.y, yzw.z)) {}
605
606 // Returns the inner 2D vector, <X, Y>, as a C++ vector.
607 SHZ_FORCE_INLINE vec2 xy() const noexcept {
608 return shz_vec4_t::xy;
609 }
610
611 // Returns the inner 2D vector, <Z, W>, as a C++ vector.
612 SHZ_FORCE_INLINE vec2 zw() const noexcept {
613 return shz_vec4_t::zw;
614 }
615
616 // Returns the inner 3D vector, <X, Y, Z>, as a C++ vector.
617 SHZ_FORCE_INLINE vec3 xyz() const noexcept {
618 return shz_vec4_t::xyz;
619 }
620};
621
622//! C++ alias for vec4 for those who like POSIX-style.s
623using vec4_t = vec4;
624
625template<typename CRTP, typename C, size_t R>
626SHZ_FORCE_INLINE vec2 vecN<CRTP, C, R>::dot(CppType v1, CppType v2) const noexcept {
627 return shz_vec_dot2(*static_cast<const CRTP*>(this), v1, v2);
628}
629
630template<typename CRTP, typename C, size_t R>
631SHZ_FORCE_INLINE vec3 vecN<CRTP, C, R>::dot(CppType v1, CppType v2, CppType v3) const noexcept {
632 return shz_vec_dot3(*static_cast<const CRTP*>(this), v1, v2, v3);
633}
634
635}
636
637#endif // SHZ_VECTOR_HPP
Namespace enclosing the SH4ZAM C++ API.
Definition shz_cdefs.hpp:21
CRTP operator*(vecN< CRTP, C, R > lhs, vecN< CRTP, C, R > rhs) noexcept
Overloaded multiplication operator, performing element-wise multiplication between two vectors,...
CRTP operator/(float lhs, vecN< CRTP, C, R > rhs) noexcept
Reverse overloaded division operator for component-wise dividing a vector whose elements have all bee...
CRTP operator-(vecN< CRTP, C, R > lhs, vecN< CRTP, C, R > rhs) noexcept
Overloaded subtraction operator, subtracting one vector from another, returning the result.
CRTP operator+(vecN< CRTP, C, R > lhs, vecN< CRTP, C, R > rhs) noexcept
Overloaded addition operator, adding two vectors together and returning the result.
CRTP operator/(vecN< CRTP, C, R > lhs, vecN< CRTP, C, R > rhs) noexcept
Overloaded division operator, returning the resulting vector from component-wise dividing the element...
CRTP operator/(vecN< CRTP, C, R > lhs, float rhs) noexcept
Overloaded division operator for component-wise dividing each element of the given vector by the give...
constexpr auto invf
C++ alias for shz_invf().
CRTP operator*(float lhs, vecN< CRTP, C, R > rhs) noexcept
Reverse overloaded multiplication operator for scaling a vector by a scalar and returning the resulti...
CRTP operator*(vecN< CRTP, C, R > lhs, float rhs) noexcept
Overloaded multiplication operator for scaling a vector by a scalar and returning the resulting vecto...
shz_vec2_t shz_vec2_from_angle(float radians) SHZ_NOEXCEPT
Returns the 2D unit vector representing a rotation from the positive X axis in radians.
shz_vec2_t shz_vec2_from_angle_deg(float degrees) SHZ_NOEXCEPT
Returns the 2D unit vector representing a rotation from the positive X axis in degrees.
shz_vec3_t shz_vec3_from_angles_deg(float azimuth, float elevation) SHZ_NOEXCEPT
Returns the 3D unit vector representing the given rotation angles relative to the positive X axis in ...
shz_vec3_t shz_vec3_from_angles(float azimuth, float elevation) SHZ_NOEXCEPT
Returns the 3D unit vector representing the given rotation angles relative to the positive X axis in ...
C++ sine/cosine approximation pairs.
Definition shz_trig.hpp:42
2D Vector type
vec2(float v) noexcept
Single-value constructor: sets both components equal to v.
vec2()=default
Default constructor: does nothing.
vec2(float x, float y) noexcept
Constructs a vec2 with the given values as components.
vec2(sincos pair) noexcept
Constructs a vec2 from the given angle of rotation from the +X axis.
float cross(vec2 other) const noexcept
C++ wrapper for shz_vec2_cross().
static vec2 from_angle_deg(float deg) noexcept
Constructs a vec2 from the given angle of rotation from the +X axis, in degrees.
vec2 rotate(float radians) const noexcept
C++ wrapper for shz_vec2_rotate().
static vec2 from_angle(float rads) noexcept
Constructs a vec2 from the given angle of rotation from the +X axis, in radians.
3D Vector type
vec3 reject(vec3 onto) const noexcept
Returns the 3D reject vector of the given vector and another.
static void orthonormalize(vec3 in1, vec3 in2, vec3 *out1, vec3 *out2) noexcept
Returns 2 3D vectors which are normalized and orthogonal to the two input vectors via output pointers...
vec3(float x, float y, float z) noexcept
Value constructor: initializes each component to its given value.
vec3 cross(vec3 other) const noexcept
Returns a 3D vector which forms the given angles with the +X axis.
static vec3 from_angles_deg(float azimuth_deg, float elevation_deg) noexcept
Returns a 3D vector which forms the given angles with the +X axis, in degrees.
static auto orthonormalize(vec3 in1, vec3 in2) noexcept
Returns 2 3D vectors which are normalized and orthogonal to the two input vectors as a std::pair<>.
float triple(vec3 b, vec3 c) const noexcept
Returns the 3D vector "triple product" between the given vector and vectors a and b.
vec3 barycenter(vec3 a, vec3 b, vec3 c) const noexcept
Computes the barycentric coordinates <u, v, w> for the given 3D vector, within the plane of the trian...
vec3(float v) noexcept
Single-value constructor: initializes all components to v.
static vec3 cubic_hermite(vec3 v1, vec3 tangent1, vec3 v2, vec3 tangent2, float amount) noexcept
Calculates the cubic hermite interpolation between two vectors and their tangents.
vec3(const shz_vec3_t &other) noexcept
C constructor: constructs a C++ vec3 from a C shz_vec3_t.
vec3(shz::vec2 xy, float z) noexcept
Constructs a vec3 from a shz::vec2 and a scalar value for its z component.
vec3(sincos azimuth, sincos elevation) noexcept
Returns a 3D vector which forms the given angles with the +X axis.
vec3 perp() const noexcept
Returns a 3D vector which is perpendicular to this vector.
vec3(float x, shz::vec2 yz) noexcept
Constructs a vec3 from a scalar as its x component and a shz::vec2 as its Y and Z components.
vec3()=default
Default constructor: does nothing.
static vec3 from_angles(float azimuth_rads, float elevation_rads) noexcept
Returns a 3D vector which forms the given angles with the +X axis, in radians.
4D Vector type
vec4(shz::vec2 xy, float z, float w) noexcept
Constructs a 4D vector with a 2D vector providing the X and Y coordinates and scalars providing Z and...
vec4(float x, shz::vec3 yzw) noexcept
Constructs a 4D vector with the X component given by a scalar and the Y, Z, and W components given by...
vec4(float v) noexcept
Single-value constructor: initializes each element to the given value.
vec4(shz::vec3 xyz, float w) noexcept
Constructs a 4D vector with the X, Y, and Z components given by a 3D vector and W given by a scalar.
vec4(const shz_vec4_t &other) noexcept
C Constructor: initializes a C++ shz::vec4 from a C shz_vec4_t.
vec4(float x, shz::vec2 yz, float w) noexcept
Constructs a 4D vector with scalars providing X and W coordinates and a 2D vector providing Y and Z.
vec4(shz::vec2 xy, shz::vec2 zw) noexcept
Constructs a 4D vector from the components provided by the given pair of 2D vectors.
vec4()=default
Default constructor: does nothing.
vec4(float x, float y, shz::vec2 zw) noexcept
Constructs a 4D vector with scalars providing X and Y coordinaets and a 2D vector providing Z and W.
vec4(float x, float y, float z, float w) noexcept
Value constructor: initializes each element to its corresponding parameter value.
Common C++ base structure inherited by all vector types.
float angle_between(CppType other) const noexcept
Returns the angle between the given vector and another, in radians.
float magnitude_inv() const noexcept
Returns the inverse magnitude of the given vector.
T to() const noexcept
Conversion operator for going from a SH4ZAM vector type to another layout-compatible type.
float max() const noexcept
Returns the maximum value of every element within the vector.
CppType & operator/=(CppType other) noexcept
Overloaded division assignment operator, divides the left vector by the right, assigning the left to ...
vecN(const vecN &other) noexcept=default
Default copy constructor.
CppType clamp(float min, float max) const noexcept
Returns a new vector whose values are the clamped components of the given vector.
CppType & operator*=(float other) noexcept
Overloaded multiplication assignment operator, multiplies and accumulates each vector component by th...
CppType & operator-=(CppType other) noexcept
Overloaded subtraction assignment operator, subtracts a vector from the left-hand vector.
float min() const noexcept
Returns the minimum value of every element within the vector.
CppType round() const noexcept
Returns a new vector with the component-wise rounding of the given vector.
static CppType from(const auto &raw) noexcept
Conversion operator for going from a layout-compatible vector type to a SH4ZAM vector type.
CppType maxv(CppType other) const noexcept
Returns a new vector with the component-wise maximum of two vectors.
CppType ceil() const noexcept
Returns a new vector with the component-wise ceil of the given vector.
friend CppType operator-(CppType vec) noexcept
Overloaded unary negation operator, returns the negated vector.
static constexpr size_t Rows
Number of rows.
float distance(const CppType &other) const noexcept
Returns the magnitude of the difference between two vectors as their distance.
CppType refract(CppType normal, float eta) const noexcept
Returns the vector create from refracting the given incidence vector over the normal of a surface,...
static CppType lerp(CppType start, CppType end, float t) noexcept
Returns the vector that is linearly interpolated between the two given vectors by the 0....
CppType project(CppType onto) const noexcept
Returns the vector created from projecting the given vector onto another.
CppType fract() const noexcept
Returns a new vector with the fractional part of each component.
volatile CppType & operator=(volatile CType other) volatile noexcept
Overloaded operator for assigning to volatile reference to base C type.
vec2 dot(CppType v1, CppType v2) const noexcept
Returns the dot product of the given vector against two others.
static CppType step(CppType vec, T edge) noexcept
Compares each component of the vector to the edge. 0 returned in that component if x[i] < edge....
vecN(const CType &other) noexcept
Converting constructor from existing C instance.
CppType reflect(CppType normal) const noexcept
Returns the vector created from reflecting the given vector over the normal of a surface.
CppType move(CppType target, float maxdist) const noexcept
Moves the given vector towards the target by the given maxdist.
CppType & operator+=(CppType other) noexcept
Overloaded operator for adding and accumulating a vector onto another.
static CppType smoothstep_safe(CppType vec, T edge0, T edge1) noexcept
Returns a vector where each component is smoothly interpolated from 0 to 1 between edge0 and edge1.
void normalize() noexcept
Normalizes the given vector.
CppType & deref(const auto *raw) noexcept
Conversion operator for accessing an existing pointer type as though it were a refrence to a SH4ZAM t...
static constexpr size_t Cols
Number of columns.
friend bool operator==(CppType lhs, CppType rhs) noexcept
Overloaded equality operator, for comparing vectors.
float distance_sqr(const CppType &other) const noexcept
Returns the value of the distance between two vectors squared (faster than actual distance)
CppType minv(CppType other) const noexcept
Returns a new vector with the component-wise minimum of two vectors.
static CppType smoothstep(CppType vec, T edge0, T edge1) noexcept
Returns a vector where each component is smoothly interpolated from 0 to 1 between edge0 and edge1.
CppType & operator/=(float other) noexcept
Overloaded division assignment operator, dividing and assigning each vector component by the given sc...
void normalize_safe() noexcept
Normalizes the given vector, safely protecting against division-by-zero.
CppType swizzle() const noexcept
Swizzle oeprator which takes a compile-time list of indices as non-type template arguments for the in...
CppType direction_safe() const noexcept
Returns the direction vector of a given vector, safely protecting against division-by-zero.
CppType saturate() const noexcept
Returns a new vector with each component clamped to [0, 1].
CppType floor() const noexcept
Returns a new vector with the component-wise floor of the given vector.
CppType & operator*=(CppType other) noexcept
Overloaded multiplication assignment operator, multiplies and accumulates a vector onto the left-hand...
vec3 dot(CppType v1, CppType v2, CppType v3) const noexcept
Returns the dot product of the given vector against three others.
float dot(CppType other) const noexcept
Returns the dot product of the given vector and another.
auto angles() const noexcept
Returns the angle(s) created between the given vector axis and the +X axis, in radians.
vecN(const volatile CType &other) noexcept
Converting constructor from existing volatile C instance.
CppType abs() const noexcept
Returns a new vector whose components are the absolute value of the given vector.
CppType direction() const noexcept
Returns the direction vector resulting from normalizing the given vector.
float magnitude_sqr() const noexcept
Returns the squared magnitude of the given vector.
CppType project_safe(CppType onto) const noexcept
Returns the vector created from projecting the given vector onto another, safely protecting against d...
CppType neg() const noexcept
Returns a new vector whose components are the negative values of the given vector.
vecN() noexcept=default
Default constructor, does nothing.
float magnitude() const noexcept
Returns the magnitude of the given vector.
CppType sign() const noexcept
Returns a new vector with the sign of each component (-1, 0, or 1).
CppType inv() const noexcept
Returns a new vector whose components are the reciprocal values of the given vector.