1
2/* ---------------------------------------------------------------------- */
3/** \name Common Math Utilities
4 * \{ */
5
6#define M_PI 3.14159265358979323846     /* pi */
7#define M_2PI 6.28318530717958647692    /* 2*pi */
8#define M_PI_2 1.57079632679489661923   /* pi/2 */
9#define M_1_PI 0.318309886183790671538  /* 1/pi */
10#define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */
11#define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */
12#define FLT_MAX 3.402823e+38
13
14vec3 mul(mat3 m, vec3 v)
15{
16  return m * v;
17}
18mat3 mul(mat3 m1, mat3 m2)
19{
20  return m1 * m2;
21}
22vec3 transform_direction(mat4 m, vec3 v)
23{
24  return mat3(m) * v;
25}
26vec3 transform_point(mat4 m, vec3 v)
27{
28  return (m * vec4(v, 1.0)).xyz;
29}
30vec3 project_point(mat4 m, vec3 v)
31{
32  vec4 tmp = m * vec4(v, 1.0);
33  return tmp.xyz / tmp.w;
34}
35
36#define min3(a, b, c) min(a, min(b, c))
37#define min4(a, b, c, d) min(a, min3(b, c, d))
38#define min5(a, b, c, d, e) min(a, min4(b, c, d, e))
39#define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f))
40#define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g))
41#define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h))
42#define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i))
43
44#define max3(a, b, c) max(a, max(b, c))
45#define max4(a, b, c, d) max(a, max3(b, c, d))
46#define max5(a, b, c, d, e) max(a, max4(b, c, d, e))
47#define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f))
48#define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g))
49#define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h))
50#define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i))
51
52#define avg3(a, b, c) (a + b + c) * (1.0 / 3.0)
53#define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0)
54#define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0)
55#define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0)
56#define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0)
57#define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0)
58#define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0)
59
60/* clang-format off */
61float min_v2(vec2 v) { return min(v.x, v.y); }
62float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
63float min_v4(vec4 v) { return min(min(v.x, v.y), min(v.z, v.w)); }
64float max_v2(vec2 v) { return max(v.x, v.y); }
65float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
66float max_v4(vec4 v) { return max(max(v.x, v.y), max(v.z, v.w)); }
67
68float sum(vec2 v) { return dot(vec2(1.0), v); }
69float sum(vec3 v) { return dot(vec3(1.0), v); }
70float sum(vec4 v) { return dot(vec4(1.0), v); }
71
72float avg(vec2 v) { return dot(vec2(1.0 / 2.0), v); }
73float avg(vec3 v) { return dot(vec3(1.0 / 3.0), v); }
74float avg(vec4 v) { return dot(vec4(1.0 / 4.0), v); }
75/* clang-format on */
76
77#define saturate(a) clamp(a, 0.0, 1.0)
78
79float distance_squared(vec2 a, vec2 b)
80{
81  a -= b;
82  return dot(a, a);
83}
84
85float distance_squared(vec3 a, vec3 b)
86{
87  a -= b;
88  return dot(a, a);
89}
90
91float len_squared(vec3 a)
92{
93  return dot(a, a);
94}
95
96/** \} */
97
98/* ---------------------------------------------------------------------- */
99/** \name Fast Math
100 * \{ */
101
102/* [Drobot2014a] Low Level Optimizations for GCN */
103float fast_sqrt(float v)
104{
105  return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
106}
107
108vec2 fast_sqrt(vec2 v)
109{
110  return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
111}
112
113/* [Eberly2014] GPGPU Programming for Games and Science */
114float fast_acos(float v)
115{
116  float res = -0.156583 * abs(v) + M_PI_2;
117  res *= fast_sqrt(1.0 - abs(v));
118  return (v >= 0) ? res : M_PI - res;
119}
120
121vec2 fast_acos(vec2 v)
122{
123  vec2 res = -0.156583 * abs(v) + M_PI_2;
124  res *= fast_sqrt(1.0 - abs(v));
125  v.x = (v.x >= 0) ? res.x : M_PI - res.x;
126  v.y = (v.y >= 0) ? res.y : M_PI - res.y;
127  return v;
128}
129
130/** \} */
131