diff --git a/CMakeLists.txt b/CMakeLists.txt index e80bd8a..a331595 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,7 @@ add_library(${PROJECT_NAME} src/mat4x2.c src/mat4x3.c src/plane.c + src/noise.c src/frustum.c src/box.c src/aabb2d.c diff --git a/Makefile.am b/Makefile.am index a8b64d0..2b4c299 100644 --- a/Makefile.am +++ b/Makefile.am @@ -67,6 +67,7 @@ cglm_HEADERS = include/cglm/version.h \ include/cglm/util.h \ include/cglm/quat.h \ include/cglm/plane.h \ + include/cglm/noise.h \ include/cglm/frustum.h \ include/cglm/box.h \ include/cglm/aabb2d.h \ @@ -120,6 +121,7 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \ include/cglm/call/quat.h \ include/cglm/call/euler.h \ include/cglm/call/plane.h \ + include/cglm/call/noise.h \ include/cglm/call/frustum.h \ include/cglm/call/box.h \ include/cglm/call/project.h \ @@ -210,6 +212,7 @@ cglm_struct_HEADERS = include/cglm/struct/mat4.h \ include/cglm/struct/quat.h \ include/cglm/struct/euler.h \ include/cglm/struct/plane.h \ + include/cglm/struct/noise.h \ include/cglm/struct/frustum.h \ include/cglm/struct/box.h \ include/cglm/struct/aabb2d.h \ @@ -261,6 +264,7 @@ libcglm_la_SOURCES=\ src/mat4x2.c \ src/mat4x3.c \ src/plane.c \ + src/noise.c \ src/frustum.c \ src/box.c \ src/project.c \ diff --git a/docs/source/api_inline_array.rst b/docs/source/api_inline_array.rst index 5d8ead8..f989bfe 100644 --- a/docs/source/api_inline_array.rst +++ b/docs/source/api_inline_array.rst @@ -66,6 +66,7 @@ Follow the :doc:`build` documentation for this ivec4 color plane + noise project util io diff --git a/docs/source/noise.rst b/docs/source/noise.rst new file mode 100644 index 0000000..0976eee --- /dev/null +++ b/docs/source/noise.rst @@ -0,0 +1,60 @@ +.. default-domain:: C + +perlin +================================================================================ + +Header: cglm/noise.h + +Classic Perlin noise implementation. + +Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise": +https://github.com/stegu/webgl-noise +Following Stefan Gustavson's paper "Simplex noise demystified": +http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf + +Implementation based on glm::perlin function: +https://github.com/g-truc/glm/blob/master/glm/gtc/noise.inl + +Table of contents (click to go): +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Functions: + +1. :c:func:`glm_perlin_vec4` +#. :c:func:`glm_perlin_vec3` +#. :c:func:`glm_perlin_vec2` + + +Functions documentation +~~~~~~~~~~~~~~~~~~~~~~~ + +.. c:function:: float glm_perlin_vec4(vec4 point) + + | Classic Perlin noise + + Parameters: + | *[in]* **point** 4D point + + Returns: + | noise value + + +.. c:function:: float glm_perlin_vec3(vec3 point) + + | Classic Perlin noise + + Parameters: + | *[in]* **point** 3D point + + Returns: + | noise value + +.. c:function:: float glm_perlin_vec2(vec2 point) + + | Classic Perlin noise + + Parameters: + | *[in]* **point** 2D point + + Returns: + | noise value diff --git a/docs/source/vec2-ext.rst b/docs/source/vec2-ext.rst index f8d8fe5..70ef4f6 100644 --- a/docs/source/vec2-ext.rst +++ b/docs/source/vec2-ext.rst @@ -27,6 +27,8 @@ Functions: #. :c:func:`glm_vec2_isvalid` #. :c:func:`glm_vec2_sign` #. :c:func:`glm_vec2_abs` +#. :c:func:`glm_vec2_fract` +#. :c:func:`glm_vec2_floor` #. :c:func:`glm_vec2_sqrt` Functions documentation @@ -134,6 +136,22 @@ Functions documentation | *[in]* **v** vector | *[out]* **dest** destination vector +.. c:function:: void glm_vec2_fract(vec2 v, vec2 dest) + + get fractional part of each vector item + + Parameters: + | *[in]* **v** vector + | *[out]* **dest** destination vector + +.. c:function:: void glm_vec2_floor(vec2 v, vec2 dest) + + floor value of each vector item + + Parameters: + | *[in]* **v** vector + | *[out]* **dest** destination vector + .. c:function:: void glm_vec2_sqrt(vec2 v, vec2 dest) square root of each vector item diff --git a/docs/source/vec3-ext.rst b/docs/source/vec3-ext.rst index f99e770..9668932 100644 --- a/docs/source/vec3-ext.rst +++ b/docs/source/vec3-ext.rst @@ -28,6 +28,8 @@ Functions: #. :c:func:`glm_vec3_isvalid` #. :c:func:`glm_vec3_sign` #. :c:func:`glm_vec3_abs` +#. :c:func:`glm_vec3_fract` +#. :c:func:`glm_vec3_floor` #. :c:func:`glm_vec3_sqrt` Functions documentation @@ -151,6 +153,22 @@ Functions documentation | *[in]* **v** vector | *[out]* **dest** destination vector +.. c:function:: void glm_vec3_fract(vec3 v, vec3 dest) + + fractional part of each vector item + + Parameters: + | *[in]* **v** vector + | *[out]* **dest** destination vector + +.. c:function:: void glm_vec3_floor(vec3 v, vec3 dest) + + floor of each vector item + + Parameters: + | *[in]* **v** vector + | *[out]* **dest** destination vector + .. c:function:: void glm_vec3_sqrt(vec3 v, vec3 dest) square root of each vector item diff --git a/docs/source/vec4-ext.rst b/docs/source/vec4-ext.rst index 722424e..bf7eca2 100644 --- a/docs/source/vec4-ext.rst +++ b/docs/source/vec4-ext.rst @@ -23,6 +23,15 @@ Functions: #. :c:func:`glm_vec4_eqv_eps` #. :c:func:`glm_vec4_max` #. :c:func:`glm_vec4_min` +#. :c:func:`glm_vec4_isnan` +#. :c:func:`glm_vec4_isinf` +#. :c:func:`glm_vec4_isvalid` +#. :c:func:`glm_vec4_sign` +#. :c:func:`glm_vec4_abs` +#. :c:func:`glm_vec4_fract` +#. :c:func:`glm_vec4_floor` +#. :c:func:`glm_vec4_sqrt` + Functions documentation ~~~~~~~~~~~~~~~~~~~~~~~ @@ -129,6 +138,30 @@ Functions documentation | *[in]* **v** vector | *[out]* **dest** sign vector (only keeps signs as -1, 0, -1) +.. c:function:: void glm_vec4_abs(vec4 v, vec4 dest) + + absolute value of each vector item + + Parameters: + | *[in]* **v** vector + | *[out]* **dest** destination vector (abs(v)) + +.. c:function:: void glm_vec4_fract(vec4 v, vec4 dest) + + fractional part of each vector item + + Parameters: + | *[in]* **v** vector + | *[out]* **dest** destination vector (fract(v)) + +.. c:function:: void glm_vec4_floor(vec4 v, vec4 dest) + + floor of each vector item + + Parameters: + | *[in]* **v** vector + | *[out]* **dest** destination vector (floor(v)) + .. c:function:: void glm_vec4_sqrt(vec4 v, vec4 dest) square root of each vector item diff --git a/include/cglm/call.h b/include/cglm/call.h index de775d2..165f502 100644 --- a/include/cglm/call.h +++ b/include/cglm/call.h @@ -32,6 +32,7 @@ extern "C" { #include "call/quat.h" #include "call/euler.h" #include "call/plane.h" +#include "call/noise.h" #include "call/frustum.h" #include "call/aabb2d.h" #include "call/box.h" diff --git a/include/cglm/call/noise.h b/include/cglm/call/noise.h new file mode 100644 index 0000000..6020c89 --- /dev/null +++ b/include/cglm/call/noise.h @@ -0,0 +1,31 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglmc_noise_h +#define cglmc_noise_h +#ifdef __cplusplus +extern "C" { +#endif + +#include "../cglm.h" + +CGLM_EXPORT +float +glmc_perlin_vec4(vec4 point); + +CGLM_EXPORT +float +glmc_perlin_vec3(vec3 point); + +CGLM_EXPORT +float +glmc_perlin_vec2(vec2 point); + +#ifdef __cplusplus +} +#endif +#endif /* cglmc_noise_h */ diff --git a/include/cglm/call/vec2.h b/include/cglm/call/vec2.h index 4264887..0284a8c 100644 --- a/include/cglm/call/vec2.h +++ b/include/cglm/call/vec2.h @@ -189,10 +189,38 @@ CGLM_EXPORT void glmc_vec2_abs(vec2 v, vec2 dest); +CGLM_EXPORT +void +glmc_vec2_fract(vec2 v, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_floor(vec2 v, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_mods(vec2 v, float s, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_swizzle(vec2 v, int mask, vec2 dest); + CGLM_EXPORT void glmc_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest); +CGLM_EXPORT +void +glmc_vec2_step(vec2 edge, vec2 x, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_steps(float edge, vec2 x, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_stepr(vec2 edge, float x, vec2 dest); + CGLM_EXPORT void glmc_vec2_complex_mul(vec2 a, vec2 b, vec2 dest); diff --git a/include/cglm/call/vec3.h b/include/cglm/call/vec3.h index bb5a5d7..640fac7 100644 --- a/include/cglm/call/vec3.h +++ b/include/cglm/call/vec3.h @@ -19,6 +19,7 @@ extern "C" { #define glmc_vec3_flipsign_to(v, dest) glmc_vec3_negate_to(v, dest) #define glmc_vec3_inv(v) glmc_vec3_negate(v) #define glmc_vec3_inv_to(v, dest) glmc_vec3_negate_to(v, dest) +#define glmc_vec3_step_uni(edge, x, dest) glmc_vec3_steps(edge, x, dest); CGLM_EXPORT void @@ -55,7 +56,7 @@ glmc_vec3_norm(vec3 v); CGLM_EXPORT float glmc_vec3_norm2(vec3 v); - + CGLM_EXPORT float glmc_vec3_norm_one(vec3 v); @@ -211,15 +212,15 @@ glmc_vec3_clamp(vec3 v, float minVal, float maxVal); CGLM_EXPORT void glmc_vec3_ortho(vec3 v, vec3 dest); - + CGLM_EXPORT void glmc_vec3_lerp(vec3 from, vec3 to, float t, vec3 dest); - + CGLM_EXPORT void glmc_vec3_lerpc(vec3 from, vec3 to, float t, vec3 dest); - + CGLM_INLINE void glmc_vec3_mix(vec3 from, vec3 to, float t, vec3 dest) { @@ -231,31 +232,31 @@ void glmc_vec3_mixc(vec3 from, vec3 to, float t, vec3 dest) { glmc_vec3_lerpc(from, to, t, dest); } - -CGLM_EXPORT -void -glmc_vec3_step_uni(float edge, vec3 x, vec3 dest); - + CGLM_EXPORT void glmc_vec3_step(vec3 edge, vec3 x, vec3 dest); - + CGLM_EXPORT void glmc_vec3_smoothstep_uni(float edge0, float edge1, vec3 x, vec3 dest); - + CGLM_EXPORT void glmc_vec3_smoothstep(vec3 edge0, vec3 edge1, vec3 x, vec3 dest); - + CGLM_EXPORT void glmc_vec3_smoothinterp(vec3 from, vec3 to, float t, vec3 dest); - + CGLM_EXPORT void glmc_vec3_smoothinterpc(vec3 from, vec3 to, float t, vec3 dest); +CGLM_EXPORT +void +glmc_vec3_swizzle(vec3 v, int mask, vec3 dest); + /* ext */ CGLM_EXPORT @@ -265,7 +266,7 @@ glmc_vec3_mulv(vec3 a, vec3 b, vec3 d); CGLM_EXPORT void glmc_vec3_broadcast(float val, vec3 d); - + CGLM_EXPORT void glmc_vec3_fill(vec3 v, float val); @@ -313,15 +314,31 @@ glmc_vec3_isvalid(vec3 v); CGLM_EXPORT void glmc_vec3_sign(vec3 v, vec3 dest); - + CGLM_EXPORT void glmc_vec3_abs(vec3 v, vec3 dest); - + CGLM_EXPORT void glmc_vec3_fract(vec3 v, vec3 dest); - + +CGLM_EXPORT +void +glmc_vec3_floor(vec3 v, vec3 dest); + +CGLM_EXPORT +void +glmc_vec3_mods(vec3 v, float s, vec3 dest); + +CGLM_EXPORT +void +glmc_vec3_steps(float edge, vec3 x, vec3 dest); + +CGLM_EXPORT +void +glmc_vec3_stepr(vec3 edge, float x, vec3 dest); + CGLM_EXPORT float glmc_vec3_hadd(vec3 v); diff --git a/include/cglm/call/vec4.h b/include/cglm/call/vec4.h index 9857473..22eee24 100644 --- a/include/cglm/call/vec4.h +++ b/include/cglm/call/vec4.h @@ -20,6 +20,7 @@ extern "C" { #define glmc_vec4_flipsign_to(v, dest) glmc_vec4_negate_to(v, dest) #define glmc_vec4_inv(v) glmc_vec4_negate(v) #define glmc_vec4_inv_to(v, dest) glmc_vec4_negate_to(v, dest) +#define glmc_vec4_step_uni(edge, x, dest) glmc_vec4_steps(edge, x, dest) CGLM_EXPORT void @@ -56,7 +57,7 @@ glmc_vec4_norm(vec4 v); CGLM_EXPORT float glmc_vec4_norm2(vec4 v); - + CGLM_EXPORT float glmc_vec4_norm_one(vec4 v); @@ -164,11 +165,11 @@ glmc_vec4_negate(vec4 v); CGLM_EXPORT void glmc_vec4_negate_to(vec4 v, vec4 dest); - + CGLM_EXPORT float glmc_vec4_distance(vec4 a, vec4 b); - + CGLM_EXPORT float glmc_vec4_distance2(vec4 a, vec4 b); @@ -184,15 +185,15 @@ glmc_vec4_minv(vec4 a, vec4 b, vec4 dest); CGLM_EXPORT void glmc_vec4_clamp(vec4 v, float minVal, float maxVal); - + CGLM_EXPORT void glmc_vec4_lerp(vec4 from, vec4 to, float t, vec4 dest); - + CGLM_EXPORT void glmc_vec4_lerpc(vec4 from, vec4 to, float t, vec4 dest); - + CGLM_INLINE void glmc_vec4_mix(vec4 from, vec4 to, float t, vec4 dest) { @@ -204,27 +205,23 @@ void glmc_vec4_mixc(vec4 from, vec4 to, float t, vec4 dest) { glmc_vec4_lerpc(from, to, t, dest); } - -CGLM_EXPORT -void -glmc_vec4_step_uni(float edge, vec4 x, vec4 dest); - + CGLM_EXPORT void glmc_vec4_step(vec4 edge, vec4 x, vec4 dest); - + CGLM_EXPORT void glmc_vec4_smoothstep_uni(float edge0, float edge1, vec4 x, vec4 dest); - + CGLM_EXPORT void glmc_vec4_smoothstep(vec4 edge0, vec4 edge1, vec4 x, vec4 dest); - + CGLM_EXPORT void glmc_vec4_smoothinterp(vec4 from, vec4 to, float t, vec4 dest); - + CGLM_EXPORT void glmc_vec4_smoothinterpc(vec4 from, vec4 to, float t, vec4 dest); @@ -233,6 +230,10 @@ CGLM_EXPORT void glmc_vec4_cubic(float s, vec4 dest); +CGLM_EXPORT +void +glmc_vec4_swizzle(vec4 v, int mask, vec4 dest); + /* ext */ CGLM_EXPORT @@ -242,7 +243,7 @@ glmc_vec4_mulv(vec4 a, vec4 b, vec4 d); CGLM_EXPORT void glmc_vec4_broadcast(float val, vec4 d); - + CGLM_EXPORT void glmc_vec4_fill(vec4 v, float val); @@ -290,15 +291,31 @@ glmc_vec4_isvalid(vec4 v); CGLM_EXPORT void glmc_vec4_sign(vec4 v, vec4 dest); - + CGLM_EXPORT void glmc_vec4_abs(vec4 v, vec4 dest); - + CGLM_EXPORT void glmc_vec4_fract(vec4 v, vec4 dest); - + +CGLM_EXPORT +void +glmc_vec4_floor(vec4 v, vec4 dest); + +CGLM_EXPORT +void +glmc_vec4_mods(vec4 v, float s, vec4 dest); + +CGLM_EXPORT +void +glmc_vec4_steps(float edge, vec4 x, vec4 dest); + +CGLM_EXPORT +void +glmc_vec4_stepr(vec4 edge, float x, vec4 dest); + CGLM_EXPORT float glmc_vec4_hadd(vec4 v); diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h index 5e15a3c..146ded0 100644 --- a/include/cglm/cglm.h +++ b/include/cglm/cglm.h @@ -30,6 +30,7 @@ #include "quat.h" #include "euler.h" #include "plane.h" +#include "noise.h" #include "aabb2d.h" #include "box.h" #include "color.h" diff --git a/include/cglm/common.h b/include/cglm/common.h index af1116f..11588cf 100644 --- a/include/cglm/common.h +++ b/include/cglm/common.h @@ -51,6 +51,7 @@ #define GLM_SHUFFLE4(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) #define GLM_SHUFFLE3(z, y, x) (((z) << 4) | ((y) << 2) | (x)) +#define GLM_SHUFFLE2(y, x) (((y) << 2) | (x)) #include "types.h" #include "simd/intrin.h" diff --git a/include/cglm/noise.h b/include/cglm/noise.h new file mode 100644 index 0000000..bec12e9 --- /dev/null +++ b/include/cglm/noise.h @@ -0,0 +1,734 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + * + * Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise": + * https://github.com/stegu/webgl-noise + * Following Stefan Gustavson's paper "Simplex noise demystified": + * http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf + * + * Implementation based on glm::perlin function: + * https://github.com/g-truc/glm/blob/master/glm/gtc/noise.inl + */ + +#ifndef cglm_noise_h +#define cglm_noise_h + +#include "vec4.h" +#include "vec4-ext.h" + +#include "vec3.h" +#include "vec3-ext.h" + +#include "vec2.h" +#include "vec2-ext.h" + +#define glm__noiseDetail_mod289(x) (x - floorf(x * (1.0f / 289.0f)) * 289.0f) + +/* glm__noiseDetail_permute(vec4 x, vec4 dest) */ +#define glm__noiseDetail_permute(x, dest) { \ + dest[0] = glm__noiseDetail_mod289((x[0] * 34.0f + 1.0f) * x[0]); \ + dest[1] = glm__noiseDetail_mod289((x[1] * 34.0f + 1.0f) * x[1]); \ + dest[2] = glm__noiseDetail_mod289((x[2] * 34.0f + 1.0f) * x[2]); \ + dest[3] = glm__noiseDetail_mod289((x[3] * 34.0f + 1.0f) * x[3]); \ +} + +/* glm__noiseDetail_fade_vec4(vec4 t, vec4 dest) */ +#define glm__noiseDetail_fade_vec4(t, dest) { \ + /* dest = (t * t * t) * (t * (t * 6.0f - 15.0f) + 10.0f) */ \ + vec4 temp; \ + glm_vec4_mul(t, t, temp); \ + glm_vec4_mul(temp, t, temp); \ + /* dest = (t * (t * 6.0f - 15.0f) + 10.0f) */ \ + glm_vec4_scale(t, 6.0f, dest); \ + glm_vec4_subs(dest, 15.0f, dest); \ + glm_vec4_mul(t, dest, dest); \ + glm_vec4_adds(dest, 10.0f, dest); \ + /* dest = temp * dest */ \ + glm_vec4_mul(temp, dest, dest); \ +} + +/* glm__noiseDetail_fade_vec3(vec3 t, vec3 dest) */ +#define glm__noiseDetail_fade_vec3(t, dest) { \ + /* dest = (t * t * t) * (t * (t * 6.0f - 15.0f) + 10.0f) */ \ + /* temp = t * t * t */ \ + vec3 temp; \ + glm_vec3_mul(t, t, temp); \ + glm_vec3_mul(temp, t, temp); \ + /* dest = (t * (t * 6.0f - 15.0f) + 10.0f) */ \ + glm_vec3_scale(t, 6.0f, dest); \ + glm_vec3_subs(dest, 15.0f, dest); \ + glm_vec3_mul(t, dest, dest); \ + glm_vec3_adds(dest, 10.0f, dest); \ + /* dest = temp * dest */ \ + glm_vec3_mul(temp, dest, dest); \ +} + +/* glm__noiseDetail_fade_vec2(vec2 t, vec2 dest) */ +#define glm__noiseDetail_fade_vec2(t, dest) { \ + /* dest = (t * t * t) * (t * (t * 6.0f - 15.0f) + 10.0f) */ \ + /* temp = t * t * t */ \ + vec2 temp; \ + glm_vec2_mul(t, t, temp); \ + glm_vec2_mul(temp, t, temp); \ + /* dest = (t * (t * 6.0f - 15.0f) + 10.0f) */ \ + glm_vec2_scale(t, 6.0f, dest); \ + glm_vec2_subs(dest, 15.0f, dest); \ + glm_vec2_mul(t, dest, dest); \ + glm_vec2_adds(dest, 10.0f, dest); \ + /* dest = temp * dest */ \ + glm_vec2_mul(temp, dest, dest); \ +} + +/* glm__noiseDetail_taylorInvSqrt(vec4 x, vec4 dest) */ +#define glm__noiseDetail_taylorInvSqrt(x, dest) { \ + /* dest = 1.79284291400159f - 0.85373472095314f * x */ \ + vec4 temp; \ + glm_vec4_scale(x, 0.85373472095314f, temp); /* temp = 0.853...f * x */ \ + glm_vec4_fill(dest, 1.79284291400159f); /* dest = 1.792...f */ \ + glm_vec4_sub(dest, temp, dest); /* dest = 1.79284291400159f - temp */ \ +} + +/* norm = taylorInvSqrt(vec4( + * dot(g00__, g00__), + * dot(g01__, g01__), + * dot(g10__, g10__), + * dot(g11__, g11__) + * )); +*/ + +/* glm__noiseDetail_gradNorm_vec4(vec4 g00__, vec4 g01__, vec4 g10__, vec4 g11__) */ +#define glm__noiseDetail_gradNorm_vec4(g00__, g01__, g10__, g11__) { \ + vec4 norm; \ + norm[0] = glm_vec4_dot(g00__, g00__); /* norm.x = dot(g00__, g00__) */ \ + norm[1] = glm_vec4_dot(g01__, g01__); /* norm.y = dot(g01__, g01__) */ \ + norm[2] = glm_vec4_dot(g10__, g10__); /* norm.z = dot(g10__, g10__) */ \ + norm[3] = glm_vec4_dot(g11__, g11__); /* norm.w = dot(g11__, g11__) */ \ + glm__noiseDetail_taylorInvSqrt(norm, norm); /* norm = taylorInvSqrt(norm) */ \ + \ + glm_vec4_scale(g00__, norm[0], g00__); /* g00__ *= norm.x */ \ + glm_vec4_scale(g01__, norm[1], g01__); /* g01__ *= norm.y */ \ + glm_vec4_scale(g10__, norm[2], g10__); /* g10__ *= norm.z */ \ + glm_vec4_scale(g11__, norm[3], g11__); /* g11__ *= norm.w */ \ +} + +/* glm__noiseDetail_gradNorm_vec3(vec3 g00_, vec3 g01_, vec3 g10_, vec3 g11_) */ +#define glm__noiseDetail_gradNorm_vec3(g00_, g01_, g10_, g11_) { \ + vec4 norm; \ + norm[0] = glm_vec3_dot(g00_, g00_); /* norm.x = dot(g00_, g00_) */ \ + norm[1] = glm_vec3_dot(g01_, g01_); /* norm.y = dot(g01_, g01_) */ \ + norm[2] = glm_vec3_dot(g10_, g10_); /* norm.z = dot(g10_, g10_) */ \ + norm[3] = glm_vec3_dot(g11_, g11_); /* norm.w = dot(g11_, g11_) */ \ + glm__noiseDetail_taylorInvSqrt(norm, norm); /* norm = taylorInvSqrt(norm) */ \ + \ + glm_vec3_scale(g00_, norm[0], g00_); /* g00_ *= norm.x */ \ + glm_vec3_scale(g01_, norm[1], g01_); /* g01_ *= norm.y */ \ + glm_vec3_scale(g10_, norm[2], g10_); /* g10_ *= norm.z */ \ + glm_vec3_scale(g11_, norm[3], g11_); /* g11_ *= norm.w */ \ +} + +/* glm__noiseDetail_gradNorm_vec2(vec2 g00, vec2 g01, vec2 g10, vec2 g11) */ +#define glm__noiseDetail_gradNorm_vec2(g00, g01, g10, g11) { \ + vec4 norm; \ + norm[0] = glm_vec2_dot(g00, g00); /* norm.x = dot(g00, g00) */ \ + norm[1] = glm_vec2_dot(g01, g01); /* norm.y = dot(g01, g01) */ \ + norm[2] = glm_vec2_dot(g10, g10); /* norm.z = dot(g10, g10) */ \ + norm[3] = glm_vec2_dot(g11, g11); /* norm.w = dot(g11, g11) */ \ + glm__noiseDetail_taylorInvSqrt(norm, norm); /* norm = taylorInvSqrt(norm) */ \ + \ + glm_vec2_scale(g00, norm[0], g00); /* g00 *= norm.x */ \ + glm_vec2_scale(g01, norm[1], g01); /* g01 *= norm.y */ \ + glm_vec2_scale(g10, norm[2], g10); /* g10 *= norm.z */ \ + glm_vec2_scale(g11, norm[3], g11); /* g11 *= norm.w */ \ +} + +/* glm__noiseDetail_i2gxyzw(vec4 ixy, vec4 gx, vec4 gy, vec4 gz, vec4 gw) */ +#define glm__noiseDetail_i2gxyzw(ixy, gx, gy, gz, gw) { \ + /* gx = ixy / 7.0 */ \ + glm_vec4_divs(ixy, 7.0f, gx); /* gx = ixy / 7.0 */ \ + \ + /* gy = fract(gx) / 7.0 */ \ + glm_vec4_floor(gx, gy); /* gy = floor(gx) */ \ + glm_vec4_divs(gy, 7.0f, gy); /* gy /= 7.0 */ \ + \ + /* gz = floor(gy) / 6.0 */ \ + glm_vec4_floor(gy, gz); /* gz = floor(gy) */ \ + glm_vec4_divs(gz, 6.0f, gz); /* gz /= 6.0 */ \ + \ + /* gx = fract(gx) - 0.5f */ \ + glm_vec4_fract(gx, gx); /* gx = fract(gx) */ \ + glm_vec4_subs(gx, 0.5f, gx); /* gx -= 0.5f */ \ + \ + /* gy = fract(gy) - 0.5f */ \ + glm_vec4_fract(gy, gy); /* gy = fract(gy) */ \ + glm_vec4_subs(gy, 0.5f, gy); /* gy -= 0.5f */ \ + \ + /* gz = fract(gz) - 0.5f */ \ + glm_vec4_fract(gz, gz); /* gz = fract(gz) */ \ + glm_vec4_subs(gz, 0.5f, gz); /* gz -= 0.5f */ \ + \ + /* abs(gx), abs(gy), abs(gz) */ \ + vec4 gxa, gya, gza; \ + glm_vec4_abs(gx, gxa); /* gxa = abs(gx) */ \ + glm_vec4_abs(gy, gya); /* gya = abs(gy) */ \ + glm_vec4_abs(gz, gza); /* gza = abs(gz) */ \ + \ + /* gw = 0.75 - abs(gx) - abs(gy) - abs(gz) */ \ + glm_vec4_fill(gw, 0.75f); /* gw = 0.75 */ \ + glm_vec4_sub(gw, gxa, gw); /* gw -= gxa */ \ + glm_vec4_sub(gw, gza, gw); /* gw -= gza */ \ + glm_vec4_sub(gw, gya, gw); /* gw -= gya */ \ + \ + /* sw = step(gw, 0.0); */ \ + vec4 sw; \ + glm_vec4_stepr(gw, 0.0f, sw); /* sw = step(gw, 0.0) */ \ + \ + /* gx -= sw * (step(vec4(0), gx) - T(0.5)); */ \ + vec4 temp = {0.0f}; /* temp = 0.0 */ \ + glm_vec4_step(temp, gx, temp); /* temp = step(temp, gx) */ \ + glm_vec4_subs(temp, 0.5f, temp); /* temp -= 0.5 */ \ + glm_vec4_mul(sw, temp, temp); /* temp *= sw */ \ + glm_vec4_sub(gx, temp, gx); /* gx -= temp */ \ + \ + /* gy -= sw * (step(vec4(0), gy) - T(0.5)); */ \ + glm_vec4_zero(temp); /* reset temp */ \ + glm_vec4_step(temp, gy, temp); /* temp = step(temp, gy) */ \ + glm_vec4_subs(temp, 0.5f, temp); /* temp -= 0.5 */ \ + glm_vec4_mul(sw, temp, temp); /* temp *= sw */ \ + glm_vec4_sub(gy, temp, gy); /* gy -= temp */ \ +} + +/* NOTE: This function is not *quite* analogous to glm__noiseDetail_i2gxyzw + * to try to match the output of glm::perlin. I think it might be a bug in + * in the original implementation, but for now I'm keeping it consistent. -MK + * + * Follow up: The original implementation (glm v 1.0.1) does: + * + * vec<4, T, Q> gx0 = ixy0 * T(1.0 / 7.0); + * + * as opposed to: + * + * vec<4, T, Q> gx0 = ixy0 / T(7); + * + * This ends up mapping to different simd instructions, at least on AMD. + * The delta is tiny but it gets amplified by the rest of the noise function. + * Hence we too need to do `glm_vec4_scale` as opposed to `glm_vec4_divs`, to + * match it. -MK + */ + +/* glm__noiseDetail_i2gxyz(vec4 i, vec4 gx, vec4 gy, vec4 gz) */ +#define glm__noiseDetail_i2gxyz(ixy, gx, gy, gz) { \ + /* gx = ixy / 7.0 */ \ + glm_vec4_scale(ixy, 1.0f / 7.0f, gx); /* gx = ixy * (1/7.0) */\ + \ + /* gy = fract(floor(gx0) / 7.0)) - 0.5; */ \ + glm_vec4_floor(gx, gy); /* gy = floor(gx) */ \ + glm_vec4_scale(gy, 1.0f / 7.0f, gy); /* gy *= 1 / 7.0 */ \ + glm_vec4_fract(gy, gy); /* gy = fract(gy) */ \ + glm_vec4_subs(gy, 0.5f, gy); /* gy -= 0.5f */ \ + \ + /* gx = fract(gx); */ \ + glm_vec4_fract(gx, gx); /* gx = fract(gx) */ \ + \ + /* abs(gx), abs(gy) */ \ + vec4 gxa, gya; \ + glm_vec4_abs(gx, gxa); /* gxa = abs(gx) */ \ + glm_vec4_abs(gy, gya); /* gya = abs(gy) */ \ + \ + /* gz = vec4(0.5) - abs(gx0) - abs(gy0); */ \ + glm_vec4_fill(gz, 0.5f); /* gz = 0.5 */ \ + glm_vec4_sub(gz, gxa, gz); /* gz -= gxa */ \ + glm_vec4_sub(gz, gya, gz); /* gz -= gya */ \ + \ + /* sz = step(gw, 0.0); */ \ + vec4 sz; \ + glm_vec4_stepr(gz, 0.0f, sz); /* sz = step(gz, 0.0) */ \ + \ + /* gx0 -= sz0 * (step(0.0, gx0) - T(0.5)); */ \ + vec4 temp = {0.0f}; /* temp = 0.0 */ \ + glm_vec4_step(temp, gx, temp); /* temp = step(temp, gx) */ \ + glm_vec4_subs(temp, 0.5f, temp); /* temp -= 0.5 */ \ + glm_vec4_mul(sz, temp, temp); /* temp *= sz */ \ + glm_vec4_sub(gx, temp, gx); /* gx -= temp */ \ + \ + /* gy0 -= sz0 * (step(0.0, gy0) - T(0.5)); */ \ + glm_vec4_zero(temp); /* reset temp */ \ + glm_vec4_step(temp, gy, temp); /* temp = step(temp, gy) */ \ + glm_vec4_subs(temp, 0.5f, temp); /* temp -= 0.5 */ \ + glm_vec4_mul(sz, temp, temp); /* temp *= sz */ \ + glm_vec4_sub(gy, temp, gy); /* gy -= temp */ \ +} + +/* glm__noiseDetail_i2gxy(vec4 i, vec4 gx, vec4 gy) */ +#define glm__noiseDetail_i2gxy(i, gx, gy) { \ + /* gx = 2.0 * fract(i / 41.0) - 1.0; */ \ + glm_vec4_divs(i, 41.0f, gx); /* gx = i / 41.0 */ \ + glm_vec4_fract(gx, gx); /* gx = fract(gx) */ \ + glm_vec4_scale(gx, 2.0f, gx); /* gx *= 2.0 */ \ + glm_vec4_subs(gx, 1.0f, gx); /* gx -= 1.0 */ \ + \ + /* gy = abs(gx) - 0.5; */ \ + glm_vec4_abs(gx, gy); /* gy = abs(gx) */ \ + glm_vec4_subs(gy, 0.5f, gy); /* gy -= 0.5 */ \ + \ + /* tx = floor(gx + 0.5); */ \ + vec4 tx; \ + glm_vec4_adds(gx, 0.5f, tx); /* tx = gx + 0.5 */ \ + glm_vec4_floor(tx, tx); /* tx = floor(tx) */ \ + \ + /* gx = gx - tx; */ \ + glm_vec4_sub(gx, tx, gx); /* gx -= tx */ \ +} + +/* ============================================================================ + * Classic perlin noise + * ============================================================================ + */ + +/*! + * @brief Classic perlin noise + * + * @param[in] point 4D vector + * @returns perlin noise value + */ +CGLM_INLINE +float +glm_perlin_vec4(vec4 point) { + /* Integer part of p for indexing */ + vec4 Pi0; + glm_vec4_floor(point, Pi0); /* Pi0 = floor(point); */ + + /* Integer part + 1 */ + vec4 Pi1; + glm_vec4_adds(Pi0, 1.0f, Pi1); /* Pi1 = Pi0 + 1.0f; */ + + glm_vec4_mods(Pi0, 289.0f, Pi0); /* Pi0 = mod(Pi0, 289.0f); */ + glm_vec4_mods(Pi1, 289.0f, Pi1); /* Pi1 = mod(Pi1, 289.0f); */ + + /* Fractional part of p for interpolation */ + vec4 Pf0; + glm_vec4_fract(point, Pf0); + + /* Fractional part - 1.0 */ + vec4 Pf1; + glm_vec4_subs(Pf0, 1.0f, Pf1); + + vec4 ix = {Pi0[0], Pi1[0], Pi0[0], Pi1[0]}; + vec4 iy = {Pi0[1], Pi0[1], Pi1[1], Pi1[1]}; + vec4 iz0 = {Pi0[2], Pi0[2], Pi0[2], Pi0[2]}; /* iz0 = vec4(Pi0.z); */ + vec4 iz1 = {Pi1[2], Pi1[2], Pi1[2], Pi1[2]}; /* iz1 = vec4(Pi1.z); */ + vec4 iw0 = {Pi0[3], Pi0[3], Pi0[3], Pi0[3]}; /* iw0 = vec4(Pi0.w); */ + vec4 iw1 = {Pi1[3], Pi1[3], Pi1[3], Pi1[3]}; /* iw1 = vec4(Pi1.w); */ + + /* ------------ */ + + /* ixy = permute(permute(ix) + iy) */ + vec4 ixy; + glm__noiseDetail_permute(ix, ixy); /* ixy = permute(ix) */ + glm_vec4_add(ixy, iy, ixy); /* ixy += iy; */ + glm__noiseDetail_permute(ixy, ixy); /* ixy = permute(ixy) */ + + /* ixy0 = permute(ixy + iz0) */ + vec4 ixy0; + glm_vec4_add(ixy, iz0, ixy0); /* ixy0 = ixy + iz0 */ + glm__noiseDetail_permute(ixy0, ixy0); /* ixy0 = permute(ixy0) */ + + /* ixy1 = permute(ixy + iz1) */ + vec4 ixy1; + glm_vec4_add(ixy, iz1, ixy1); /* ixy1 = ixy, iz1 */ + glm__noiseDetail_permute(ixy1, ixy1); /* ixy1 = permute(ixy1) */ + + /* ixy00 = permute(ixy0 + iw0) */ + vec4 ixy00; + glm_vec4_add(ixy0, iw0, ixy00); /* ixy00 = ixy0 + iw0 */ + glm__noiseDetail_permute(ixy00, ixy00); /* ixy00 = permute(ixy00) */ + + /* ixy01 = permute(ixy0 + iw1) */ + vec4 ixy01; + glm_vec4_add(ixy0, iw1, ixy01); /* ixy01 = ixy0 + iw1 */ + glm__noiseDetail_permute(ixy01, ixy01); /* ixy01 = permute(ixy01) */ + + /* ixy10 = permute(ixy1 + iw0) */ + vec4 ixy10; + glm_vec4_add(ixy1, iw0, ixy10); /* ixy10 = ixy1 + iw0 */ + glm__noiseDetail_permute(ixy10, ixy10); /* ixy10 = permute(ixy10) */ + + /* ixy11 = permute(ixy1 + iw1) */ + vec4 ixy11; + glm_vec4_add(ixy1, iw1, ixy11); /* ixy11 = ixy1 + iw1 */ + glm__noiseDetail_permute(ixy11, ixy11); /* ixy11 = permute(ixy11) */ + + /* ------------ */ + + vec4 gx00, gy00, gz00, gw00; + glm__noiseDetail_i2gxyzw(ixy00, gx00, gy00, gz00, gw00); + + vec4 gx01, gy01, gz01, gw01; + glm__noiseDetail_i2gxyzw(ixy01, gx01, gy01, gz01, gw01); + + vec4 gx10, gy10, gz10, gw10; + glm__noiseDetail_i2gxyzw(ixy10, gx10, gy10, gz10, gw10); + + vec4 gx11, gy11, gz11, gw11; + glm__noiseDetail_i2gxyzw(ixy11, gx11, gy11, gz11, gw11); + + /* ------------ */ + + vec4 g0000 = {gx00[0], gy00[0], gz00[0], gw00[0]}; /* g0000 = vec4(gx00.x, gy00.x, gz00.x, gw00.x); */ + vec4 g0100 = {gx00[2], gy00[2], gz00[2], gw00[2]}; /* g0100 = vec4(gx00.z, gy00.z, gz00.z, gw00.z); */ + vec4 g1000 = {gx00[1], gy00[1], gz00[1], gw00[1]}; /* g1000 = vec4(gx00.y, gy00.y, gz00.y, gw00.y); */ + vec4 g1100 = {gx00[3], gy00[3], gz00[3], gw00[3]}; /* g1100 = vec4(gx00.w, gy00.w, gz00.w, gw00.w); */ + + vec4 g0001 = {gx01[0], gy01[0], gz01[0], gw01[0]}; /* g0001 = vec4(gx01.x, gy01.x, gz01.x, gw01.x); */ + vec4 g0101 = {gx01[2], gy01[2], gz01[2], gw01[2]}; /* g0101 = vec4(gx01.z, gy01.z, gz01.z, gw01.z); */ + vec4 g1001 = {gx01[1], gy01[1], gz01[1], gw01[1]}; /* g1001 = vec4(gx01.y, gy01.y, gz01.y, gw01.y); */ + vec4 g1101 = {gx01[3], gy01[3], gz01[3], gw01[3]}; /* g1101 = vec4(gx01.w, gy01.w, gz01.w, gw01.w); */ + + vec4 g0010 = {gx10[0], gy10[0], gz10[0], gw10[0]}; /* g0010 = vec4(gx10.x, gy10.x, gz10.x, gw10.x); */ + vec4 g0110 = {gx10[2], gy10[2], gz10[2], gw10[2]}; /* g0110 = vec4(gx10.z, gy10.z, gz10.z, gw10.z); */ + vec4 g1010 = {gx10[1], gy10[1], gz10[1], gw10[1]}; /* g1010 = vec4(gx10.y, gy10.y, gz10.y, gw10.y); */ + vec4 g1110 = {gx10[3], gy10[3], gz10[3], gw10[3]}; /* g1110 = vec4(gx10.w, gy10.w, gz10.w, gw10.w); */ + + vec4 g0011 = {gx11[0], gy11[0], gz11[0], gw11[0]}; /* g0011 = vec4(gx11.x, gy11.x, gz11.x, gw11.x); */ + vec4 g0111 = {gx11[2], gy11[2], gz11[2], gw11[2]}; /* g0111 = vec4(gx11.z, gy11.z, gz11.z, gw11.z); */ + vec4 g1011 = {gx11[1], gy11[1], gz11[1], gw11[1]}; /* g1011 = vec4(gx11.y, gy11.y, gz11.y, gw11.y); */ + vec4 g1111 = {gx11[3], gy11[3], gz11[3], gw11[3]}; /* g1111 = vec4(gx11.w, gy11.w, gz11.w, gw11.w); */ + + glm__noiseDetail_gradNorm_vec4(g0000, g0100, g1000, g1100); + glm__noiseDetail_gradNorm_vec4(g0001, g0101, g1001, g1101); + glm__noiseDetail_gradNorm_vec4(g0010, g0110, g1010, g1110); + glm__noiseDetail_gradNorm_vec4(g0011, g0111, g1011, g1111); + + /* ------------ */ + + float n0000 = glm_vec4_dot(g0000, Pf0); /* n0000 = dot(g0000, Pf0) */ + + /* n1000 = dot(g1000, vec4(Pf1.x, Pf0.y, Pf0.z, Pf0.w)) */ + vec4 n1000d = {Pf1[0], Pf0[1], Pf0[2], Pf0[3]}; + float n1000 = glm_vec4_dot(g1000, n1000d); + + /* n0100 = dot(g0100, vec4(Pf0.x, Pf1.y, Pf0.z, Pf0.w)) */ + vec4 n0100d = {Pf0[0], Pf1[1], Pf0[2], Pf0[3]}; + float n0100 = glm_vec4_dot(g0100, n0100d); + + /* n1100 = dot(g1100, vec4(Pf1.x, Pf1.y, Pf0.z, Pf0.w)) */ + vec4 n1100d = {Pf1[0], Pf1[1], Pf0[2], Pf0[3]}; + float n1100 = glm_vec4_dot(g1100, n1100d); + + /* n0010 = dot(g0010, vec4(Pf0.x, Pf0.y, Pf1.z, Pf0.w)) */ + vec4 n0010d = {Pf0[0], Pf0[1], Pf1[2], Pf0[3]}; + float n0010 = glm_vec4_dot(g0010, n0010d); + + /* n1010 = dot(g1010, vec4(Pf1.x, Pf0.y, Pf1.z, Pf0.w)) */ + vec4 n1010d = {Pf1[0], Pf0[1], Pf1[2], Pf0[3]}; + float n1010 = glm_vec4_dot(g1010, n1010d); + + /* n0110 = dot(g0110, vec4(Pf0.x, Pf1.y, Pf1.z, Pf0.w)) */ + vec4 n0110d = {Pf0[0], Pf1[1], Pf1[2], Pf0[3]}; + float n0110 = glm_vec4_dot(g0110, n0110d); + + /* n1110 = dot(g1110, vec4(Pf1.x, Pf1.y, Pf1.z, Pf0.w)) */ + vec4 n1110d = {Pf1[0], Pf1[1], Pf1[2], Pf0[3]}; + float n1110 = glm_vec4_dot(g1110, n1110d); + + /* n0001 = dot(g0001, vec4(Pf0.x, Pf0.y, Pf0.z, Pf1.w)) */ + vec4 n0001d = {Pf0[0], Pf0[1], Pf0[2], Pf1[3]}; + float n0001 = glm_vec4_dot(g0001, n0001d); + + /* n1001 = dot(g1001, vec4(Pf1.x, Pf0.y, Pf0.z, Pf1.w)) */ + vec4 n1001d = {Pf1[0], Pf0[1], Pf0[2], Pf1[3]}; + float n1001 = glm_vec4_dot(g1001, n1001d); + + /* n0101 = dot(g0101, vec4(Pf0.x, Pf1.y, Pf0.z, Pf1.w)) */ + vec4 n0101d = {Pf0[0], Pf1[1], Pf0[2], Pf1[3]}; + float n0101 = glm_vec4_dot(g0101, n0101d); + + /* n1101 = dot(g1101, vec4(Pf1.x, Pf1.y, Pf0.z, Pf1.w)) */ + vec4 n1101d = {Pf1[0], Pf1[1], Pf0[2], Pf1[3]}; + float n1101 = glm_vec4_dot(g1101, n1101d); + + /* n0011 = dot(g0011, vec4(Pf0.x, Pf0.y, Pf1.z, Pf1.w)) */ + vec4 n0011d = {Pf0[0], Pf0[1], Pf1[2], Pf1[3]}; + float n0011 = glm_vec4_dot(g0011, n0011d); + + /* n1011 = dot(g1011, vec4(Pf1.x, Pf0.y, Pf1.z, Pf1.w)) */ + vec4 n1011d = {Pf1[0], Pf0[1], Pf1[2], Pf1[3]}; + float n1011 = glm_vec4_dot(g1011, n1011d); + + /* n0111 = dot(g0111, vec4(Pf0.x, Pf1.y, Pf1.z, Pf1.w)) */ + vec4 n0111d = {Pf0[0], Pf1[1], Pf1[2], Pf1[3]}; + float n0111 = glm_vec4_dot(g0111, n0111d); + + float n1111 = glm_vec4_dot(g1111, Pf1); /* n1111 = dot(g1111, Pf1) */ + + /* ------------ */ + + vec4 fade_xyzw; + glm__noiseDetail_fade_vec4(Pf0, fade_xyzw); /* fade_xyzw = fade(Pf0) */ + + /* n_0w = lerp(vec4(n0000, n1000, n0100, n1100), vec4(n0001, n1001, n0101, n1101), fade_xyzw.w) */ + vec4 n_0w1 = {n0000, n1000, n0100, n1100}; + vec4 n_0w2 = {n0001, n1001, n0101, n1101}; + vec4 n_0w; + glm_vec4_lerp(n_0w1, n_0w2, fade_xyzw[3], n_0w); + + /* n_1w = lerp(vec4(n0010, n1010, n0110, n1110), vec4(n0011, n1011, n0111, n1111), fade_xyzw.w) */ + vec4 n_1w1 = {n0010, n1010, n0110, n1110}; + vec4 n_1w2 = {n0011, n1011, n0111, n1111}; + vec4 n_1w; + glm_vec4_lerp(n_1w1, n_1w2, fade_xyzw[3], n_1w); + + /* n_zw = lerp(n_0w, n_1w, fade_xyzw.z) */ + vec4 n_zw; + glm_vec4_lerp(n_0w, n_1w, fade_xyzw[2], n_zw); + + /* n_yzw = lerp(vec2(n_zw.x, n_zw.y), vec2(n_zw.z, n_zw.w), fade_xyzw.y) */ + vec2 n_yzw; + vec2 n_yzw1 = {n_zw[0], n_zw[1]}; + vec2 n_yzw2 = {n_zw[2], n_zw[3]}; + glm_vec2_lerp(n_yzw1, n_yzw2, fade_xyzw[1], n_yzw); + + /* n_xyzw = lerp(n_yzw.x, n_yzw.y, fade_xyzw.x) */ + float n_xyzw = glm_lerp(n_yzw[0], n_yzw[1], fade_xyzw[0]); + + return n_xyzw * 2.2f; +} + + +/*! + * @brief Classic perlin noise + * + * @param[in] point 3D vector + * @returns perlin noise value + */ +CGLM_INLINE +float +glm_perlin_vec3(vec3 point) { + /* Integer part of p for indexing */ + vec3 Pi0; + glm_vec3_floor(point, Pi0); /* Pi0 = floor(point); */ + + /* Integer part + 1 */ + vec3 Pi1; + glm_vec3_adds(Pi0, 1.0f, Pi1); /* Pi1 = Pi0 + 1.0f; */ + + glm_vec3_mods(Pi0, 289.0f, Pi0); /* Pi0 = mod(Pi0, 289.0f); */ + glm_vec3_mods(Pi1, 289.0f, Pi1); /* Pi1 = mod(Pi1, 289.0f); */ + + /* Fractional part of p for interpolation */ + vec3 Pf0; + glm_vec3_fract(point, Pf0); + + /* Fractional part - 1.0 */ + vec3 Pf1; + glm_vec3_subs(Pf0, 1.0f, Pf1); + + vec4 ix = {Pi0[0], Pi1[0], Pi0[0], Pi1[0]}; + vec4 iy = {Pi0[1], Pi0[1], Pi1[1], Pi1[1]}; + vec4 iz0 = {Pi0[2], Pi0[2], Pi0[2], Pi0[2]}; /* iz0 = vec4(Pi0.z); */ + vec4 iz1 = {Pi1[2], Pi1[2], Pi1[2], Pi1[2]}; /* iz1 = vec4(Pi1.z); */ + + /* ------------ */ + + /* ixy = permute(permute(ix) + iy) */ + vec4 ixy; + glm__noiseDetail_permute(ix, ixy); /* ixy = permute(ix) */ + glm_vec4_add(ixy, iy, ixy); /* ixy += iy; */ + glm__noiseDetail_permute(ixy, ixy); /* ixy = permute(ixy) */ + + /* ixy0 = permute(ixy + iz0) */ + vec4 ixy0; + glm_vec4_add(ixy, iz0, ixy0); /* ixy0 = ixy + iz0 */ + glm__noiseDetail_permute(ixy0, ixy0); /* ixy0 = permute(ixy0) */ + + /* ixy1 = permute(ixy + iz1) */ + vec4 ixy1; + glm_vec4_add(ixy, iz1, ixy1); /* ixy1 = ixy, iz1 */ + glm__noiseDetail_permute(ixy1, ixy1); /* ixy1 = permute(ixy1) */ + + /* ------------ */ + + vec4 gx0, gy0, gz0; + glm__noiseDetail_i2gxyz(ixy0, gx0, gy0, gz0); + + vec4 gx1, gy1, gz1; + glm__noiseDetail_i2gxyz(ixy1, gx1, gy1, gz1); + + /* ------------ */ + + vec3 g000 = {gx0[0], gy0[0], gz0[0]}; /* g000 = vec3(gx0.x, gy0.x, gz0.x); */ + vec3 g100 = {gx0[1], gy0[1], gz0[1]}; /* g100 = vec3(gx0.y, gy0.y, gz0.y); */ + vec3 g010 = {gx0[2], gy0[2], gz0[2]}; /* g010 = vec3(gx0.z, gy0.z, gz0.z); */ + vec3 g110 = {gx0[3], gy0[3], gz0[3]}; /* g110 = vec3(gx0.w, gy0.w, gz0.w); */ + + vec3 g001 = {gx1[0], gy1[0], gz1[0]}; /* g001 = vec3(gx1.x, gy1.x, gz1.x); */ + vec3 g101 = {gx1[1], gy1[1], gz1[1]}; /* g101 = vec3(gx1.y, gy1.y, gz1.y); */ + vec3 g011 = {gx1[2], gy1[2], gz1[2]}; /* g011 = vec3(gx1.z, gy1.z, gz1.z); */ + vec3 g111 = {gx1[3], gy1[3], gz1[3]}; /* g111 = vec3(gx1.w, gy1.w, gz1.w); */ + + glm__noiseDetail_gradNorm_vec3(g000, g010, g100, g110); + glm__noiseDetail_gradNorm_vec3(g001, g011, g101, g111); + + /* ------------ */ + + float n000 = glm_vec3_dot(g000, Pf0); /* n000 = dot(g000, Pf0) */ + + /* n100 = dot(g100, vec3(Pf1.x, Pf0.y, Pf0.z)) */ + vec3 n100d = {Pf1[0], Pf0[1], Pf0[2]}; + float n100 = glm_vec3_dot(g100, n100d); + + /* n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)) */ + vec3 n010d = {Pf0[0], Pf1[1], Pf0[2]}; + float n010 = glm_vec3_dot(g010, n010d); + + /* n110 = dot(g110, vec3(Pf1.x, Pf1.y, Pf0.z)) */ + vec3 n110d = {Pf1[0], Pf1[1], Pf0[2]}; + float n110 = glm_vec3_dot(g110, n110d); + + /* n001 = dot(g001, vec3(Pf0.x, Pf0.y, Pf1.z)) */ + vec3 n001d = {Pf0[0], Pf0[1], Pf1[2]}; + float n001 = glm_vec3_dot(g001, n001d); + + /* n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)) */ + vec3 n101d = {Pf1[0], Pf0[1], Pf1[2]}; + float n101 = glm_vec3_dot(g101, n101d); + + /* n011 = dot(g011, vec3(Pf0.x, Pf1.y, Pf1.z)) */ + vec3 n011d = {Pf0[0], Pf1[1], Pf1[2]}; + float n011 = glm_vec3_dot(g011, n011d); + + float n111 = glm_vec3_dot(g111, Pf1); /* n111 = dot(g111, Pf1) */ + + /* ------------ */ + + vec3 fade_xyz; + glm__noiseDetail_fade_vec3(Pf0, fade_xyz); /* fade_xyz = fade(Pf0) */ + + /* n_z = lerp(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); */ + vec4 n_z; + vec4 n_z1 = {n000, n100, n010, n110}; + vec4 n_z2 = {n001, n101, n011, n111}; + glm_vec4_lerp(n_z1, n_z2, fade_xyz[2], n_z); + + /* vec2 n_yz = lerp(vec2(n_z.x, n_z.y), vec2(n_z.z, n_z.w), fade_xyz.y); */ + vec2 n_yz; + vec2 n_yz1 = {n_z[0], n_z[1]}; + vec2 n_yz2 = {n_z[2], n_z[3]}; + glm_vec2_lerp(n_yz1, n_yz2, fade_xyz[1], n_yz); + + /* n_xyz = lerp(n_yz.x, n_yz.y, fade_xyz.x); */ + float n_xyz = glm_lerp(n_yz[0], n_yz[1], fade_xyz[0]); + + return n_xyz * 2.2f; +} + +/*! + * @brief Classic perlin noise + * + * @param[in] point 2D vector + * @returns perlin noise value + */ +CGLM_INLINE +float +glm_perlin_vec2(vec2 point) { + + /* Integer part of p for indexing */ + /* Pi = floor(vec4(point.x, point.y, point.x, point.y)) + vec4(0.0, 0.0, 1.0, 1.0); */ + vec4 Pi = {point[0], point[1], point[0], point[1]}; /* Pi = vec4(point.x, point.y, point.x, point.y) */ + glm_vec4_floor(Pi, Pi); /* Pi = floor(Pi) */ + Pi[2] += 1.0f; /* Pi.z += 1.0 */ + Pi[3] += 1.0f; /* Pi.w += 1.0 */ + + /* Fractional part of p for interpolation */ + /* vec<4, T, Q> Pf = glm::fract(vec<4, T, Q>(Position.x, Position.y, Position.x, Position.y)) - vec<4, T, Q>(0.0, 0.0, 1.0, 1.0); */ + vec4 Pf = {point[0], point[1], point[0], point[1]}; /* Pf = vec4(point.x, point.y, point.x, point.y) */ + glm_vec4_fract(Pf, Pf); /* Pf = fract(Pf) */ + Pf[2] -= 1.0f; /* Pf.z -= 1.0 */ + Pf[3] -= 1.0f; /* Pf.w -= 1.0 */ + + /* Mod to avoid truncation effects in permutation */ + glm_vec4_mods(Pi, 289.0f, Pi); /* Pi = mod(Pi, 289.0f); */ + + vec4 ix = {Pi[0], Pi[2], Pi[0], Pi[2]}; /* ix = vec4(Pi.x, Pi.z, Pi.x, Pi.z) */ + vec4 iy = {Pi[1], Pi[1], Pi[3], Pi[3]}; /* iy = vec4(Pi.y, Pi.y, Pi.w, Pi.w) */ + vec4 fx = {Pf[0], Pf[2], Pf[0], Pf[2]}; /* fx = vec4(Pf.x, Pf.z, Pf.x, Pf.z) */ + vec4 fy = {Pf[1], Pf[1], Pf[3], Pf[3]}; /* fy = vec4(Pf.y, Pf.y, Pf.w, Pf.w) */ + + /* ------------ */ + + /* i = permute(permute(ix) + iy); */ + vec4 i; + glm__noiseDetail_permute(ix, i); /* i = permute(ix) */ + glm_vec4_add(i, iy, i); /* i += iy; */ + glm__noiseDetail_permute(i, i); /* i = permute(i) */ + + /* ------------ */ + + vec4 gx, gy; + glm__noiseDetail_i2gxy(i, gx, gy); + + /* ------------ */ + + vec2 g00 = {gx[0], gy[0]}; /* g00 = vec2(gx.x, gy.x) */ + vec2 g10 = {gx[1], gy[1]}; /* g10 = vec2(gx.y, gy.y) */ + vec2 g01 = {gx[2], gy[2]}; /* g01 = vec2(gx.z, gy.z) */ + vec2 g11 = {gx[3], gy[3]}; /* g11 = vec2(gx.w, gy.w) */ + + glm__noiseDetail_gradNorm_vec2(g00, g01, g10, g11); + + /* ------------ */ + + /* n00 = dot(g00, vec2(fx.x, fy.x)) */ + vec2 n00d = {fx[0], fy[0]}; /* n00d = vec2(fx.x, fy.x) */ + float n00 = glm_vec2_dot(g00, n00d); /* n00 = dot(g00, n00d) */ + + /* n10 = dot(g10, vec2(fx.y, fy.y)) */ + vec2 n10d = {fx[1], fy[1]}; /* n10d = vec2(fx.y, fy.y) */ + float n10 = glm_vec2_dot(g10, n10d); /* n10 = dot(g10, n10d) */ + + /* n01 = dot(g01, vec2(fx.z, fy.z)) */ + vec2 n01d = {fx[2], fy[2]}; /* n01d = vec2(fx.z, fy.z) */ + float n01 = glm_vec2_dot(g01, n01d); /* n01 = dot(g01, n01d) */ + + /* n11 = dot(g11, vec2(fx.w, fy.w)) */ + vec2 n11d = {fx[3], fy[3]}; /* n11d = vec2(fx.w, fy.w) */ + float n11 = glm_vec2_dot(g11, n11d); /* n11 = dot(g11, n11d) */ + + /* ------------ */ + + /* fade_xyz = fade(vec2(Pf.x, Pf.y)) */ + vec2 fade_xy; + vec2 temp2 = {Pf[0], Pf[1]}; /* temp = vec2(Pf.x, Pf.y) */ + glm__noiseDetail_fade_vec2(temp2, fade_xy); /* fade_xy = fade(temp) */ + + /* n_x = lerp(vec2(n00, n01), vec2(n10, n11), fade_xy.x); */ + vec2 n_x; + vec2 n_x1 = {n00, n01}; /* n_x1 = vec2(n00, n01) */ + vec2 n_x2 = {n10, n11}; /* n_x2 = vec2(n10, n11) */ + glm_vec2_lerp(n_x1, n_x2, fade_xy[0], n_x); /* n_x = lerp(n_x1, n_x2, fade_xy.x) */ + + /* T n_xy = mix(n_x.x, n_x.y, fade_xy.y); */ + /* n_xy = lerp(n_x.x, n_x.y, fade_xy.y); */ + float n_xy = glm_lerp(n_x[0], n_x[1], fade_xy[1]); + + return n_xy * 2.3f; +} + +/* Undefine all helper macros */ + +#undef glm__noiseDetail_mod289 +#undef glm__noiseDetail_permute +#undef glm__noiseDetail_fade_vec4 +#undef glm__noiseDetail_fade_vec3 +#undef glm__noiseDetail_fade_vec2 +#undef glm__noiseDetail_taylorInvSqrt +#undef glm__noiseDetail_gradNorm_vec4 +#undef glm__noiseDetail_gradNorm_vec3 +#undef glm__noiseDetail_gradNorm_vec2 +#undef glm__noiseDetail_i2gxyzw +#undef glm__noiseDetail_i2gxyz +#undef glm__noiseDetail_i2gxy + +#endif /* cglm_noise_h */ diff --git a/include/cglm/struct.h b/include/cglm/struct.h index 1426589..31ca4e2 100644 --- a/include/cglm/struct.h +++ b/include/cglm/struct.h @@ -31,6 +31,7 @@ extern "C" { #include "struct/affine.h" #include "struct/frustum.h" #include "struct/plane.h" +#include "struct/noise.h" #include "struct/box.h" #include "struct/color.h" #include "struct/io.h" diff --git a/include/cglm/struct/noise.h b/include/cglm/struct/noise.h new file mode 100644 index 0000000..3fd7d2e --- /dev/null +++ b/include/cglm/struct/noise.h @@ -0,0 +1,57 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglms_noises_h +#define cglms_noises_h + +#include "../common.h" +#include "../types-struct.h" +#include "../noise.h" +#include "vec4.h" + +/* + Functions: + CGLM_INLINE float glms_perlin_vec4(vec4s point); + */ + +/*! + * @brief Classic perlin noise + * + * @param[in] point 4D vector + * @returns perlin noise value + */ +CGLM_INLINE +float +glms_perlin_vec4(vec4s point) { + return glm_perlin_vec4(point.raw); +} + +/*! + * @brief Classic perlin noise + * + * @param[in] point 3D vector + * @returns perlin noise value + */ +CGLM_INLINE +float +glms_perlin_vec3(vec3s point) { + return glm_perlin_vec3(point.raw); +} + +/*! + * @brief Classic perlin noise + * + * @param[in] point 2D vector + * @returns perlin noise value + */ +CGLM_INLINE +float +glms_perlin_vec2(vec2s point) { + return glm_perlin_vec2(point.raw); +} + +#endif /* cglms_noises_h */ diff --git a/include/cglm/struct/vec2-ext.h b/include/cglm/struct/vec2-ext.h index 7d77386..246132f 100644 --- a/include/cglm/struct/vec2-ext.h +++ b/include/cglm/struct/vec2-ext.h @@ -23,6 +23,12 @@ CGLM_INLINE bool glms_vec2_isinf(vec2s v) CGLM_INLINE bool glms_vec2_isvalid(vec2s v) CGLM_INLINE vec2s glms_vec2_sign(vec2s v) + CGLM_INLINE vec2s glms_vec2_abs(vec2s v) + CGLM_INLINE vec2s glms_vec2_fract(vec2s v) + CGLM_INLINE vec2s glms_vec2_floor(vec2s v) + CGLM_INLINE vec2s glms_vec2_mods(vec2s v, float s) + CGLM_INLINE vec2s glms_vec2_steps(float edge, vec2s v) + CGLM_INLINE vec2s glms_vec2_stepr(vec2s edge, float v) CGLM_INLINE vec2s glms_vec2_sqrt(vec2s v) */ @@ -184,6 +190,95 @@ glms_vec2_(sign)(vec2s v) { return r; } +/*! + * @brief fractional part of each vector item + * + * @param v vector + * @returns abs vector + */ +CGLM_INLINE +vec2s +glms_vec2_(abs)(vec2s v) { + vec2s r; + glm_vec2_abs(v.raw, r.raw); + return r; +} + +/*! + * @brief fractional part of each vector item + * + * @param[in] v vector + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_(fract)(vec2s v) { + vec2s r; + glm_vec2_fract(v.raw, r.raw); + return r; +} + +/*! + * @brief floor of each vector item + * + * @param[in] v vector + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_(floor)(vec2s v) { + vec2s r; + glm_vec2_floor(v.raw, r.raw); + return r; +} + +/*! + * @brief mod of each vector item by scalar + * + * @param[in] v vector + * @param[in] s scalar + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_(mods)(vec2s v, float s) { + vec2s r; + glm_vec2_mods(v.raw, s, r.raw); + return r; +} + +/*! + * @brief threshold each vector item with scalar + * condition is: (x[i] < edge) ? 0.0 : 1.0 + * + * @param[in] edge threshold + * @param[in] x vector to test against threshold + * @returns destination + */ +CGLM_INLINE +vec2s +glms_vec2_(steps)(float edge, vec2s x) { + vec2s r; + glm_vec2_steps(edge, x.raw, r.raw); + return r; +} + +/*! + * @brief threshold a value with *vector* as the threshold + * condition is: (x < edge[i]) ? 0.0 : 1.0 + * + * @param[in] edge threshold vector + * @param[in] x value to test against threshold + * @returns destination + */ +CGLM_INLINE +vec2s +glms_vec2_(stepr)(vec2s edge, float x) { + vec2s r; + glm_vec2_stepr(edge.raw, x, r.raw); + return r; +} + /*! * @brief square root of each vector item * diff --git a/include/cglm/struct/vec2.h b/include/cglm/struct/vec2.h index e1190e2..40ed659 100644 --- a/include/cglm/struct/vec2.h +++ b/include/cglm/struct/vec2.h @@ -53,6 +53,7 @@ CGLM_INLINE vec2s glms_vec2_minv(vec2s a, vec2s b) CGLM_INLINE vec2s glms_vec2_clamp(vec2s v, float minVal, float maxVal) CGLM_INLINE vec2s glms_vec2_lerp(vec2s from, vec2s to, float t) + CGLM_INLINE vec2s glms_vec2_step(vec2s edge, vec2s x) CGLM_INLINE vec2s glms_vec2_make(float * restrict src) CGLM_INLINE vec2s glms_vec2_reflect(vec2s v, vec2s n) CGLM_INLINE bool glms_vec2_refract(vec2s v, vec2s n, float eta, vec2s *dest) @@ -679,6 +680,21 @@ glms_vec2_(lerp)(vec2s from, vec2s to, float t) { return r; } +/*! + * @brief threshold function + * + * @param[in] edge threshold + * @param[in] x value to test against threshold + * @returns destination + */ +CGLM_INLINE +vec2s +glms_vec2_(step)(vec2s edge, vec2s x) { + vec2s r; + glm_vec2_step(edge.raw, x.raw, r.raw); + return r; +} + /*! * @brief Create two dimensional vector from pointer * diff --git a/include/cglm/struct/vec3-ext.h b/include/cglm/struct/vec3-ext.h index 1a3e88a..6cd8ca0 100644 --- a/include/cglm/struct/vec3-ext.h +++ b/include/cglm/struct/vec3-ext.h @@ -26,6 +26,10 @@ CGLM_INLINE vec3s glms_vec3_sign(vec3s v); CGLM_INLINE vec3s glms_vec3_abs(vec3s v); CGLM_INLINE vec3s glms_vec3_fract(vec3s v); + CGLM_INLINE vec3s glms_vec3_floor(vec3s v); + CGLM_INLINE vec3s glms_vec3_mods(vec3s v, float s); + CGLM_INLINE vec3s glms_vec3_steps(float edge, vec3s v); + CGLM_INLINE vec3s glms_vec3_stepr(vec3s edge, float v); CGLM_INLINE float glms_vec3_hadd(vec3s v); CGLM_INLINE vec3s glms_vec3_sqrt(vec3s v); */ @@ -230,6 +234,67 @@ glms_vec3_(fract)(vec3s v) { return r; } +/*! + * @brief floor of each vector item + * + * @param[in] v vector + * @return dest destination vector + */ +CGLM_INLINE +vec3s +glms_vec3_(floor)(vec3s v) { + vec3s r; + glm_vec3_floor(v.raw, r.raw); + return r; +} + +/*! + * @brief mod of each vector item by scalar + * + * @param[in] v vector + * @param[in] s scalar + * @returns destination vector + */ +CGLM_INLINE +vec3s +glms_vec3_(mods)(vec3s v, float s) { + vec3s r; + glm_vec3_mods(v.raw, s, r.raw); + return r; +} + +/*! + * @brief threshold each vector item with scalar + * condition is: (x[i] < edge) ? 0.0 : 1.0 + * + * @param[in] edge threshold + * @param[in] x vector to test against threshold + * @returns destination + */ +CGLM_INLINE +vec3s +glms_vec3_(steps)(float edge, vec3s x) { + vec3s r; + glm_vec3_steps(edge, x.raw, r.raw); + return r; +} + +/*! + * @brief threshold a value with *vector* as the threshold + * condition is: (x < edge[i]) ? 0.0 : 1.0 + * + * @param[in] edge threshold vector + * @param[in] x value to test against threshold + * @returns destination + */ +CGLM_INLINE +vec3s +glms_vec3_(stepr)(vec3s edge, float x) { + vec3s r; + glm_vec3_stepr(edge.raw, x, r.raw); + return r; +} + /*! * @brief vector reduction by summation * @warning could overflow diff --git a/include/cglm/struct/vec3.h b/include/cglm/struct/vec3.h index 536af03..a1d901e 100644 --- a/include/cglm/struct/vec3.h +++ b/include/cglm/struct/vec3.h @@ -68,7 +68,6 @@ 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_uni(float edge, vec3s x); 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); @@ -84,6 +83,9 @@ 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 @@ -95,6 +97,9 @@ #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} @@ -910,21 +915,6 @@ glms_vec3_(mixc)(vec3s from, vec3s to, float t) { return r; } -/*! - * @brief threshold function (unidimensional) - * - * @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_uni)(float edge, vec3s x) { - vec3s r; - glm_vec3_step_uni(edge, x.raw, r.raw); - return r; -} - /*! * @brief threshold function * diff --git a/include/cglm/struct/vec4-ext.h b/include/cglm/struct/vec4-ext.h index 6f48d93..f57348e 100644 --- a/include/cglm/struct/vec4-ext.h +++ b/include/cglm/struct/vec4-ext.h @@ -26,6 +26,10 @@ CGLM_INLINE vec4s glms_vec4_sign(vec4s v); CGLM_INLINE vec4s glms_vec4_abs(vec4s v); CGLM_INLINE vec4s glms_vec4_fract(vec4s v); + CGLM_INLINE float glms_vec4_floor(vec4s v); + CGLM_INLINE float glms_vec4_mods(vec4s v, float s); + CGLM_INLINE float glms_vec4_steps(float edge, vec4s v); + CGLM_INLINE void glms_vec4_stepr(vec4s edge, float v); CGLM_INLINE float glms_vec4_hadd(vec4s v); CGLM_INLINE vec4s glms_vec4_sqrt(vec4s v); */ @@ -230,6 +234,67 @@ glms_vec4_(fract)(vec4s v) { return r; } +/*! + * @brief floor of each vector item + * + * @param[in] v vector + * @returns dest destination vector + */ +CGLM_INLINE +vec4s +glms_vec4_(floor)(vec4s v) { + vec4s r; + glm_vec4_floor(v.raw, r.raw); + return r; +} + +/*! + * @brief mod of each vector item by scalar + * + * @param[in] v vector + * @param[in] s scalar + * @returns destination vector + */ +CGLM_INLINE +vec4s +glms_vec4_(mods)(vec4s v, float s) { + vec4s r; + glm_vec4_mods(v.raw, s, r.raw); + return r; +} + +/*! + * @brief threshold each vector item with scalar + * condition is: (x[i] < edge) ? 0.0 : 1.0 + * + * @param[in] edge threshold + * @param[in] x vector to test against threshold + * @returns destination + */ +CGLM_INLINE +vec4s +glms_vec4_(steps)(float edge, vec4s x) { + vec4s r; + glm_vec4_steps(edge, x.raw, r.raw); + return r; +} + +/*! + * @brief threshold a value with *vector* as the threshold + * condition is: (x < edge[i]) ? 0.0 : 1.0 + * + * @param[in] edge threshold vector + * @param[in] x value to test against threshold + * @returns destination + */ +CGLM_INLINE +vec4s +glms_vec4_(stepr)(vec4s edge, float x) { + vec4s r; + glm_vec4_stepr(edge.raw, x, r.raw); + return r; +} + /*! * @brief vector reduction by summation * @warning could overflow diff --git a/include/cglm/struct/vec4.h b/include/cglm/struct/vec4.h index 8b2ef00..a64c1a3 100644 --- a/include/cglm/struct/vec4.h +++ b/include/cglm/struct/vec4.h @@ -58,7 +58,6 @@ CGLM_INLINE vec4s glms_vec4_lerpc(vec4s from, vec4s to, float t); CGLM_INLINE vec4s glms_vec4_mix(vec4s from, vec4s to, float t); CGLM_INLINE vec4s glms_vec4_mixc(vec4s from, vec4s to, float t); - CGLM_INLINE vec4s glms_vec4_step_uni(float edge, vec4s x); CGLM_INLINE vec4s glms_vec4_step(vec4s edge, vec4s x); CGLM_INLINE vec4s glms_vec4_smoothstep_uni(float edge0, float edge1, vec4s x); CGLM_INLINE vec4s glms_vec4_smoothstep(vec4s edge0, vec4s edge1, vec4s x); @@ -69,6 +68,9 @@ CGLM_INLINE vec4s glms_vec4_make(float * restrict src); CGLM_INLINE vec4s glms_vec4_reflect(vec4s v, vec4s n); CGLM_INLINE bool glms_vec4_refract(vec4s v, vec4s n, float eta, vec4s *dest) + + Deprecated: + glms_vec4_step_uni --> use glms_vec4_steps */ #ifndef cglms_vec4s_h @@ -80,6 +82,9 @@ #include "../vec4.h" #include "vec4-ext.h" +/* DEPRECATED! */ +#define glms_vec4_step_uni(edge, x) glms_vec4_steps(edge, x) + #define GLMS_VEC4_ONE_INIT {GLM_VEC4_ONE_INIT} #define GLMS_VEC4_BLACK_INIT {GLM_VEC4_BLACK_INIT} #define GLMS_VEC4_ZERO_INIT {GLM_VEC4_ZERO_INIT} @@ -786,21 +791,6 @@ glms_vec4_(mixc)(vec4s from, vec4s to, float t) { return r; } -/*! - * @brief threshold function (unidimensional) - * - * @param[in] edge threshold - * @param[in] x value to test against threshold - * @returns 0.0 if x < edge, else 1.0 - */ -CGLM_INLINE -vec4s -glms_vec4_(step_uni)(float edge, vec4s x) { - vec4s r; - glm_vec4_step_uni(edge, x.raw, r.raw); - return r; -} - /*! * @brief threshold function * diff --git a/include/cglm/vec2-ext.h b/include/cglm/vec2-ext.h index ac6615e..4322618 100644 --- a/include/cglm/vec2-ext.h +++ b/include/cglm/vec2-ext.h @@ -20,6 +20,11 @@ CGLM_INLINE bool glm_vec2_isvalid(vec2 v); CGLM_INLINE void glm_vec2_sign(vec2 v, vec2 dest); CGLM_INLINE void glm_vec2_abs(vec2 v, vec2 dest); + CGLM_INLINE void glm_vec2_fract(vec2 v, vec2 dest); + CGLM_INLINE void glm_vec2_floor(vec2 v, vec2 dest); + CGLM_INLINE float glm_vec2_mods(vec2 v, float s, vec2 dest); + CGLM_INLINE float glm_vec2_steps(float edge, vec2 v, vec2 dest); + CGLM_INLINE void glm_vec2_stepr(vec2 edge, float v, vec2 dest); CGLM_INLINE void glm_vec2_sqrt(vec2 v, vec2 dest); CGLM_INLINE void glm_vec2_complex_mul(vec2 a, vec2 b, vec2 dest) CGLM_INLINE void glm_vec2_complex_div(vec2 a, vec2 b, vec2 dest) @@ -198,6 +203,46 @@ glm_vec2_abs(vec2 v, vec2 dest) { dest[1] = fabsf(v[1]); } +/*! + * @brief fractional part of each vector item + * + * @param[in] v vector + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_fract(vec2 v, vec2 dest) { + dest[0] = fminf(v[0] - floorf(v[0]), 0.999999940395355224609375f); + dest[1] = fminf(v[1] - floorf(v[1]), 0.999999940395355224609375f); +} + +/*! + * @brief floor of each vector item + * + * @param[in] v vector + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_floor(vec2 x, vec2 dest) { + dest[0] = floorf(x[0]); + dest[1] = floorf(x[1]); +} + +/*! + * @brief mod of each vector item, result is written to dest (dest = v % s) + * + * @param[in] v vector + * @param[in] s scalar + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_mods(vec2 x, float y, vec2 dest) { + dest[0] = fmodf(x[0], y); + dest[1] = fmodf(x[1], y); +} + /*! * @brief square root of each vector item * @@ -228,6 +273,36 @@ glm_vec2_complex_mul(vec2 a, vec2 b, vec2 dest) { dest[1] = ti; } +/*! + * @brief threshold each vector item with scalar + * condition is: (x[i] < edge) ? 0.0 : 1.0 + * + * @param[in] edge threshold + * @param[in] x vector to test against threshold + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_steps(float edge, vec2 x, vec2 dest) { + dest[0] = glm_step(edge, x[0]); + dest[1] = glm_step(edge, x[1]); +} + +/*! + * @brief threshold a value with *vector* as the threshold + * condition is: (x < edge[i]) ? 0.0 : 1.0 + * + * @param[in] edge threshold vector + * @param[in] x value to test against threshold + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_stepr(vec2 edge, float x, vec2 dest) { + dest[0] = glm_step(edge[0], x); + dest[1] = glm_step(edge[1], x); +} + /*! * @brief treat vectors as complex numbers and divide them as such. * diff --git a/include/cglm/vec2.h b/include/cglm/vec2.h index 98cd4df..655fb4b 100644 --- a/include/cglm/vec2.h +++ b/include/cglm/vec2.h @@ -53,7 +53,9 @@ CGLM_INLINE void glm_vec2_maxv(vec2 v1, vec2 v2, vec2 dest) CGLM_INLINE void glm_vec2_minv(vec2 v1, vec2 v2, vec2 dest) CGLM_INLINE void glm_vec2_clamp(vec2 v, float minVal, float maxVal) + CGLM_INLINE void glm_vec2_swizzle(vec2 v, int mask, vec2 dest) CGLM_INLINE void glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) + CGLM_INLINE void glm_vec2_step(vec2 edge, vec2 x, vec2 dest) CGLM_INLINE void glm_vec2_make(float * restrict src, vec2 dest) CGLM_INLINE void glm_vec2_reflect(vec2 v, vec2 n, vec2 dest) CGLM_INLINE void glm_vec2_refract(vec2 v, vec2 n, float eta, vec2 dest) @@ -679,6 +681,24 @@ glm_vec2_clamp(vec2 v, float minval, float maxval) { v[1] = glm_clamp(v[1], minval, maxval); } +/*! + * @brief swizzle vector components + * + * @param[in] v source + * @param[in] mask mask + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_swizzle(vec2 v, int mask, vec2 dest) { + vec2 t; + + t[0] = v[(mask & (3 << 0))]; + t[1] = v[(mask & (3 << 2)) >> 2]; + + glm_vec2_copy(t, dest); +} + /*! * @brief linear interpolation between two vector * @@ -701,6 +721,20 @@ glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) { glm_vec2_add(from, v, dest); } +/*! + * @brief threshold function + * + * @param[in] edge threshold + * @param[in] x value to test against threshold + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_step(vec2 edge, vec2 x, vec2 dest) { + dest[0] = glm_step(edge[0], x[0]); + dest[1] = glm_step(edge[1], x[1]); +} + /*! * @brief Create two dimensional vector from pointer * diff --git a/include/cglm/vec3-ext.h b/include/cglm/vec3-ext.h index 808d32c..6b8c041 100644 --- a/include/cglm/vec3-ext.h +++ b/include/cglm/vec3-ext.h @@ -26,6 +26,10 @@ CGLM_INLINE void glm_vec3_sign(vec3 v, vec3 dest); CGLM_INLINE void glm_vec3_abs(vec3 v, vec3 dest); CGLM_INLINE void glm_vec3_fract(vec3 v, vec3 dest); + CGLM_INLINE void glm_vec3_floor(vec3 v, vec3 dest); + CGLM_INLINE float glm_vec3_mods(vec3 v, float s, vec3 dest); + CGLM_INLINE float glm_vec3_steps(float edge, vec3 v, vec3 dest); + CGLM_INLINE void glm_vec3_stepr(vec3 edge, float v, vec3 dest); CGLM_INLINE float glm_vec3_hadd(vec3 v); CGLM_INLINE void glm_vec3_sqrt(vec3 v, vec3 dest); */ @@ -250,6 +254,67 @@ glm_vec3_fract(vec3 v, vec3 dest) { dest[2] = fminf(v[2] - floorf(v[2]), 0.999999940395355224609375f); } +/*! + * @brief floor of each vector item + * + * @param[in] v vector + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec3_floor(vec3 x, vec3 dest) { + dest[0] = floorf(x[0]); + dest[1] = floorf(x[1]); + dest[2] = floorf(x[2]); +} + +/*! + * @brief mod of each vector item, result is written to dest (dest = v % s) + * + * @param[in] v vector + * @param[in] s scalar + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec3_mods(vec3 x, float y, vec3 dest) { + dest[0] = fmodf(x[0], y); + dest[1] = fmodf(x[1], y); + dest[2] = fmodf(x[2], y); +} + +/*! + * @brief threshold each vector item with scalar + * condition is: (x[i] < edge) ? 0.0 : 1.0 + * + * @param[in] edge threshold + * @param[in] x vector to test against threshold + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec3_steps(float edge, vec3 x, vec3 dest) { + dest[0] = glm_step(edge, x[0]); + dest[1] = glm_step(edge, x[1]); + dest[2] = glm_step(edge, x[2]); +} + +/*! + * @brief threshold a value with *vector* as the threshold + * condition is: (x < edge[i]) ? 0.0 : 1.0 + * + * @param[in] edge threshold vector + * @param[in] x value to test against threshold + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec3_stepr(vec3 edge, float x, vec3 dest) { + dest[0] = glm_step(edge[0], x); + dest[1] = glm_step(edge[1], x); + dest[2] = glm_step(edge[2], x); +} + /*! * @brief vector reduction by summation * @warning could overflow diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h index e6a9898..1350818 100644 --- a/include/cglm/vec3.h +++ b/include/cglm/vec3.h @@ -72,7 +72,6 @@ CGLM_INLINE void glm_vec3_lerpc(vec3 from, vec3 to, float t, vec3 dest); CGLM_INLINE void glm_vec3_mix(vec3 from, vec3 to, float t, vec3 dest); CGLM_INLINE void glm_vec3_mixc(vec3 from, vec3 to, float t, vec3 dest); - CGLM_INLINE void glm_vec3_step_uni(float edge, vec3 x, vec3 dest); CGLM_INLINE void glm_vec3_step(vec3 edge, vec3 x, vec3 dest); CGLM_INLINE void glm_vec3_smoothstep_uni(float edge0, float edge1, vec3 x, vec3 dest); CGLM_INLINE void glm_vec3_smoothstep(vec3 edge0, vec3 edge1, vec3 x, vec3 dest); @@ -97,6 +96,7 @@ glm_vec3_inv glm_vec3_inv_to glm_vec3_mulv + glm_vec3_step_uni --> use glm_vec3_steps */ #ifndef cglm_vec3_h @@ -114,6 +114,7 @@ #define glm_vec3_inv(v) glm_vec3_negate(v) #define glm_vec3_inv_to(v, dest) glm_vec3_negate_to(v, dest) #define glm_vec3_mulv(a, b, d) glm_vec3_mul(a, b, d) +#define glm_vec3_step_uni(edge, x, dest) glm_vec3_steps(edge, x, dest) #define GLM_VEC3_ONE_INIT {1.0f, 1.0f, 1.0f} #define GLM_VEC3_ZERO_INIT {0.0f, 0.0f, 0.0f} @@ -1012,21 +1013,6 @@ glm_vec3_mixc(vec3 from, vec3 to, float t, vec3 dest) { glm_vec3_lerpc(from, to, t, dest); } -/*! - * @brief threshold function (unidimensional) - * - * @param[in] edge threshold - * @param[in] x value to test against threshold - * @param[out] dest destination - */ -CGLM_INLINE -void -glm_vec3_step_uni(float edge, vec3 x, vec3 dest) { - dest[0] = glm_step(edge, x[0]); - dest[1] = glm_step(edge, x[1]); - dest[2] = glm_step(edge, x[2]); -} - /*! * @brief threshold function * diff --git a/include/cglm/vec4-ext.h b/include/cglm/vec4-ext.h index e8678c3..1f03eea 100644 --- a/include/cglm/vec4-ext.h +++ b/include/cglm/vec4-ext.h @@ -26,6 +26,10 @@ CGLM_INLINE void glm_vec4_sign(vec4 v, vec4 dest); CGLM_INLINE void glm_vec4_abs(vec4 v, vec4 dest); CGLM_INLINE void glm_vec4_fract(vec4 v, vec4 dest); + CGLM_INLINE void glm_vec4_floor(vec4 v, vec4 dest); + CGLM_INLINE float glm_vec4_mods(vec4 v, float s, vec4 dest); + CGLM_INLINE float glm_vec4_steps(float edge, vec4 v, vec4 dest); + CGLM_INLINE void glm_vec4_stepr(vec4 edge, float v, vec4 dest); CGLM_INLINE float glm_vec4_hadd(vec4 v); CGLM_INLINE void glm_vec4_sqrt(vec4 v, vec4 dest); */ @@ -288,6 +292,71 @@ glm_vec4_fract(vec4 v, vec4 dest) { dest[3] = fminf(v[3] - floorf(v[3]), 0.999999940395355224609375f); } +/*! + * @brief floor of each vector item + * + * @param[in] v vector + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec4_floor(vec4 x, vec4 dest) { + dest[0] = floorf(x[0]); + dest[1] = floorf(x[1]); + dest[2] = floorf(x[2]); + dest[3] = floorf(x[3]); +} + +/*! + * @brief mod of each vector item, result is written to dest (dest = v % s) + * + * @param[in] v vector + * @param[in] s scalar + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec4_mods(vec4 x, float y, vec4 dest) { + dest[0] = fmodf(x[0], y); + dest[1] = fmodf(x[1], y); + dest[2] = fmodf(x[2], y); + dest[3] = fmodf(x[3], y); +} + +/*! + * @brief threshold each vector item with scalar + * condition is: (x[i] < edge) ? 0.0 : 1.0 + * + * @param[in] edge threshold + * @param[in] x vector to test against threshold + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec4_steps(float edge, vec4 x, vec4 dest) { + dest[0] = glm_step(edge, x[0]); + dest[1] = glm_step(edge, x[1]); + dest[2] = glm_step(edge, x[2]); + dest[3] = glm_step(edge, x[3]); +} + +/*! + * @brief threshold a value with *vector* as the threshold + * condition is: (x < edge[i]) ? 0.0 : 1.0 + * + * @param[in] edge threshold vector + * @param[in] x value to test against threshold + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec4_stepr(vec4 edge, float x, vec4 dest) { + dest[0] = glm_step(edge[0], x); + dest[1] = glm_step(edge[1], x); + dest[2] = glm_step(edge[2], x); + dest[3] = glm_step(edge[3], x); +} + /*! * @brief vector reduction by summation * @warning could overflow diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index b259235..c8bc15b 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -57,7 +57,6 @@ CGLM_INLINE void glm_vec4_clamp(vec4 v, float minVal, float maxVal); CGLM_INLINE void glm_vec4_lerp(vec4 from, vec4 to, float t, vec4 dest); CGLM_INLINE void glm_vec4_lerpc(vec4 from, vec4 to, float t, vec4 dest); - CGLM_INLINE void glm_vec4_step_uni(float edge, vec4 x, vec4 dest); CGLM_INLINE void glm_vec4_step(vec4 edge, vec4 x, vec4 dest); CGLM_INLINE void glm_vec4_smoothstep_uni(float edge0, float edge1, vec4 x, vec4 dest); CGLM_INLINE void glm_vec4_smoothstep(vec4 edge0, vec4 edge1, vec4 x, vec4 dest); @@ -75,6 +74,7 @@ glm_vec4_inv glm_vec4_inv_to glm_vec4_mulv + glm_vec4_step_uni --> use glm_vec4_steps */ #ifndef cglm_vec4_h @@ -92,6 +92,7 @@ #define glm_vec4_inv(v) glm_vec4_negate(v) #define glm_vec4_inv_to(v, dest) glm_vec4_negate_to(v, dest) #define glm_vec4_mulv(a, b, d) glm_vec4_mul(a, b, d) +#define glm_vec4_step_uni(edge, x, dest) glm_vec4_steps(edge, x, dest) #define GLM_VEC4_ONE_INIT {1.0f, 1.0f, 1.0f, 1.0f} #define GLM_VEC4_BLACK_INIT {0.0f, 0.0f, 0.0f, 1.0f} @@ -529,6 +530,8 @@ glm_vec4_divs(vec4 v, float s, vec4 dest) { glmm_store(dest, wasm_f32x4_div(glmm_load(v), wasm_f32x4_splat(s))); #elif defined( __SSE__ ) || defined( __SSE2__ ) glmm_store(dest, _mm_div_ps(glmm_load(v), _mm_set1_ps(s))); +#elif defined(CGLM_NEON_FP) + vst1q_f32(dest, vdivq_f32(vld1q_f32(v), vdupq_n_f32(s))); #else glm_vec4_scale(v, 1.0f / s, dest); #endif @@ -1148,22 +1151,6 @@ glm_vec4_mixc(vec4 from, vec4 to, float t, vec4 dest) { glm_vec4_lerpc(from, to, t, dest); } -/*! - * @brief threshold function (unidimensional) - * - * @param[in] edge threshold - * @param[in] x value to test against threshold - * @param[out] dest destination - */ -CGLM_INLINE -void -glm_vec4_step_uni(float edge, vec4 x, vec4 dest) { - dest[0] = glm_step(edge, x[0]); - dest[1] = glm_step(edge, x[1]); - dest[2] = glm_step(edge, x[2]); - dest[3] = glm_step(edge, x[3]); -} - /*! * @brief threshold function * diff --git a/meson.build b/meson.build index 663f2ba..485a1b0 100644 --- a/meson.build +++ b/meson.build @@ -56,6 +56,7 @@ cglm_src = files( 'src/mat4x2.c', 'src/mat4x3.c', 'src/plane.c', + 'src/noise.c', 'src/frustum.c', 'src/box.c', 'src/aabb2d.c', diff --git a/src/noise.c b/src/noise.c new file mode 100644 index 0000000..f464202 --- /dev/null +++ b/src/noise.c @@ -0,0 +1,27 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#include "../include/cglm/cglm.h" +#include "../include/cglm/call.h" + +CGLM_EXPORT +float +glmc_perlin_vec4(vec4 p) { + return glm_perlin_vec4(p); +} + +CGLM_EXPORT +float +glmc_perlin_vec3(vec3 p) { + return glm_perlin_vec3(p); +} + +CGLM_EXPORT +float +glmc_perlin_vec2(vec2 p) { + return glm_perlin_vec2(p); +} \ No newline at end of file diff --git a/src/vec2.c b/src/vec2.c index b124f86..479c41e 100644 --- a/src/vec2.c +++ b/src/vec2.c @@ -273,6 +273,48 @@ glmc_vec2_abs(vec2 v, vec2 dest) { glm_vec2_abs(v, dest); } +CGLM_EXPORT +void +glmc_vec2_fract(vec2 v, vec2 dest) { + glm_vec2_fract(v, dest); +} + +CGLM_EXPORT +void +glmc_vec2_floor(vec2 v, vec2 dest) { + glm_vec2_floor(v, dest); +} + +CGLM_EXPORT +void +glmc_vec2_mods(vec2 v, float s, vec2 dest) { + glm_vec2_mods(v, s, dest); +} + +CGLM_EXPORT +void +glmc_vec2_step(vec2 edge, vec2 v, vec2 dest) { + glm_vec2_step(edge, v, dest); +} + +CGLM_EXPORT +void +glmc_vec2_steps(float edge, vec2 v, vec2 dest) { + glm_vec2_steps(edge, v, dest); +} + +CGLM_EXPORT +void +glmc_vec2_stepr(vec2 edge, float v, vec2 dest) { + glm_vec2_stepr(edge, v, dest); +} + +CGLM_EXPORT +void +glmc_vec2_swizzle(vec2 v, int mask, vec2 dest) { + glm_vec2_swizzle(v, mask, dest); +} + CGLM_EXPORT void glmc_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) { diff --git a/src/vec3.c b/src/vec3.c index c1316dc..a8c1083 100644 --- a/src/vec3.c +++ b/src/vec3.c @@ -308,12 +308,6 @@ glmc_vec3_lerpc(vec3 from, vec3 to, float t, vec3 dest) { glm_vec3_lerpc(from, to, t, dest); } -CGLM_EXPORT -void -glmc_vec3_step_uni(float edge, vec3 x, vec3 dest) { - glm_vec3_step_uni(edge, x, dest); -} - CGLM_EXPORT void glmc_vec3_step(vec3 edge, vec3 x, vec3 dest) { @@ -344,6 +338,12 @@ glmc_vec3_smoothinterpc(vec3 from, vec3 to, float t, vec3 dest) { glm_vec3_smoothinterpc(from, to, t, dest); } +CGLM_EXPORT +void +glmc_vec3_swizzle(vec3 v, int mask, vec3 dest) { + glm_vec3_swizzle(v, mask, dest); +} + /* ext */ CGLM_EXPORT @@ -442,6 +442,30 @@ glmc_vec3_fract(vec3 v, vec3 dest) { glm_vec3_fract(v, dest); } +CGLM_EXPORT +void +glmc_vec3_floor(vec3 v, vec3 dest) { + glm_vec3_floor(v, dest); +} + +CGLM_EXPORT +void +glmc_vec3_mods(vec3 v, float s, vec3 dest) { + glm_vec3_mods(v, s, dest); +} + +CGLM_EXPORT +void +glmc_vec3_steps(float edge, vec3 v, vec3 dest) { + glm_vec3_steps(edge, v, dest); +} + +CGLM_EXPORT +void +glmc_vec3_stepr(vec3 edge, float v, vec3 dest) { + glm_vec3_stepr(edge, v, dest); +} + CGLM_EXPORT float glmc_vec3_hadd(vec3 v) { diff --git a/src/vec4.c b/src/vec4.c index cac6606..4b08abf 100644 --- a/src/vec4.c +++ b/src/vec4.c @@ -266,12 +266,6 @@ glmc_vec4_lerpc(vec4 from, vec4 to, float t, vec4 dest) { glm_vec4_lerpc(from, to, t, dest); } -CGLM_EXPORT -void -glmc_vec4_step_uni(float edge, vec4 x, vec4 dest) { - glm_vec4_step_uni(edge, x, dest); -} - CGLM_EXPORT void glmc_vec4_step(vec4 edge, vec4 x, vec4 dest) { @@ -308,6 +302,12 @@ glmc_vec4_cubic(float s, vec4 dest) { glm_vec4_cubic(s, dest); } +CGLM_EXPORT +void +glmc_vec4_swizzle(vec4 v, int mask, vec4 dest) { + glm_vec4_swizzle(v, mask, dest); +} + /* ext */ CGLM_EXPORT @@ -406,6 +406,30 @@ glmc_vec4_fract(vec4 v, vec4 dest) { glm_vec4_fract(v, dest); } +CGLM_EXPORT +void +glmc_vec4_floor(vec4 v, vec4 dest) { + glm_vec4_floor(v, dest); +} + +CGLM_EXPORT +void +glmc_vec4_mods(vec4 v, float s, vec4 dest) { + glm_vec4_mods(v, s, dest); +} + +CGLM_EXPORT +void +glmc_vec4_steps(float edge, vec4 v, vec4 dest) { + glm_vec4_steps(edge, v, dest); +} + +CGLM_EXPORT +void +glmc_vec4_stepr(vec4 edge, float v, vec4 dest) { + glm_vec4_stepr(edge, v, dest); +} + CGLM_EXPORT float glmc_vec4_hadd(vec4 v) { diff --git a/test/src/test_noise.h b/test/src/test_noise.h new file mode 100644 index 0000000..cc7ea3c --- /dev/null +++ b/test/src/test_noise.h @@ -0,0 +1,118 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#include "test_common.h" + +TEST_IMPL(GLM_PREFIX, perlin_vec4) { + vec4 p1[] = { + {0.1f, 0.2f, 0.3f, 0.4f}, + {0.2f, 0.3f, 0.4f, 0.5f}, + {0.3f, 0.4f, 0.5f, 0.6f}, + {0.4f, 0.5f, 0.6f, 0.7f}, + {0.5f, 0.6f, 0.7f, 0.8f}, + {0.6f, 0.7f, 0.8f, 0.9f}, + {0.7f, 0.8f, 0.9f, 1.0f}, + {0.8f, 0.9f, 1.0f, 1.1f}, + {0.9f, 1.0f, 1.1f, 1.2f}, + {1.0f, 1.1f, 1.2f, 1.3f}, + }; + + /* expected values calculated by glm::perlin */ + float e[] = { + -0.5091819763183594f, + -0.4375732541084290f, + -0.3212279379367828f, + -0.2279999703168869f, + -0.1577337533235550f, + -0.0445968918502331f, + 0.1069696992635727f, + 0.2067739963531494f, + 0.2106968611478806f, + 0.1397782564163208f + }; + + for (int i = 0; i < 10; i++) { + ASSERT(test_eq(GLM(perlin_vec4)(p1[i]), e[i])); + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, perlin_vec3) { + vec3 p1[] = { + {0.1f, 0.2f, 0.3f}, + {0.2f, 0.3f, 0.4f}, + {0.3f, 0.4f, 0.5f}, + {0.4f, 0.5f, 0.6f}, + {0.5f, 0.6f, 0.7f}, + {0.6f, 0.7f, 0.8f}, + {0.7f, 0.8f, 0.9f}, + {0.8f, 0.9f, 1.0f}, + {0.9f, 1.0f, 1.1f}, + {1.0f, 1.1f, 1.2f}, + }; + + /* expected values calculated by glm::perlin */ + float e[] = { + -0.2909241318702698f, + -0.4667602181434631f, + -0.4679279625415802f, + -0.2616460621356964f, + 0.0562822706997395f, + 0.3178773224353790f, + 0.3981811404228210f, + 0.3011017739772797f, + 0.1263920217752457f, + -0.0602480024099350f + }; + + for (int i = 0; i < 10; i++) { + ASSERT(test_eq(GLM(perlin_vec3)(p1[i]), e[i])); + } + + TEST_SUCCESS +} + + +TEST_IMPL(GLM_PREFIX, perlin_vec2) { + vec2 p1[] = { + {0.1f, 0.2f}, + {0.2f, 0.3f}, + {0.3f, 0.4f}, + {0.4f, 0.5f}, + {0.5f, 0.6f}, + {0.6f, 0.7f}, + {0.7f, 0.8f}, + {0.8f, 0.9f}, + {0.9f, 1.0f}, + {1.0f, 1.1f}, + }; + + /* expected values calculated by glm::perlin */ + float e[] = { + 0.2841092348098755f, + 0.2328013032674789f, + -0.0017980185803026f, + -0.3300299644470215f, + -0.5998955368995667f, + -0.6914522647857666f, + -0.5896517634391785f, + -0.3778679668903351f, + -0.1557840555906296f, + 0.0453133136034012f + }; + + for (int i = 0; i < 10; i++) { + ASSERT(test_eq(GLM(perlin_vec2)(p1[i]), e[i])); + } + + TEST_SUCCESS +} + + + + diff --git a/test/src/test_vec2.h b/test/src/test_vec2.h index 870d6eb..026c387 100644 --- a/test/src/test_vec2.h +++ b/test/src/test_vec2.h @@ -688,6 +688,70 @@ TEST_IMPL(GLM_PREFIX, vec2_abs) { TEST_SUCCESS } +TEST_IMPL(GLM_PREFIX, vec2_fract) { + vec2 v1 = {2.104f, 3.012f}, v2 = {12.35f, 31.140f}, v3, v4; + vec2 v5 = {0.104f, 0.012f}, v6 = {0.35f, 0.140f}; + + GLM(vec2_fract)(v1, v3); + GLM(vec2_fract)(v2, v4); + + ASSERTIFY(test_assert_vec2_eq(v3, v5)) + ASSERTIFY(test_assert_vec2_eq(v4, v6)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_floor) { + vec2 v1 = {2.104f, 3.012f}, v2 = {12.35f, 31.140f}, v3, v4; + vec2 v5 = {2.0f, 3.0f}, v6 = {12.0f, 31.0f}; + + GLM(vec2_floor)(v1, v3); + GLM(vec2_floor)(v2, v4); + + ASSERTIFY(test_assert_vec2_eq(v3, v5)) + ASSERTIFY(test_assert_vec2_eq(v4, v6)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_mods) { + vec2 v1 = {2.104f, 3.012f}, v2 = {12.35f, 31.140f}, v3, v4; + vec2 v5 = {0.104f, 0.012f}, v6 = {0.35f, 0.140f}; + + /* Mod 1 - leaves just the fractional part */ + GLM(vec2_mods)(v1, 1.0f, v3); + GLM(vec2_mods)(v2, 1.0f, v4); + + ASSERTIFY(test_assert_vec2_eq(v3, v5)) + ASSERTIFY(test_assert_vec2_eq(v4, v6)) + + /* Mod 2 - parity + fractional part */ + GLM(vec2_mods)(v1, 2.0f, v3); + GLM(vec2_mods)(v2, 2.0f, v4); + + vec2 v7 = {0.104f, 1.012f}, v8 = {0.35f, 1.140f}; + + ASSERTIFY(test_assert_vec2_eq(v3, v7)) + ASSERTIFY(test_assert_vec2_eq(v4, v8)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_swizzle) { + vec2 v; + + v[0] = 1; + v[1] = 2; + + GLM(vec2_swizzle)(v, GLM_SHUFFLE2(1, 0), v); + ASSERTIFY(test_assert_vec2_eq(v, (vec2){2, 1})) + + GLM(vec2_swizzle)(v, GLM_SHUFFLE2(0, 0), v); + ASSERTIFY(test_assert_vec2_eq(v, (vec2){1, 1})) + + TEST_SUCCESS +} + TEST_IMPL(GLM_PREFIX, vec2_lerp) { vec2 v1 = {-100.0f, -200.0f}; vec2 v2 = {100.0f, 200.0f}; @@ -704,6 +768,66 @@ TEST_IMPL(GLM_PREFIX, vec2_lerp) { TEST_SUCCESS } +TEST_IMPL(GLM_PREFIX, vec2_steps) { + vec2 v1 = {-100.0f, -200.0f}; + vec2 v2; + + GLM(vec2_steps)(-2.5f, v1, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + + GLM(vec2_steps)(-150.0f, v1, v2); + ASSERT(test_eq(v2[0], 1.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + + GLM(vec2_steps)(-300.0f, v1, v2); + ASSERT(test_eq(v2[0], 1.0f)) + ASSERT(test_eq(v2[1], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_stepr) { + vec2 v1 = {-2.5f, -150.0f}; + vec2 v2; + + GLM(vec2_stepr)(v1, -200.0f, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + + GLM(vec2_stepr)(v1, -150.0f, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 1.0f)) + + GLM(vec2_stepr)(v1, 0.0f, v2); + ASSERT(test_eq(v2[0], 1.0f)) + ASSERT(test_eq(v2[1], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_step) { + vec2 v1 = {-100.0f, -200.0f}; + vec2 s1 = {-100.0f, 0.0f}; + vec2 s2 = {100.0f, -220.0f}; + vec2 s3 = {100.0f, 200.0f}; + vec2 v2; + + GLM(vec2_step)(s1, v1, v2); + ASSERT(test_eq(v2[0], 1.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + + GLM(vec2_step)(s2, v1, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 1.0f)) + + GLM(vec2_step)(s3, v1, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + + TEST_SUCCESS +} + TEST_IMPL(GLM_PREFIX, vec2_complex_mul) { vec2 v1 = { 3.0f, 5.0f }, v2 = { 7.0f, 11.0f }, diff --git a/test/src/test_vec3.h b/test/src/test_vec3.h index 5e9c387..4d963d5 100644 --- a/test/src/test_vec3.h +++ b/test/src/test_vec3.h @@ -1393,21 +1393,43 @@ TEST_IMPL(GLM_PREFIX, vec3_mixc) { TEST_SUCCESS } -TEST_IMPL(GLM_PREFIX, vec3_step_uni) { +TEST_IMPL(GLM_PREFIX, vec3_steps) { vec3 v1 = {-100.0f, -200.0f, -10.0f}; vec3 v2; - GLM(vec3_step_uni)(-2.5f, v1, v2); + GLM(vec3_steps)(-2.5f, v1, v2); ASSERT(test_eq(v2[0], 0.0f)) ASSERT(test_eq(v2[1], 0.0f)) ASSERT(test_eq(v2[2], 0.0f)) - GLM(vec3_step_uni)(-10.0f, v1, v2); + GLM(vec3_steps)(-10.0f, v1, v2); ASSERT(test_eq(v2[0], 0.0f)) ASSERT(test_eq(v2[1], 0.0f)) ASSERT(test_eq(v2[2], 1.0f)) - GLM(vec3_step_uni)(-1000.0f, v1, v2); + GLM(vec3_steps)(-1000.0f, v1, v2); + ASSERT(test_eq(v2[0], 1.0f)) + ASSERT(test_eq(v2[1], 1.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec3_stepr) { + vec3 v1 = {-2.5f, -10.0f, -1000.0f}; + vec3 v2; + + GLM(vec3_stepr)(v1, -100.0f, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + GLM(vec3_stepr)(v1, -5.0f, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 1.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + GLM(vec3_stepr)(v1, -1.0f, v2); ASSERT(test_eq(v2[0], 1.0f)) ASSERT(test_eq(v2[1], 1.0f)) ASSERT(test_eq(v2[2], 1.0f)) @@ -1552,24 +1574,24 @@ TEST_IMPL(GLM_PREFIX, vec3_swizzle) { v[1] = 2; v[2] = 3; - glm_vec3_swizzle(v, GLM_ZYX, v); + GLM(vec3_swizzle)(v, GLM_ZYX, v); ASSERTIFY(test_assert_vec3_eq(v, (vec3){3, 2, 1})) - glm_vec3_swizzle(v, GLM_XXX, v); + GLM(vec3_swizzle)(v, GLM_XXX, v); ASSERTIFY(test_assert_vec3_eq(v, (vec3){3, 3, 3})) v[0] = 1; v[1] = 2; v[2] = 3; - glm_vec3_swizzle(v, GLM_YYY, v); + GLM(vec3_swizzle)(v, GLM_YYY, v); ASSERTIFY(test_assert_vec3_eq(v, (vec3){2, 2, 2})) v[0] = 1; v[1] = 2; v[2] = 3; - glm_vec3_swizzle(v, GLM_ZZZ, v); + GLM(vec3_swizzle)(v, GLM_ZZZ, v); ASSERTIFY(test_assert_vec3_eq(v, (vec3){3, 3, 3})) TEST_SUCCESS @@ -1826,6 +1848,42 @@ TEST_IMPL(GLM_PREFIX, vec3_fract) { TEST_SUCCESS } +TEST_IMPL(GLM_PREFIX, vec3_floor) { + vec3 v1 = {2.104f, 3.012f, 4.10f}, v2 = {12.35f, 31.140f, 43.502f}, v3, v4; + vec3 v5 = {2.0f, 3.0f, 4.0f}, v6 = {12.0f, 31.0f, 43.0f}; + + GLM(vec3_floor)(v1, v3); + GLM(vec3_floor)(v2, v4); + + ASSERTIFY(test_assert_vec3_eq(v3, v5)) + ASSERTIFY(test_assert_vec3_eq(v4, v6)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec3_mods) { + vec3 v1 = {2.104f, 3.012f, 4.10f}, v2 = {12.35f, 31.140f, 43.502f}, v3, v4; + vec3 v5 = {0.104f, 0.012f, 0.10f}, v6 = {0.35f, 0.140f, 0.502f}; + + /* Mod 1 - leaves just the fractional part */ + GLM(vec3_mods)(v1, 1.0f, v3); + GLM(vec3_mods)(v2, 1.0f, v4); + + ASSERTIFY(test_assert_vec3_eq(v3, v5)) + ASSERTIFY(test_assert_vec3_eq(v4, v6)) + + /* Mod 2 - parity + fractional part */ + GLM(vec3_mods)(v1, 2.0f, v3); + GLM(vec3_mods)(v2, 2.0f, v4); + + vec3 v7 = {0.104f, 1.012f, 0.10f}, v8 = {0.35f, 1.140f, 1.502f}; + + ASSERTIFY(test_assert_vec3_eq(v3, v7)) + ASSERTIFY(test_assert_vec3_eq(v4, v8)) + + TEST_SUCCESS +} + TEST_IMPL(GLM_PREFIX, vec3_hadd) { vec3 v1 = {2.0f, 3.0f, 4.0f}, v2 = {12.0f, 31.0f, 43.0f}; float r1, r2, r3, r4; diff --git a/test/src/test_vec4.h b/test/src/test_vec4.h index cb34543..417babb 100644 --- a/test/src/test_vec4.h +++ b/test/src/test_vec4.h @@ -980,23 +980,60 @@ TEST_IMPL(GLM_PREFIX, vec4_mixc) { TEST_SUCCESS } -TEST_IMPL(GLM_PREFIX, vec4_step_uni) { +TEST_IMPL(GLM_PREFIX, vec4_steps) { vec4 v1 = {-100.0f, -200.0f, -10.0f, -10.0f}; vec4 v2; - GLM(vec4_step_uni)(-2.5f, v1, v2); + GLM(vec4_steps)(-2.5f, v1, v2); ASSERT(test_eq(v2[0], 0.0f)) ASSERT(test_eq(v2[1], 0.0f)) ASSERT(test_eq(v2[2], 0.0f)) ASSERT(test_eq(v2[3], 0.0f)) - GLM(vec4_step_uni)(-10.0f, v1, v2); + GLM(vec4_steps)(-10.0f, v1, v2); ASSERT(test_eq(v2[0], 0.0f)) ASSERT(test_eq(v2[1], 0.0f)) ASSERT(test_eq(v2[2], 1.0f)) ASSERT(test_eq(v2[3], 1.0f)) - GLM(vec4_step_uni)(-1000.0f, v1, v2); + GLM(vec4_steps)(-1000.0f, v1, v2); + ASSERT(test_eq(v2[0], 1.0f)) + ASSERT(test_eq(v2[1], 1.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + ASSERT(test_eq(v2[3], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec4_stepr) { + vec4 v1 = {-2.5f, -100.0f, -200.0f, -300.0f}; + vec4 v2; + + GLM(vec4_stepr)(v1, -1000.0f, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + ASSERT(test_eq(v2[2], 0.0f)) + ASSERT(test_eq(v2[3], 0.0f)) + + GLM(vec4_stepr)(v1, -250.0f, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + ASSERT(test_eq(v2[2], 0.0f)) + ASSERT(test_eq(v2[3], 1.0f)) + + GLM(vec4_stepr)(v1, -150.0f, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 0.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + ASSERT(test_eq(v2[3], 1.0f)) + + GLM(vec4_stepr)(v1, -10.0f, v2); + ASSERT(test_eq(v2[0], 0.0f)) + ASSERT(test_eq(v2[1], 1.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + ASSERT(test_eq(v2[3], 1.0f)) + + GLM(vec4_stepr)(v1, 0.0f, v2); ASSERT(test_eq(v2[0], 1.0f)) ASSERT(test_eq(v2[1], 1.0f)) ASSERT(test_eq(v2[2], 1.0f)) @@ -1184,10 +1221,10 @@ TEST_IMPL(GLM_PREFIX, vec4_swizzle) { v[2] = 3; v[3] = 4; - glm_vec4_swizzle(v, GLM_WZYX, v); + GLM(vec4_swizzle)(v, GLM_WZYX, v); ASSERTIFY(test_assert_vec4_eq(v, (vec4){4, 3, 2, 1})) - glm_vec4_swizzle(v, GLM_XXXX, v); + GLM(vec4_swizzle)(v, GLM_XXXX, v); ASSERTIFY(test_assert_vec4_eq(v, (vec4){4, 4, 4, 4})) v[0] = 1; @@ -1195,7 +1232,7 @@ TEST_IMPL(GLM_PREFIX, vec4_swizzle) { v[2] = 3; v[3] = 4; - glm_vec4_swizzle(v, GLM_YYYY, v); + GLM(vec4_swizzle)(v, GLM_YYYY, v); ASSERTIFY(test_assert_vec4_eq(v, (vec4){2, 2, 2, 2})) v[0] = 1; @@ -1203,7 +1240,7 @@ TEST_IMPL(GLM_PREFIX, vec4_swizzle) { v[2] = 3; v[3] = 4; - glm_vec4_swizzle(v, GLM_ZZZZ, v); + GLM(vec4_swizzle)(v, GLM_ZZZZ, v); ASSERTIFY(test_assert_vec4_eq(v, (vec4){3, 3, 3, 3})) v[0] = 1; @@ -1211,7 +1248,7 @@ TEST_IMPL(GLM_PREFIX, vec4_swizzle) { v[2] = 3; v[3] = 4; - glm_vec4_swizzle(v, GLM_WWWW, v); + GLM(vec4_swizzle)(v, GLM_WWWW, v); ASSERTIFY(test_assert_vec4_eq(v, (vec4){4, 4, 4, 4})) TEST_SUCCESS @@ -1490,6 +1527,47 @@ TEST_IMPL(GLM_PREFIX, vec4_fract) { TEST_SUCCESS } +TEST_IMPL(GLM_PREFIX, vec4_floor) { + vec4 v1 = {2.104f, 3.012f, 4.10f, 4.10f}; + vec4 v2 = {12.35f, 31.140f, 43.502f, 43.502f}; + vec4 v3, v4; + vec4 v5 = {2.0f, 3.0f, 4.0f, 4.0f}; + vec4 v6 = {12.0f, 31.0f, 43.0f, 43.0f}; + + GLM(vec4_floor)(v1, v3); + GLM(vec4_floor)(v2, v4); + + ASSERTIFY(test_assert_vec4_eq(v3, v5)) + ASSERTIFY(test_assert_vec4_eq(v4, v6)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec4_mods) { + vec4 v1 = {2.104f, 3.012f, 4.10f, 5.78f}, v2 = {12.35f, 31.140f, 43.502f, 198.999f}; + vec4 v3, v4; + vec4 v5 = {0.104f, 0.012f, 0.10f, 0.78f}, v6 = {0.35f, 0.140f, 0.502f, 0.999f}; + + /* Mod 1 - leaves just the fractional part */ + GLM(vec4_mods)(v1, 1.0f, v3); + GLM(vec4_mods)(v2, 1.0f, v4); + + ASSERTIFY(test_assert_vec4_eq(v3, v5)) + ASSERTIFY(test_assert_vec4_eq(v4, v6)) + + /* Mod 2 - parity + fractional part */ + GLM(vec4_mods)(v1, 2.0f, v3); + GLM(vec4_mods)(v2, 2.0f, v4); + + vec4 v7 = {0.104f, 1.012f, 0.10f, 1.78f}, v8 = {0.35f, 1.140f, 1.502f, 0.999f}; + + ASSERTIFY(test_assert_vec4_eq(v3, v7)) + ASSERTIFY(test_assert_vec4_eq(v4, v8)) + + TEST_SUCCESS +} + + TEST_IMPL(GLM_PREFIX, vec4_hadd) { vec4 v1 = {2.0f, 3.0f, 4.0f, 4.0f}, v2 = {12.0f, 31.0f, 43.0f, 43.0f}; float r1, r2, r3, r4; diff --git a/test/src/tests.c b/test/src/tests.c index b9a00b2..bc24668 100644 --- a/test/src/tests.c +++ b/test/src/tests.c @@ -30,6 +30,7 @@ #include "test_quat.h" #include "test_project.h" #include "test_plane.h" +#include "test_noise.h" #include "test_affine.h" #include "test_affine2d.h" #include "test_affine_mat.h" @@ -70,6 +71,7 @@ #include "test_quat.h" #include "test_project.h" #include "test_plane.h" +#include "test_noise.h" #include "test_affine.h" #include "test_affine2d.h" #include "test_affine_mat.h" diff --git a/test/tests.h b/test/tests.h index 751095e..b959ad6 100644 --- a/test/tests.h +++ b/test/tests.h @@ -359,6 +359,14 @@ TEST_DECLARE(glmc_project) TEST_DECLARE(glm_plane_normalize) TEST_DECLARE(glmc_plane_normalize) +/* noise */ +TEST_DECLARE(glm_perlin_vec4) +TEST_DECLARE(glmc_perlin_vec4) +TEST_DECLARE(glm_perlin_vec3) +TEST_DECLARE(glmc_perlin_vec3) +TEST_DECLARE(glm_perlin_vec2) +TEST_DECLARE(glmc_perlin_vec2) + /* utils */ TEST_DECLARE(clamp) @@ -534,6 +542,11 @@ TEST_DECLARE(glm_vec2_maxv) TEST_DECLARE(glm_vec2_minv) TEST_DECLARE(glm_vec2_clamp) TEST_DECLARE(glm_vec2_abs) +TEST_DECLARE(glm_vec2_fract) +TEST_DECLARE(glm_vec2_floor) +TEST_DECLARE(glm_vec2_mods) +TEST_DECLARE(glm_vec2_steps) +TEST_DECLARE(glm_vec2_stepr) TEST_DECLARE(glm_vec2_lerp) TEST_DECLARE(glm_vec2_complex_mul) TEST_DECLARE(glm_vec2_complex_div) @@ -582,6 +595,11 @@ TEST_DECLARE(glmc_vec2_maxv) TEST_DECLARE(glmc_vec2_minv) TEST_DECLARE(glmc_vec2_clamp) TEST_DECLARE(glmc_vec2_abs) +TEST_DECLARE(glmc_vec2_fract) +TEST_DECLARE(glmc_vec2_floor) +TEST_DECLARE(glmc_vec2_mods) +TEST_DECLARE(glmc_vec2_steps) +TEST_DECLARE(glmc_vec2_stepr) TEST_DECLARE(glmc_vec2_lerp) TEST_DECLARE(glmc_vec2_complex_mul) TEST_DECLARE(glmc_vec2_complex_div) @@ -665,7 +683,6 @@ TEST_DECLARE(glm_vec3_ortho) TEST_DECLARE(glm_vec3_clamp) TEST_DECLARE(glm_vec3_mix) TEST_DECLARE(glm_vec3_mixc) -TEST_DECLARE(glm_vec3_step_uni) TEST_DECLARE(glm_vec3_step) TEST_DECLARE(glm_vec3_smoothstep_uni) TEST_DECLARE(glm_vec3_smoothstep) @@ -687,6 +704,10 @@ TEST_DECLARE(glm_vec3_isvalid) TEST_DECLARE(glm_vec3_sign) TEST_DECLARE(glm_vec3_abs) TEST_DECLARE(glm_vec3_fract) +TEST_DECLARE(glm_vec3_floor) +TEST_DECLARE(glm_vec3_mods) +TEST_DECLARE(glm_vec3_steps) +TEST_DECLARE(glm_vec3_stepr) TEST_DECLARE(glm_vec3_hadd) TEST_DECLARE(glm_vec3_sqrt) TEST_DECLARE(glm_vec3_make) @@ -744,7 +765,6 @@ TEST_DECLARE(glmc_vec3_ortho) TEST_DECLARE(glmc_vec3_clamp) TEST_DECLARE(glmc_vec3_mix) TEST_DECLARE(glmc_vec3_mixc) -TEST_DECLARE(glmc_vec3_step_uni) TEST_DECLARE(glmc_vec3_step) TEST_DECLARE(glmc_vec3_smoothstep_uni) TEST_DECLARE(glmc_vec3_smoothstep) @@ -766,6 +786,10 @@ TEST_DECLARE(glmc_vec3_isvalid) TEST_DECLARE(glmc_vec3_sign) TEST_DECLARE(glmc_vec3_abs) TEST_DECLARE(glmc_vec3_fract) +TEST_DECLARE(glmc_vec3_floor) +TEST_DECLARE(glmc_vec3_mods) +TEST_DECLARE(glmc_vec3_steps) +TEST_DECLARE(glmc_vec3_stepr) TEST_DECLARE(glmc_vec3_hadd) TEST_DECLARE(glmc_vec3_sqrt) TEST_DECLARE(glmc_vec3_make) @@ -834,7 +858,6 @@ TEST_DECLARE(glm_vec4_lerp) TEST_DECLARE(glm_vec4_lerpc) TEST_DECLARE(glm_vec4_mix) TEST_DECLARE(glm_vec4_mixc) -TEST_DECLARE(glm_vec4_step_uni) TEST_DECLARE(glm_vec4_step) TEST_DECLARE(glm_vec4_smoothstep_uni) TEST_DECLARE(glm_vec4_smoothstep) @@ -857,6 +880,10 @@ TEST_DECLARE(glm_vec4_isvalid) TEST_DECLARE(glm_vec4_sign) TEST_DECLARE(glm_vec4_abs) TEST_DECLARE(glm_vec4_fract) +TEST_DECLARE(glm_vec4_floor) +TEST_DECLARE(glm_vec4_mods) +TEST_DECLARE(glm_vec4_steps) +TEST_DECLARE(glm_vec4_stepr) TEST_DECLARE(glm_vec4_hadd) TEST_DECLARE(glm_vec4_sqrt) TEST_DECLARE(glm_vec4_make) @@ -908,7 +935,6 @@ TEST_DECLARE(glmc_vec4_lerp) TEST_DECLARE(glmc_vec4_lerpc) TEST_DECLARE(glmc_vec4_mix) TEST_DECLARE(glmc_vec4_mixc) -TEST_DECLARE(glmc_vec4_step_uni) TEST_DECLARE(glmc_vec4_step) TEST_DECLARE(glmc_vec4_smoothstep_uni) TEST_DECLARE(glmc_vec4_smoothstep) @@ -931,6 +957,10 @@ TEST_DECLARE(glmc_vec4_isvalid) TEST_DECLARE(glmc_vec4_sign) TEST_DECLARE(glmc_vec4_abs) TEST_DECLARE(glmc_vec4_fract) +TEST_DECLARE(glmc_vec4_floor) +TEST_DECLARE(glmc_vec4_mods) +TEST_DECLARE(glmc_vec4_steps) +TEST_DECLARE(glmc_vec4_stepr) TEST_DECLARE(glmc_vec4_hadd) TEST_DECLARE(glmc_vec4_sqrt) TEST_DECLARE(glmc_vec4_make) @@ -1539,6 +1569,14 @@ TEST_LIST { /* plane */ TEST_ENTRY(glm_plane_normalize) TEST_ENTRY(glmc_plane_normalize) + + /* noise */ + TEST_ENTRY(glm_perlin_vec4) + TEST_ENTRY(glmc_perlin_vec4) + TEST_ENTRY(glm_perlin_vec3) + TEST_ENTRY(glmc_perlin_vec3) + TEST_ENTRY(glm_perlin_vec2) + TEST_ENTRY(glmc_perlin_vec2) /* utils */ TEST_ENTRY(clamp) @@ -1714,6 +1752,12 @@ TEST_LIST { TEST_ENTRY(glm_vec2_maxv) TEST_ENTRY(glm_vec2_minv) TEST_ENTRY(glm_vec2_clamp) + TEST_ENTRY(glm_vec2_abs) + TEST_ENTRY(glm_vec2_fract) + TEST_ENTRY(glm_vec2_floor) + TEST_ENTRY(glm_vec2_mods) + TEST_ENTRY(glm_vec2_steps) + TEST_ENTRY(glm_vec2_stepr) TEST_ENTRY(glm_vec2_lerp) TEST_ENTRY(glm_vec2_complex_mul) TEST_ENTRY(glm_vec2_complex_div) @@ -1762,6 +1806,11 @@ TEST_LIST { TEST_ENTRY(glmc_vec2_minv) TEST_ENTRY(glmc_vec2_clamp) TEST_ENTRY(glmc_vec2_abs) + TEST_ENTRY(glmc_vec2_fract) + TEST_ENTRY(glmc_vec2_floor) + TEST_ENTRY(glmc_vec2_mods) + TEST_ENTRY(glmc_vec2_steps) + TEST_ENTRY(glmc_vec2_stepr) TEST_ENTRY(glmc_vec2_lerp) TEST_ENTRY(glmc_vec2_complex_mul) TEST_ENTRY(glmc_vec2_complex_div) @@ -1844,7 +1893,6 @@ TEST_LIST { TEST_ENTRY(glm_vec3_clamp) TEST_ENTRY(glm_vec3_mix) TEST_ENTRY(glm_vec3_mixc) - TEST_ENTRY(glm_vec3_step_uni) TEST_ENTRY(glm_vec3_step) TEST_ENTRY(glm_vec3_smoothstep_uni) TEST_ENTRY(glm_vec3_smoothstep) @@ -1866,6 +1914,10 @@ TEST_LIST { TEST_ENTRY(glm_vec3_sign) TEST_ENTRY(glm_vec3_abs) TEST_ENTRY(glm_vec3_fract) + TEST_ENTRY(glm_vec3_floor) + TEST_ENTRY(glm_vec3_mods) + TEST_ENTRY(glm_vec3_steps) + TEST_ENTRY(glm_vec3_stepr) TEST_ENTRY(glm_vec3_hadd) TEST_ENTRY(glm_vec3_sqrt) TEST_ENTRY(glm_vec3_make) @@ -1923,7 +1975,6 @@ TEST_LIST { TEST_ENTRY(glmc_vec3_clamp) TEST_ENTRY(glmc_vec3_mix) TEST_ENTRY(glmc_vec3_mixc) - TEST_ENTRY(glmc_vec3_step_uni) TEST_ENTRY(glmc_vec3_step) TEST_ENTRY(glmc_vec3_smoothstep_uni) TEST_ENTRY(glmc_vec3_smoothstep) @@ -1945,6 +1996,10 @@ TEST_LIST { TEST_ENTRY(glmc_vec3_sign) TEST_ENTRY(glmc_vec3_abs) TEST_ENTRY(glmc_vec3_fract) + TEST_ENTRY(glmc_vec3_floor) + TEST_ENTRY(glmc_vec3_mods) + TEST_ENTRY(glmc_vec3_steps) + TEST_ENTRY(glmc_vec3_stepr) TEST_ENTRY(glmc_vec3_hadd) TEST_ENTRY(glmc_vec3_sqrt) TEST_ENTRY(glmc_vec3_make) @@ -2013,7 +2068,6 @@ TEST_LIST { TEST_ENTRY(glm_vec4_lerpc) TEST_ENTRY(glm_vec4_mix) TEST_ENTRY(glm_vec4_mixc) - TEST_ENTRY(glm_vec4_step_uni) TEST_ENTRY(glm_vec4_step) TEST_ENTRY(glm_vec4_smoothstep_uni) TEST_ENTRY(glm_vec4_smoothstep) @@ -2036,6 +2090,10 @@ TEST_LIST { TEST_ENTRY(glm_vec4_sign) TEST_ENTRY(glm_vec4_abs) TEST_ENTRY(glm_vec4_fract) + TEST_ENTRY(glm_vec4_floor) + TEST_ENTRY(glm_vec4_mods) + TEST_ENTRY(glm_vec4_steps) + TEST_ENTRY(glm_vec4_stepr) TEST_ENTRY(glm_vec4_hadd) TEST_ENTRY(glm_vec4_sqrt) TEST_ENTRY(glm_vec4_make) @@ -2087,7 +2145,6 @@ TEST_LIST { TEST_ENTRY(glmc_vec4_lerpc) TEST_ENTRY(glmc_vec4_mix) TEST_ENTRY(glmc_vec4_mixc) - TEST_ENTRY(glmc_vec4_step_uni) TEST_ENTRY(glmc_vec4_step) TEST_ENTRY(glmc_vec4_smoothstep_uni) TEST_ENTRY(glmc_vec4_smoothstep) @@ -2110,6 +2167,10 @@ TEST_LIST { TEST_ENTRY(glmc_vec4_sign) TEST_ENTRY(glmc_vec4_abs) TEST_ENTRY(glmc_vec4_fract) + TEST_ENTRY(glmc_vec4_floor) + TEST_ENTRY(glmc_vec4_mods) + TEST_ENTRY(glmc_vec4_steps) + TEST_ENTRY(glmc_vec4_stepr) TEST_ENTRY(glmc_vec4_hadd) TEST_ENTRY(glmc_vec4_sqrt) TEST_ENTRY(glmc_vec4_make)