aboutsummaryrefslogtreecommitdiff
path: root/src/un_math.c
blob: f6b7cab2f047a62bb423545846bec9d65ccf2c84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/* lerps */
UN_INLINE float un_m_lerpf(float a, float b, float t) {
    return (1.0 - t) * a + b * t;
}

UN_INLINE double un_m_lerpd(double a, double b, double t) {
    return (1.0 - t) * a + b * t;
}

/* easing */
UN_INLINE float un_m_ease_isinef(float t) {
    return 1.0 - cosf((t * PI) / 2.0);
}

UN_INLINE float un_m_ease_iosinef(float t) {
    return sinf((t * PI) / 2.0f);
}

UN_INLINE float un_m_ease_osinef(float t) {
    return -(cosf(t * PI) - 1.0) / 2.0;
}

UN_INLINE float un_m_ease_iquadf(float t) {
    return t * t;
}

UN_INLINE float un_m_ease_ioquadf(float t) {
    return 1.0 - (1.0 - t) * (1.0 - t);
}

UN_INLINE float un_m_ease_oquadf(float t) {
    return t < 0.5 ? 2.0 * t * t : 1.0 - ((-2.0 * t + 2.0) * (-2.0 * t + 2.0)) / 2.0;
}

UN_INLINE double un_m_ease_isined(double t) {
    return 1.0 - cos((t * PI) / 2.0);
}

UN_INLINE double un_m_ease_iosined(double t) {
    return sin((t * PI) / 2.0f);
}

UN_INLINE double un_m_ease_osined(double t) {
    return -(cos(t * PI) - 1.0) / 2.0;
}

UN_INLINE double un_m_ease_iquadd(double t) {
    return t * t;
}

UN_INLINE double un_m_ease_ioquadd(double t) {
    return 1.0 - (1.0 - t) * (1.0 - t);
}

UN_INLINE double un_m_ease_oquadd(double t) {
    return t < 0.5 ? 2.0 * t * t : 1.0 - ((-2.0 * t + 2.0) * (-2.0 * t + 2.0)) / 2.0;
}

/* complex */

UN_INLINE float2 un_m_complex_divf(float2 a, float2 b) {
    float f;
    float2 result;

    // un_m_complex_mulf(v, a, conjugated_b)
    result.x = a.x *  b.x - a.y * -b.y;
    result.y = a.x * -b.y + a.y * b.x;

    f = b.x * b.x + b.y * b.y;

    result.x /= f;
    result.y /= f;

    return result;
}

UN_INLINE float2 un_m_complex_mulf(float2 a, float2 b) {
    float2 result;
    result.x = a.x * b.x - a.y * b.y;
    result.y = a.x * b.y + a.y * b.x;
    return result;
}

UN_INLINE double2 un_m_complex_divd(double2 a, double2 b) {
    double f;
    double2 result;

    // un_m_complex_mulf(v, a, conjugated_b)
    result.x = a.x *  b.x - a.y * -b.y;
    result.y = a.x * -b.y + a.y * b.x;

    f = b.x * b.x + b.y * b.y;

    result.x /= f;
    result.y /= f;

    return result;
}

UN_INLINE double2 un_m_complex_muld(double2 a, double2 b) {
    double2 result;
    result.x = a.x * b.x - a.y * b.y;
    result.y = a.x * b.y + a.y * b.x;
    return result;
}

/* splines */

UN_INLINE float un_m_bezierf(float a, float q0, float q1, float b, float t) {
    float i0, i1, i2, p0, p1, ti;

    ti = 1.0 - t;

    i0 = ti * a  + q0 * t;
    i1 = ti * q0 + q1 * t;
    i2 = ti * q1 + b * t;

    p0 = ti * i0 + i1 * t;
    p1 = ti * i1 + i2 * t;

    return ti * p0 + p1 * t;
}

UN_INLINE float2 un_m_bezier2f(float2 a, float2 q0, float2 q1, float2 b, float t) {
    float2 result;
    result.x = un_m_bezierf(a.x, q0.x, q1.x, b.x, t);
    result.y = un_m_bezierf(a.y, q0.y, q1.y, b.y, t);
    return result;
}

float3 un_m_bezier3f(float3 a, float3 q0, float3 q1, float3 b, float t) {
    float3 result;
    result.x = un_m_bezierf(a.x, q0.x, q1.x, b.x, t);
    result.y = un_m_bezierf(a.y, q0.y, q1.y, b.y, t);
    result.z = un_m_bezierf(a.z, q0.z, q1.z, b.z, t);
    return result;
}

