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