SH4ZAM! 0.7.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(const CppType& start, const 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(const 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(const 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(const 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_like<decltype(self)>(self.e[index]);
107 }
108
109 //! Returns an iterator to the beginning of the vector -- For STL support.
110 SHZ_FORCE_INLINE auto begin(this auto&& self) noexcept {
111 return std::forward_like<decltype(self)>(&self[0]);
112 }
113
114 //! Returns an iterator to the end of the vector -- For STL support.
115 SHZ_FORCE_INLINE auto end(this auto&& self) noexcept {
116 return std::forward_like<decltype(self)>(&self[Rows]);
117 }
118
119 //! Overloaded space-ship operator, for generic lexicographical comparison of vectors.
120 friend auto operator<=>(const CppType& lhs, const CppType& rhs) noexcept {
122 }
123
124 //! Generic overloaded operator for assigning a generic "this" type to volatile reference to base C type.
125 template<typename T>
126 SHZ_FORCE_INLINE auto&& operator=(this T&& self, volatile CType other) noexcept {
127 const_cast<std::remove_cvref_t<T>&>(self) = CppType(const_cast<CType&>(other));
128 return std::forward<T>(self);
129 }
130#endif
131
132 //! Overloaded equality operator, for comparing vectors.
133 friend bool operator==(const CppType& lhs, const CppType& rhs) noexcept {
134 return shz_vec_equal(lhs, rhs);
135 }
136
137 //! Overloaded unary negation operator, returns the negated vector.
138 friend CppType operator-(const CppType& vec) noexcept {
139 return vec.neg();
140 }
141
142 //! Overloaded operator for adding and accumulating a vector onto another.
143 SHZ_FORCE_INLINE CppType& operator+=(const CppType& other) noexcept {
144 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) + other;
145 return *static_cast<CppType*>(this);
146 }
147
148 //! Overloaded subtraction assignment operator, subtracts a vector from the left-hand vector.
149 SHZ_FORCE_INLINE CppType& operator-=(const CppType& other) noexcept {
150 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) - other;
151 return *static_cast<CppType*>(this);
152 }
153
154 //! Overloaded multiplication assignment operator, multiplies and accumulates a vector onto the left-hand vector.
155 SHZ_FORCE_INLINE CppType& operator*=(const CppType& other) noexcept {
156 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) * other;
157 return *static_cast<CppType*>(this);
158 }
159
160 //! Overloaded division assignment operator, divides the left vector by the right, assigning the left to the result.
161 SHZ_FORCE_INLINE CppType& operator/=(const CppType& other) noexcept {
162 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) / other;
163 return *static_cast<CppType*>(this);
164 }
165
166 //! Overloaded multiplication assignment operator, multiplies and accumulates each vector component by the given scalar.
167 SHZ_FORCE_INLINE CppType& operator*=(float other) noexcept {
168 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) * other;
169 return *static_cast<CppType*>(this);
170 }
171
172 //! Overloaded division assignment operator, dividing and assigning each vector component by the given scalar value.
173 SHZ_FORCE_INLINE CppType& operator/=(float other) noexcept {
174 *static_cast<CppType*>(this) = *static_cast<CppType*>(this) / other;
175 return *static_cast<CppType*>(this);
176 }
177
178 //! 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.
179 template<unsigned... Indices>
180 SHZ_FORCE_INLINE CppType swizzle() const noexcept {
181 return shz_vec_swizzle(*static_cast<const CppType*>(this), Indices...);
182 }
183
184 //! Returns a new vector whose components are the absolute value of the given vector.
185 SHZ_FORCE_INLINE CppType abs() const noexcept {
186 return shz_vec_abs(*static_cast<const CppType*>(this));
187 }
188
189 //! Returns a new vector whose components are the negative values of the given vector.
190 SHZ_FORCE_INLINE CppType neg() const noexcept {
191 return shz_vec_neg(*static_cast<const CppType*>(this));
192 }
193
194 //! Returns a new vector whose components are the reciprocal values of the given vector.
195 SHZ_FORCE_INLINE CppType inv() const noexcept {
196 return shz_vec_inv(*static_cast<const CppType*>(this));
197 }
198
199 //! Returns the maximum value of every element within the vector.
200 SHZ_FORCE_INLINE float max() const noexcept {
201 return shz_vec_max(*static_cast<const CppType*>(this));
202 }
203
204 //! Returns the minimum value of every element within the vector.
205 SHZ_FORCE_INLINE float min() const noexcept {
206 return shz_vec_min(*static_cast<const CppType*>(this));
207 }
208
209 //! Returns a new vector whose values are the clamped components of the given vector.
210 SHZ_FORCE_INLINE CppType clamp(float min, float max) const noexcept {
211 return shz_vec_clamp(*static_cast<const CppType*>(this), min, max);
212 }
213
214 //! Returns a new vector with the component-wise floor of the given vector.
215 SHZ_FORCE_INLINE CppType floor() const noexcept {
216 return shz_vec_floor(*static_cast<const CppType*>(this));
217 }
218
219 //! Returns a new vector with the component-wise ceil of the given vector.
220 SHZ_FORCE_INLINE CppType ceil() const noexcept {
221 return shz_vec_ceil(*static_cast<const CppType*>(this));
222 }
223
224 //! Returns a new vector with the component-wise rounding of the given vector.
225 SHZ_FORCE_INLINE CppType round() const noexcept {
226 return shz_vec_round(*static_cast<const CppType*>(this));
227 }
228
229 //! Returns a new vector with the fractional part of each component.
230 SHZ_FORCE_INLINE CppType fract() const noexcept {
231 return shz_vec_fract(*static_cast<const CppType*>(this));
232 }
233
234 //! Returns a new vector with the sign of each component (-1, 0, or 1).
235 SHZ_FORCE_INLINE CppType sign() const noexcept {
236 return shz_vec_sign(*static_cast<const CppType*>(this));
237 }
238
239 //! Returns a new vector with each component clamped to [0, 1].
240 SHZ_FORCE_INLINE CppType saturate() const noexcept {
241 return shz_vec_saturate(*static_cast<const CppType*>(this));
242 }
243
244 //! Returns a new vector with the component-wise minimum of two vectors.
245 SHZ_FORCE_INLINE CppType minv(const CppType& other) const noexcept {
246 return shz_vec_minv(*static_cast<const CppType*>(this), other);
247 }
248
249 //! Returns a new vector with the component-wise maximum of two vectors.
250 SHZ_FORCE_INLINE CppType maxv(const CppType& other) const noexcept {
251 return shz_vec_maxv(*static_cast<const CppType*>(this), other);
252 }
253
254 //! Returns the dot product of the given vector and another.
255 SHZ_FORCE_INLINE float dot(const CppType& other) const noexcept {
256 return shz_vec_dot(*static_cast<const CppType*>(this), other);
257 }
258
259 //! Returns the dot product of the given vector against two others.
260 SHZ_FORCE_INLINE vec2 dot(const CppType& v1, const CppType& v2) const noexcept;
261
262 //! Returns the dot product of the given vector against three others.
263 SHZ_FORCE_INLINE vec3 dot(const CppType& v1, const CppType& v2, const CppType& v3) const noexcept;
264
265 //! Returns the magnitude of the given vector.
266 SHZ_FORCE_INLINE float magnitude() const noexcept {
267 return shz_vec_magnitude(*static_cast<const CppType*>(this));
268 }
269
270 //! Returns the squared magnitude of the given vector.
271 SHZ_FORCE_INLINE float magnitude_sqr() const noexcept {
272 return shz_vec_magnitude_sqr(*static_cast<const CppType*>(this));
273 }
274
275 //! Returns the inverse magnitude of the given vector.
276 SHZ_FORCE_INLINE float magnitude_inv() const noexcept {
277 return shz_vec_magnitude_inv(*static_cast<const CppType*>(this));
278 }
279
280 //! Returns the direction vector resulting from normalizing the given vector.
281 SHZ_FORCE_INLINE CppType direction() const noexcept {
282 return shz_vec_normalize(*static_cast<const CppType*>(this));
283 }
284
285 //! Returns the direction vector of a given vector, safely protecting against division-by-zero.
286 SHZ_FORCE_INLINE CppType direction_safe() const noexcept {
287 return shz_vec_normalize_safe(*static_cast<const CppType*>(this));
288 }
289
290 //! Normalizes the given vector.
291 SHZ_FORCE_INLINE void normalize() noexcept {
292 *static_cast<CppType*>(this) = shz_vec_normalize(*static_cast<const CppType*>(this));
293 }
294
295 //! Normalizes the given vector, safely protecting against division-by-zero.
296 SHZ_FORCE_INLINE void normalize_safe() noexcept {
297 *static_cast<CppType*>(this) = shz_vec_normalize_safe(*static_cast<const CppType*>(this));
298 }
299
300 //! Return the normalized vector.
301 SHZ_FORCE_INLINE CppType normalized() const noexcept {
302 return shz_vec_normalize(*static_cast<const CppType*>(this));
303 }
304
305 //! Return the normalized vector, safely protecting against division-by-zero.
306 SHZ_FORCE_INLINE CppType normalized_safe() const noexcept {
307 return shz_vec_normalize_safe(*static_cast<const CppType*>(this));
308 }
309
310 //! Returns the magnitude of the difference between two vectors as their distance.
311 SHZ_FORCE_INLINE float distance(const CppType& other) const noexcept {
312 return shz_vec_distance(*static_cast<const CppType*>(this), other);
313 }
314
315 //! Returns the value of the distance between two vectors squared (faster than actual distance)
316 SHZ_FORCE_INLINE float distance_sqr(const CppType& other) const noexcept {
317 return shz_vec_distance_sqr(*static_cast<const CppType*>(this), other);
318 }
319
320 //! Moves the given vector towards the target by the given \p maxdist.
321 SHZ_FORCE_INLINE CppType move(const CppType& target, float maxdist) const noexcept {
322 return shz_vec_move(*static_cast<const CppType*>(this), target, maxdist);
323 }
324
325 //! Returns the vector created from reflecting the given vector over the normal of a surface.
326 SHZ_FORCE_INLINE CppType reflect(const CppType& normal) const noexcept {
327 return shz_vec_reflect(*static_cast<const CppType*>(this), normal);
328 }
329
330 //! Returns the vector create from refracting the given incidence vector over the normal of a surface, using the given refraction ratio index.
331 SHZ_FORCE_INLINE CppType refract(const CppType& normal, float eta) const noexcept {
332 return shz_vec_refract(*static_cast<const CppType*>(this), normal, eta);
333 }
334
335 //! Returns the vector created from projecting the given vector onto another.
336 SHZ_FORCE_INLINE CppType project(const CppType& onto) const noexcept {
337 return shz_vec_project(*static_cast<const CppType*>(this), onto);
338 }
339
340 //! Returns the vector created from projecting the given vector onto another, safely protecting against division-by-zero.
341 SHZ_FORCE_INLINE CppType project_safe(const CppType& onto) const noexcept {
342 return shz_vec_project_safe(*static_cast<const CppType*>(this), onto);
343 }
344
345 //! Returns the angle between the given vector and another, in radians.
346 SHZ_FORCE_INLINE float angle_between(const CppType& other) const noexcept {
347 return shz_vec_angle_between(*static_cast<const CppType*>(this), other);
348 }
349
350 //! Returns the angle(s) created between the given vector axis and the +X axis, in radians.
351 SHZ_FORCE_INLINE auto angles() const noexcept {
352 return shz_vec_angles(*static_cast<const CppType*>(this));
353 }
354};
355
356//! Overloaded addition operator, adding two vectors together and returning the result.
357template<typename CRTP, typename C, size_t R>
358SHZ_FORCE_INLINE CRTP operator+(const vecN<CRTP, C, R>& lhs, const vecN<CRTP, C, R>& rhs) noexcept {
359 return shz_vec_add(lhs, rhs);
360}
361
362//! Overloaded subtraction operator, subtracting one vector from another, returning the result.
363template<typename CRTP, typename C, size_t R>
364SHZ_FORCE_INLINE CRTP operator-(const vecN<CRTP, C, R>& lhs, const vecN<CRTP, C, R>& rhs) noexcept {
365 return shz_vec_sub(lhs, rhs);
366}
367
368//! Overloaded multiplication operator, performing element-wise multiplication between two vectors, returning the resultant vector.
369template<typename CRTP, typename C, size_t R>
370SHZ_FORCE_INLINE CRTP operator*(const vecN<CRTP, C, R>& lhs, const vecN<CRTP, C, R>& rhs) noexcept {
371 return shz_vec_mul(lhs, rhs);
372}
373
374//! Overloaded division operator, returning the resulting vector from component-wise dividing the elements of \p lhs by \p rhs.
375template<typename CRTP, typename C, size_t R>
376SHZ_FORCE_INLINE CRTP operator/(const vecN<CRTP, C, R>& lhs, const vecN<CRTP, C, R>& rhs) noexcept {
377 return shz_vec_div(lhs, rhs);
378}
379
380//! 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*(const vecN<CRTP, C, R>& lhs, float rhs) noexcept {
383 return shz_vec_scale(lhs, rhs);
384}
385
386//! Reverse overloaded multiplication operator for scaling a vector by a scalar and returning the resulting vector.
387template<typename CRTP, typename C, size_t R>
388SHZ_FORCE_INLINE CRTP operator*(float lhs, const vecN<CRTP, C, R>& rhs) noexcept {
389 return shz_vec_scale(rhs, lhs);
390}
391
392//! Overloaded division operator for component-wise dividing each element of the given vector by the given scalar.
393template<typename CRTP, typename C, size_t R>
394SHZ_FORCE_INLINE CRTP operator/(const vecN<CRTP, C, R>& lhs, float rhs) noexcept {
395 return shz_vec_scale(lhs, shz::invf(rhs));
396}
397
398//! Reverse overloaded division operator for component-wise dividing a vector whose elements have all been initialized to the scalar by the given vector.
399template<typename CRTP, typename C, size_t R>
400SHZ_FORCE_INLINE CRTP operator/(float lhs, const vecN<CRTP, C, R>& rhs) noexcept {
401 return shz_vec_div(CRTP(lhs), rhs);
402}
403
404/*! 2D Vector type
405 *
406 * C++ structure for representing a 2-dimensional vector.
407 *
408 * \sa shz::vecN, shz_vec2_t, shz::vec3, shz::vec4
409 */
410struct vec2: vecN<vec2, shz_vec2_t, 2> {
411 // Inherit parent constructors and operators.
412 using vecN::vecN;
413
414 // Unhide inherited overload assignment operators.
415 using vecN::operator=;
416
417 // Unhide inherited overloaded dot product methods.
418 using vecN::dot;
419
420 //! Default constructor: does nothing.
421 vec2() = default;
422
423 //! Single-value constructor: sets both components equal to \p v.
424 SHZ_FORCE_INLINE vec2(float v) noexcept:
425 vecN(shz_vec2_fill(v)) {}
426
427 //! Constructs a vec2 with the given values as components.
428 SHZ_FORCE_INLINE vec2(float x, float y) noexcept:
429 vecN(shz_vec2_init(x, y)) {}
430
431 //! Constructs a vec2 from the given angle of rotation from the +X axis.
432 SHZ_FORCE_INLINE vec2(const sincos& pair) noexcept:
434
435 //! Constructs a vec2 from the given angle of rotation from the +X axis, in radians.
436 SHZ_FORCE_INLINE static vec2 from_angle(float rads) noexcept {
437 return shz_vec2_from_angle(rads);
438 }
439
440 //! Constructs a vec2 from the given angle of rotation from the +X axis, in degrees.
441 SHZ_FORCE_INLINE static vec2 from_angle_deg(float deg) noexcept {
443 }
444
445 //! C++ wrapper for shz_vec2_cross().
446 SHZ_FORCE_INLINE float cross(const vec2& other) const noexcept {
447 return shz_vec2_cross(*this, other);
448 }
449
450 //! C++ wrapper for shz_vec2_rotate().
451 SHZ_FORCE_INLINE vec2 rotate(float radians) const noexcept {
452 return shz_vec2_rotate(*this, radians);
453 }
454};
455
456//! C++ alias for vec2 for those who like POSIX-style.
457using vec2_t = vec2;
458
459/*! 3D Vector type
460 *
461 * C++ structure for representing a 3-dimensional vector.
462 *
463 * \sa shz::vecN, shz_vec2_t, shz::vec2, shz::vec4
464 */
465struct vec3: vecN<vec3, shz_vec3_t, 3> {
466 // Inherit parent constructors and operators.
467 using vecN::vecN;
468
469 // Unhide inherited overloaded dot product methods.
470 using vecN::dot;
471
472 // Unhide inherited overloaded assignment operators.
473 using vecN::operator=;
474
475 //! Default constructor: does nothing
476 vec3() = default;
477
478 //! C constructor: constructs a C++ vec3 from a C shz_vec3_t.
479 SHZ_FORCE_INLINE vec3(const shz_vec3_t& other) noexcept:
480 vecN(other) {}
481
482 //! Single-value constructor: initializes all components to \p v.
483 SHZ_FORCE_INLINE vec3(float v) noexcept:
484 vecN(shz_vec3_fill(v)) {}
485
486 //! Value constructor: initializes each component to its given value.
487 SHZ_FORCE_INLINE vec3(float x, float y, float z) noexcept:
488 vecN(shz_vec3_init(x, y, z)) {}
489
490 //! Constructs a vec3 from a shz::vec2 and a scalar value for its z component.
491 SHZ_FORCE_INLINE vec3(const shz::vec2& xy, float z) noexcept:
492 vecN(shz_vec2_vec3(xy, z)) {}
493
494 //! Constructs a vec3 from a scalar as its x component and a shz::vec2 as its Y and Z components.
495 SHZ_FORCE_INLINE vec3(float x, const shz::vec2& yz) noexcept:
496 vecN(shz_vec3_init(x, yz.x, yz.y)) {}
497
498 //! Returns a 3D vector which forms the given angles with the +X axis.
499 SHZ_FORCE_INLINE vec3(const sincos& azimuth, const sincos& elevation) noexcept:
501
502 //! Returns 2 3D vectors which are normalized and orthogonal to the two input vectors as a std::pair<>.
503 SHZ_FORCE_INLINE static auto orthonormalize(const vec3& in1, const vec3& in2) noexcept {
504 vec3 out1, out2;
505 shz_vec3_orthonormalize(in1, in2, &out1, &out2);
506 return std::make_pair(out1, out2);
507 }
508
509 //! Returns 2 3D vectors which are normalized and orthogonal to the two input vectors via output pointers.
510 SHZ_FORCE_INLINE static void orthonormalize(const vec3& in1, const vec3& in2, vec3* out1, vec3* out2) noexcept {
511 shz_vec3_orthonormalize(in1, in2, out1, out2);
512 }
513
514 //! Calculates the cubic hermite interpolation between two vectors and their tangents.
515 SHZ_FORCE_INLINE static vec3 cubic_hermite(const vec3& v1, const vec3& tangent1, const vec3& v2, const vec3& tangent2, float amount) noexcept {
516 return shz_vec3_cubic_hermite(v1, tangent1, v2, tangent2, amount);
517 }
518
519 // Returns the inner 2D vector, <X, Y>, as a C++ vector.
520 SHZ_FORCE_INLINE vec2 xy() const noexcept {
521 return shz_vec3_t::xy;
522 }
523
524 //! Returns a 3D vector which forms the given angles with the +X axis, in radians.
525 SHZ_FORCE_INLINE static vec3 from_angles(float azimuth_rads, float elevation_rads) noexcept {
526 return shz_vec3_from_angles(azimuth_rads, elevation_rads);
527 }
528
529 //! Returns a 3D vector which forms the given angles with the +X axis, in degrees.
530 SHZ_FORCE_INLINE static vec3 from_angles_deg(float azimuth_deg, float elevation_deg) noexcept {
531 return shz_vec3_from_angles_deg(azimuth_deg, elevation_deg);
532 }
533
534 //! Returns a 3D vector which forms the given angles with the +X axis.
535 SHZ_FORCE_INLINE vec3 cross(const vec3& other) const noexcept {
536 return shz_vec3_cross(*this, other);
537 }
538
539 //! Returns the 3D vector "triple product" between the given vector and vectors \p a and \p b.
540 SHZ_FORCE_INLINE float triple(const vec3& b, const vec3& c) const noexcept {
541 return shz_vec3_triple(*this, b, c);
542 }
543
544 //! Returns a 3D vector which is perpendicular to this vector.
545 SHZ_FORCE_INLINE vec3 perp() const noexcept {
546 return shz_vec3_perp(*this);
547 }
548
549 //! Returns the 3D reject vector of the given vector and another.
550 SHZ_FORCE_INLINE vec3 reject(const vec3& onto) const noexcept {
551 return shz_vec3_reject(*this, onto);
552 }
553
554 //! 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.
555 SHZ_FORCE_INLINE vec3 barycenter(const vec3& a, const vec3& b, const vec3& c) const noexcept {
556 return shz_vec3_barycenter(*this, a, b, c);
557 }
558};
559
560//! C++ alias for vec3 for those who like POSIX-style.
561using vec3_t = vec3;
562
563/*! 4D Vector type
564 *
565 * C++ structure for representing a 4-dimensional vector.
566 *
567 * \sa shz::vecN, shz_vec4_t, shz::vec2, shz::vec3
568 */
569struct vec4: vecN<vec4, shz_vec4_t, 4> {
570 // Inherit parent constructors and operators.
571 using vecN::vecN;
572
573 // Unhide inherited overloaded dot product methods.
574 using vecN::dot;
575
576 // Unhide inherited overload assignment operators.
577 using vecN::operator=;
578
579 //! Default constructor: does nothing.
580 vec4() = default;
581
582 //! C Constructor: initializes a C++ shz::vec4 from a C shz_vec4_t.
583 SHZ_FORCE_INLINE vec4(const shz_vec4_t& other) noexcept:
584 vecN(other) {}
585
586 //! Single-value constructor: initializes each element to the given value.
587 SHZ_FORCE_INLINE vec4(float v) noexcept:
588 vecN(shz_vec4_fill(v)) {}
589
590 //! Value constructor: initializes each element to its corresponding parameter value.
591 SHZ_FORCE_INLINE vec4(float x, float y, float z, float w) noexcept:
592 vecN(shz_vec4_init(x, y, z, w)) {}
593
594 //! Constructs a 4D vector with a 2D vector providing the X and Y coordinates and scalars providing Z and W.
595 SHZ_FORCE_INLINE vec4(const shz::vec2& xy, float z, float w) noexcept:
596 vecN(shz_vec2_vec4(xy, z, w)) {}
597
598 //! Constructs a 4D vector with scalars providing X and W coordinates and a 2D vector providing Y and Z.
599 SHZ_FORCE_INLINE vec4(float x, const shz::vec2& yz, float w) noexcept:
600 vecN(shz_vec4_init(x, yz.x, yz.y, w)) {}
601
602 //! Constructs a 4D vector with scalars providing X and Y coordinaets and a 2D vector providing Z and W.
603 SHZ_FORCE_INLINE vec4(float x, float y, const shz::vec2& zw) noexcept:
604 vecN(shz_vec4_init(x, y, zw.x, zw.y )) {}
605
606 //! Constructs a 4D vector from the components provided by the given pair of 2D vectors.
607 SHZ_FORCE_INLINE vec4(const shz::vec2& xy, const shz::vec2& zw) noexcept:
608 vecN(shz_vec4_init(xy.x, xy.y, zw.x, zw.y)) {}
609
610 //! Constructs a 4D vector with the X, Y, and Z components given by a 3D vector and W given by a scalar.
611 SHZ_FORCE_INLINE vec4(const shz::vec3& xyz, float w) noexcept:
612 vecN(shz_vec3_vec4(xyz, w)) {}
613
614 //! Constructs a 4D vector with the X component given by a scalar and the Y, Z, and W components given by a 3D vector.
615 SHZ_FORCE_INLINE vec4(float x, const shz::vec3& yzw) noexcept:
616 vecN(shz_vec4_init(x, yzw.x, yzw.y, yzw.z)) {}
617
618 // Returns the inner 2D vector, <X, Y>, as a C++ vector.
619 SHZ_FORCE_INLINE vec2 xy() const noexcept {
620 return shz_vec4_t::xy;
621 }
622
623 // Returns the inner 2D vector, <Z, W>, as a C++ vector.
624 SHZ_FORCE_INLINE vec2 zw() const noexcept {
625 return shz_vec4_t::zw;
626 }
627
628 // Returns the inner 3D vector, <X, Y, Z>, as a C++ vector.
629 SHZ_FORCE_INLINE vec3 xyz() const noexcept {
630 return shz_vec4_t::xyz;
631 }
632};
633
634//! C++ alias for vec4 for those who like POSIX-style.s
635using vec4_t = vec4;
636
637template<typename CRTP, typename C, size_t R>
638SHZ_FORCE_INLINE vec2 vecN<CRTP, C, R>::dot(const CppType& v1, const CppType& v2) const noexcept {
639 return shz_vec_dot2(*static_cast<const CRTP*>(this), v1, v2);
640}
641
642template<typename CRTP, typename C, size_t R>
643SHZ_FORCE_INLINE vec3 vecN<CRTP, C, R>::dot(const CppType& v1, const CppType& v2, const CppType& v3) const noexcept {
644 return shz_vec_dot3(*static_cast<const CRTP*>(this), v1, v2, v3);
645}
646
647}
648
649#endif // SHZ_VECTOR_HPP
Namespace enclosing the SH4ZAM C++ API.
Definition shz_cdefs.hpp:21
CRTP operator+(const vecN< CRTP, C, R > &lhs, const vecN< CRTP, C, R > &rhs) noexcept
Overloaded addition operator, adding two vectors together and returning the result.
CRTP operator*(float lhs, const vecN< CRTP, C, R > &rhs) noexcept
Reverse overloaded multiplication operator for scaling a vector by a scalar and returning the resulti...
CRTP operator-(const vecN< CRTP, C, R > &lhs, const vecN< CRTP, C, R > &rhs) noexcept
Overloaded subtraction operator, subtracting one vector from another, returning the result.
CRTP operator*(const vecN< CRTP, C, R > &lhs, float rhs) noexcept
Overloaded multiplication operator for scaling a vector by a scalar and returning the resulting vecto...
CRTP operator/(const vecN< CRTP, C, R > &lhs, float rhs) noexcept
Overloaded division operator for component-wise dividing each element of the given vector by the give...
CRTP operator/(const vecN< CRTP, C, R > &lhs, const vecN< CRTP, C, R > &rhs) noexcept
Overloaded division operator, returning the resulting vector from component-wise dividing the element...
CRTP operator/(float lhs, const vecN< CRTP, C, R > &rhs) noexcept
Reverse overloaded division operator for component-wise dividing a vector whose elements have all bee...
constexpr auto invf
C++ alias for shz_invf().
CRTP operator*(const vecN< CRTP, C, R > &lhs, const vecN< CRTP, C, R > &rhs) noexcept
Overloaded multiplication operator, performing element-wise multiplication between two vectors,...
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(const sincos &pair) noexcept
Constructs a vec2 from the given angle of rotation from the +X axis.
float cross(const 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 barycenter(const vec3 &a, const vec3 &b, const vec3 &c) const noexcept
Computes the barycentric coordinates <u, v, w> for the given 3D vector, within the plane of the trian...
vec3 reject(const vec3 &onto) const noexcept
Returns the 3D reject vector of the given vector and another.
vec3(const sincos &azimuth, const sincos &elevation) noexcept
Returns a 3D vector which forms the given angles with the +X axis.
static void orthonormalize(const vec3 &in1, const 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.
static vec3 cubic_hermite(const vec3 &v1, const vec3 &tangent1, const vec3 &v2, const vec3 &tangent2, float amount) noexcept
Calculates the cubic hermite interpolation between two vectors and their tangents.
static auto orthonormalize(const vec3 &in1, const vec3 &in2) noexcept
Returns 2 3D vectors which are normalized and orthogonal to the two input vectors as a std::pair<>.
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.
vec3(const shz::vec2 &xy, float z) noexcept
Constructs a vec3 from a shz::vec2 and a scalar value for its z component.
vec3 cross(const vec3 &other) const noexcept
Returns a 3D vector which forms the given angles with the +X axis.
vec3(float v) noexcept
Single-value constructor: initializes all components to v.
vec3(const shz_vec3_t &other) noexcept
C constructor: constructs a C++ vec3 from a C shz_vec3_t.
vec3(float x, const 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 perp() const noexcept
Returns a 3D vector which is perpendicular to this vector.
float triple(const vec3 &b, const vec3 &c) const noexcept
Returns the 3D vector "triple product" between the given vector and vectors a and b.
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(float x, float y, const 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, const 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(float v) noexcept
Single-value constructor: initializes each element to the given value.
vec4(const shz::vec2 &xy, const shz::vec2 &zw) noexcept
Constructs a 4D vector from the components provided by the given pair of 2D vectors.
vec4(const shz_vec4_t &other) noexcept
C Constructor: initializes a C++ shz::vec4 from a C shz_vec4_t.
vec4(const 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, const 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(const 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()=default
Default constructor: does nothing.
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.
CppType project(const CppType &onto) const noexcept
Returns the vector created from projecting the given vector onto another.
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-=(const CppType &other) noexcept
Overloaded subtraction assignment operator, subtracts a vector from the left-hand vector.
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...
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.
CppType project_safe(const CppType &onto) const noexcept
Returns the vector created from projecting the given vector onto another, safely protecting against d...
CppType maxv(const CppType &other) const noexcept
Returns a new vector with the component-wise maximum of two vectors.
static CppType smoothstep(const CppType &vec, T &&edge0, T &&edge1) noexcept
Returns a vector where each component is smoothly interpolated from 0 to 1 between edge0 and edge1.
static CppType from(const auto &raw) noexcept
Conversion operator for going from a layout-compatible vector type to a SH4ZAM vector type.
CppType ceil() const noexcept
Returns a new vector with the component-wise ceil of the given 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 fract() const noexcept
Returns a new vector with the fractional part of each component.
CppType minv(const CppType &other) const noexcept
Returns a new vector with the component-wise minimum of two vectors.
CppType reflect(const CppType &normal) const noexcept
Returns the vector created from reflecting the given vector over the normal of a surface.
vecN(const CType &other) noexcept
Converting constructor from existing C instance.
CppType & operator+=(const CppType &other) noexcept
Overloaded operator for adding and accumulating a vector onto another.
friend CppType operator-(const CppType &vec) noexcept
Overloaded unary negation operator, returns the negated vector.
void normalize() noexcept
Normalizes the given vector.
CppType normalized_safe() const noexcept
Return the normalized vector, safely protecting against division-by-zero.
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.
float distance_sqr(const CppType &other) const noexcept
Returns the value of the distance between two vectors squared (faster than actual distance)
CppType & operator/=(float other) noexcept
Overloaded division assignment operator, dividing and assigning each vector component by the given sc...
vec2 dot(const CppType &v1, const CppType &v2) const noexcept
Returns the dot product of the given vector against two others.
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.
static CppType step(const CppType &vec, T &&edge) noexcept
Compares each component of the vector to the edge. 0 returned in that component if x[i] < edge....
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/=(const CppType &other) noexcept
Overloaded division assignment operator, divides the left vector by the right, assigning the left to ...
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 normalized() const noexcept
Return the normalized vector.
CppType abs() const noexcept
Returns a new vector whose components are the absolute value of the given vector.
static CppType smoothstep_safe(const 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 refract(const CppType &normal, float eta) const noexcept
Returns the vector create from refracting the given incidence vector over the normal of a surface,...
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.
vec3 dot(const CppType &v1, const CppType &v2, const CppType &v3) const noexcept
Returns the dot product of the given vector against three others.
float dot(const CppType &other) const noexcept
Returns the dot product of the given vector and another.
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.
friend bool operator==(const CppType &lhs, const CppType &rhs) noexcept
Overloaded equality operator, for comparing vectors.
static CppType lerp(const CppType &start, const CppType &end, float t) noexcept
Returns the vector that is linearly interpolated between the two given vectors by the 0....
CppType sign() const noexcept
Returns a new vector with the sign of each component (-1, 0, or 1).
float angle_between(const CppType &other) const noexcept
Returns the angle between the given vector and another, in radians.
CppType move(const CppType &target, float maxdist) const noexcept
Moves the given vector towards the target by the given maxdist.
CppType inv() const noexcept
Returns a new vector whose components are the reciprocal values of the given vector.
CppType & operator*=(const CppType &other) noexcept
Overloaded multiplication assignment operator, multiplies and accumulates a vector onto the left-hand...