SH4ZAM! 0.1.0
Fast math library for the Sega Dreamcast's SH4 CPU
Loading...
Searching...
No Matches
shz_vector.h
Go to the documentation of this file.
1/*! \file
2 * \brief Vector types and operations.
3 * \ingroup vector
4 *
5 * This file provides types and mathematical routines for representing and
6 * operating on vectors.
7 *
8 * \author 2025, 2026 Falco Girgis
9 * \author 2025 Paul Cercueil
10 *
11 * \copyright MIT License
12 */
13
14#ifndef SHZ_VECTOR_H
15#define SHZ_VECTOR_H
16
17#include <math.h>
18#include <float.h>
19
20#include "shz_scalar.h"
21#include "shz_trig.h"
22
23/** \defgroup vector Vector
24 * \brief API for vector math.
25 *
26 * The Vector API provides structures representing commonly-used vector types
27 * as well as routines implementing various mathematical operations on them.
28 */
29
30SHZ_DECLS_BEGIN
31
32/*! 2D Vector type
33 *
34 * Structure for holding coordinates of a 2-dimensional vector.
35 *
36 * \sa shz_vec3_t, shz_vec4_t
37 */
38typedef struct shz_vec2 {
39 union {
40 float e[2]; //!< <X, Y> coordinates as an array
41 struct {
42 float x; //!< X coordinate
43 float y; //!< Y coordinate
44 };
45 };
46} shz_vec2_t;
47
48//! Alternate typedef for the shz_vec2 struct for those who hate POSIX-style.
49typedef shz_vec2_t shz_vec2;
50
51/*! 3D Vector type
52 *
53 * Structure for holding coordinates of a 3-dimensional vector.
54 *
55 * \sa shz_vec2_t, shz_vec4_t
56 */
57typedef struct shz_vec3 {
58 union {
59 float e[3]; //!< <X, Y, Z> coordinates as an array
60 struct {
61 union {
62 struct {
63 float x; //!< X coordinate
64 float y; //!< Y coordinate
65 };
66 shz_vec2_t xy; //!< Inner 2D vector containing <X, Y> coords
67 };
68 float z; //!< Z coordinate
69 };
70 };
71} shz_vec3_t;
72
73//! Alternate typedef for the shz_vec3 struct for those who hate POSIX-style.
74typedef shz_vec3_t shz_vec3;
75
76/*! 4D Vector type
77 *
78 * Structure for holding coordinates of a 4-dimensional vector.
79 *
80 * \sa shz_vec2_t, shz_vec3_t
81 */
82typedef struct shz_vec4 {
83 union {
84 float e[4]; //!< <X, Y, Z, W> coordinates as an array.
85 struct {
86 union {
87 struct {
88 float x; //!< X coordinate
89 float y; //!< Y coordinate
90 float z; //!< Z coordinate
91 };
92 shz_vec3_t xyz; //!< <X, Y, Z> coordinates as a 3D vector
93 };
94 float w; //!< W coordinate
95 };
96 struct {
97 shz_vec2_t xy; //!< <X, Y> coordinates as a 2D vector
98 shz_vec2_t zw; //!< <Z, W> coordinates as a 2D vector
99 };
100 };
101} shz_vec4_t;
102
103
104//! Alternate typedef for the shz_vec4 struct for those who hate POSIX-style.
105typedef shz_vec4_t shz_vec4;
106
107/*! \name Initializers
108 \brief Component-based initialization routines.
109 @{
110*/
111
112//! Returns a 2D vector with the given \p x, and \p y coordinates.
113SHZ_FORCE_INLINE shz_vec2_t shz_vec2_init(float x, float y) SHZ_NOEXCEPT;
114
115//! Returns a 3D vector with the given \p x, \p y, and \p z coordinates.
116SHZ_FORCE_INLINE shz_vec3_t shz_vec3_init(float x, float y, float z) SHZ_NOEXCEPT;
117
118//! Returns a 4D vector with the given \p x, \p y, \p z, and \p w coordinates.
119SHZ_FORCE_INLINE shz_vec4_t shz_vec4_init(float x, float y, float z, float w) SHZ_NOEXCEPT;
120
121//! Returns a 2D vector with the value of each component equal to \p v.
122SHZ_FORCE_INLINE shz_vec2_t shz_vec2_fill(float v) SHZ_NOEXCEPT;
123
124//! Returns a 3D vector with the value of each compoonent equal to \p v.
125SHZ_FORCE_INLINE shz_vec3_t shz_vec3_fill(float v) SHZ_NOEXCEPT;
126
127//! Returns a 4D vector with the value of each component equal to \p v.
128SHZ_FORCE_INLINE shz_vec4_t shz_vec4_fill(float v) SHZ_NOEXCEPT;
129
130//! @}
131
132/*! \name Component-wise Operations
133 \brief Routines which apply to each vector component.
134 @{
135*/
136
137//! Returns a 2D vector whose components are the absolute values of the given vector's components.
138SHZ_FORCE_INLINE shz_vec2_t shz_vec2_abs(shz_vec2_t vec) SHZ_NOEXCEPT;
139
140//! Returns a 3D vector whose components are the absolute values of the given vector's components.
141SHZ_FORCE_INLINE shz_vec3_t shz_vec3_abs(shz_vec3_t vec) SHZ_NOEXCEPT;
142
143//! Returns a 4D vector whose components are the absolute values of the given vector's components.
144SHZ_FORCE_INLINE shz_vec4_t shz_vec4_abs(shz_vec4_t vec) SHZ_NOEXCEPT;
145
146//! Returns a 2D vector whose components are the negative values of the given vector's components.
147SHZ_FORCE_INLINE shz_vec2_t shz_vec2_neg(shz_vec2_t vec) SHZ_NOEXCEPT;
148
149//! Returns a 3D vector whose components are the negative values of the given vector's components.
150SHZ_FORCE_INLINE shz_vec3_t shz_vec3_neg(shz_vec3_t vec) SHZ_NOEXCEPT;
151
152//! Returns a 4D vector whose components are the negative values of the given vector's components.
153SHZ_FORCE_INLINE shz_vec4_t shz_vec4_neg(shz_vec4_t vec) SHZ_NOEXCEPT;
154
155//! Returns the 4D vector whose components have been inverted or reciprocated.
156SHZ_FORCE_INLINE shz_vec2_t shz_vec2_inv(shz_vec2_t vec) SHZ_NOEXCEPT;
157
158//! Returns the 4D vector whose components have been inverted or reciprocated.
159SHZ_FORCE_INLINE shz_vec3_t shz_vec3_inv(shz_vec3_t vec) SHZ_NOEXCEPT;
160
161//! Returns the 4D vector whose components have been inverted or reciprocated.
162SHZ_FORCE_INLINE shz_vec4_t shz_vec4_inv(shz_vec4_t vec) SHZ_NOEXCEPT;
163
164//! Returns the maximum value of both of the given vector's components.
165SHZ_FORCE_INLINE float shz_vec2_max(shz_vec2_t vec) SHZ_NOEXCEPT;
166
167//! Returns the maximum value of the given vector's 3 components.
168SHZ_FORCE_INLINE float shz_vec3_max(shz_vec3_t vec) SHZ_NOEXCEPT;
169
170//! Returns the maximum value of the given vector's 4 componetns.
171SHZ_FORCE_INLINE float shz_vec4_max(shz_vec4_t vec) SHZ_NOEXCEPT;
172
173//! Retuns the minimum value of both of the given vector's components.
174SHZ_FORCE_INLINE float shz_vec2_min(shz_vec2_t vec) SHZ_NOEXCEPT;
175
176//! Returns the minimum value of the given vector's 3 components.
177SHZ_FORCE_INLINE float shz_vec3_min(shz_vec3_t vec) SHZ_NOEXCEPT;
178
179//! Returns the minimum value of the given vector's 4 components.
180SHZ_FORCE_INLINE float shz_vec4_min(shz_vec4_t vec) SHZ_NOEXCEPT;
181
182//! Clamps the values of the given 2D \p vec between \p min and \p max, returning a new vector.
183SHZ_FORCE_INLINE shz_vec2_t shz_vec2_clamp(shz_vec2_t vec, float min, float max) SHZ_NOEXCEPT;
184
185//! Clamps the values of the given 3D \p vec between \p min and \p max, returning a new vector.
186SHZ_FORCE_INLINE shz_vec3_t shz_vec3_clamp(shz_vec3_t vec, float min, float max) SHZ_NOEXCEPT;
187
188//! Clamps the values of the given 4D \p vec between \p min and \p max, returning a new vector.
189SHZ_FORCE_INLINE shz_vec4_t shz_vec4_clamp(shz_vec4_t vec, float min, float max) SHZ_NOEXCEPT;
190
191//! Returns a 2D vector whose components are the floor of the given vector's components.
192SHZ_FORCE_INLINE shz_vec2_t shz_vec2_floor(shz_vec2_t vec) SHZ_NOEXCEPT;
193
194//! Returns a 3D vector whose components are the floor of the given vector's components.
195SHZ_FORCE_INLINE shz_vec3_t shz_vec3_floor(shz_vec3_t vec) SHZ_NOEXCEPT;
196
197//! Returns a 4D vector whose components are the floor of the given vector's components.
198SHZ_FORCE_INLINE shz_vec4_t shz_vec4_floor(shz_vec4_t vec) SHZ_NOEXCEPT;
199
200//! Returns a 2D vector whose components are the ceil of the given vector's components.
201SHZ_FORCE_INLINE shz_vec2_t shz_vec2_ceil(shz_vec2_t vec) SHZ_NOEXCEPT;
202
203//! Returns a 3D vector whose components are the ceil of the given vector's components.
204SHZ_FORCE_INLINE shz_vec3_t shz_vec3_ceil(shz_vec3_t vec) SHZ_NOEXCEPT;
205
206//! Returns a 4D vector whose components are the ceil of the given vector's components.
207SHZ_FORCE_INLINE shz_vec4_t shz_vec4_ceil(shz_vec4_t vec) SHZ_NOEXCEPT;
208
209//! Returns a 2D vector whose components are the rounded values of the given vector's components.
210SHZ_FORCE_INLINE shz_vec2_t shz_vec2_round(shz_vec2_t vec) SHZ_NOEXCEPT;
211
212//! Returns a 3D vector whose components are the rounded values of the given vector's components.
213SHZ_FORCE_INLINE shz_vec3_t shz_vec3_round(shz_vec3_t vec) SHZ_NOEXCEPT;
214
215//! Returns a 4D vector whose components are the rounded values of the given vector's components.
216SHZ_FORCE_INLINE shz_vec4_t shz_vec4_round(shz_vec4_t vec) SHZ_NOEXCEPT;
217
218//! Returns a 2D vector whose components are the fractional parts of the given vector's components.
219SHZ_FORCE_INLINE shz_vec2_t shz_vec2_fract(shz_vec2_t vec) SHZ_NOEXCEPT;
220
221//! Returns a 3D vector whose components are the fractional parts of the given vector's components.
222SHZ_FORCE_INLINE shz_vec3_t shz_vec3_fract(shz_vec3_t vec) SHZ_NOEXCEPT;
223
224//! Returns a 4D vector whose components are the fractional parts of the given vector's components.
225SHZ_FORCE_INLINE shz_vec4_t shz_vec4_fract(shz_vec4_t vec) SHZ_NOEXCEPT;
226
227//! Returns a 2D vector whose components are the signs (-1, 0, or 1) of the given vector's components.
228SHZ_FORCE_INLINE shz_vec2_t shz_vec2_sign(shz_vec2_t vec) SHZ_NOEXCEPT;
229
230//! Returns a 3D vector whose components are the signs (-1, 0, or 1) of the given vector's components.
231SHZ_FORCE_INLINE shz_vec3_t shz_vec3_sign(shz_vec3_t vec) SHZ_NOEXCEPT;
232
233//! Returns a 4D vector whose components are the signs (-1, 0, or 1) of the given vector's components.
234SHZ_FORCE_INLINE shz_vec4_t shz_vec4_sign(shz_vec4_t vec) SHZ_NOEXCEPT;
235
236//! Returns a 2D vector whose components are saturated (clamped to [0, 1]) values of the given vector's components.
237SHZ_FORCE_INLINE shz_vec2_t shz_vec2_saturate(shz_vec2_t vec) SHZ_NOEXCEPT;
238
239//! Returns a 3D vector whose components are saturated (clamped to [0, 1]) values of the given vector's components.
240SHZ_FORCE_INLINE shz_vec3_t shz_vec3_saturate(shz_vec3_t vec) SHZ_NOEXCEPT;
241
242//! Returns a 4D vector whose components are saturated (clamped to [0, 1]) values of the given vector's components.
243SHZ_FORCE_INLINE shz_vec4_t shz_vec4_saturate(shz_vec4_t vec) SHZ_NOEXCEPT;
244
245//! Returns a 2D vector whose components are the pairwise minimums of the two given vectors' components.
246SHZ_FORCE_INLINE shz_vec2_t shz_vec2_minv(shz_vec2_t a, shz_vec2_t b) SHZ_NOEXCEPT;
247
248//! Returns a 3D vector whose components are the pairwise minimums of the two given vectors' components.
249SHZ_FORCE_INLINE shz_vec3_t shz_vec3_minv(shz_vec3_t a, shz_vec3_t b) SHZ_NOEXCEPT;
250
251//! Returns a 4D vector whose components are the pairwise minimums of the two given vectors' components.
252SHZ_FORCE_INLINE shz_vec4_t shz_vec4_minv(shz_vec4_t a, shz_vec4_t b) SHZ_NOEXCEPT;
253
254//! Returns a 2D vector whose components are the pairwise maximums of the two given vectors' components.
255SHZ_FORCE_INLINE shz_vec2_t shz_vec2_maxv(shz_vec2_t a, shz_vec2_t b) SHZ_NOEXCEPT;
256
257//! Returns a 3D vector whose components are the pairwise maximums of the two given vectors' components.
258SHZ_FORCE_INLINE shz_vec3_t shz_vec3_maxv(shz_vec3_t a, shz_vec3_t b) SHZ_NOEXCEPT;
259
260//! Returns a 4D vector whose components are the pairwise maximums of the two given vectors' components.
261SHZ_FORCE_INLINE shz_vec4_t shz_vec4_maxv(shz_vec4_t a, shz_vec4_t b) SHZ_NOEXCEPT;
262
263//! Returns true if the values of each element within the two 2D vectors are approximately equal based on relative or absolute tolerance.
264SHZ_FORCE_INLINE bool shz_vec2_equal(shz_vec2_t a, shz_vec2_t b) SHZ_NOEXCEPT;
265
266//! Returns true if the values of each element within the two 3D vectors are approximately equal based on relative or absolute tolerance.
267SHZ_FORCE_INLINE bool shz_vec3_equal(shz_vec3_t a, shz_vec3_t b) SHZ_NOEXCEPT;
268
269//! Returns true if the values of each element within the two 4D vectors are approximately equal based on relative or absolute tolerance.
270SHZ_FORCE_INLINE bool shz_vec4_equal(shz_vec4_t a, shz_vec4_t b) SHZ_NOEXCEPT;
271
272//! For each component: returns 0.0f if vec[i] < edge[i], otherwise 1.0f
273SHZ_FORCE_INLINE shz_vec2_t shz_vec2_stepv( shz_vec2_t vec, shz_vec2_t edge) SHZ_NOEXCEPT;
274
275//! For each component: returns 0.0f if vec[i] < edge[i], otherwise 1.0f
276SHZ_FORCE_INLINE shz_vec3_t shz_vec3_stepv(shz_vec3_t vec, shz_vec3_t edge) SHZ_NOEXCEPT;
277
278//! For each component: returns 0.0f if vec[i] < edge[i], otherwise 1.0f
279SHZ_FORCE_INLINE shz_vec4_t shz_vec4_stepv(shz_vec4_t vec, shz_vec4_t edge) SHZ_NOEXCEPT;
280
281//! For each component: returns 0.0f if vec[i] < edge, otherwise 1.0f
282SHZ_FORCE_INLINE shz_vec2_t shz_vec2_step(shz_vec2_t vec, float edge) SHZ_NOEXCEPT;
283
284//! For each component: returns 0.0f if vec[i] < edge, otherwise 1.0f
285SHZ_FORCE_INLINE shz_vec3_t shz_vec3_step(shz_vec3_t vec, float edge) SHZ_NOEXCEPT;
286
287//! For each component: returns 0.0f if vec[i] < edge, otherwise 1.0f
288SHZ_FORCE_INLINE shz_vec4_t shz_vec4_step(shz_vec4_t vec, float edge) SHZ_NOEXCEPT;
289
290//! For each component: returns 0.0f at/below edge0[i], 1.0f at/above edge1[i], smoothly varying in-between.
291SHZ_FORCE_INLINE shz_vec2_t shz_vec2_smoothstepv(shz_vec2_t vec, shz_vec2_t edge0, shz_vec2_t edge1) SHZ_NOEXCEPT;
292
293//! For each component i: returns 0.0f at/below edge0[i], 1.0f at/above edge1[i], smoothly varying in-between.
294SHZ_FORCE_INLINE shz_vec3_t shz_vec3_smoothstepv(shz_vec3_t vec, shz_vec3_t edge0, shz_vec3_t edge1) SHZ_NOEXCEPT;
295
296//! For each component i: returns 0.0f at/below edge0[i], 1.0f at/above edge1[i], smoothly varying in-between.
297SHZ_FORCE_INLINE shz_vec4_t shz_vec4_smoothstepv(shz_vec4_t vec, shz_vec4_t edge0, shz_vec4_t edge1) SHZ_NOEXCEPT;
298
299//! For each component: returns 0.0f at/below edge0, 1.0f at/above edge1, smoothly varying in-between.
300SHZ_FORCE_INLINE shz_vec2_t shz_vec2_smoothstep(shz_vec2_t vec, float edge0, float edge1) SHZ_NOEXCEPT;
301
302//! For each component: returns 0.0f at/below edge0, 1.0f at/above edge1, smoothly varying in-between
303SHZ_FORCE_INLINE shz_vec3_t shz_vec3_smoothstep(shz_vec3_t vec, float edge0, float edge1) SHZ_NOEXCEPT;
304
305//! For each component: returns 0.0f at/below edge0, 1.0f at/above edge1, smoothly varying in-between
306SHZ_FORCE_INLINE shz_vec4_t shz_vec4_smoothstep(shz_vec4_t vec, float edge0, float edge1) SHZ_NOEXCEPT;
307
308//! @}
309
310/*! \name Arithmetic
311 \brief Routines for basic vector arithmetic operations.
312 @{
313*/
314
315//! Returns a 2D vector whose components are the sums of the given vectors' components.
316SHZ_FORCE_INLINE shz_vec2_t shz_vec2_add(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
317
318//! Returns a 3D vector whose components are the sums of the given vectors' components.
319SHZ_FORCE_INLINE shz_vec3_t shz_vec3_add(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
320
321//! Returns a 4D vector whose components are the sums of the given vectors' components.
322SHZ_FORCE_INLINE shz_vec4_t shz_vec4_add(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT;
323
324//! Returns a 2D vector whose components are equal to the values of \p vec1 minus \p vec2.
325SHZ_FORCE_INLINE shz_vec2_t shz_vec2_sub(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
326
327//! Returns a 3D vector whose components are equal to the values of \p vec1 minus \p vec2.
328SHZ_FORCE_INLINE shz_vec3_t shz_vec3_sub(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
329
330//! Returns a 4D vector whose components are equal to the values of \p vec1 minus \p vec2.
331SHZ_FORCE_INLINE shz_vec4_t shz_vec4_sub(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT;
332
333//! Returns a 2D vector whose component values are those of \p vec1 times \p vec2.
334SHZ_FORCE_INLINE shz_vec2_t shz_vec2_mul(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
335
336//! Returns a 3D vector whose component values are those of \p vec1 times \p vec2.
337SHZ_FORCE_INLINE shz_vec3_t shz_vec3_mul(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
338
339//! Returns a 4D vector whose component values are those of \p vec1 times \p vec2.
340SHZ_FORCE_INLINE shz_vec4_t shz_vec4_mul(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT;
341
342//! Returns a 2D vector whose component values are those of \p vec1 divided by \p vec2.
343SHZ_FORCE_INLINE shz_vec2_t shz_vec2_div(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
344
345//! Returns a 3D vector whose component values are those of \p vec1 divided by \p vec2.
346SHZ_FORCE_INLINE shz_vec3_t shz_vec3_div(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
347
348//! Returns a 4D vector whose component values are those of \p vec1 divided by \p vec2.
349SHZ_FORCE_INLINE shz_vec4_t shz_vec4_div(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT;
350
351//! Returns a 2D vector whose component values are those of the given vector multiplied by a factor.
352SHZ_FORCE_INLINE shz_vec2_t shz_vec2_scale(shz_vec2_t vec, float factor) SHZ_NOEXCEPT;
353
354//! Returns a 3D vector whose component values are those of the given vector multiplied by a factor.
355SHZ_FORCE_INLINE shz_vec3_t shz_vec3_scale(shz_vec3_t vec, float factor) SHZ_NOEXCEPT;
356
357//! Returns a 4D vector whose component values are those of the given vector multiplied by a factor.
358SHZ_FORCE_INLINE shz_vec4_t shz_vec4_scale(shz_vec4_t vec, float factor) SHZ_NOEXCEPT;
359
360//! @}
361
362/*! \name Magnitude
363 \brief Math routines for vector length and normalization.
364 @{
365*/
366
367//! Returns the squared magnitude of the given 2D vector.
368SHZ_FORCE_INLINE float shz_vec2_magnitude_sqr(shz_vec2_t vec) SHZ_NOEXCEPT;
369
370//! Returns the squared magnitude of the given 4D vector.
371SHZ_FORCE_INLINE float shz_vec4_magnitude_sqr(shz_vec4_t vec) SHZ_NOEXCEPT;
372
373//! Returns the squared magnitude of the given 3D vector.
374SHZ_FORCE_INLINE float shz_vec3_magnitude_sqr(shz_vec3_t vec) SHZ_NOEXCEPT;
375
376//! Returns the magnitude of the given 2D vector.
377SHZ_FORCE_INLINE float shz_vec2_magnitude(shz_vec2_t vec) SHZ_NOEXCEPT;
378
379//! Returns the magnitude of the given 3D vector.
380SHZ_FORCE_INLINE float shz_vec3_magnitude(shz_vec3_t vec) SHZ_NOEXCEPT;
381
382//! Returns the magnitude of the given 4D vector.
383SHZ_FORCE_INLINE float shz_vec4_magnitude(shz_vec4_t vec) SHZ_NOEXCEPT;
384
385//! Returns the inverse magnitude of the given 2D vector.
386SHZ_FORCE_INLINE float shz_vec2_magnitude_inv(shz_vec2_t vec) SHZ_NOEXCEPT;
387
388//! Returns the inverse magnitude of the given 3D vector.
389SHZ_FORCE_INLINE float shz_vec3_magnitude_inv(shz_vec3_t vec) SHZ_NOEXCEPT;
390
391//! Returns the inverse magnitude of the given 4D vector.
392SHZ_FORCE_INLINE float shz_vec4_magnitude_inv(shz_vec4_t vec) SHZ_NOEXCEPT;
393
394//! Returns a normalized unit vector from the given 2D vector.
395SHZ_FORCE_INLINE shz_vec2_t shz_vec2_normalize(shz_vec2_t vec) SHZ_NOEXCEPT;
396
397//! Returns a normalized unit vector from the given 3D vector.
398SHZ_FORCE_INLINE shz_vec3_t shz_vec3_normalize(shz_vec3_t vec) SHZ_NOEXCEPT;
399
400//! Returns a normalized unit vector from the given 4D vector.
401SHZ_FORCE_INLINE shz_vec4_t shz_vec4_normalize(shz_vec4_t vec) SHZ_NOEXCEPT;
402
403/*! SAFELY returns a normalized unit vector from the given 2D vector.
404
405 If the vector's magnitude is not `> 0.0f`, safely returns a zero vector.
406*/
407SHZ_FORCE_INLINE shz_vec2_t shz_vec2_normalize_safe(shz_vec2_t vec) SHZ_NOEXCEPT;
408
409/*! SAFELY returns a normalized unit vector from the given 3D vector.
410
411 If the vector's magnitude is not `> 0.0f`, safely returns a zero vector.
412*/
413SHZ_FORCE_INLINE shz_vec3_t shz_vec3_normalize_safe(shz_vec3_t vec) SHZ_NOEXCEPT;
414
415/*! SAFELY returns a normalized unit vector from the given 4D vector.
416
417 If the vector's magnitude is not `> 0.0f`, safely returns a zero vector.
418*/
419SHZ_FORCE_INLINE shz_vec4_t shz_vec4_normalize_safe(shz_vec4_t vec) SHZ_NOEXCEPT;
420
421//! @}
422
423/*! \name Binary Operations
424 \brief Linear algebra operations performed with multiple vectors.
425 @{
426*/
427
428//! Returns the dot product between the two given 2D vectors.
429SHZ_FORCE_INLINE float shz_vec2_dot(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
430
431//! Returns the two dot products taken between the 2D vector \p l and 2D vectors \p r1 and \p r2.
432SHZ_FORCE_INLINE shz_vec2_t shz_vec2_dot2(shz_vec2_t l, shz_vec2_t r1, shz_vec2_t r2) SHZ_NOEXCEPT;
433
434//! Returns the three dot products taken between the 2D vector \p l and 2D vectors \p r1, \p r2, and \p r3.
435SHZ_FORCE_INLINE shz_vec3_t shz_vec2_dot3(shz_vec2_t l, shz_vec2_t r1, shz_vec2_t r2, shz_vec2_t r3) SHZ_NOEXCEPT;
436
437//! Returns the dot product between the two given 3D vectors.
438SHZ_FORCE_INLINE float shz_vec3_dot(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
439
440//! Returns the two dot products taken between the 3D vector \p l and 3D vectors \p r1 and \p r2.
441SHZ_FORCE_INLINE shz_vec2_t shz_vec3_dot2(shz_vec3_t l, shz_vec3_t r1, shz_vec3_t r2) SHZ_NOEXCEPT;
442
443//! Returns the three dot products taken between the 3D vector \p l and 3D vectors \p r1, \p r2, and \p r3.
444SHZ_FORCE_INLINE shz_vec3_t shz_vec3_dot3(shz_vec3_t l, shz_vec3_t r1, shz_vec3_t r2, shz_vec3_t r3) SHZ_NOEXCEPT;
445
446//! Returns the dot product between the two given 4D vectors.
447SHZ_FORCE_INLINE float shz_vec4_dot(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT;
448
449//! Returns the two dot products taken between the 4D vector \p l and 4D vectors \p r1 and \p r2.
450SHZ_FORCE_INLINE shz_vec2_t shz_vec4_dot2(shz_vec4_t l, shz_vec4_t r1, shz_vec4_t r2) SHZ_NOEXCEPT;
451
452//! Returns the three dot products taken between the 4D vector \p l and 4D vectors \p r1, \p r2, and \p r3.
453SHZ_FORCE_INLINE shz_vec3_t shz_vec4_dot3(shz_vec4_t l, shz_vec4_t r1, shz_vec4_t r2, shz_vec4_t r3) SHZ_NOEXCEPT;
454
455//! Returns the distance between the two given 2D vectors.
456SHZ_FORCE_INLINE float shz_vec2_distance(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
457
458//! Returns the distance between the two given 3D vectors.
459SHZ_FORCE_INLINE float shz_vec3_distance(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
460
461//! Returns the distance between the two given 4D vectors.
462SHZ_FORCE_INLINE float shz_vec4_distance(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT;
463
464//! Returns the squared-distance between the two given 2D vectors.
465SHZ_FORCE_INLINE float shz_vec2_distance_sqr(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
466
467//! Returns the squared-distance between the two given 3D vectors.
468SHZ_FORCE_INLINE float shz_vec3_distance_sqr(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
469
470//! Returns the squared-distance between the two given 4D vectors.
471SHZ_FORCE_INLINE float shz_vec4_distance_sqr(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT;
472
473//! Returns the given 2D vector, translated towards the \p target by the given \p max_distance.
474SHZ_FORCE_INLINE shz_vec2_t shz_vec2_move(shz_vec2_t vec, shz_vec2_t target, float max_distance) SHZ_NOEXCEPT;
475
476//! Returns the given 3D vector, translated towards the \p target by the given \p max_distance.
477SHZ_FORCE_INLINE shz_vec3_t shz_vec3_move(shz_vec3_t vec, shz_vec3_t target, float max_distance) SHZ_NOEXCEPT;
478
479//! Returns the given 4D vector, translated towards the \p target by the given \p max_distance.
480SHZ_FORCE_INLINE shz_vec4_t shz_vec4_move(shz_vec4_t vec, shz_vec4_t target, float max_distance) SHZ_NOEXCEPT;
481
482//! Returns a 2D vector that is linearly interpolated from \p a to \p b by the given `0.0f-1.0f` factor, \p t.
483SHZ_FORCE_INLINE shz_vec2_t shz_vec2_lerp(shz_vec2_t a, shz_vec2_t b, float t) SHZ_NOEXCEPT;
484
485//! Returns a 3D vector that is linearly interpolated from \p a to \p b by the given `0.0f-1.0f` factor, \p t.
486SHZ_FORCE_INLINE shz_vec3_t shz_vec3_lerp(shz_vec3_t a, shz_vec3_t b, float t) SHZ_NOEXCEPT;
487
488//! Returns a 4D vector that is linearly interpolated from \p a to \p b by the given `0.0f-1.0f` factor, \p t.
489SHZ_FORCE_INLINE shz_vec4_t shz_vec4_lerp(shz_vec4_t a, shz_vec4_t b, float t) SHZ_NOEXCEPT;
490
491//! Reflects the given 2D \p incidence vector against a surface with the given \p normal, returning the result.
492SHZ_FORCE_INLINE shz_vec2_t shz_vec2_reflect(shz_vec2_t incidence, shz_vec2_t normal) SHZ_NOEXCEPT;
493
494//! Reflects the given 3D \p incidence vector against a surface with the given \p normal, returning the result.
495SHZ_FORCE_INLINE shz_vec3_t shz_vec3_reflect(shz_vec3_t incidence, shz_vec3_t normal) SHZ_NOEXCEPT;
496
497//! Reflects the given 4D \p incidence vector against a surface with the given \p normal, returning the result.
498SHZ_FORCE_INLINE shz_vec4_t shz_vec4_reflect(shz_vec4_t incidence, shz_vec4_t normal) SHZ_NOEXCEPT;
499
500//! Refracts the given 2D \p incidence vector against a surface with the given \p normal using the given refraction index ratio, \p eta.
501SHZ_INLINE shz_vec2_t shz_vec2_refract(shz_vec2_t incidence, shz_vec2_t normal, float eta) SHZ_NOEXCEPT;
502
503//! Refracts the given 3D \p incidence vector against a surface with the given \p normal using the given refraction index ratio, \p eta.
504SHZ_INLINE shz_vec3_t shz_vec3_refract(shz_vec3_t incidence, shz_vec3_t normal, float eta) SHZ_NOEXCEPT;
505
506//! Refracts the given 4D \p incidence vector against a surface with the given \p normal using the given refraction index ratio, \p eta.
507SHZ_INLINE shz_vec4_t shz_vec4_refract(shz_vec4_t incidence, shz_vec4_t normal, float eta) SHZ_NOEXCEPT;
508
509/*! Returns the cross product, as a scalar, between two 2D vectors.
510
511 \note
512 The definition of the cross-product is ambiguous in 2D space, but the geometric
513 interpretation here is that the result is the magnitude of the orthogonal vector
514 created from the given two along the Z-axis.
515*/
516SHZ_FORCE_INLINE float shz_vec2_cross(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
517
518//! Returns the vector produced by taking the cross-product of the two given 3D vectors.
519SHZ_FORCE_INLINE shz_vec3_t shz_vec3_cross(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
520
521//! Returns the resulting vector from projecting the given 2D vector along the given (unit) axis
522SHZ_FORCE_INLINE shz_vec2_t shz_vec2_project(shz_vec2_t vec, shz_vec2_t onto) SHZ_NOEXCEPT;
523
524//! Returns the resulting vector from projecting the given 3D vector along the given (unit) axis
525SHZ_FORCE_INLINE shz_vec3_t shz_vec3_project(shz_vec3_t vec, shz_vec3_t onto) SHZ_NOEXCEPT;
526
527//! Returns the resulting vector from projecting the given 4D vector along the given (unit) axis
528SHZ_FORCE_INLINE shz_vec4_t shz_vec4_project(shz_vec4_t vec, shz_vec4_t onto) SHZ_NOEXCEPT;
529
530/*! Returns the resulting vector from projecting the given 2D vector along the given (unit) axis
531
532 \note
533 This routine should safely return the zero vector when \p vec has a magnitude of 0.0f.
534*/
535SHZ_FORCE_INLINE shz_vec2_t shz_vec2_project_safe(shz_vec2_t vec, shz_vec2_t onto) SHZ_NOEXCEPT;
536
537/*! Returns the resulting vector from projecting the given 3D vector along the given (unit) axis
538
539 \note
540 This routine should safely return the zero vector when \p vec has a magnitude of 0.0f.
541*/
542SHZ_FORCE_INLINE shz_vec3_t shz_vec3_project_safe(shz_vec3_t vec, shz_vec3_t onto) SHZ_NOEXCEPT;
543
544/*! Returns the resulting vector from projecting the given 4D vector along the given (unit) axis
545
546 \note
547 This routine should safely return the zero vector when \p vec has a magnitude of 0.0f.
548*/
549SHZ_FORCE_INLINE shz_vec4_t shz_vec4_project_safe(shz_vec4_t vec, shz_vec4_t onto) SHZ_NOEXCEPT;
550
551//! Returns the rejection of the given vector, \p vec, onto another vector, \p onto.
552SHZ_FORCE_INLINE shz_vec3_t shz_vec3_reject(shz_vec3_t vec, shz_vec3_t onto) SHZ_NOEXCEPT;
553
554//! @}
555
556/*! \name Miscellaneous
557 \brief Other specialized vector routines.
558 @{
559*/
560
561//! Returns the 3D vector "triple product" between vector's \p a, \p b, and \p c.
562SHZ_INLINE float shz_vec3_triple(shz_vec3_t a, shz_vec3_t b, shz_vec3_t c) SHZ_NOEXCEPT;
563
564//! Returns a vector which is perpendicular to the given vector.
565SHZ_INLINE shz_vec3_t shz_vec3_perp(shz_vec3_t vec) SHZ_NOEXCEPT;
566
567//! Computes barycentric coordinates `<u, v, w>` for point p, within the plane of the triangle with vertices \p a, \p b, and \p c.
568SHZ_FORCE_INLINE shz_vec3_t shz_vec3_barycenter(shz_vec3_t p, shz_vec3_t a, shz_vec3_t b, shz_vec3_t c) SHZ_NOEXCEPT;
569
570//! Returns 2 3D vectors which are normalized and orthogonal to the two input vectors.
571SHZ_INLINE void shz_vec3_orthonormalize(shz_vec3_t in1, shz_vec3_t in2, shz_vec3_t* out1, shz_vec3_t* out2) SHZ_NOEXCEPT;
572
573//! Calculates the cubic hermite interpolation between two vectors and their tangents.
574SHZ_FORCE_INLINE shz_vec3_t shz_vec3_cubic_hermite(shz_vec3_t vec, shz_vec3_t tangent1, shz_vec3_t vec2, shz_vec3_t tangent2, float amounht) SHZ_NOEXCEPT;
575
576//! @}
577
578/*! \name Angles
579 \brief Routines for working with vectors and angles.
580 @{
581*/
582
583//! Returns the angle formed between the given 2D vectors in radians.
584SHZ_FORCE_INLINE float shz_vec2_angle_between(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT;
585
586//! Returns the angle formed between the given 3D vectors in radians.
587SHZ_FORCE_INLINE float shz_vec3_angle_between(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT;
588
589//! Returns the angle formed between the positive X axis and the given 2D vector, in radians.
590SHZ_FORCE_INLINE float shz_vec2_angle(shz_vec2_t vec) SHZ_NOEXCEPT;
591
592//! Returns the angles formed between the positive X axis and the given 3D vector, in radians.
593SHZ_FORCE_INLINE shz_vec3_t shz_vec3_angles(shz_vec3_t vec) SHZ_NOEXCEPT;
594
595//! Returns the 2D unit vector representing a rotation from the positive X axis.
596SHZ_FORCE_INLINE shz_vec2_t shz_vec2_from_sincos(shz_sincos_t sincos) SHZ_NOEXCEPT;
597
598//! Returns the 3D unit vector representing the given rotation angles relative to the positive X axis.
599SHZ_FORCE_INLINE shz_vec3_t shz_vec3_from_sincos(shz_sincos_t azimuth, shz_sincos_t elevation) SHZ_NOEXCEPT;
600
601//! Returns the 2D unit vector representing a rotation from the positive X axis in radians.
602SHZ_FORCE_INLINE shz_vec2_t shz_vec2_from_angle(float radians) SHZ_NOEXCEPT;
603
604//! Returns the 3D unit vector representing the given rotation angles relative to the positive X axis in radians.
605SHZ_FORCE_INLINE shz_vec3_t shz_vec3_from_angles(float azimuth, float elevation) SHZ_NOEXCEPT;
606
607//! Returns the 2D unit vector representing a rotation from the positive X axis in degrees.
608SHZ_FORCE_INLINE shz_vec2_t shz_vec2_from_angle_deg(float degrees) SHZ_NOEXCEPT;
609
610//! Returns the 3D unit vector representing the given rotation angles relative to the positive X axis in degrees.
611SHZ_FORCE_INLINE shz_vec3_t shz_vec3_from_angles_deg(float azimuth, float elevation) SHZ_NOEXCEPT;
612
613//! Rotates the given 2D vector about the Z axis by the given angle in radians.
614SHZ_FORCE_INLINE shz_vec2_t shz_vec2_rotate(shz_vec2_t vec, float radians) SHZ_NOEXCEPT;
615
616//! @}
617
618/*! \name Extending
619 \brief Routines for extending vectors into other dimensions.
620 @{
621 */
622
623//! Extends a 2D vector to 3D, using \p z as the value of the Z component.
624SHZ_FORCE_INLINE shz_vec3_t shz_vec2_vec3(shz_vec2_t vec, float z) SHZ_NOEXCEPT;
625
626//! Extends a 2D vector to 4D, using \p z and \p w as the values of the Z and W components.
627SHZ_FORCE_INLINE shz_vec4_t shz_vec2_vec4(shz_vec2_t vec, float z, float w) SHZ_NOEXCEPT;
628
629//! Extends a 3D vector to 4D, using \p w as the value of the W component.
630SHZ_FORCE_INLINE shz_vec4_t shz_vec3_vec4(shz_vec3_t vec, float w) SHZ_NOEXCEPT;
631
632//! @}
633
634/*! \name Swizzling
635 \brief Routines for swizzling the order of a vector's components.
636 @{
637 */
638
639 //! Returns a 2D vector whose elements are equal to the source vector's values at the given indices.
640 SHZ_FORCE_INLINE shz_vec2_t shz_vec2_swizzle(shz_vec2_t vec, unsigned x_idx, unsigned y_idx) SHZ_NOEXCEPT;
641
642 //! Returns a 3D vector whose elements are equal to the source vector's values at the given indices.
643 SHZ_FORCE_INLINE shz_vec3_t shz_vec3_swizzle(shz_vec3_t vec, unsigned x_idx, unsigned y_idx, unsigned z_idx) SHZ_NOEXCEPT;
644
645 //! Returns a new 2D vector whose elements are equal to the source vector's values at the given indices.
646 SHZ_FORCE_INLINE shz_vec4_t shz_vec4_swizzle(shz_vec4_t vec, unsigned x_idx, unsigned y_idx, unsigned z_idx, unsigned w_idx) SHZ_NOEXCEPT;
647
648 //! @}
649
650SHZ_DECLS_END
651
652/*! \name Adapters
653 \brief Macros for converting between SH4ZAM and other compatible formats.
654 @{
655*/
656
657//! Dereferences the given pointer to a sequence of 2 floats as a shz_vec2_t.
658#define shz_vec2_deref(ptr) (*((shz_vec2_t*)(ptr)))
659
660//! Dereferences the given pointer to a sequence of 3 floats as a shz_vec3_t.
661#define shz_vec3_deref(ptr) (*((shz_vec3_t*)(ptr)))
662
663//! Dereferences the given pointer to a sequence of 4 floats as a shz_vec4_t.
664#define shz_vec4_deref(ptr) (*((shz_vec4_t*)(ptr)))
665
666//! Converts the given \p value or expression to the equivalent 2D SH4ZAM vector value.
667#define shz_vec2_from(value) SHZ_CONVERT(shz_vec2_t, value)
668
669//! Converts the given \p value or expression to the equivalent 3D SH4ZAM vector value.
670#define shz_vec3_from(value) SHZ_CONVERT(shz_vec3_t, value)
671
672//! Converts the given \p value or expression to the equivalent 4D SH4ZAM vector value.
673#define shz_vec4_from(value) SHZ_CONVERT(shz_vec4_t, value)
674
675//! Converts the given 2D \p vector into a value of the given \p type.
676#define shz_vec2_to(type, vector) SHZ_CONVERT(type, vector)
677
678//! Converts the given 3D \p vector into a value of the given \p type.
679#define shz_vec3_to(type, vector) SHZ_CONVERT(type, vector)
680
681//! Converts the given 4D \p vector into a value of the given \p type.
682#define shz_vec4_to(type, vector) SHZ_CONVERT(type, vector)
683
684//! @}
685
686/*! \name Type-Generic Routines
687 \brief Generalized vector routines for C and C++.
688 @{
689*/
690
691#ifndef __cplusplus
692
693 //! C type-generic vector absolute value.
694# define shz_vec_abs(vec)
695 _Generic((vec),
696 shz_vec2_t: shz_vec2_abs,
697 shz_vec3_t: shz_vec3_abs,
698 shz_vec4_t: shz_vec4_abs)(vec)
699
700 //! C type-generic vector negation.
701# define shz_vec_neg(vec)
702 _Generic((vec),
703 shz_vec2_t: shz_vec2_neg,
704 shz_vec3_t: shz_vec3_neg,
705 shz_vec4_t: shz_vec4_neg)(vec)
706
707 //! C type-generic vector inversion.
708# define shz_vec_inv(vec)
709 _Generic((vec),
710 shz_vec2_t: shz_vec2_inv,
711 shz_vec3_t: shz_vec3_inv,
712 shz_vec4_t: shz_vec4_inv)(vec)
713
714 //! C type-generic vector maximum value.
715# define shz_vec_max(vec)
716 _Generic((vec),
717 shz_vec2_t: shz_vec2_max,
718 shz_vec3_t: shz_vec3_max,
719 shz_vec4_t: shz_vec4_max)(vec)
720
721 //! C type-generic vector minimum value.
722# define shz_vec_min(vec)
723 _Generic((vec),
724 shz_vec2_t: shz_vec2_min,
725 shz_vec3_t: shz_vec3_min,
726 shz_vec4_t: shz_vec4_min)(vec)
727
728 //! C type-generic vector minimum value.
729# define shz_vec_clamp(vec, min, max)
730 _Generic((vec),
731 shz_vec2_t: shz_vec2_clamp,
732 shz_vec3_t: shz_vec3_clamp,
733 shz_vec4_t: shz_vec4_clamp)(vec, min, max)
734
735 //! C type-generic vector equals.
736# define shz_vec_equal(vec1, vec2)
737 _Generic((vec1),
738 shz_vec2_t: shz_vec2_equal,
739 shz_vec3_t: shz_vec3_equal,
740 shz_vec4_t: shz_vec4_equal)(vec1, vec2)
741
742 //! C type-generic vector addition.
743# define shz_vec_add(vec1, vec2)
744 _Generic((vec1),
745 shz_vec2_t: shz_vec2_add,
746 shz_vec3_t: shz_vec3_add,
747 shz_vec4_t: shz_vec4_add)(vec1, vec2)
748
749 //! C type-generic vector subtraction.
750# define shz_vec_sub(vec1, vec2)
751 _Generic((vec1),
752 shz_vec2_t: shz_vec2_sub,
753 shz_vec3_t: shz_vec3_sub,
754 shz_vec4_t: shz_vec4_sub)(vec1, vec2)
755
756 //! C type-generic vector multiplication.
757# define shz_vec_mul(vec1, vec2)
758 _Generic((vec1),
759 shz_vec2_t: shz_vec2_mul,
760 shz_vec3_t: shz_vec3_mul,
761 shz_vec4_t: shz_vec4_mul)(vec1, vec2)
762
763 //! C type-generic vector division.
764# define shz_vec_div(vec1, vec2)
765 _Generic((vec1),
766 shz_vec2_t: shz_vec2_div,
767 shz_vec3_t: shz_vec3_div,
768 shz_vec4_t: shz_vec4_div)(vec1, vec2)
769
770 //! C type-generic vector scaling.
771# define shz_vec_scale(vec, factor)
772 _Generic((vec),
773 shz_vec2_t: shz_vec2_scale,
774 shz_vec3_t: shz_vec3_scale,
775 shz_vec4_t: shz_vec4_scale)(vec, factor)
776
777 //! C type-generic vector dot product.
778# define shz_vec_dot(vec1, vec2)
779 _Generic((vec1),
780 shz_vec2_t: shz_vec2_dot,
781 shz_vec3_t: shz_vec3_dot,
782 shz_vec4_t: shz_vec4_dot)(vec1, vec2)
783
784 //! C type-generic vector chained double dot product.
785# define shz_vec_dot2(l, r1, r2)
786 _Generic((l),
787 shz_vec2_t: shz_vec2_dot2,
788 shz_vec3_t: shz_vec3_dot2,
789 shz_vec4_t: shz_vec4_dot2)(l, r1, r2)
790
791 //! C type-generic vector chained triple dot product.
792# define shz_vec_dot3(l, r1, r2, r3)
793 _Generic((l),
794 shz_vec2_t: shz_vec2_dot3,
795 shz_vec3_t: shz_vec3_dot3,
796 shz_vec4_t: shz_vec4_dot3)(l, r1, r2, r3)
797
798 //! C type-generic vector squared magnitude.
799# define shz_vec_magnitude_sqr(vec)
800 _Generic((vec),
801 shz_vec2_t: shz_vec2_magnitude_sqr,
802 shz_vec3_t: shz_vec3_magnitude_sqr,
803 shz_vec4_t: shz_vec4_magnitude_sqr)(vec)
804
805 //! C type-generic vector magnitude.
806# define shz_vec_magnitude(vec)
807 _Generic((vec),
808 shz_vec2_t: shz_vec2_magnitude,
809 shz_vec3_t: shz_vec3_magnitude,
810 shz_vec4_t: shz_vec4_magnitude)(vec)
811
812 //! C type-generic vector inverse magnitude.
813# define shz_vec_magnitude_inv(vec)
814 _Generic((vec),
815 shz_vec2_t: shz_vec2_magnitude_inv,
816 shz_vec3_t: shz_vec3_magnitude_inv,
817 shz_vec4_t: shz_vec4_magnitude_inv)(vec)
818
819 //! C type-generic vector normalization.
820# define shz_vec_normalize(vec)
821 _Generic((vec),
822 shz_vec2_t: shz_vec2_normalize,
823 shz_vec3_t: shz_vec3_normalize,
824 shz_vec4_t: shz_vec4_normalize)(vec)
825
826 //! C type-generic safe vector normalization.
827# define shz_vec_normalize_safe(vec)
828 _Generic((vec),
829 shz_vec2_t: shz_vec2_normalize_safe,
830 shz_vec3_t: shz_vec3_normalize_safe,
831 shz_vec4_t: shz_vec4_normalize_safe)(vec)
832
833 //! C type-generic vector distance.
834# define shz_vec_distance(vec1, vec2)
835 _Generic((vec1),
836 shz_vec2_t: shz_vec2_distance,
837 shz_vec3_t: shz_vec3_distance,
838 shz_vec4_t: shz_vec4_distance)(vec1, vec2)
839
840 //! C type-generic vector move.
841# define shz_vec_move(vec, target, maxdist)
842 _Generic((vec),
843 shz_vec2_t: shz_vec2_move,
844 shz_vec3_t: shz_vec3_move,
845 shz_vec4_t: shz_vec4_move)(vec, target, maxdist)
846
847 //! C type-generic vector squared distance.
848# define shz_vec_distance_sqr(vec1, vec2)
849 _Generic((vec1),
850 shz_vec2_t: shz_vec2_distance_sqr,
851 shz_vec3_t: shz_vec3_distance_sqr,
852 shz_vec4_t: shz_vec4_distance_sqr)(vec1, vec2)
853
854 //! C type-generic linear interpolation between two vectors.
855# define shz_vec_lerp(vec1, vec2, t)
856 _Generic((vec1),
857 shz_vec2_t: shz_vec2_lerp,
858 shz_vec3_t: shz_vec3_lerp,
859 shz_vec4_t: shz_vec4_lerp)(vec1, vec2, t)
860
861 //! C type-generic vector reflection.
862# define shz_vec_reflect(incidence, normal)
863 _Generic((incidence),
864 shz_vec2_t: shz_vec2_reflect,
865 shz_vec3_t: shz_vec3_reflect,
866 shz_vec4_t: shz_vec4_reflect)(incidence, normal)
867
868 //! C type-generic vector refraction.
869# define shz_vec_refract(incidence, normal, eta)
870 _Generic((incidence),
871 shz_vec2_t: shz_vec2_refract,
872 shz_vec3_t: shz_vec3_refract,
873 shz_vec4_t: shz_vec4_refract)(incidence, normal, eta)
874
875 //! C type-generic vector cross-product.
876# define shz_vec_cross(vec1, vec2)
877 _Generic((vec1),
878 shz_vec2_t: shz_vec2_cross,
879 shz_vec3_t: shz_vec3_cross)(vec1, vec2)
880
881 //! C type-generic vector projection.
882# define shz_vec_project(vec1, vec2)
883 _Generic((vec1),
884 shz_vec2_t: shz_vec2_project,
885 shz_vec3_t: shz_vec3_project,
886 shz_vec4_t: shz_vec4_project)(vec1, vec2)
887
888 //! C type-generic safe vector projection.
889# define shz_vec_project_safe(vec1, vec2)
890 _Generic((vec1),
891 shz_vec2_t: shz_vec2_project_safe,
892 shz_vec3_t: shz_vec3_project_safe,
893 shz_vec4_t: shz_vec4_project_safe)(vec1, vec2)
894
895 //! C type-generic angle-from-vector extraction.
896# define shz_vec_angles(vec)
897 _Generic((vec),
898 shz_vec2_t: shz_vec2_angle,
899 shz_vec3_t: shz_vec3_angles)(vec)
900
901 //! C type-generic angle between two vectors.
902# define shz_vec_angle_between(vec1, vec2)
903 _Generic((vec1),
904 shz_vec2_t: shz_vec2_angle_between,
905 shz_vec3_t: shz_vec3_angle_between)(vec1, vec2)
906
907 //! C type-generic vector swizzling.
908# define shz_vec_swizzle(vec, ...)
909 _Generic((vec),
910 shz_vec2_t: shz_vec2_swizzle,
911 shz_vec3_t: shz_vec3_swizzle,
912 shz_vec4_t: shz_vec4_swizzle)(vec, __VA_ARGS__)
913
914 //! C type-generic component-wise floor.
915# define shz_vec_floor(vec)
916 _Generic((vec),
917 shz_vec2_t: shz_vec2_floor,
918 shz_vec3_t: shz_vec3_floor,
919 shz_vec4_t: shz_vec4_floor)(vec)
920
921 //! C type-generic component-wise ceil.
922# define shz_vec_ceil(vec)
923 _Generic((vec),
924 shz_vec2_t: shz_vec2_ceil,
925 shz_vec3_t: shz_vec3_ceil,
926 shz_vec4_t: shz_vec4_ceil)(vec)
927
928 //! C type-generic component-wise round.
929# define shz_vec_round(vec)
930 _Generic((vec),
931 shz_vec2_t: shz_vec2_round,
932 shz_vec3_t: shz_vec3_round,
933 shz_vec4_t: shz_vec4_round)(vec)
934
935 //! C type-generic component-wise fract.
936# define shz_vec_fract(vec)
937 _Generic((vec),
938 shz_vec2_t: shz_vec2_fract,
939 shz_vec3_t: shz_vec3_fract,
940 shz_vec4_t: shz_vec4_fract)(vec)
941
942 //! C type-generic component-wise sign.
943# define shz_vec_sign(vec)
944 _Generic((vec),
945 shz_vec2_t: shz_vec2_sign,
946 shz_vec3_t: shz_vec3_sign,
947 shz_vec4_t: shz_vec4_sign)(vec)
948
949 //! C type-generic component-wise saturate.
950# define shz_vec_saturate(vec)
951 _Generic((vec),
952 shz_vec2_t: shz_vec2_saturate,
953 shz_vec3_t: shz_vec3_saturate,
954 shz_vec4_t: shz_vec4_saturate)(vec)
955
956 //! C type-generic pairwise minimum.
957# define shz_vec_minv(a, b)
958 _Generic((a),
959 shz_vec2_t: shz_vec2_minv,
960 shz_vec3_t: shz_vec3_minv,
961 shz_vec4_t: shz_vec4_minv)(a, b)
962
963 //! C type-generic pairwise maximum.
964# define shz_vec_maxv(a, b)
965 _Generic((a),
966 shz_vec2_t: shz_vec2_maxv,
967 shz_vec3_t: shz_vec3_maxv,
968 shz_vec4_t: shz_vec4_maxv)(a, b)
969
970 //! C type-generic component-wise step
971# define shz_vec_stepv(vec, edge)
972 _Generic((vec),
973 shz_vec2_t: shz_vec2_stepv,
974 shz_vec3_t: shz_vec3_stepv,
975 shz_vec4_t: shz_vec4_stepv)(vec, edge)
976
977 //! C type-generic step
978# define shz_vec_step(vec, edge)
979 _Generic((vec),
980 shz_vec2_t: shz_vec2_step,
981 shz_vec3_t: shz_vec3_step,
982 shz_vec4_t: shz_vec4_step)(vec, edge)
983
984 //! C type-generic component-wise smoothstep
985# define shz_vec_smoothstepv(vec, edge0, edge1)
986 _Generic((vec),
987 shz_vec2_t: shz_vec2_smoothstepv,
988 shz_vec3_t: shz_vec3_smoothstepv,
989 shz_vec4_t: shz_vec4_smoothstepv)(vec, edge0, edge1)
990
991 //! C type-generic smoothstep
992# define shz_vec_smoothstep(vec, edge0, edge1)
993 _Generic((vec),
994 shz_vec2_t: shz_vec2_smoothstep,
995 shz_vec3_t: shz_vec3_smoothstep,
996 shz_vec4_t: shz_vec4_smoothstep)(vec, edge0, edge1)
997
998 //! C type-generic component-wise smoothstep_safe
999# define shz_vec_smoothstepv_safe(vec, edge0, edge1)
1000 _Generic((vec),
1001 shz_vec2_t: shz_vec2_smoothstepv_safe,
1002 shz_vec3_t: shz_vec3_smoothstepv_safe,
1003 shz_vec4_t: shz_vec4_smoothstepv_safe)(vec, edge0, edge1)
1004
1005 //! C type-generic smoothstep_safe
1006# define shz_vec_smoothstep_safe(vec, edge0, edge1)
1007 _Generic((vec),
1008 shz_vec2_t: shz_vec2_smoothstep_safe,
1009 shz_vec3_t: shz_vec3_smoothstep_safe,
1010 shz_vec4_t: shz_vec4_smoothstep_safe)(vec, edge0, edge1)
1011
1012#else // C++ generics (because it's too dumb to support _Generic()).
1013
1014# include <concepts>
1015
1016 //! C++ type-generic vector absolute value.
1017 template<typename T>
1018 SHZ_FORCE_INLINE T shz_vec_abs(T vec) SHZ_NOEXCEPT {
1019 if constexpr(std::convertible_to<T, shz_vec2_t>)
1020 return shz_vec2_abs(vec);
1021 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1022 return shz_vec3_abs(vec);
1023 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1024 return shz_vec4_abs(vec);
1025 else static_assert(false, "Incompatible type!");
1026 }
1027
1028 //! C++ type-generic vector negation.
1029 template<typename T>
1030 SHZ_FORCE_INLINE T shz_vec_neg(T vec) SHZ_NOEXCEPT {
1031 if constexpr(std::convertible_to<T, shz_vec2_t>)
1032 return shz_vec2_neg(vec);
1033 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1034 return shz_vec3_neg(vec);
1035 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1036 return shz_vec4_neg(vec);
1037 else static_assert(false, "Incompatible type!");
1038 }
1039
1040 //! C++ type-generic vector inversion.
1041 template<typename T>
1042 SHZ_FORCE_INLINE T shz_vec_inv(T vec) SHZ_NOEXCEPT {
1043 if constexpr(std::convertible_to<T, shz_vec2_t>)
1044 return shz_vec2_inv(vec);
1045 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1046 return shz_vec3_inv(vec);
1047 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1048 return shz_vec4_inv(vec);
1049 else static_assert(false, "Incompatible type!");
1050 }
1051
1052 //! C++ type-generic vector maximum value.
1053 template<typename T>
1054 SHZ_FORCE_INLINE float shz_vec_max(T vec) SHZ_NOEXCEPT {
1055 if constexpr(std::convertible_to<T, shz_vec2_t>)
1056 return shz_vec2_max(vec);
1057 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1058 return shz_vec3_max(vec);
1059 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1060 return shz_vec4_max(vec);
1061 else static_assert(false, "Incompatible type!");
1062 }
1063
1064 //! C++ type-generic vector minimum value.
1065 template<typename T>
1066 SHZ_FORCE_INLINE float shz_vec_min(T vec) SHZ_NOEXCEPT {
1067 if constexpr(std::convertible_to<T, shz_vec2_t>)
1068 return shz_vec2_min(vec);
1069 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1070 return shz_vec3_min(vec);
1071 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1072 return shz_vec4_min(vec);
1073 else static_assert(false, "Incompatible type!");
1074 }
1075
1076 //! C++ type-generic vector clamp.
1077 template<typename T>
1078 SHZ_FORCE_INLINE T shz_vec_clamp(T vec, float min, float max) SHZ_NOEXCEPT {
1079 if constexpr(std::convertible_to<T, shz_vec2_t>)
1080 return shz_vec2_clamp(vec, min, max);
1081 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1082 return shz_vec3_clamp(vec, min, max);
1083 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1084 return shz_vec4_clamp(vec, min, max);
1085 else static_assert(false, "Incompatible type!");
1086 }
1087
1088 //! C++ type-generic vector equal.
1089 template<typename T>
1090 SHZ_FORCE_INLINE bool shz_vec_equal(T vec1, T vec2) SHZ_NOEXCEPT {
1091 if constexpr(std::convertible_to<T, shz_vec2_t>)
1092 return shz_vec2_equal(vec1, vec2);
1093 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1094 return shz_vec3_equal(vec1, vec2);
1095 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1096 return shz_vec4_equal(vec1, vec2);
1097 else static_assert(false, "Incompatible type!");
1098 }
1099
1100 //! C++ type-generic vector addition.
1101 template<typename T>
1102 SHZ_FORCE_INLINE T shz_vec_add(T vec1, T vec2) SHZ_NOEXCEPT {
1103 if constexpr(std::convertible_to<T, shz_vec2_t>)
1104 return shz_vec2_add(vec1, vec2);
1105 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1106 return shz_vec3_add(vec1, vec2);
1107 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1108 return shz_vec4_add(vec1, vec2);
1109 else static_assert(false, "Incompatible type!");
1110 }
1111
1112 //! C++ type-generic vector subtraction.
1113 template<typename T>
1114 SHZ_FORCE_INLINE T shz_vec_sub(T vec1, T vec2) SHZ_NOEXCEPT {
1115 if constexpr(std::convertible_to<T, shz_vec2_t>)
1116 return shz_vec2_sub(vec1, vec2);
1117 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1118 return shz_vec3_sub(vec1, vec2);
1119 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1120 return shz_vec4_sub(vec1, vec2);
1121 else static_assert(false, "Incompatible type!");
1122 }
1123
1124 //! C++ type-generic multiplication of each vector component.
1125 template<typename T>
1126 SHZ_FORCE_INLINE T shz_vec_mul(T vec1, T vec2) SHZ_NOEXCEPT {
1127 if constexpr(std::convertible_to<T, shz_vec2_t>)
1128 return shz_vec2_mul(vec1, vec2);
1129 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1130 return shz_vec3_mul(vec1, vec2);
1131 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1132 return shz_vec4_mul(vec1, vec2);
1133 else static_assert(false, "Incompatible type!");
1134 }
1135
1136 //! C++ type-generic division of each vector component.
1137 template<typename T>
1138 SHZ_FORCE_INLINE T shz_vec_div(T vec1, T vec2) SHZ_NOEXCEPT {
1139 if constexpr(std::convertible_to<T, shz_vec2_t>)
1140 return shz_vec2_div(vec1, vec2);
1141 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1142 return shz_vec3_div(vec1, vec2);
1143 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1144 return shz_vec4_div(vec1, vec2);
1145 else static_assert(false, "Incompatible type!");
1146 }
1147
1148 //! C++ type-generic uniform scaling of each vector component.
1149 template<typename T>
1150 SHZ_FORCE_INLINE T shz_vec_scale(T vec, float factor) SHZ_NOEXCEPT {
1151 if constexpr(std::convertible_to<T, shz_vec2_t>)
1152 return shz_vec2_scale(vec, factor);
1153 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1154 return shz_vec3_scale(vec, factor);
1155 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1156 return shz_vec4_scale(vec, factor);
1157 else static_assert(false, "Incompatible type!");
1158 }
1159
1160 //! C++ type-generic vector dot product operation.
1161 template<typename T>
1162 SHZ_FORCE_INLINE float shz_vec_dot(T vec1, T vec2) SHZ_NOEXCEPT {
1163 if constexpr(std::convertible_to<T, shz_vec2_t>)
1164 return shz_vec2_dot(vec1, vec2);
1165 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1166 return shz_vec3_dot(vec1, vec2);
1167 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1168 return shz_vec4_dot(vec1, vec2);
1169 else static_assert(false, "Incompatible type!");
1170 }
1171
1172 //! C++ type-generic vector dot product operation.
1173 template<typename T>
1174 SHZ_FORCE_INLINE shz_vec2_t shz_vec_dot2(T l, T r1, T r2) SHZ_NOEXCEPT {
1175 if constexpr(std::convertible_to<T, shz_vec2_t>)
1176 return shz_vec2_dot2(l, r1, r2);
1177 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1178 return shz_vec3_dot2(l, r1, r2);
1179 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1180 return shz_vec4_dot2(l, r1, r2);
1181 else static_assert(false, "Incompatible type!");
1182 }
1183
1184 //! C++ type-generic vector dot product operation.
1185 template<typename T>
1186 SHZ_FORCE_INLINE shz_vec3_t shz_vec_dot3(T l, T r1, T r2, T r3) SHZ_NOEXCEPT {
1187 if constexpr(std::convertible_to<T, shz_vec2_t>)
1188 return shz_vec2_dot3(l, r1, r2, r3);
1189 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1190 return shz_vec3_dot3(l, r1, r2, r3);
1191 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1192 return shz_vec4_dot3(l, r1, r2, r3);
1193 else static_assert(false, "Incompatible type!");
1194 }
1195
1196 //! C++ type-generic squared magnitude of the given vector.
1197 SHZ_FORCE_INLINE float shz_vec_magnitude_sqr(auto vec) SHZ_NOEXCEPT {
1198 using T = decltype(vec);
1199 if constexpr(std::convertible_to<T, shz_vec2_t>)
1200 return shz_vec2_magnitude_sqr(vec);
1201 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1202 return shz_vec3_magnitude_sqr(vec);
1203 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1204 return shz_vec4_magnitude_sqr(vec);
1205 else static_assert(false, "Incompatible type!");
1206 }
1207
1208 //! C++ type-generic magnitude of the given vector.
1209 SHZ_FORCE_INLINE float shz_vec_magnitude(auto vec) SHZ_NOEXCEPT {
1210 using T = decltype(vec);
1211 if constexpr(std::convertible_to<T, shz_vec2_t>)
1212 return shz_vec2_magnitude(vec);
1213 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1214 return shz_vec3_magnitude(vec);
1215 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1216 return shz_vec4_magnitude(vec);
1217 else static_assert(false, "Incompatible type!");
1218 }
1219
1220 //! C++ type-generic inverse magnitude of the given vector.
1221 SHZ_FORCE_INLINE float shz_vec_magnitude_inv(auto vec) SHZ_NOEXCEPT {
1222 using T = decltype(vec);
1223 if constexpr(std::convertible_to<T, shz_vec2_t>)
1224 return shz_vec2_magnitude_inv(vec);
1225 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1226 return shz_vec3_magnitude_inv(vec);
1227 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1228 return shz_vec4_magnitude_inv(vec);
1229 else static_assert(false, "Incompatible type!");
1230 }
1231
1232 //! C++ type-generic vector normalization: returns normalized vector.
1233 template<typename T>
1234 SHZ_FORCE_INLINE T shz_vec_normalize(T vec) SHZ_NOEXCEPT {
1235 if constexpr(std::convertible_to<T, shz_vec2_t>)
1236 return shz_vec2_normalize(vec);
1237 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1238 return shz_vec3_normalize(vec);
1239 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1240 return shz_vec4_normalize(vec);
1241 else static_assert(false, "Incompatible type!");
1242 }
1243
1244 //! C++ type-generic safe vector normalization: returns normalized vector, avoids divide-by-zero.
1245 template<typename T>
1246 SHZ_FORCE_INLINE T shz_vec_normalize_safe(T vec) SHZ_NOEXCEPT {
1247 if constexpr(std::convertible_to<T, shz_vec2_t>)
1248 return shz_vec2_normalize_safe(vec);
1249 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1250 return shz_vec3_normalize_safe(vec);
1251 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1252 return shz_vec4_normalize_safe(vec);
1253 else static_assert(false, "Incompatible type!");
1254 }
1255
1256 //! C++ type-generic distance between two points.
1257 template<typename T>
1258 SHZ_FORCE_INLINE float shz_vec_distance(T vec1, T vec2) SHZ_NOEXCEPT {
1259 if constexpr(std::convertible_to<T, shz_vec2_t>)
1260 return shz_vec2_distance(vec1, vec2);
1261 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1262 return shz_vec3_distance(vec1, vec2);
1263 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1264 return shz_vec4_distance(vec1, vec2);
1265 else static_assert(false, "Incompatible type!");
1266 }
1267
1268 //! C++ type-generic square distance between two points.
1269 template<typename T>
1270 SHZ_FORCE_INLINE float shz_vec_distance_sqr(T vec1, T vec2) SHZ_NOEXCEPT {
1271 if constexpr(std::convertible_to<T, shz_vec2_t>)
1272 return shz_vec2_distance_sqr(vec1, vec2);
1273 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1274 return shz_vec3_distance_sqr(vec1, vec2);
1275 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1276 return shz_vec4_distance_sqr(vec1, vec2);
1277 else static_assert(false, "Incompatible type!");
1278 }
1279
1280 //! C++ type-generic moving of one vector to the position of another.
1281 template<typename T>
1282 SHZ_FORCE_INLINE T shz_vec_move(T vec, T target, float maxdist) SHZ_NOEXCEPT {
1283 if constexpr(std::convertible_to<T, shz_vec2_t>)
1284 return shz_vec2_move(vec, target, maxdist);
1285 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1286 return shz_vec3_move(vec, target, maxdist);
1287 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1288 return shz_vec4_move(vec, target, maxdist);
1289 else static_assert(false, "Incompatible type!");
1290 }
1291
1292 //! Returns the linear interpolation between the two given type-generic vectors.
1293 template<typename T>
1294 SHZ_FORCE_INLINE T shz_vec_lerp(T vec1, T vec2, float t) SHZ_NOEXCEPT {
1295 if constexpr(std::convertible_to<T, shz_vec2_t>)
1296 return shz_vec2_lerp(vec1, vec2, t);
1297 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1298 return shz_vec3_lerp(vec1, vec2, t);
1299 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1300 return shz_vec4_lerp(vec1, vec2, t);
1301 else static_assert(false, "Incompatible type!");
1302 }
1303
1304 //! Type-generic reflection of a vector over the given surface normal returned.
1305 template<typename T>
1306 SHZ_FORCE_INLINE T shz_vec_reflect(T incidence, T normal) SHZ_NOEXCEPT {
1307 if constexpr(std::convertible_to<T, shz_vec2_t>)
1308 return shz_vec2_reflect(incidence, normal);
1309 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1310 return shz_vec3_reflect(incidence, normal);
1311 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1312 return shz_vec4_reflect(incidence, normal);
1313 else static_assert(false, "Incompatible type!");
1314 }
1315
1316 //! Type-generic refraction of a vector over the given surface normal returned.
1317 template<typename T>
1318 SHZ_FORCE_INLINE T shz_vec_refract(T incidence, T normal, float eta) SHZ_NOEXCEPT {
1319 if constexpr(std::convertible_to<T, shz_vec2_t>)
1320 return shz_vec2_refract(incidence, normal, eta);
1321 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1322 return shz_vec3_refract(incidence, normal, eta);
1323 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1324 return shz_vec4_refract(incidence, normal, eta);
1325 else static_assert(false, "Incompatible type!");
1326 }
1327
1328 //! Type-generic cross product between the two given vectors returned.
1329 template<typename T>
1330 SHZ_FORCE_INLINE auto shz_vec_cross(T vec1, T vec2) SHZ_NOEXCEPT {
1331 if constexpr(std::convertible_to<T, shz_vec2_t>)
1332 return shz_vec2_cross(vec1, vec2);
1333 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1334 return shz_vec3_cross(vec1, vec2);
1335 else static_assert(false, "Incompatible type!");
1336 }
1337
1338 //! Type generic projection of the first vector onto the second vector returned.
1339 template<typename T>
1340 SHZ_FORCE_INLINE T shz_vec_project(T vec1, T vec2) SHZ_NOEXCEPT {
1341 if constexpr(std::convertible_to<T, shz_vec2_t>)
1342 return shz_vec2_project(vec1, vec2);
1343 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1344 return shz_vec3_project(vec1, vec2);
1345 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1346 return shz_vec4_project(vec1, vec2);
1347 else static_assert(false, "Incompatible type!");
1348 }
1349
1350 //! Type generic safe projection of \p vec1 onto \p vec2 returned, avoiding division-by-zero.
1351 template<typename T>
1352 SHZ_FORCE_INLINE T shz_vec_project_safe(T vec1, T vec2) SHZ_NOEXCEPT {
1353 if constexpr(std::convertible_to<T, shz_vec2_t>)
1354 return shz_vec2_project_safe(vec1, vec2);
1355 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1356 return shz_vec3_project_safe(vec1, vec2);
1357 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1358 return shz_vec4_project_safe(vec1, vec2);
1359 else static_assert(false, "Incompatible type!");
1360 }
1361
1362 //! Returns the angles formed by the given type-generic vector and the +X axis direction vector.
1363 SHZ_FORCE_INLINE auto shz_vec_angles(auto vec) SHZ_NOEXCEPT {
1364 using T = decltype(vec);
1365 if constexpr(std::convertible_to<T, shz_vec2_t>)
1366 return shz_vec2_angle(vec);
1367 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1368 return shz_vec3_angles(vec);
1369 else static_assert(false, "Incompatible type!");
1370 }
1371
1372 //! Returns the angles formed between the given two type-generic vectors.
1373 template<typename T>
1374 SHZ_FORCE_INLINE float shz_vec_angle_between(T vec1, T vec2) SHZ_NOEXCEPT {
1375 if constexpr(std::convertible_to<T, shz_vec2_t>)
1376 return shz_vec2_angle_between(vec1, vec2);
1377 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1378 return shz_vec3_angle_between(vec1, vec2);
1379 else static_assert(false, "Incompatible type!");
1380 }
1381
1382 //! Overloaded generic swizzle function for 2D vectors.
1383 SHZ_FORCE_INLINE shz_vec2_t shz_vec_swizzle(shz_vec2_t vec, unsigned x_idx, unsigned y_idx) SHZ_NOEXCEPT {
1384 return shz_vec2_swizzle(vec, x_idx, y_idx);
1385 }
1386
1387 //! Overloaded generic swizzle function for 3D vectors.
1388 SHZ_FORCE_INLINE shz_vec3_t shz_vec_swizzle(shz_vec3_t vec, unsigned x_idx, unsigned y_idx, unsigned z_idx) SHZ_NOEXCEPT {
1389 return shz_vec3_swizzle(vec, x_idx, y_idx, z_idx);
1390 }
1391
1392 //! Overloaded generic swizzle function for 3D vectors.
1393 SHZ_FORCE_INLINE shz_vec4_t shz_vec_swizzle(shz_vec4_t vec, unsigned x_idx, unsigned y_idx, unsigned z_idx, unsigned w_idx) SHZ_NOEXCEPT {
1394 return shz_vec4_swizzle(vec, x_idx, y_idx, z_idx, w_idx);
1395 }
1396
1397 //! C++ type-generic component-wise floor.
1398 template<typename T>
1399 SHZ_FORCE_INLINE T shz_vec_floor(T vec) SHZ_NOEXCEPT {
1400 if constexpr(std::convertible_to<T, shz_vec2_t>)
1401 return shz_vec2_floor(vec);
1402 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1403 return shz_vec3_floor(vec);
1404 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1405 return shz_vec4_floor(vec);
1406 else static_assert(false, "Incompatible type!");
1407 }
1408
1409 //! C++ type-generic component-wise ceil.
1410 template<typename T>
1411 SHZ_FORCE_INLINE T shz_vec_ceil(T vec) SHZ_NOEXCEPT {
1412 if constexpr(std::convertible_to<T, shz_vec2_t>)
1413 return shz_vec2_ceil(vec);
1414 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1415 return shz_vec3_ceil(vec);
1416 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1417 return shz_vec4_ceil(vec);
1418 else static_assert(false, "Incompatible type!");
1419 }
1420
1421 //! C++ type-generic component-wise round.
1422 template<typename T>
1423 SHZ_FORCE_INLINE T shz_vec_round(T vec) SHZ_NOEXCEPT {
1424 if constexpr(std::convertible_to<T, shz_vec2_t>)
1425 return shz_vec2_round(vec);
1426 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1427 return shz_vec3_round(vec);
1428 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1429 return shz_vec4_round(vec);
1430 else static_assert(false, "Incompatible type!");
1431 }
1432
1433 //! C++ type-generic component-wise fract.
1434 template<typename T>
1435 SHZ_FORCE_INLINE T shz_vec_fract(T vec) SHZ_NOEXCEPT {
1436 if constexpr(std::convertible_to<T, shz_vec2_t>)
1437 return shz_vec2_fract(vec);
1438 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1439 return shz_vec3_fract(vec);
1440 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1441 return shz_vec4_fract(vec);
1442 else static_assert(false, "Incompatible type!");
1443 }
1444
1445 //! C++ type-generic component-wise sign.
1446 template<typename T>
1447 SHZ_FORCE_INLINE T shz_vec_sign(T vec) SHZ_NOEXCEPT {
1448 if constexpr(std::convertible_to<T, shz_vec2_t>)
1449 return shz_vec2_sign(vec);
1450 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1451 return shz_vec3_sign(vec);
1452 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1453 return shz_vec4_sign(vec);
1454 else static_assert(false, "Incompatible type!");
1455 }
1456
1457 //! C++ type-generic component-wise saturate.
1458 template<typename T>
1459 SHZ_FORCE_INLINE T shz_vec_saturate(T vec) SHZ_NOEXCEPT {
1460 if constexpr(std::convertible_to<T, shz_vec2_t>)
1461 return shz_vec2_saturate(vec);
1462 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1463 return shz_vec3_saturate(vec);
1464 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1465 return shz_vec4_saturate(vec);
1466 else static_assert(false, "Incompatible type!");
1467 }
1468
1469 //! C++ type-generic pairwise minimum.
1470 template<typename T>
1471 SHZ_FORCE_INLINE T shz_vec_minv(T a, T b) SHZ_NOEXCEPT {
1472 if constexpr(std::convertible_to<T, shz_vec2_t>)
1473 return shz_vec2_minv(a, b);
1474 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1475 return shz_vec3_minv(a, b);
1476 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1477 return shz_vec4_minv(a, b);
1478 else static_assert(false, "Incompatible type!");
1479 }
1480
1481 //! C++ type-generic pairwise maximum.
1482 template<typename T>
1483 SHZ_FORCE_INLINE T shz_vec_maxv(T a, T b) SHZ_NOEXCEPT {
1484 if constexpr(std::convertible_to<T, shz_vec2_t>)
1485 return shz_vec2_maxv(a, b);
1486 else if constexpr(std::convertible_to<T, shz_vec3_t>)
1487 return shz_vec3_maxv(a, b);
1488 else if constexpr(std::convertible_to<T, shz_vec4_t>)
1489 return shz_vec4_maxv(a, b);
1490 else static_assert(false, "Incompatible type!");
1491 }
1492
1493 //! Compares each component of the vector to the edge. 0 returned in that component if x[i] < edge. Otherwise the component is 1.
1494 template<typename V, typename T>
1495 SHZ_FORCE_INLINE V shz_vec_step(V vec, T edge) SHZ_NOEXCEPT {
1496 constexpr bool scalar = std::is_same_v<T, float>;
1497 constexpr bool vector = std::is_same_v<T, V>;
1498
1499 static_assert(scalar || vector, "Incompatible type!");
1500
1501 if constexpr(std::convertible_to<V, shz_vec2_t>) {
1502 if constexpr(scalar)
1503 return shz_vec2_step(vec, edge);
1504 else
1505 return shz_vec2_stepv(vec, edge);
1506 } else if constexpr(std::convertible_to<V, shz_vec3_t>) {
1507 if constexpr(scalar)
1508 return shz_vec3_step(vec, edge);
1509 else
1510 return shz_vec3_stepv(vec, edge);
1511 } else if constexpr(std::convertible_to<V, shz_vec4_t>) {
1512 if constexpr(scalar)
1513 return shz_vec4_step(vec, edge);
1514 else
1515 return shz_vec4_stepv(vec, edge);
1516 } else static_assert(false, "Incompatible type!");
1517 }
1518
1519 //! Returns 0.0f at/below edge0, 1.0f at/above edge1, smoothly varying in-between. Undefined for \p edge0 > \p edge1
1520 template<typename V, typename T>
1521 SHZ_FORCE_INLINE V shz_vec_smoothstep(V vec, T edge0, T edge1) SHZ_NOEXCEPT {
1522 constexpr bool scalar = std::is_same_v<T, float>;
1523 constexpr bool vector = std::is_same_v<T, V>;
1524
1525 static_assert(scalar || vector, "Incompatible type!");
1526
1527 if constexpr (std::convertible_to<V, shz_vec2_t>) {
1528 if constexpr (scalar)
1529 return shz_vec2_smoothstep(vec, edge0, edge1);
1530 else
1531 return shz_vec2_smoothstepv(vec, edge0, edge1);
1532 } else if constexpr (std::convertible_to<V, shz_vec3_t>) {
1533 if constexpr (scalar)
1534 return shz_vec3_smoothstep(vec, edge0, edge1);
1535 else
1536 return shz_vec3_smoothstepv(vec, edge0, edge1);
1537 } else if constexpr (std::convertible_to<V, shz_vec4_t>) {
1538 if constexpr (scalar)
1539 return shz_vec4_smoothstep(vec, edge0, edge1);
1540 else
1541 return shz_vec4_smoothstepv(vec, edge0, edge1);
1542 } else static_assert(false, "Incompatible type!");
1543 }
1544
1545 //! Returns 0.0f at/below edge0, 1.0f at/above edge1, smoothly varying in-between. Accepts inverse edges.
1546 template<typename V, typename T>
1547 SHZ_FORCE_INLINE V shz_vec_smoothstep_safe(V vec, T edge0, T edge1) SHZ_NOEXCEPT {
1548 constexpr bool scalar = std::is_same_v<T, float>;
1549 constexpr bool vector = std::is_same_v<T, V>;
1550
1551 static_assert(scalar || vector, "Incompatible type!");
1552
1553 if constexpr (std::convertible_to<V, shz_vec2_t>) {
1554 if constexpr (scalar)
1555 return shz_vec2_smoothstep_safe(vec, edge0, edge1);
1556 else
1557 return shz_vec2_smoothstepv_safe(vec, edge0, edge1);
1558 } else if constexpr (std::convertible_to<V, shz_vec3_t>) {
1559 if constexpr (scalar)
1560 return shz_vec3_smoothstep_safe(vec, edge0, edge1);
1561 else
1562 return shz_vec3_smoothstepv_safe(vec, edge0, edge1);
1563 } else if constexpr (std::convertible_to<V, shz_vec4_t>) {
1564 if constexpr (scalar)
1565 return shz_vec4_smoothstep_safe(vec, edge0, edge1);
1566 else
1567 return shz_vec4_smoothstepv_safe(vec, edge0, edge1);
1568 } else static_assert(false, "Incompatible type!");
1569 }
1570
1571#endif
1572
1573#include "inline/shz_vector.inl.h"
1574
1575//! @}
1576
1577#endif // SHZ_VECTOR_H
float shz_vec3_magnitude(shz_vec3_t vec) SHZ_NOEXCEPT
Returns the magnitude of the given 3D vector.
shz_vec4_t shz_vec4_sign(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a 4D vector whose components are the signs (-1, 0, or 1) of the given vector's components.
shz_vec3_t shz_vec3_mul(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns a 3D vector whose component values are those of vec1 times vec2.
shz_vec4_t shz_vec4_minv(shz_vec4_t a, shz_vec4_t b) SHZ_NOEXCEPT
Returns a 4D vector whose components are the pairwise minimums of the two given vectors' components.
shz_vec3_t shz_vec3_project_safe(shz_vec3_t vec, shz_vec3_t onto) SHZ_NOEXCEPT
Returns the resulting vector from projecting the given 3D vector along the given (unit) axis.
shz_vec4_t shz_vec4_sub(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT
Returns a 4D vector whose components are equal to the values of vec1 minus vec2.
bool shz_vec4_equal(shz_vec4_t a, shz_vec4_t b) SHZ_NOEXCEPT
Returns true if the values of each element within the two 4D vectors are approximately equal based on...
shz_vec3_t shz_vec3_angles(shz_vec3_t vec) SHZ_NOEXCEPT
Returns the angles formed between the positive X axis and the given 3D vector, in radians.
shz_vec3_t shz_vec3_smoothstep(shz_vec3_t vec, float edge0, float edge1) SHZ_NOEXCEPT
For each component: returns 0.0f at/below edge0, 1.0f at/above edge1, smoothly varying in-between.
shz_vec2_t shz_vec2_saturate(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a 2D vector whose components are saturated (clamped to [0, 1]) values of the given vector's c...
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_vec3_t shz_vec2_vec3(shz_vec2_t vec, float z) SHZ_NOEXCEPT
Extends a 2D vector to 3D, using z as the value of the Z component.
shz_vec3_t shz_vec3_cross(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns the vector produced by taking the cross-product of the two given 3D vectors.
shz_vec2_t shz_vec2_div(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns a 2D vector whose component values are those of vec1 divided by vec2.
float shz_vec3_dot(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns the dot product between the two given 3D vectors.
shz_vec4_t shz_vec4_init(float x, float y, float z, float w) SHZ_NOEXCEPT
Returns a 4D vector with the given x, y, z, and w coordinates.
shz_vec3_t shz_vec3
Alternate typedef for the shz_vec3 struct for those who hate POSIX-style.
Definition shz_vector.h:74
shz_vec3_t shz_vec3_saturate(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a 3D vector whose components are saturated (clamped to [0, 1]) values of the given vector's c...
shz_vec3_t shz_vec3_sub(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns a 3D vector whose components are equal to the values of vec1 minus vec2.
shz_vec2_t shz_vec2_smoothstepv(shz_vec2_t vec, shz_vec2_t edge0, shz_vec2_t edge1) SHZ_NOEXCEPT
For each component: returns 0.0f at/below edge0[i], 1.0f at/above edge1[i], smoothly varying in-betwe...
float shz_vec3_magnitude_sqr(shz_vec3_t vec) SHZ_NOEXCEPT
Returns the squared magnitude of the given 3D vector.
shz_vec4_t shz_vec4_floor(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a 4D vector whose components are the floor of the given vector's components.
shz_vec2_t shz_vec2_abs(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a 2D vector whose components are the absolute values of the given vector's components.
float shz_vec2_min(shz_vec2_t vec) SHZ_NOEXCEPT
Retuns the minimum value of both of the given vector's components.
float shz_vec4_min(shz_vec4_t vec) SHZ_NOEXCEPT
Returns the minimum value of the given vector's 4 components.
shz_vec2_t shz_vec2_normalize_safe(shz_vec2_t vec) SHZ_NOEXCEPT
SAFELY returns a normalized unit vector from the given 2D vector.
shz_vec3_t shz_vec3_fill(float v) SHZ_NOEXCEPT
Returns a 3D vector with the value of each compoonent equal to v.
shz_vec2_t shz_vec4_dot2(shz_vec4_t l, shz_vec4_t r1, shz_vec4_t r2) SHZ_NOEXCEPT
Returns the two dot products taken between the 4D vector l and 4D vectors r1 and r2.
shz_vec2_t shz_vec2_add(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns a 2D vector whose components are the sums of the given vectors' components.
shz_vec4_t shz_vec4_round(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a 4D vector whose components are the rounded values of the given vector's components.
shz_vec3_t shz_vec3_dot3(shz_vec3_t l, shz_vec3_t r1, shz_vec3_t r2, shz_vec3_t r3) SHZ_NOEXCEPT
Returns the three dot products taken between the 3D vector l and 3D vectors r1, r2,...
shz_vec4_t shz_vec4_stepv(shz_vec4_t vec, shz_vec4_t edge) SHZ_NOEXCEPT
For each component: returns 0.0f if vec[i] < edge[i], otherwise 1.0f.
shz_vec2_t shz_vec3_dot2(shz_vec3_t l, shz_vec3_t r1, shz_vec3_t r2) SHZ_NOEXCEPT
Returns the two dot products taken between the 3D vector l and 3D vectors r1 and r2.
shz_vec2_t shz_vec2_rotate(shz_vec2_t vec, float radians) SHZ_NOEXCEPT
Rotates the given 2D vector about the Z axis by the given angle in radians.
shz_vec4_t shz_vec4_maxv(shz_vec4_t a, shz_vec4_t b) SHZ_NOEXCEPT
Returns a 4D vector whose components are the pairwise maximums of the two given vectors' components.
shz_vec3_t shz_vec3_normalize_safe(shz_vec3_t vec) SHZ_NOEXCEPT
SAFELY returns a normalized unit vector from the given 3D vector.
shz_vec4_t shz_vec4_swizzle(shz_vec4_t vec, unsigned x_idx, unsigned y_idx, unsigned z_idx, unsigned w_idx) SHZ_NOEXCEPT
Returns a new 2D vector whose elements are equal to the source vector's values at the given indices.
float shz_vec3_distance_sqr(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns the squared-distance between the two given 3D vectors.
shz_vec4_t shz_vec4_smoothstepv(shz_vec4_t vec, shz_vec4_t edge0, shz_vec4_t edge1) SHZ_NOEXCEPT
For each component i: returns 0.0f at/below edge0[i], 1.0f at/above edge1[i], smoothly varying in-bet...
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_vec4_t shz_vec4_smoothstep(shz_vec4_t vec, float edge0, float edge1) SHZ_NOEXCEPT
For each component: returns 0.0f at/below edge0, 1.0f at/above edge1, smoothly varying in-between.
shz_vec3_t shz_vec3_round(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a 3D vector whose components are the rounded values of the given vector's components.
float shz_vec4_max(shz_vec4_t vec) SHZ_NOEXCEPT
Returns the maximum value of the given vector's 4 componetns.
shz_vec2_t shz_vec2_neg(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a 2D vector whose components are the negative values of the given vector's components.
shz_vec3_t shz_vec4_dot3(shz_vec4_t l, shz_vec4_t r1, shz_vec4_t r2, shz_vec4_t r3) SHZ_NOEXCEPT
Returns the three dot products taken between the 4D vector l and 4D vectors r1, r2,...
shz_vec4_t shz_vec4_refract(shz_vec4_t incidence, shz_vec4_t normal, float eta) SHZ_NOEXCEPT
Refracts the given 4D incidence vector against a surface with the given normal using the given refrac...
float shz_vec3_distance(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns the distance between the two given 3D vectors.
float shz_vec4_magnitude(shz_vec4_t vec) SHZ_NOEXCEPT
Returns the magnitude of the given 4D vector.
shz_vec2_t shz_vec2_from_sincos(shz_sincos_t sincos) SHZ_NOEXCEPT
Returns the 2D unit vector representing a rotation from the positive X axis.
shz_vec4_t shz_vec4_mul(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT
Returns a 4D vector whose component values are those of vec1 times vec2.
shz_vec3_t shz_vec3_floor(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a 3D vector whose components are the floor of the given vector's components.
shz_vec3_t shz_vec3_neg(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a 3D vector whose components are the negative values of the given vector's components.
shz_vec3_t shz_vec3_normalize(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a normalized unit vector from the given 3D vector.
float shz_vec4_dot(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT
Returns the dot product between the two given 4D vectors.
shz_vec3_t shz_vec3_maxv(shz_vec3_t a, shz_vec3_t b) SHZ_NOEXCEPT
Returns a 3D vector whose components are the pairwise maximums of the two given vectors' components.
shz_vec4_t shz_vec4_step(shz_vec4_t vec, float edge) SHZ_NOEXCEPT
For each component: returns 0.0f if vec[i] < edge, otherwise 1.0f.
shz_vec3_t shz_vec3_swizzle(shz_vec3_t vec, unsigned x_idx, unsigned y_idx, unsigned z_idx) SHZ_NOEXCEPT
Returns a 3D vector whose elements are equal to the source vector's values at the given indices.
float shz_vec4_distance(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT
Returns the distance between the two given 4D vectors.
shz_vec4_t shz_vec4_abs(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a 4D vector whose components are the absolute values of the given vector's components.
shz_vec2_t shz_vec2_scale(shz_vec2_t vec, float factor) SHZ_NOEXCEPT
Returns a 2D vector whose component values are those of the given vector multiplied by a factor.
float shz_vec2_angle(shz_vec2_t vec) SHZ_NOEXCEPT
Returns the angle formed between the positive X axis and the given 2D vector, in radians.
float shz_vec2_max(shz_vec2_t vec) SHZ_NOEXCEPT
Returns the maximum value of both of the given vector's components.
shz_vec4_t shz_vec4_normalize_safe(shz_vec4_t vec) SHZ_NOEXCEPT
SAFELY returns a normalized unit vector from the given 4D vector.
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_vec2_t shz_vec2_round(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a 2D vector whose components are the rounded values of the given vector's components.
shz_vec3_t shz_vec3_add(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns a 3D vector whose components are the sums of the given vectors' components.
shz_vec3_t shz_vec3_smoothstepv(shz_vec3_t vec, shz_vec3_t edge0, shz_vec3_t edge1) SHZ_NOEXCEPT
For each component i: returns 0.0f at/below edge0[i], 1.0f at/above edge1[i], smoothly varying in-bet...
shz_vec2_t shz_vec2_fract(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a 2D vector whose components are the fractional parts of the given vector's components.
shz_vec2_t shz_vec2_maxv(shz_vec2_t a, shz_vec2_t b) SHZ_NOEXCEPT
Returns a 2D vector whose components are the pairwise maximums of the two given vectors' components.
shz_vec2_t shz_vec2_move(shz_vec2_t vec, shz_vec2_t target, float max_distance) SHZ_NOEXCEPT
Returns the given 2D vector, translated towards the target by the given max_distance.
shz_vec2_t shz_vec2_inv(shz_vec2_t vec) SHZ_NOEXCEPT
Returns the 4D vector whose components have been inverted or reciprocated.
shz_vec4_t shz_vec4_inv(shz_vec4_t vec) SHZ_NOEXCEPT
Returns the 4D vector whose components have been inverted or reciprocated.
shz_vec3_t shz_vec3_barycenter(shz_vec3_t p, shz_vec3_t a, shz_vec3_t b, shz_vec3_t c) SHZ_NOEXCEPT
Computes barycentric coordinates <u, v, w> for point p, within the plane of the triangle with vertice...
shz_vec2_t shz_vec2_clamp(shz_vec2_t vec, float min, float max) SHZ_NOEXCEPT
Clamps the values of the given 2D vec between min and max, returning a new vector.
shz_vec4_t shz_vec4_saturate(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a 4D vector whose components are saturated (clamped to [0, 1]) values of the given vector's c...
shz_vec2_t shz_vec2_step(shz_vec2_t vec, float edge) SHZ_NOEXCEPT
For each component: returns 0.0f if vec[i] < edge, otherwise 1.0f.
shz_vec2_t shz_vec2_floor(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a 2D vector whose components are the floor of the given vector's components.
float shz_vec2_angle_between(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns the angle formed between the given 2D vectors in radians.
shz_vec4_t shz_vec4_div(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT
Returns a 4D vector whose component values are those of vec1 divided by vec2.
shz_vec2_t shz_vec2_project_safe(shz_vec2_t vec, shz_vec2_t onto) SHZ_NOEXCEPT
Returns the resulting vector from projecting the given 2D vector along the given (unit) axis.
shz_vec2_t shz_vec2_normalize(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a normalized unit vector from the given 2D vector.
shz_vec4_t shz_vec4_lerp(shz_vec4_t a, shz_vec4_t b, float t) SHZ_NOEXCEPT
Returns a 4D vector that is linearly interpolated from a to b by the given 0.0f-1....
shz_vec4_t shz_vec4_project_safe(shz_vec4_t vec, shz_vec4_t onto) SHZ_NOEXCEPT
Returns the resulting vector from projecting the given 4D vector along the given (unit) axis.
shz_vec4_t shz_vec4_move(shz_vec4_t vec, shz_vec4_t target, float max_distance) SHZ_NOEXCEPT
Returns the given 4D vector, translated towards the target by the given max_distance.
shz_vec4_t shz_vec4_fract(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a 4D vector whose components are the fractional parts of the given vector's components.
shz_vec2_t shz_vec2_fill(float v) SHZ_NOEXCEPT
Returns a 2D vector with the value of each component equal to v.
float shz_vec3_magnitude_inv(shz_vec3_t vec) SHZ_NOEXCEPT
Returns the inverse magnitude of the given 3D vector.
float shz_vec3_triple(shz_vec3_t a, shz_vec3_t b, shz_vec3_t c) SHZ_NOEXCEPT
Returns the 3D vector "triple product" between vector's a, b, and c.
shz_vec3_t shz_vec3_init(float x, float y, float z) SHZ_NOEXCEPT
Returns a 3D vector with the given x, y, and z coordinates.
float shz_vec3_min(shz_vec3_t vec) SHZ_NOEXCEPT
Returns the minimum value of the given vector's 3 components.
bool shz_vec2_equal(shz_vec2_t a, shz_vec2_t b) SHZ_NOEXCEPT
Returns true if the values of each element within the two 2D vectors are approximately equal based on...
shz_vec4_t shz_vec4_reflect(shz_vec4_t incidence, shz_vec4_t normal) SHZ_NOEXCEPT
Reflects the given 4D incidence vector against a surface with the given normal, returning the result.
void shz_vec3_orthonormalize(shz_vec3_t in1, shz_vec3_t in2, shz_vec3_t *out1, shz_vec3_t *out2) SHZ_NOEXCEPT
Returns 2 3D vectors which are normalized and orthogonal to the two input vectors.
float shz_vec2_magnitude_inv(shz_vec2_t vec) SHZ_NOEXCEPT
Returns the inverse magnitude of the given 2D vector.
float shz_vec4_magnitude_sqr(shz_vec4_t vec) SHZ_NOEXCEPT
Returns the squared magnitude of the given 4D vector.
shz_vec3_t shz_vec3_lerp(shz_vec3_t a, shz_vec3_t b, float t) SHZ_NOEXCEPT
Returns a 3D vector that is linearly interpolated from a to b by the given 0.0f-1....
float shz_vec2_distance(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns the distance between the two given 2D vectors.
shz_vec3_t shz_vec2_dot3(shz_vec2_t l, shz_vec2_t r1, shz_vec2_t r2, shz_vec2_t r3) SHZ_NOEXCEPT
Returns the three dot products taken between the 2D vector l and 2D vectors r1, r2,...
shz_vec3_t shz_vec3_from_sincos(shz_sincos_t azimuth, shz_sincos_t elevation) SHZ_NOEXCEPT
Returns the 3D unit vector representing the given rotation angles relative to the positive X axis.
shz_vec2_t shz_vec2_minv(shz_vec2_t a, shz_vec2_t b) SHZ_NOEXCEPT
Returns a 2D vector whose components are the pairwise minimums of the two given vectors' components.
shz_vec3_t shz_vec3_stepv(shz_vec3_t vec, shz_vec3_t edge) SHZ_NOEXCEPT
For each component: returns 0.0f if vec[i] < edge[i], otherwise 1.0f.
shz_vec3_t shz_vec3_ceil(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a 3D vector whose components are the ceil of the given vector's components.
bool shz_vec3_equal(shz_vec3_t a, shz_vec3_t b) SHZ_NOEXCEPT
Returns true if the values of each element within the two 3D vectors are approximately equal based on...
shz_vec2_t shz_vec2_reflect(shz_vec2_t incidence, shz_vec2_t normal) SHZ_NOEXCEPT
Reflects the given 2D incidence vector against a surface with the given normal, returning the result.
shz_vec3_t shz_vec3_sign(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a 3D vector whose components are the signs (-1, 0, or 1) of the given vector's components.
shz_vec3_t shz_vec3_step(shz_vec3_t vec, float edge) SHZ_NOEXCEPT
For each component: returns 0.0f if vec[i] < edge, otherwise 1.0f.
float shz_vec2_cross(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns the cross product, as a scalar, between two 2D vectors.
float shz_vec4_distance_sqr(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT
Returns the squared-distance between the two given 4D vectors.
shz_vec4_t shz_vec4_fill(float v) SHZ_NOEXCEPT
Returns a 4D vector with the value of each component equal to v.
shz_vec2_t shz_vec2_lerp(shz_vec2_t a, shz_vec2_t b, float t) SHZ_NOEXCEPT
Returns a 2D vector that is linearly interpolated from a to b by the given 0.0f-1....
shz_vec3_t shz_vec3_perp(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a vector which is perpendicular to the given vector.
shz_vec4_t shz_vec4_scale(shz_vec4_t vec, float factor) SHZ_NOEXCEPT
Returns a 4D vector whose component values are those of the given vector multiplied by a factor.
shz_vec3_t shz_vec3_project(shz_vec3_t vec, shz_vec3_t onto) SHZ_NOEXCEPT
Returns the resulting vector from projecting the given 3D vector along the given (unit) axis.
shz_vec4_t shz_vec2_vec4(shz_vec2_t vec, float z, float w) SHZ_NOEXCEPT
Extends a 2D vector to 4D, using z and w as the values of the Z and W components.
shz_vec2_t shz_vec2_stepv(shz_vec2_t vec, shz_vec2_t edge) SHZ_NOEXCEPT
For each component: returns 0.0f if vec[i] < edge[i], otherwise 1.0f.
shz_vec3_t shz_vec3_reject(shz_vec3_t vec, shz_vec3_t onto) SHZ_NOEXCEPT
Returns the rejection of the given vector, vec, onto another vector, onto.
shz_vec4_t shz_vec4_project(shz_vec4_t vec, shz_vec4_t onto) SHZ_NOEXCEPT
Returns the resulting vector from projecting the given 4D vector along the given (unit) axis.
float shz_vec4_magnitude_inv(shz_vec4_t vec) SHZ_NOEXCEPT
Returns the inverse magnitude of the given 4D vector.
shz_vec3_t shz_vec3_scale(shz_vec3_t vec, float factor) SHZ_NOEXCEPT
Returns a 3D vector whose component values are those of the given vector multiplied by a factor.
shz_vec4_t shz_vec3_vec4(shz_vec3_t vec, float w) SHZ_NOEXCEPT
Extends a 3D vector to 4D, using w as the value of the W component.
shz_vec2_t shz_vec2_mul(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns a 2D vector whose component values are those of vec1 times vec2.
float shz_vec2_distance_sqr(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns the squared-distance between the two given 2D vectors.
shz_vec3_t shz_vec3_move(shz_vec3_t vec, shz_vec3_t target, float max_distance) SHZ_NOEXCEPT
Returns the given 3D vector, translated towards the target by the given max_distance.
shz_vec3_t shz_vec3_refract(shz_vec3_t incidence, shz_vec3_t normal, float eta) SHZ_NOEXCEPT
Refracts the given 3D incidence vector against a surface with the given normal using the given refrac...
shz_vec4_t shz_vec4_neg(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a 4D vector whose components are the negative values of the given vector's components.
shz_vec2_t shz_vec2_swizzle(shz_vec2_t vec, unsigned x_idx, unsigned y_idx) SHZ_NOEXCEPT
Returns a 2D vector whose elements are equal to the source vector's values at the given indices.
float shz_vec3_angle_between(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns the angle formed between the given 3D vectors in radians.
shz_vec3_t shz_vec3_inv(shz_vec3_t vec) SHZ_NOEXCEPT
Returns the 4D vector whose components have been inverted or reciprocated.
shz_vec3_t shz_vec3_reflect(shz_vec3_t incidence, shz_vec3_t normal) SHZ_NOEXCEPT
Reflects the given 3D incidence vector against a surface with the given normal, returning the result.
shz_vec2_t shz_vec2_refract(shz_vec2_t incidence, shz_vec2_t normal, float eta) SHZ_NOEXCEPT
Refracts the given 2D incidence vector against a surface with the given normal using the given refrac...
shz_vec2_t shz_vec2
Alternate typedef for the shz_vec2 struct for those who hate POSIX-style.
Definition shz_vector.h:49
shz_vec3_t shz_vec3_abs(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a 3D vector whose components are the absolute values of the given vector's components.
float shz_vec2_magnitude(shz_vec2_t vec) SHZ_NOEXCEPT
Returns the magnitude of the given 2D vector.
shz_vec3_t shz_vec3_cubic_hermite(shz_vec3_t vec, shz_vec3_t tangent1, shz_vec3_t vec2, shz_vec3_t tangent2, float amounht) SHZ_NOEXCEPT
Calculates the cubic hermite interpolation between two vectors and their tangents.
float shz_vec2_dot(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns the dot product between the two given 2D vectors.
float shz_vec3_max(shz_vec3_t vec) SHZ_NOEXCEPT
Returns the maximum value of the given vector's 3 components.
shz_vec4_t shz_vec4_normalize(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a normalized unit vector from the given 4D vector.
shz_vec2_t shz_vec2_ceil(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a 2D vector whose components are the ceil of the given vector's components.
shz_vec3_t shz_vec3_clamp(shz_vec3_t vec, float min, float max) SHZ_NOEXCEPT
Clamps the values of the given 3D vec between min and max, returning a new vector.
shz_vec3_t shz_vec3_div(shz_vec3_t vec1, shz_vec3_t vec2) SHZ_NOEXCEPT
Returns a 3D vector whose component values are those of vec1 divided by vec2.
shz_vec3_t shz_vec3_minv(shz_vec3_t a, shz_vec3_t b) SHZ_NOEXCEPT
Returns a 3D vector whose components are the pairwise minimums of the two given vectors' components.
shz_vec2_t shz_vec2_dot2(shz_vec2_t l, shz_vec2_t r1, shz_vec2_t r2) SHZ_NOEXCEPT
Returns the two dot products taken between the 2D vector l and 2D vectors r1 and r2.
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 ...
shz_vec4_t shz_vec4
Alternate typedef for the shz_vec4 struct for those who hate POSIX-style.
Definition shz_vector.h:105
shz_vec2_t shz_vec2_sign(shz_vec2_t vec) SHZ_NOEXCEPT
Returns a 2D vector whose components are the signs (-1, 0, or 1) of the given vector's components.
shz_vec4_t shz_vec4_ceil(shz_vec4_t vec) SHZ_NOEXCEPT
Returns a 4D vector whose components are the ceil of the given vector's components.
shz_vec2_t shz_vec2_sub(shz_vec2_t vec1, shz_vec2_t vec2) SHZ_NOEXCEPT
Returns a 2D vector whose components are equal to the values of vec1 minus vec2.
shz_vec3_t shz_vec3_fract(shz_vec3_t vec) SHZ_NOEXCEPT
Returns a 3D vector whose components are the fractional parts of the given vector's components.
shz_vec2_t shz_vec2_smoothstep(shz_vec2_t vec, float edge0, float edge1) SHZ_NOEXCEPT
For each component: returns 0.0f at/below edge0, 1.0f at/above edge1, smoothly varying in-between.
float shz_vec2_magnitude_sqr(shz_vec2_t vec) SHZ_NOEXCEPT
Returns the squared magnitude of the given 2D vector.
shz_vec2_t shz_vec2_init(float x, float y) SHZ_NOEXCEPT
Returns a 2D vector with the given x, and y coordinates.
shz_vec2_t shz_vec2_project(shz_vec2_t vec, shz_vec2_t onto) SHZ_NOEXCEPT
Returns the resulting vector from projecting the given 2D vector along the given (unit) axis.
shz_vec4_t shz_vec4_add(shz_vec4_t vec1, shz_vec4_t vec2) SHZ_NOEXCEPT
Returns a 4D vector whose components are the sums of the given vectors' components.
shz_vec4_t shz_vec4_clamp(shz_vec4_t vec, float min, float max) SHZ_NOEXCEPT
Clamps the values of the given 4D vec between min and max, returning a new vector.
2D Vector type
Definition shz_vector.h:38
float x
X coordinate.
Definition shz_vector.h:42
float y
Y coordinate.
Definition shz_vector.h:43
float e[2]
<X, Y> coordinates as an array
Definition shz_vector.h:40
3D Vector type
Definition shz_vector.h:57
float y
Y coordinate.
Definition shz_vector.h:64
shz_vec2_t xy
Inner 2D vector containing <X, Y> coords.
Definition shz_vector.h:66
float x
X coordinate.
Definition shz_vector.h:63
float e[3]
<X, Y, Z> coordinates as an array
Definition shz_vector.h:59
float z
Z coordinate.
Definition shz_vector.h:68
4D Vector type
Definition shz_vector.h:82
float z
Z coordinate.
Definition shz_vector.h:90
shz_vec2_t xy
<X, Y> coordinates as a 2D vector
Definition shz_vector.h:97
float w
W coordinate.
Definition shz_vector.h:94
float x
X coordinate.
Definition shz_vector.h:88
float e[4]
<X, Y, Z, W> coordinates as an array.
Definition shz_vector.h:84
float y
Y coordinate.
Definition shz_vector.h:89
shz_vec3_t xyz
<X, Y, Z> coordinates as a 3D vector
Definition shz_vector.h:92
shz_vec2_t zw
<Z, W> coordinates as a 2D vector
Definition shz_vector.h:98