summaryrefslogtreecommitdiff
path: root/include/cglm/struct/vec3.h
diff options
context:
space:
mode:
authorAaditya Dhruv <[email protected]>2026-01-25 15:10:37 -0600
committerAaditya Dhruv <[email protected]>2026-01-25 15:10:37 -0600
commit118980e02e59ff31871df59dce257075394f3533 (patch)
tree26fba4492bb4b561d21bf49b35d892a821d54fab /include/cglm/struct/vec3.h
parent0e6e1245b70df4dfcba135d50e1b53d1a8ef7eb8 (diff)
wip
Diffstat (limited to 'include/cglm/struct/vec3.h')
-rw-r--r--include/cglm/struct/vec3.h1132
1 files changed, 1132 insertions, 0 deletions
diff --git a/include/cglm/struct/vec3.h b/include/cglm/struct/vec3.h
new file mode 100644
index 0000000..a1d901e
--- /dev/null
+++ b/include/cglm/struct/vec3.h
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+/*
+ Macros:
+ GLMS_VEC3_ONE_INIT
+ GLMS_VEC3_ZERO_INIT
+ GLMS_VEC3_ONE
+ GLMS_VEC3_ZERO
+ GLMS_YUP
+ GLMS_ZUP
+ GLMS_XUP
+
+ Functions:
+ CGLM_INLINE vec3s glms_vec3(vec4s v4);
+ CGLM_INLINE void glms_vec3_pack(vec3s dst[], vec3 src[], size_t len);
+ CGLM_INLINE void glms_vec3_unpack(vec3 dst[], vec3s src[], size_t len);
+ CGLM_INLINE vec3s glms_vec3_zero(void);
+ CGLM_INLINE vec3s glms_vec3_one(void);
+ CGLM_INLINE float glms_vec3_dot(vec3s a, vec3s b);
+ CGLM_INLINE float glms_vec3_norm2(vec3s v);
+ CGLM_INLINE float glms_vec3_norm(vec3s v);
+ CGLM_INLINE float glms_vec3_norm_one(vec3s v);
+ CGLM_INLINE float glms_vec3_norm_inf(vec3s v);
+ CGLM_INLINE vec3s glms_vec3_add(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_adds(vec3s a, float s);
+ CGLM_INLINE vec3s glms_vec3_sub(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_subs(vec3s a, float s);
+ CGLM_INLINE vec3s glms_vec3_mul(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_scale(vec3s v, float s);
+ CGLM_INLINE vec3s glms_vec3_scale_as(vec3s v, float s);
+ CGLM_INLINE vec3s glms_vec3_div(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_divs(vec3s a, float s);
+ CGLM_INLINE vec3s glms_vec3_addadd(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_subadd(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_muladd(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_muladds(vec3s a, float s, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_maxadd(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_minadd(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_subsub(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_addsub(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_mulsub(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_mulsubs(vec3s a, float s, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_maxsub(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_minsub(vec3s a, vec3s b, vec3s dest);
+ CGLM_INLINE vec3s glms_vec3_flipsign(vec3s v);
+ CGLM_INLINE vec3s glms_vec3_negate(vec3s v);
+ CGLM_INLINE vec3s glms_vec3_normalize(vec3s v);
+ CGLM_INLINE vec3s glms_vec3_cross(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_crossn(vec3s a, vec3s b);
+ CGLM_INLINE float glms_vec3_angle(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_rotate(vec3s v, float angle, vec3s axis);
+ CGLM_INLINE vec3s glms_vec3_rotate_m4(mat4s m, vec3s v);
+ CGLM_INLINE vec3s glms_vec3_rotate_m3(mat3s m, vec3s v);
+ CGLM_INLINE vec3s glms_vec3_proj(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_center(vec3s a, vec3s b);
+ CGLM_INLINE float glms_vec3_distance(vec3s a, vec3s b);
+ CGLM_INLINE float glms_vec3_distance2(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_maxv(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_minv(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_vec3_ortho(vec3s v);
+ CGLM_INLINE vec3s glms_vec3_clamp(vec3s v, float minVal, float maxVal);
+ CGLM_INLINE vec3s glms_vec3_lerp(vec3s from, vec3s to, float t);
+ CGLM_INLINE vec3s glms_vec3_lerpc(vec3s from, vec3s to, float t);
+ CGLM_INLINE vec3s glms_vec3_mix(vec3s from, vec3s to, float t);
+ CGLM_INLINE vec3s glms_vec3_mixc(vec3s from, vec3s to, float t);
+ CGLM_INLINE vec3s glms_vec3_step(vec3s edge, vec3s x);
+ CGLM_INLINE vec3s glms_vec3_smoothstep_uni(float edge0, float edge1, vec3s x);
+ CGLM_INLINE vec3s glms_vec3_smoothstep(vec3s edge0, vec3s edge1, vec3s x);
+ CGLM_INLINE vec3s glms_vec3_smoothinterp(vec3s from, vec3s to, float t);
+ CGLM_INLINE vec3s glms_vec3_smoothinterpc(vec3s from, vec3s to, float t);
+ CGLM_INLINE vec3s glms_vec3_swizzle(vec3s v, int mask);
+ CGLM_INLINE vec3s glms_vec3_make(float * restrict src);
+ CGLM_INLINE vec3s glms_vec3_faceforward(vec3s n, vec3s v, vec3s nref);
+ CGLM_INLINE vec3s glms_vec3_reflect(vec3s v, vec3s n);
+ CGLM_INLINE bool glms_vec3_refract(vec3s v, vec3s n, float eta, vec3s *dest)
+
+ Convenient:
+ CGLM_INLINE vec3s glms_cross(vec3s a, vec3s b);
+ CGLM_INLINE float glms_dot(vec3s a, vec3s b);
+ CGLM_INLINE vec3s glms_normalize(vec3s v);
+
+ Deprecated:
+ glms_vec3_step_uni --> use glms_vec3_steps
+ */
+
+#ifndef cglms_vec3s_h
+#define cglms_vec3s_h
+
+#include "../common.h"
+#include "../types-struct.h"
+#include "../util.h"
+#include "../vec3.h"
+#include "vec3-ext.h"
+
+/* DEPRECATED! */
+#define glms_vec3_step_uni(edge, x) glms_vec3_steps(edge, x)
+
+#define GLMS_VEC3_ONE_INIT {GLM_VEC3_ONE_INIT}
+#define GLMS_VEC3_ZERO_INIT {GLM_VEC3_ZERO_INIT}
+
+#define GLMS_VEC3_ONE ((vec3s)GLMS_VEC3_ONE_INIT)
+#define GLMS_VEC3_ZERO ((vec3s)GLMS_VEC3_ZERO_INIT)
+
+#define GLMS_YUP ((vec3s){{0.0f, 1.0f, 0.0f}})
+#define GLMS_ZUP ((vec3s){{0.0f, 0.0f, 1.0f}})
+#define GLMS_XUP ((vec3s){{1.0f, 0.0f, 0.0f}})
+
+/*!
+ * @brief init vec3 using vec4
+ *
+ * @param[in] v4 vector4
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3(vec4s v4) {
+ vec3s r;
+ glm_vec3(v4.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief pack an array of vec3 into an array of vec3s
+ *
+ * @param[out] dst array of vec3
+ * @param[in] src array of vec3s
+ * @param[in] len number of elements
+ */
+CGLM_INLINE
+void
+glms_vec3_(pack)(vec3s dst[], vec3 src[], size_t len) {
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ glm_vec3_copy(src[i], dst[i].raw);
+ }
+}
+
+/*!
+ * @brief unpack an array of vec3s into an array of vec3
+ *
+ * @param[out] dst array of vec3s
+ * @param[in] src array of vec3
+ * @param[in] len number of elements
+ */
+CGLM_INLINE
+void
+glms_vec3_(unpack)(vec3 dst[], vec3s src[], size_t len) {
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ glm_vec3_copy(src[i].raw, dst[i]);
+ }
+}
+
+/*!
+ * @brief make vector zero
+ *
+ * @returns zero vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(zero)(void) {
+ vec3s r;
+ glm_vec3_zero(r.raw);
+ return r;
+}
+
+/*!
+ * @brief make vector one
+ *
+ * @returns one vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(one)(void) {
+ vec3s r;
+ glm_vec3_one(r.raw);
+ return r;
+}
+
+/*!
+ * @brief vec3 dot product
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ *
+ * @return dot product
+ */
+CGLM_INLINE
+float
+glms_vec3_(dot)(vec3s a, vec3s b) {
+ return glm_vec3_dot(a.raw, b.raw);
+}
+
+/*!
+ * @brief norm * norm (magnitude) of vec
+ *
+ * we can use this func instead of calling norm * norm, because it would call
+ * sqrtf function twice but with this func we can avoid func call, maybe this is
+ * not good name for this func
+ *
+ * @param[in] v vector
+ *
+ * @return norm * norm
+ */
+CGLM_INLINE
+float
+glms_vec3_(norm2)(vec3s v) {
+ return glm_vec3_norm2(v.raw);
+}
+
+/*!
+ * @brief norm (magnitude) of vec3
+ *
+ * @param[in] v vector
+ *
+ * @return norm
+ */
+CGLM_INLINE
+float
+glms_vec3_(norm)(vec3s v) {
+ return glm_vec3_norm(v.raw);
+}
+
+/*!
+ * @brief L1 norm of vec3
+ * Also known as Manhattan Distance or Taxicab norm.
+ * L1 Norm is the sum of the magnitudes of the vectors in a space.
+ * It is calculated as the sum of the absolute values of the vector components.
+ * In this norm, all the components of the vector are weighted equally.
+ *
+ * This computes:
+ * R = |v[0]| + |v[1]| + |v[2]|
+ *
+ * @param[in] v vector
+ *
+ * @return L1 norm
+ */
+CGLM_INLINE
+float
+glms_vec3_(norm_one)(vec3s v) {
+ return glm_vec3_norm_one(v.raw);
+}
+
+/*!
+ * @brief Infinity norm of vec3
+ * Also known as Maximum norm.
+ * Infinity Norm is the largest magnitude among each element of a vector.
+ * It is calculated as the maximum of the absolute values of the vector components.
+ *
+ * This computes:
+ * inf norm = max(|v[0]|, |v[1]|, |v[2]|)
+ *
+ * @param[in] v vector
+ *
+ * @return Infinity norm
+ */
+CGLM_INLINE
+float
+glms_vec3_(norm_inf)(vec3s v) {
+ return glm_vec3_norm_inf(v.raw);
+}
+
+/*!
+ * @brief add a vector to b vector store result in dest
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(add)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_add(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief add scalar to v vector store result in dest (d = v + s)
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(adds)(vec3s a, float s) {
+ vec3s r;
+ glm_vec3_adds(a.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief subtract b vector from a vector store result in dest
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(sub)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_sub(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief subtract scalar from v vector store result in dest (d = v - s)
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(subs)(vec3s a, float s) {
+ vec3s r;
+ glm_vec3_subs(a.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief multiply two vectors (component-wise multiplication)
+ *
+ * @param a vector1
+ * @param b vector2
+ * @returns v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2])
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(mul)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_mul(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief multiply/scale vec3 vector with scalar: result = v * s
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(scale)(vec3s v, float s) {
+ vec3s r;
+ glm_vec3_scale(v.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief make vec3 vector scale as specified: result = unit(v) * s
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(scale_as)(vec3s v, float s) {
+ vec3s r;
+ glm_vec3_scale_as(v.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief div vector with another component-wise division: d = a / b
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns result = (a[0]/b[0], a[1]/b[1], a[2]/b[2])
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(div)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_div(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief div vector with scalar: d = v / s
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns result = (a[0]/s, a[1]/s, a[2]/s)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(divs)(vec3s a, float s) {
+ vec3s r;
+ glm_vec3_divs(a.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief add two vectors and add result to sum
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += (a + b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(addadd)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_addadd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief sub two vectors and add result to dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += (a + b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(subadd)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_subadd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief mul two vectors and add result to dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += (a * b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(muladd)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_muladd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief mul vector with scalar and add result to sum
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns dest += (a * b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(muladds)(vec3s a, float s, vec3s dest) {
+ glm_vec3_muladds(a.raw, s, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief add max of two vectors to result/dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += max(a, b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(maxadd)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_maxadd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief add min of two vectors to result/dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += min(a, b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(minadd)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_minadd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief sub two vectors and sub result to dest
+ *
+ * it applies -= operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest -= (a - b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(subsub)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_subsub(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief add two vectors and sub result to dest
+ *
+ * it applies -= operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest -= (a + b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(addsub)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_addsub(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief mul two vectors and sub result to dest
+ *
+ * it applies -= operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest -= (a * b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(mulsub)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_mulsub(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief mul vector with scalar and sub result to dest
+ *
+ * it applies -= operator so dest must be initialized
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns dest -= (a * b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(mulsubs)(vec3s a, float s, vec3s dest) {
+ glm_vec3_mulsubs(a.raw, s, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief sub max of two vectors to dest
+ *
+ * it applies -= operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest -= max(a, b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(maxsub)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_maxsub(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief sub min of two vectors to dest
+ *
+ * it applies -= operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest -= min(a, b)
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(minsub)(vec3s a, vec3s b, vec3s dest) {
+ glm_vec3_minsub(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief negate vector components and store result in dest
+ *
+ * @param[in] v vector
+ * @returns result vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(flipsign)(vec3s v) {
+ glm_vec3_flipsign(v.raw);
+ return v;
+}
+
+/*!
+ * @brief negate vector components
+ *
+ * @param[in] v vector
+ * @returns negated vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(negate)(vec3s v) {
+ glm_vec3_negate(v.raw);
+ return v;
+}
+
+/*!
+ * @brief normalize vec3 and store result in same vec
+ *
+ * @param[in] v vector
+ * @returns normalized vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(normalize)(vec3s v) {
+ glm_vec3_normalize(v.raw);
+ return v;
+}
+
+/*!
+ * @brief cross product of two vector (RH)
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(cross)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_cross(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief cross product of two vector (RH) and normalize the result
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(crossn)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_crossn(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief angle between two vector
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ *
+ * @return angle as radians
+ */
+CGLM_INLINE
+float
+glms_vec3_(angle)(vec3s a, vec3s b) {
+ return glm_vec3_angle(a.raw, b.raw);
+}
+
+/*!
+ * @brief rotate vec3 around axis by angle using Rodrigues' rotation formula
+ *
+ * @param[in] v vector
+ * @param[in] axis axis vector (must be unit vector)
+ * @param[in] angle angle by radians
+ * @returns rotated vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(rotate)(vec3s v, float angle, vec3s axis) {
+ glm_vec3_rotate(v.raw, angle, axis.raw);
+ return v;
+}
+
+/*!
+ * @brief apply rotation matrix to vector
+ *
+ * matrix format should be (no perspective):
+ * a b c x
+ * e f g y
+ * i j k z
+ * 0 0 0 w
+ *
+ * @param[in] m affine matrix or rot matrix
+ * @param[in] v vector
+ * @returns rotated vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(rotate_m4)(mat4s m, vec3s v) {
+ vec3s r;
+ glm_vec3_rotate_m4(m.raw, v.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief apply rotation matrix to vector
+ *
+ * @param[in] m affine matrix or rot matrix
+ * @param[in] v vector
+ * @returns rotated vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(rotate_m3)(mat3s m, vec3s v) {
+ vec3s r;
+ glm_vec3_rotate_m3(m.raw, v.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief project a vector onto b vector
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns projected vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(proj)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_proj(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/**
+ * @brief find center point of two vector
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns center point
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(center)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_center(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/**
+ * @brief distance between two vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @return distance
+ */
+CGLM_INLINE
+float
+glms_vec3_(distance)(vec3s a, vec3s b) {
+ return glm_vec3_distance(a.raw, b.raw);
+}
+
+/**
+ * @brief squared distance between two vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @return squared distance (distance * distance)
+ */
+CGLM_INLINE
+float
+glms_vec3_(distance2)(vec3s a, vec3s b) {
+ return glm_vec3_distance2(a.raw, b.raw);
+}
+
+/*!
+ * @brief max values of vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(maxv)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_maxv(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief min values of vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(minv)(vec3s a, vec3s b) {
+ vec3s r;
+ glm_vec3_minv(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief possible orthogonal/perpendicular vector
+ *
+ * @param[in] v vector
+ * @returns orthogonal/perpendicular vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(ortho)(vec3s v) {
+ vec3s r;
+ glm_vec3_ortho(v.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief clamp vector's individual members between min and max values
+ *
+ * @param[in] v vector
+ * @param[in] minVal minimum value
+ * @param[in] maxVal maximum value
+ * @returns clamped vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(clamp)(vec3s v, float minVal, float maxVal) {
+ glm_vec3_clamp(v.raw, minVal, maxVal);
+ return v;
+}
+
+/*!
+ * @brief linear interpolation between two vectors
+ *
+ * formula: from + s * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount)
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(lerp)(vec3s from, vec3s to, float t) {
+ vec3s r;
+ glm_vec3_lerp(from.raw, to.raw, t, r.raw);
+ return r;
+}
+
+/*!
+ * @brief linear interpolation between two vectors (clamped)
+ *
+ * formula: from + s * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount) clamped between 0 and 1
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(lerpc)(vec3s from, vec3s to, float t) {
+ vec3s r;
+ glm_vec3_lerpc(from.raw, to.raw, t, r.raw);
+ return r;
+}
+
+/*!
+ * @brief linear interpolation between two vectors
+ *
+ * formula: from + s * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount)
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(mix)(vec3s from, vec3s to, float t) {
+ vec3s r;
+ glm_vec3_mix(from.raw, to.raw, t, r.raw);
+ return r;
+}
+
+/*!
+ * @brief linear interpolation between two vectors (clamped)
+ *
+ * formula: from + s * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount) clamped between 0 and 1
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(mixc)(vec3s from, vec3s to, float t) {
+ vec3s r;
+ glm_vec3_mixc(from.raw, to.raw, t, r.raw);
+ return r;
+}
+
+/*!
+ * @brief threshold function
+ *
+ * @param[in] edge threshold
+ * @param[in] x value to test against threshold
+ * @returns 0.0 if x < edge, else 1.0
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(step)(vec3s edge, vec3s x) {
+ vec3s r;
+ glm_vec3_step(edge.raw, x.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief threshold function with a smooth transition (unidimensional)
+ *
+ * @param[in] edge0 low threshold
+ * @param[in] edge1 high threshold
+ * @param[in] x value to test against threshold
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(smoothstep_uni)(float edge0, float edge1, vec3s x) {
+ vec3s r;
+ glm_vec3_smoothstep_uni(edge0, edge1, x.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief threshold function with a smooth transition
+ *
+ * @param[in] edge0 low threshold
+ * @param[in] edge1 high threshold
+ * @param[in] x value to test against threshold
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(smoothstep)(vec3s edge0, vec3s edge1, vec3s x) {
+ vec3s r;
+ glm_vec3_smoothstep(edge0.raw, edge1.raw, x.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief smooth Hermite interpolation between two vectors
+ *
+ * formula: from + s * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount)
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(smoothinterp)(vec3s from, vec3s to, float t) {
+ vec3s r;
+ glm_vec3_smoothinterp(from.raw, to.raw, t, r.raw);
+ return r;
+}
+
+/*!
+ * @brief smooth Hermite interpolation between two vectors (clamped)
+ *
+ * formula: from + s * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount) clamped between 0 and 1
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(smoothinterpc)(vec3s from, vec3s to, float t) {
+ vec3s r;
+ glm_vec3_smoothinterpc(from.raw, to.raw, t, r.raw);
+ return r;
+}
+
+/*!
+ * @brief vec3 cross product
+ *
+ * this is just convenient wrapper
+ *
+ * @param[in] a source 1
+ * @param[in] b source 2
+ * @returns destination
+ */
+CGLM_INLINE
+vec3s
+glms_cross(vec3s a, vec3s b) {
+ vec3s r;
+ glm_cross(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief vec3 dot product
+ *
+ * this is just convenient wrapper
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @return dot product
+ */
+CGLM_INLINE
+float
+glms_dot(vec3s a, vec3s b) {
+ return glm_dot(a.raw, b.raw);
+}
+
+/*!
+ * @brief normalize vec3 and store result in same vec
+ *
+ * this is just convenient wrapper
+ *
+ * @param[in] v vector
+ * @returns normalized vector
+ */
+CGLM_INLINE
+vec3s
+glms_normalize(vec3s v) {
+ glm_normalize(v.raw);
+ return v;
+}
+
+/*!
+ * @brief swizzle vector components
+ *
+ * you can use existing masks e.g. GLM_XXX, GLM_ZYX
+ *
+ * @param[in] v source
+ * @param[in] mask mask
+ * @returns swizzled vector
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(swizzle)(vec3s v, int mask) {
+ vec3s dest;
+ glm_vec3_swizzle(v.raw, mask, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief Create three dimensional vector from pointer
+ *
+ * @param[in] src pointer to an array of floats
+ * @returns constructed 3D vector from raw pointer
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(make)(const float * __restrict src) {
+ vec3s dest;
+ glm_vec3_make(src, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief a vector pointing in the same direction as another
+ *
+ * orients a vector to point away from a surface as defined by its normal
+ *
+ * @param[in] n vector to orient.
+ * @param[in] v incident vector
+ * @param[in] nref reference vector
+ * @returns oriented vector, pointing away from the surface.
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(faceforward)(vec3s n, vec3s v, vec3s nref) {
+ vec3s dest;
+ glm_vec3_faceforward(n.raw, v.raw, nref.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief reflection vector using an incident ray and a surface normal
+ *
+ * @param[in] I incident vector
+ * @param[in] N normalized normal vector
+ * @returns reflection result
+ */
+CGLM_INLINE
+vec3s
+glms_vec3_(reflect)(vec3s v, vec3s n) {
+ vec3s dest;
+ glm_vec3_reflect(v.raw, n.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief computes refraction vector for an incident vector and a surface normal.
+ *
+ * calculates the refraction vector based on Snell's law. If total internal reflection
+ * occurs (angle too great given eta), dest is set to zero and returns false.
+ * Otherwise, computes refraction vector, stores it in dest, and returns true.
+ *
+ * @param[in] v normalized incident vector
+ * @param[in] n normalized normal vector
+ * @param[in] eta ratio of indices of refraction (incident/transmitted)
+ * @param[out] dest refraction vector if refraction occurs; zero vector otherwise
+ *
+ * @returns true if refraction occurs; false if total internal reflection occurs.
+ */
+CGLM_INLINE
+bool
+glms_vec3_(refract)(vec3s v, vec3s n, float eta, vec3s * __restrict dest) {
+ return glm_vec3_refract(v.raw, n.raw, eta, dest->raw);
+}
+
+#endif /* cglms_vec3s_h */