UN_INLINE float4 un_m_bezier4f(float4 a, float4 q0, float4 q1, float4 b, float t) {
    float4 result;
    result.x = un_m_bezierf(a.x, q0.x, q1.x, b.x, t);
    result.y = un_m_bezierf(a.y, q0.y, q1.y, b.y, t);
    result.z = un_m_bezierf(a.z, q0.z, q1.z, b.z, t);
    result.w = un_m_bezierf(a.w, q0.w, q1.w, b.w, t);
    return result;
}

UN_INLINE double un_m_bezierd(double a, double q0, double q1, double b, double t) {
    double i0, i1, i2, p0, p1, ti;

    ti = 1.0 - t;

    i0 = ti * a  + q0 * t;
    i1 = ti * q0 + q1 * t;
    i2 = ti * q1 + b  * t;

    p0 = ti * i0 + i1 * t;
    p1 = ti * i1 + i2 * t;

    return ti * p0 + p1 * t;
}

UN_INLINE double2 un_m_bezier2d(double2 a, double2 q0, double2 q1, double2 b, double t) {
    double2 result;
    result.x = un_m_bezierd(a.x, q0.x, q1.x, b.x, t);
    result.y = un_m_bezierd(a.y, q0.y, q1.y, b.y, t);
    return result;
}

UN_INLINE double3 un_m_bezier3d(double3 a, double3 q0, double3 q1, double3 b, double t) {
    double3 result;
    result.x = un_m_bezierd(a.x, q0.x, q1.x, b.x, t);
    result.y = un_m_bezierd(a.y, q0.y, q1.y, b.y, t);
    result.z = un_m_bezierd(a.z, q0.z, q1.z, b.z, t);
    return result;
}

UN_INLINE double4 un_m_bezier4d(double4 a, double4 q0, double4 q1, double4 b, double t) {
    double4 result;
    result.x = un_m_bezierd(a.x, q0.x, q1.x, b.x, t);
    result.y = un_m_bezierd(a.y, q0.y, q1.y, b.y, t);
    result.z = un_m_bezierd(a.z, q0.z, q1.z, b.z, t);
    result.w = un_m_bezierd(a.w, q0.w, q1.w, b.w, t);
    return result;
}

/* matrix and quaternions */

/* convention of matrix is: Column-major
 *
 * stored in memory as x0 y0 z0 w0 x1 y1 z1 w1 ...
 *
 * transform
 * inverse transform
 * multiply
 * reverse
 * rotate
 * quaternion -> matrix
 * matrix -> quaternion
 * matrix to components: un_mat_disassemble(float *pos3, float *scale3, float *quat4)
 * un_mat_assemble(float *v, float *pos3, float *scale3, float *quat4)
 * assembe_inverse
 *
 * */



UN_INLINE void un_m_mat_identityf(float *v) {
    memset((void*)v, 0, sizeof(*v) * UN_MATRIX_SIZE);

    v[0 + 0 * UN_MATRIX_STRIPE] = 1.0f;
    v[1 + 1 * UN_MATRIX_STRIPE] = 1.0f;
    v[2 + 2 * UN_MATRIX_STRIPE] = 1.0f;
    v[3 + 3 * UN_MATRIX_STRIPE] = 1.0f;
}

UN_INLINE void un_m_mat_mulf(float *v, float *left, float *right) {
    u64 row, col, i;
    memset((void*)v, 0, sizeof(*v) * UN_MATRIX_SIZE);

    for (col = 0; col < 4; col++) {
        for (row = 0; row < 4; row++) {
            for (i = 0; i < 4; i++) {
                v[row + col * UN_MATRIX_STRIPE] += left[row + i * UN_MATRIX_STRIPE] * right[i + col * UN_MATRIX_STRIPE];
            }
        }
    }
}

UN_INLINE void un_mat_xformf(float *v, float *xform) {
    un_m_mat_identityf(v);

    v[3 + 0 * UN_MATRIX_STRIPE] += xform[0];
    v[3 + 1 * UN_MATRIX_STRIPE] += xform[1];
    v[3 + 2 * UN_MATRIX_STRIPE] += xform[2];
}

UN_INLINE void un_mat_scalef(float *v, float *scale) {
    un_m_mat_identityf(v);

    v[0 + 0 * UN_MATRIX_STRIPE] = scale[0];
    v[1 + 1 * UN_MATRIX_STRIPE] = scale[1];
    v[2 + 2 * UN_MATRIX_STRIPE] = scale[2];
}