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