summaryrefslogtreecommitdiff
path: root/include/cglm/util.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/util.h
parent0e6e1245b70df4dfcba135d50e1b53d1a8ef7eb8 (diff)
wip
Diffstat (limited to 'include/cglm/util.h')
-rw-r--r--include/cglm/util.h375
1 files changed, 375 insertions, 0 deletions
diff --git a/include/cglm/util.h b/include/cglm/util.h
new file mode 100644
index 0000000..8c5f2cb
--- /dev/null
+++ b/include/cglm/util.h
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+/*
+ Functions:
+ CGLM_INLINE int glm_sign(int val);
+ CGLM_INLINE float glm_signf(float val);
+ CGLM_INLINE float glm_rad(float deg);
+ CGLM_INLINE float glm_deg(float rad);
+ CGLM_INLINE void glm_make_rad(float *deg);
+ CGLM_INLINE void glm_make_deg(float *rad);
+ CGLM_INLINE float glm_pow2(float x);
+ CGLM_INLINE float glm_min(float a, float b);
+ CGLM_INLINE float glm_max(float a, float b);
+ CGLM_INLINE float glm_clamp(float val, float minVal, float maxVal);
+ CGLM_INLINE float glm_clamp_zo(float val, float minVal, float maxVal);
+ CGLM_INLINE float glm_lerp(float from, float to, float t);
+ CGLM_INLINE float glm_lerpc(float from, float to, float t);
+ CGLM_INLINE float glm_step(float edge, float x);
+ CGLM_INLINE float glm_smooth(float t);
+ CGLM_INLINE float glm_smoothstep(float edge0, float edge1, float x);
+ CGLM_INLINE float glm_smoothinterp(float from, float to, float t);
+ CGLM_INLINE float glm_smoothinterpc(float from, float to, float t);
+ CGLM_INLINE bool glm_eq(float a, float b);
+ CGLM_INLINE float glm_percent(float from, float to, float current);
+ CGLM_INLINE float glm_percentc(float from, float to, float current);
+ */
+
+#ifndef cglm_util_h
+#define cglm_util_h
+
+#include "common.h"
+
+#define GLM_MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define GLM_MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
+
+/*!
+ * @brief get sign of 32 bit integer as +1, -1, 0
+ *
+ * Important: It returns 0 for zero input
+ *
+ * @param val integer value
+ */
+CGLM_INLINE
+int
+glm_sign(int val) {
+ return ((val >> 31) - (-val >> 31));
+}
+
+/*!
+ * @brief get sign of 32 bit float as +1, -1, 0
+ *
+ * Important: It returns 0 for zero/NaN input
+ *
+ * @param val float value
+ */
+CGLM_INLINE
+float
+glm_signf(float val) {
+ return (float)((val > 0.0f) - (val < 0.0f));
+}
+
+/*!
+ * @brief convert degree to radians
+ *
+ * @param[in] deg angle in degrees
+ */
+CGLM_INLINE
+float
+glm_rad(float deg) {
+ return deg * GLM_PIf / 180.0f;
+}
+
+/*!
+ * @brief convert radians to degree
+ *
+ * @param[in] rad angle in radians
+ */
+CGLM_INLINE
+float
+glm_deg(float rad) {
+ return rad * 180.0f / GLM_PIf;
+}
+
+/*!
+ * @brief convert existing degree to radians. this will override degrees value
+ *
+ * @param[in, out] deg pointer to angle in degrees
+ */
+CGLM_INLINE
+void
+glm_make_rad(float *deg) {
+ *deg = *deg * GLM_PIf / 180.0f;
+}
+
+/*!
+ * @brief convert existing radians to degree. this will override radians value
+ *
+ * @param[in, out] rad pointer to angle in radians
+ */
+CGLM_INLINE
+void
+glm_make_deg(float *rad) {
+ *rad = *rad * 180.0f / GLM_PIf;
+}
+
+/*!
+ * @brief multiplies given parameter with itself = x * x or powf(x, 2)
+ *
+ * @param[in] x x
+ */
+CGLM_INLINE
+float
+glm_pow2(float x) {
+ return x * x;
+}
+
+/*!
+ * @brief find minimum of given two values
+ *
+ * @param[in] a number 1
+ * @param[in] b number 2
+ */
+CGLM_INLINE
+float
+glm_min(float a, float b) {
+ if (a < b)
+ return a;
+ return b;
+}
+
+/*!
+ * @brief find maximum of given two values
+ *
+ * @param[in] a number 1
+ * @param[in] b number 2
+ */
+CGLM_INLINE
+float
+glm_max(float a, float b) {
+ if (a > b)
+ return a;
+ return b;
+}
+
+/*!
+ * @brief find minimum of given two values
+ *
+ * @param[in] a number 1
+ * @param[in] b number 2
+ *
+ * @return smallest of the two values
+ */
+CGLM_INLINE
+int
+glm_imin(int a, int b) {
+ if (a < b)
+ return a;
+ return b;
+}
+
+/*!
+ * @brief find maximum of given two values
+ *
+ * @param[in] a number 1
+ * @param[in] b number 2
+ *
+ * @return largest of the two values
+ */
+CGLM_INLINE
+int
+glm_imax(int a, int b) {
+ if (a > b)
+ return a;
+ return b;
+}
+
+/*!
+ * @brief clamp a number between min and max
+ *
+ * @param[in] val value to clamp
+ * @param[in] minVal minimum value
+ * @param[in] maxVal maximum value
+ */
+CGLM_INLINE
+float
+glm_clamp(float val, float minVal, float maxVal) {
+ return glm_min(glm_max(val, minVal), maxVal);
+}
+
+/*!
+ * @brief clamp a number to zero and one
+ *
+ * @param[in] val value to clamp
+ */
+CGLM_INLINE
+float
+glm_clamp_zo(float val) {
+ return glm_clamp(val, 0.0f, 1.0f);
+}
+
+/*!
+ * @brief linear interpolation between two numbers
+ *
+ * formula: from + t * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount)
+ */
+CGLM_INLINE
+float
+glm_lerp(float from, float to, float t) {
+ return from + t * (to - from);
+}
+
+/*!
+ * @brief clamped linear interpolation between two numbers
+ *
+ * formula: from + t * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount) clamped between 0 and 1
+ */
+CGLM_INLINE
+float
+glm_lerpc(float from, float to, float t) {
+ return glm_lerp(from, to, glm_clamp_zo(t));
+}
+
+/*!
+ * @brief threshold function
+ *
+ * @param[in] edge threshold
+ * @param[in] x value to test against threshold
+ * @return returns 0.0 if x < edge, else 1.0
+ */
+CGLM_INLINE
+float
+glm_step(float edge, float x) {
+ /* branching - no type conversion */
+ return (x < edge) ? 0.0f : 1.0f;
+ /*
+ * An alternative implementation without branching
+ * but with type conversion could be:
+ * return !(x < edge);
+ */
+}
+
+/*!
+ * @brief smooth Hermite interpolation
+ *
+ * formula: t^2 * (3-2t)
+ *
+ * @param[in] t interpolant (amount)
+ */
+CGLM_INLINE
+float
+glm_smooth(float t) {
+ return t * t * (3.0f - 2.0f * t);
+}
+
+/*!
+ * @brief threshold function with a smooth transition (according to OpenCL specs)
+ *
+ * formula: t^2 * (3-2t)
+ *
+ * @param[in] edge0 low threshold
+ * @param[in] edge1 high threshold
+ * @param[in] x interpolant (amount)
+ */
+CGLM_INLINE
+float
+glm_smoothstep(float edge0, float edge1, float x) {
+ float t;
+ t = glm_clamp_zo((x - edge0) / (edge1 - edge0));
+ return glm_smooth(t);
+}
+
+/*!
+ * @brief smoothstep interpolation between two numbers
+ *
+ * formula: from + smoothstep(t) * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount)
+ */
+CGLM_INLINE
+float
+glm_smoothinterp(float from, float to, float t) {
+ return from + glm_smooth(t) * (to - from);
+}
+
+/*!
+ * @brief clamped smoothstep interpolation between two numbers
+ *
+ * formula: from + smoothstep(t) * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount) clamped between 0 and 1
+ */
+CGLM_INLINE
+float
+glm_smoothinterpc(float from, float to, float t) {
+ return glm_smoothinterp(from, to, glm_clamp_zo(t));
+}
+
+/*!
+ * @brief check if two float equal with using EPSILON
+ *
+ * @param[in] a a
+ * @param[in] b b
+ */
+CGLM_INLINE
+bool
+glm_eq(float a, float b) {
+ return fabsf(a - b) <= GLM_FLT_EPSILON;
+}
+
+/*!
+ * @brief percentage of current value between start and end value
+ *
+ * maybe fraction could be alternative name.
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] current current value
+ */
+CGLM_INLINE
+float
+glm_percent(float from, float to, float current) {
+ float t;
+
+ if ((t = to - from) == 0.0f)
+ return 1.0f;
+
+ return (current - from) / t;
+}
+
+/*!
+ * @brief clamped percentage of current value between start and end value
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] current current value
+ */
+CGLM_INLINE
+float
+glm_percentc(float from, float to, float current) {
+ return glm_clamp_zo(glm_percent(from, to, current));
+}
+
+/*!
+* @brief swap two float values
+*
+* @param[in] a float value 1 (pointer)
+* @param[in] b float value 2 (pointer)
+*/
+CGLM_INLINE
+void
+glm_swapf(float * __restrict a, float * __restrict b) {
+ float t;
+ t = *a;
+ *a = *b;
+ *b = t;
+}
+
+#endif /* cglm_util_h */