Home | History | Annotate | Download | only in demos
      1 /*
      2  * Copyright (c) 2015-2016 The Khronos Group Inc.
      3  * Copyright (c) 2015-2016 Valve Corporation
      4  * Copyright (c) 2015-2016 LunarG, Inc.
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  *
     18  * Relicensed from the WTFPL (http://www.wtfpl.net/faq/).
     19  */
     20 
     21 #ifndef LINMATH_H
     22 #define LINMATH_H
     23 
     24 #include <math.h>
     25 
     26 // Converts degrees to radians.
     27 #define degreesToRadians(angleDegrees) (angleDegrees * M_PI / 180.0)
     28 
     29 // Converts radians to degrees.
     30 #define radiansToDegrees(angleRadians) (angleRadians * 180.0 / M_PI)
     31 
     32 typedef float vec3[3];
     33 static inline void vec3_add(vec3 r, vec3 const a, vec3 const b) {
     34     int i;
     35     for (i = 0; i < 3; ++i)
     36         r[i] = a[i] + b[i];
     37 }
     38 static inline void vec3_sub(vec3 r, vec3 const a, vec3 const b) {
     39     int i;
     40     for (i = 0; i < 3; ++i)
     41         r[i] = a[i] - b[i];
     42 }
     43 static inline void vec3_scale(vec3 r, vec3 const v, float const s) {
     44     int i;
     45     for (i = 0; i < 3; ++i)
     46         r[i] = v[i] * s;
     47 }
     48 static inline float vec3_mul_inner(vec3 const a, vec3 const b) {
     49     float p = 0.f;
     50     int i;
     51     for (i = 0; i < 3; ++i)
     52         p += b[i] * a[i];
     53     return p;
     54 }
     55 static inline void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b) {
     56     r[0] = a[1] * b[2] - a[2] * b[1];
     57     r[1] = a[2] * b[0] - a[0] * b[2];
     58     r[2] = a[0] * b[1] - a[1] * b[0];
     59 }
     60 static inline float vec3_len(vec3 const v) {
     61     return sqrtf(vec3_mul_inner(v, v));
     62 }
     63 static inline void vec3_norm(vec3 r, vec3 const v) {
     64     float k = 1.f / vec3_len(v);
     65     vec3_scale(r, v, k);
     66 }
     67 static inline void vec3_reflect(vec3 r, vec3 const v, vec3 const n) {
     68     float p = 2.f * vec3_mul_inner(v, n);
     69     int i;
     70     for (i = 0; i < 3; ++i)
     71         r[i] = v[i] - p * n[i];
     72 }
     73 
     74 typedef float vec4[4];
     75 static inline void vec4_add(vec4 r, vec4 const a, vec4 const b) {
     76     int i;
     77     for (i = 0; i < 4; ++i)
     78         r[i] = a[i] + b[i];
     79 }
     80 static inline void vec4_sub(vec4 r, vec4 const a, vec4 const b) {
     81     int i;
     82     for (i = 0; i < 4; ++i)
     83         r[i] = a[i] - b[i];
     84 }
     85 static inline void vec4_scale(vec4 r, vec4 v, float s) {
     86     int i;
     87     for (i = 0; i < 4; ++i)
     88         r[i] = v[i] * s;
     89 }
     90 static inline float vec4_mul_inner(vec4 a, vec4 b) {
     91     float p = 0.f;
     92     int i;
     93     for (i = 0; i < 4; ++i)
     94         p += b[i] * a[i];
     95     return p;
     96 }
     97 static inline void vec4_mul_cross(vec4 r, vec4 a, vec4 b) {
     98     r[0] = a[1] * b[2] - a[2] * b[1];
     99     r[1] = a[2] * b[0] - a[0] * b[2];
    100     r[2] = a[0] * b[1] - a[1] * b[0];
    101     r[3] = 1.f;
    102 }
    103 static inline float vec4_len(vec4 v) { return sqrtf(vec4_mul_inner(v, v)); }
    104 static inline void vec4_norm(vec4 r, vec4 v) {
    105     float k = 1.f / vec4_len(v);
    106     vec4_scale(r, v, k);
    107 }
    108 static inline void vec4_reflect(vec4 r, vec4 v, vec4 n) {
    109     float p = 2.f * vec4_mul_inner(v, n);
    110     int i;
    111     for (i = 0; i < 4; ++i)
    112         r[i] = v[i] - p * n[i];
    113 }
    114 
    115 typedef vec4 mat4x4[4];
    116 static inline void mat4x4_identity(mat4x4 M) {
    117     int i, j;
    118     for (i = 0; i < 4; ++i)
    119         for (j = 0; j < 4; ++j)
    120             M[i][j] = i == j ? 1.f : 0.f;
    121 }
    122 static inline void mat4x4_dup(mat4x4 M, mat4x4 N) {
    123     int i, j;
    124     for (i = 0; i < 4; ++i)
    125         for (j = 0; j < 4; ++j)
    126             M[i][j] = N[i][j];
    127 }
    128 static inline void mat4x4_row(vec4 r, mat4x4 M, int i) {
    129     int k;
    130     for (k = 0; k < 4; ++k)
    131         r[k] = M[k][i];
    132 }
    133 static inline void mat4x4_col(vec4 r, mat4x4 M, int i) {
    134     int k;
    135     for (k = 0; k < 4; ++k)
    136         r[k] = M[i][k];
    137 }
    138 static inline void mat4x4_transpose(mat4x4 M, mat4x4 N) {
    139     int i, j;
    140     for (j = 0; j < 4; ++j)
    141         for (i = 0; i < 4; ++i)
    142             M[i][j] = N[j][i];
    143 }
    144 static inline void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b) {
    145     int i;
    146     for (i = 0; i < 4; ++i)
    147         vec4_add(M[i], a[i], b[i]);
    148 }
    149 static inline void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b) {
    150     int i;
    151     for (i = 0; i < 4; ++i)
    152         vec4_sub(M[i], a[i], b[i]);
    153 }
    154 static inline void mat4x4_scale(mat4x4 M, mat4x4 a, float k) {
    155     int i;
    156     for (i = 0; i < 4; ++i)
    157         vec4_scale(M[i], a[i], k);
    158 }
    159 static inline void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y,
    160                                       float z) {
    161     int i;
    162     vec4_scale(M[0], a[0], x);
    163     vec4_scale(M[1], a[1], y);
    164     vec4_scale(M[2], a[2], z);
    165     for (i = 0; i < 4; ++i) {
    166         M[3][i] = a[3][i];
    167     }
    168 }
    169 static inline void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b) {
    170     int k, r, c;
    171     for (c = 0; c < 4; ++c)
    172         for (r = 0; r < 4; ++r) {
    173             M[c][r] = 0.f;
    174             for (k = 0; k < 4; ++k)
    175                 M[c][r] += a[k][r] * b[c][k];
    176         }
    177 }
    178 static inline void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v) {
    179     int i, j;
    180     for (j = 0; j < 4; ++j) {
    181         r[j] = 0.f;
    182         for (i = 0; i < 4; ++i)
    183             r[j] += M[i][j] * v[i];
    184     }
    185 }
    186 static inline void mat4x4_translate(mat4x4 T, float x, float y, float z) {
    187     mat4x4_identity(T);
    188     T[3][0] = x;
    189     T[3][1] = y;
    190     T[3][2] = z;
    191 }
    192 static inline void mat4x4_translate_in_place(mat4x4 M, float x, float y,
    193                                              float z) {
    194     vec4 t = {x, y, z, 0};
    195     vec4 r;
    196     int i;
    197     for (i = 0; i < 4; ++i) {
    198         mat4x4_row(r, M, i);
    199         M[3][i] += vec4_mul_inner(r, t);
    200     }
    201 }
    202 static inline void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b) {
    203     int i, j;
    204     for (i = 0; i < 4; ++i)
    205         for (j = 0; j < 4; ++j)
    206             M[i][j] = i < 3 && j < 3 ? a[i] * b[j] : 0.f;
    207 }
    208 static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
    209                                  float angle) {
    210     float s = sinf(angle);
    211     float c = cosf(angle);
    212     vec3 u = {x, y, z};
    213 
    214     if (vec3_len(u) > 1e-4) {
    215         vec3_norm(u, u);
    216         mat4x4 T;
    217         mat4x4_from_vec3_mul_outer(T, u, u);
    218 
    219         mat4x4 S = {{0, u[2], -u[1], 0},
    220                     {-u[2], 0, u[0], 0},
    221                     {u[1], -u[0], 0, 0},
    222                     {0, 0, 0, 0}};
    223         mat4x4_scale(S, S, s);
    224 
    225         mat4x4 C;
    226         mat4x4_identity(C);
    227         mat4x4_sub(C, C, T);
    228 
    229         mat4x4_scale(C, C, c);
    230 
    231         mat4x4_add(T, T, C);
    232         mat4x4_add(T, T, S);
    233 
    234         T[3][3] = 1.;
    235         mat4x4_mul(R, M, T);
    236     } else {
    237         mat4x4_dup(R, M);
    238     }
    239 }
    240 static inline void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle) {
    241     float s = sinf(angle);
    242     float c = cosf(angle);
    243     mat4x4 R = {{1.f, 0.f, 0.f, 0.f},
    244                 {0.f, c, s, 0.f},
    245                 {0.f, -s, c, 0.f},
    246                 {0.f, 0.f, 0.f, 1.f}};
    247     mat4x4_mul(Q, M, R);
    248 }
    249 static inline void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle) {
    250     float s = sinf(angle);
    251     float c = cosf(angle);
    252     mat4x4 R = {{c, 0.f, s, 0.f},
    253                 {0.f, 1.f, 0.f, 0.f},
    254                 {-s, 0.f, c, 0.f},
    255                 {0.f, 0.f, 0.f, 1.f}};
    256     mat4x4_mul(Q, M, R);
    257 }
    258 static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle) {
    259     float s = sinf(angle);
    260     float c = cosf(angle);
    261     mat4x4 R = {{c, s, 0.f, 0.f},
    262                 {-s, c, 0.f, 0.f},
    263                 {0.f, 0.f, 1.f, 0.f},
    264                 {0.f, 0.f, 0.f, 1.f}};
    265     mat4x4_mul(Q, M, R);
    266 }
    267 static inline void mat4x4_invert(mat4x4 T, mat4x4 M) {
    268     float s[6];
    269     float c[6];
    270     s[0] = M[0][0] * M[1][1] - M[1][0] * M[0][1];
    271     s[1] = M[0][0] * M[1][2] - M[1][0] * M[0][2];
    272     s[2] = M[0][0] * M[1][3] - M[1][0] * M[0][3];
    273     s[3] = M[0][1] * M[1][2] - M[1][1] * M[0][2];
    274     s[4] = M[0][1] * M[1][3] - M[1][1] * M[0][3];
    275     s[5] = M[0][2] * M[1][3] - M[1][2] * M[0][3];
    276 
    277     c[0] = M[2][0] * M[3][1] - M[3][0] * M[2][1];
    278     c[1] = M[2][0] * M[3][2] - M[3][0] * M[2][2];
    279     c[2] = M[2][0] * M[3][3] - M[3][0] * M[2][3];
    280     c[3] = M[2][1] * M[3][2] - M[3][1] * M[2][2];
    281     c[4] = M[2][1] * M[3][3] - M[3][1] * M[2][3];
    282     c[5] = M[2][2] * M[3][3] - M[3][2] * M[2][3];
    283 
    284     /* Assumes it is invertible */
    285     float idet = 1.0f / (s[0] * c[5] - s[1] * c[4] + s[2] * c[3] + s[3] * c[2] -
    286                          s[4] * c[1] + s[5] * c[0]);
    287 
    288     T[0][0] = (M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
    289     T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
    290     T[0][2] = (M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
    291     T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet;
    292 
    293     T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet;
    294     T[1][1] = (M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet;
    295     T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet;
    296     T[1][3] = (M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet;
    297 
    298     T[2][0] = (M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet;
    299     T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet;
    300     T[2][2] = (M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet;
    301     T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet;
    302 
    303     T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet;
    304     T[3][1] = (M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet;
    305     T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
    306     T[3][3] = (M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
    307 }
    308 static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M) {
    309     mat4x4_dup(R, M);
    310     float s = 1.;
    311     vec3 h;
    312 
    313     vec3_norm(R[2], R[2]);
    314 
    315     s = vec3_mul_inner(R[1], R[2]);
    316     vec3_scale(h, R[2], s);
    317     vec3_sub(R[1], R[1], h);
    318     vec3_norm(R[2], R[2]);
    319 
    320     s = vec3_mul_inner(R[1], R[2]);
    321     vec3_scale(h, R[2], s);
    322     vec3_sub(R[1], R[1], h);
    323     vec3_norm(R[1], R[1]);
    324 
    325     s = vec3_mul_inner(R[0], R[1]);
    326     vec3_scale(h, R[1], s);
    327     vec3_sub(R[0], R[0], h);
    328     vec3_norm(R[0], R[0]);
    329 }
    330 
    331 static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t,
    332                                   float n, float f) {
    333     M[0][0] = 2.f * n / (r - l);
    334     M[0][1] = M[0][2] = M[0][3] = 0.f;
    335 
    336     M[1][1] = 2.f * n / (t - b);
    337     M[1][0] = M[1][2] = M[1][3] = 0.f;
    338 
    339     M[2][0] = (r + l) / (r - l);
    340     M[2][1] = (t + b) / (t - b);
    341     M[2][2] = -(f + n) / (f - n);
    342     M[2][3] = -1.f;
    343 
    344     M[3][2] = -2.f * (f * n) / (f - n);
    345     M[3][0] = M[3][1] = M[3][3] = 0.f;
    346 }
    347 static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t,
    348                                 float n, float f) {
    349     M[0][0] = 2.f / (r - l);
    350     M[0][1] = M[0][2] = M[0][3] = 0.f;
    351 
    352     M[1][1] = 2.f / (t - b);
    353     M[1][0] = M[1][2] = M[1][3] = 0.f;
    354 
    355     M[2][2] = -2.f / (f - n);
    356     M[2][0] = M[2][1] = M[2][3] = 0.f;
    357 
    358     M[3][0] = -(r + l) / (r - l);
    359     M[3][1] = -(t + b) / (t - b);
    360     M[3][2] = -(f + n) / (f - n);
    361     M[3][3] = 1.f;
    362 }
    363 static inline void mat4x4_perspective(mat4x4 m, float y_fov, float aspect,
    364                                       float n, float f) {
    365     /* NOTE: Degrees are an unhandy unit to work with.
    366      * linmath.h uses radians for everything! */
    367     float const a = (float)(1.f / tan(y_fov / 2.f));
    368 
    369     m[0][0] = a / aspect;
    370     m[0][1] = 0.f;
    371     m[0][2] = 0.f;
    372     m[0][3] = 0.f;
    373 
    374     m[1][0] = 0.f;
    375     m[1][1] = a;
    376     m[1][2] = 0.f;
    377     m[1][3] = 0.f;
    378 
    379     m[2][0] = 0.f;
    380     m[2][1] = 0.f;
    381     m[2][2] = -((f + n) / (f - n));
    382     m[2][3] = -1.f;
    383 
    384     m[3][0] = 0.f;
    385     m[3][1] = 0.f;
    386     m[3][2] = -((2.f * f * n) / (f - n));
    387     m[3][3] = 0.f;
    388 }
    389 static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up) {
    390     /* Adapted from Android's OpenGL Matrix.java.                        */
    391     /* See the OpenGL GLUT documentation for gluLookAt for a description */
    392     /* of the algorithm. We implement it in a straightforward way:       */
    393 
    394     /* TODO: The negation of of can be spared by swapping the order of
    395      *       operands in the following cross products in the right way. */
    396     vec3 f;
    397     vec3_sub(f, center, eye);
    398     vec3_norm(f, f);
    399 
    400     vec3 s;
    401     vec3_mul_cross(s, f, up);
    402     vec3_norm(s, s);
    403 
    404     vec3 t;
    405     vec3_mul_cross(t, s, f);
    406 
    407     m[0][0] = s[0];
    408     m[0][1] = t[0];
    409     m[0][2] = -f[0];
    410     m[0][3] = 0.f;
    411 
    412     m[1][0] = s[1];
    413     m[1][1] = t[1];
    414     m[1][2] = -f[1];
    415     m[1][3] = 0.f;
    416 
    417     m[2][0] = s[2];
    418     m[2][1] = t[2];
    419     m[2][2] = -f[2];
    420     m[2][3] = 0.f;
    421 
    422     m[3][0] = 0.f;
    423     m[3][1] = 0.f;
    424     m[3][2] = 0.f;
    425     m[3][3] = 1.f;
    426 
    427     mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]);
    428 }
    429 
    430 typedef float quat[4];
    431 static inline void quat_identity(quat q) {
    432     q[0] = q[1] = q[2] = 0.f;
    433     q[3] = 1.f;
    434 }
    435 static inline void quat_add(quat r, quat a, quat b) {
    436     int i;
    437     for (i = 0; i < 4; ++i)
    438         r[i] = a[i] + b[i];
    439 }
    440 static inline void quat_sub(quat r, quat a, quat b) {
    441     int i;
    442     for (i = 0; i < 4; ++i)
    443         r[i] = a[i] - b[i];
    444 }
    445 static inline void quat_mul(quat r, quat p, quat q) {
    446     vec3 w;
    447     vec3_mul_cross(r, p, q);
    448     vec3_scale(w, p, q[3]);
    449     vec3_add(r, r, w);
    450     vec3_scale(w, q, p[3]);
    451     vec3_add(r, r, w);
    452     r[3] = p[3] * q[3] - vec3_mul_inner(p, q);
    453 }
    454 static inline void quat_scale(quat r, quat v, float s) {
    455     int i;
    456     for (i = 0; i < 4; ++i)
    457         r[i] = v[i] * s;
    458 }
    459 static inline float quat_inner_product(quat a, quat b) {
    460     float p = 0.f;
    461     int i;
    462     for (i = 0; i < 4; ++i)
    463         p += b[i] * a[i];
    464     return p;
    465 }
    466 static inline void quat_conj(quat r, quat q) {
    467     int i;
    468     for (i = 0; i < 3; ++i)
    469         r[i] = -q[i];
    470     r[3] = q[3];
    471 }
    472 #define quat_norm vec4_norm
    473 static inline void quat_mul_vec3(vec3 r, quat q, vec3 v) {
    474     quat v_ = {v[0], v[1], v[2], 0.f};
    475 
    476     quat_conj(r, q);
    477     quat_norm(r, r);
    478     quat_mul(r, v_, r);
    479     quat_mul(r, q, r);
    480 }
    481 static inline void mat4x4_from_quat(mat4x4 M, quat q) {
    482     float a = q[3];
    483     float b = q[0];
    484     float c = q[1];
    485     float d = q[2];
    486     float a2 = a * a;
    487     float b2 = b * b;
    488     float c2 = c * c;
    489     float d2 = d * d;
    490 
    491     M[0][0] = a2 + b2 - c2 - d2;
    492     M[0][1] = 2.f * (b * c + a * d);
    493     M[0][2] = 2.f * (b * d - a * c);
    494     M[0][3] = 0.f;
    495 
    496     M[1][0] = 2 * (b * c - a * d);
    497     M[1][1] = a2 - b2 + c2 - d2;
    498     M[1][2] = 2.f * (c * d + a * b);
    499     M[1][3] = 0.f;
    500 
    501     M[2][0] = 2.f * (b * d + a * c);
    502     M[2][1] = 2.f * (c * d - a * b);
    503     M[2][2] = a2 - b2 - c2 + d2;
    504     M[2][3] = 0.f;
    505 
    506     M[3][0] = M[3][1] = M[3][2] = 0.f;
    507     M[3][3] = 1.f;
    508 }
    509 
    510 static inline void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q) {
    511     /*  XXX: The way this is written only works for othogonal matrices. */
    512     /* TODO: Take care of non-orthogonal case. */
    513     quat_mul_vec3(R[0], q, M[0]);
    514     quat_mul_vec3(R[1], q, M[1]);
    515     quat_mul_vec3(R[2], q, M[2]);
    516 
    517     R[3][0] = R[3][1] = R[3][2] = 0.f;
    518     R[3][3] = 1.f;
    519 }
    520 static inline void quat_from_mat4x4(quat q, mat4x4 M) {
    521     float r = 0.f;
    522     int i;
    523 
    524     int perm[] = {0, 1, 2, 0, 1};
    525     int *p = perm;
    526 
    527     for (i = 0; i < 3; i++) {
    528         float m = M[i][i];
    529         if (m < r)
    530             continue;
    531         m = r;
    532         p = &perm[i];
    533     }
    534 
    535     r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]]);
    536 
    537     if (r < 1e-6) {
    538         q[0] = 1.f;
    539         q[1] = q[2] = q[3] = 0.f;
    540         return;
    541     }
    542 
    543     q[0] = r / 2.f;
    544     q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]]) / (2.f * r);
    545     q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]]) / (2.f * r);
    546     q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]]) / (2.f * r);
    547 }
    548 
    549 #endif
    550