Last active
November 8, 2015 17:32
-
-
Save warmwaffles/af0a67a7bba1196b4c54 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _COMMON_H | |
| #define _COMMON_H | |
| #include <math.h> | |
| #define square(v) ((v) * (v)) | |
| #define cube(v) ((v) * (v) * (v)) | |
| #define deg_to_rad(deg) ((deg) * (M_PI / 180.0)) | |
| #define rad_to_deg(rad) ((rad) * (180.0 / M_PI)) | |
| #define dbl_is_near(expected, actual, epsilon) ((fabs((expected) - (actual)) <= (epsilon)) ? 1 : 0) | |
| typedef enum | |
| { | |
| VX = 0, VY = 1, VZ = 2, VU = 3, VV = 4, VW = 5 | |
| } vertex_e; | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef GL_MATRIX_H | |
| #define GL_MATRIX_H | |
| #include "vec3.h" | |
| #include "mat3.h" | |
| #include "mat4.h" | |
| #include "quat.h" | |
| #include "vec4.h" | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <math.h> | |
| #include "mat3.h" | |
| // | |
| // 3 x 3 matrix | |
| // | |
| // double b00 = mat[M3_00]; | |
| // double b01 = mat[M3_01]; | |
| // double b02 = mat[M3_02]; | |
| // double b10 = mat[M3_10]; | |
| // double b11 = mat[M3_11]; | |
| // double b12 = mat[M3_12]; | |
| // double b20 = mat[M3_20]; | |
| // double b21 = mat[M3_21]; | |
| // double b22 = mat[M3_22]; | |
| // | |
| mat3_t mat3_create(mat3_t mat) | |
| { | |
| mat3_t dest = calloc(9, sizeof(double_t)); | |
| if (!dest) { | |
| return NULL; | |
| } | |
| if (mat) { | |
| mat3_set(mat, dest); | |
| } | |
| return dest; | |
| } | |
| void mat3_free(mat3_t mat) | |
| { | |
| free(mat); | |
| } | |
| void mat3_set(mat3_t mat, mat3_t dest) | |
| { | |
| dest[M3_00] = mat[M3_00]; | |
| dest[M3_01] = mat[M3_01]; | |
| dest[M3_02] = mat[M3_02]; | |
| dest[M3_10] = mat[M3_10]; | |
| dest[M3_11] = mat[M3_11]; | |
| dest[M3_12] = mat[M3_12]; | |
| dest[M3_20] = mat[M3_20]; | |
| dest[M3_21] = mat[M3_21]; | |
| dest[M3_22] = mat[M3_22]; | |
| } | |
| mat3_t mat3_identity(mat3_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat3_create(NULL); | |
| } | |
| dest[M3_00] = 1; | |
| dest[M3_01] = 0; | |
| dest[M3_02] = 0; | |
| dest[M3_10] = 0; | |
| dest[M3_11] = 1; | |
| dest[M3_12] = 0; | |
| dest[M3_20] = 0; | |
| dest[M3_21] = 0; | |
| dest[M3_22] = 1; | |
| return dest; | |
| } | |
| void mat3_transpose(mat3_t mat, mat3_t dest) | |
| { | |
| // If we are transposing ourselves we can skip a few steps but have to cache some values | |
| if (!dest || mat == dest) { | |
| double a01 = mat[M3_01]; | |
| double a02 = mat[M3_02]; | |
| double a12 = mat[M3_12]; | |
| mat[M3_01] = mat[M3_10]; | |
| mat[M3_02] = mat[M3_20]; | |
| mat[M3_10] = a01; | |
| mat[M3_12] = mat[M3_21]; | |
| mat[M3_20] = a02; | |
| mat[M3_21] = a12; | |
| return; | |
| } | |
| dest[M3_00] = mat[M3_00]; | |
| dest[M3_01] = mat[M3_10]; | |
| dest[M3_02] = mat[M3_20]; | |
| dest[M3_10] = mat[M3_01]; | |
| dest[M3_11] = mat[M3_11]; | |
| dest[M3_12] = mat[M3_21]; | |
| dest[M3_20] = mat[M3_02]; | |
| dest[M3_21] = mat[M3_12]; | |
| dest[M3_22] = mat[M3_22]; | |
| } | |
| mat4_t mat3_to_mat4(mat3_t mat, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat4_create(NULL); | |
| } | |
| dest[15] = 1; | |
| dest[14] = 0; | |
| dest[13] = 0; | |
| dest[12] = 0; | |
| dest[11] = 0; | |
| dest[10] = mat[M3_22]; | |
| dest[9] = mat[M3_21]; | |
| dest[M3_22] = mat[M3_20]; | |
| dest[M3_21] = 0; | |
| dest[M3_20] = mat[M3_12]; | |
| dest[M3_12] = mat[M3_11]; | |
| dest[M3_11] = mat[M3_10]; | |
| dest[M3_10] = 0; | |
| dest[M3_02] = mat[M3_02]; | |
| dest[M3_01] = mat[M3_01]; | |
| dest[M3_00] = mat[M3_00]; | |
| return dest; | |
| } | |
| void mat3_mul_mat3(mat3_t mata, mat3_t matb, mat3_t dest) | |
| { | |
| if (!dest) { | |
| dest = mata; | |
| } | |
| double v00 = mata[M3_00] * matb[M3_00] + mata[M3_01] * matb[M3_10] + mata[M3_02] * matb[M3_20]; | |
| double v01 = mata[M3_00] * matb[M3_01] + mata[M3_01] * matb[M3_11] + mata[M3_02] * matb[M3_21]; | |
| double v02 = mata[M3_00] * matb[M3_02] + mata[M3_01] * matb[M3_12] + mata[M3_02] * matb[M3_22]; | |
| double v10 = mata[M3_10] * matb[M3_00] + mata[M3_11] * matb[M3_10] + mata[M3_12] * matb[M3_20]; | |
| double v11 = mata[M3_10] * matb[M3_01] + mata[M3_11] * matb[M3_11] + mata[M3_12] * matb[M3_21]; | |
| double v12 = mata[M3_10] * matb[M3_02] + mata[M3_11] * matb[M3_12] + mata[M3_12] * matb[M3_22]; | |
| double v20 = mata[M3_20] * matb[M3_00] + mata[M3_21] * matb[M3_10] + mata[M3_22] * matb[M3_20]; | |
| double v21 = mata[M3_20] * matb[M3_01] + mata[M3_21] * matb[M3_11] + mata[M3_22] * matb[M3_21]; | |
| double v22 = mata[M3_20] * matb[M3_02] + mata[M3_21] * matb[M3_12] + mata[M3_22] * matb[M3_22]; | |
| dest[M3_00] = v00; | |
| dest[M3_10] = v10; | |
| dest[M3_20] = v20; | |
| dest[M3_01] = v01; | |
| dest[M3_11] = v11; | |
| dest[M3_21] = v21; | |
| dest[M3_02] = v02; | |
| dest[M3_12] = v12; | |
| dest[M3_22] = v22; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _MAT3_H | |
| #define _MAT3_H | |
| typedef double *mat3_t; | |
| typedef enum | |
| { | |
| M3_00 = 0, M3_01 = 1, M3_02 = 2, M3_10 = 3, M3_11 = 4, M3_12 = 5, M3_20 = 6, M3_21 = 7, M3_22 = 8 | |
| } mat3_pos; | |
| #include "mat4.h" | |
| #include "common.h" | |
| /** | |
| * Creates a new instance of a mat3_t | |
| * | |
| * Params: | |
| * mat - Optional, mat3_t containing values to initialize with. If NULL the result | |
| * will be initialized with zeroes. | |
| * | |
| * Returns: | |
| * New mat3 | |
| */ | |
| mat3_t mat3_create(mat3_t mat); | |
| /** | |
| * Frees a mat3_t | |
| * | |
| * @param mat | |
| * The 3x3 matrix | |
| */ | |
| void mat3_free(mat3_t mat); | |
| /** | |
| * Copies the values of one mat3_t to another | |
| * | |
| * @param mat | |
| * mat3_t containing values to copy | |
| * @param dest | |
| * mat3_t receiving copied values | |
| * | |
| */ | |
| void mat3_set(mat3_t mat, mat3_t dest); | |
| /** | |
| * Sets a mat3_t to an identity matrix | |
| * | |
| * @param dest | |
| * mat3_t to set | |
| * | |
| * @return If dest is NULL a new identity matrix is returned. | |
| */ | |
| mat3_t mat3_identity(mat3_t dest); | |
| /** | |
| * Transposes a mat3_t (flips the values over the diagonal) | |
| * | |
| * Params: | |
| * mat - mat3_t to transpose | |
| * dest - Optional, mat3_t receiving transposed values. If NULL, result is written to mat | |
| * | |
| */ | |
| void mat3_transpose(mat3_t mat, mat3_t dest); | |
| /** | |
| * Copies the elements of a mat3_t into the upper 3x3 elements of a mat4 | |
| * | |
| * Params: | |
| * mat - mat3_t containing values to copy | |
| * dest - Optional, mat4_t receiving copied values | |
| * | |
| * Returns: | |
| * dest if not NULL, a new mat4_t otherwise | |
| */ | |
| mat4_t mat3_to_mat4(mat3_t mat, mat4_t dest); | |
| void mat3_mul_mat3(mat3_t mata, mat3_t matb, mat3_t dest); | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <math.h> | |
| #include "mat4.h" | |
| // | |
| // 4 x 4 matrix | |
| // | |
| // double a00 = mat[M4_00]; | |
| // double a01 = mat[M4_01]; | |
| // double a02 = mat[M4_02]; | |
| // double a03 = mat[M4_03]; | |
| // double a10 = mat[M4_10]; | |
| // double a11 = mat[M4_11]; | |
| // double a12 = mat[M4_12]; | |
| // double a13 = mat[M4_13]; | |
| // double a20 = mat[M4_20]; | |
| // double a21 = mat[M4_21]; | |
| // double a22 = mat[M4_22]; | |
| // double a23 = mat[M4_23]; | |
| // double a30 = mat[M4_30]; | |
| // double a31 = mat[M4_31]; | |
| // double a32 = mat[M4_32]; | |
| // double a33 = mat[M4_33]; | |
| // | |
| mat4_t mat4_create(mat4_t mat) | |
| { | |
| mat4_t dest = calloc(16, sizeof(double_t)); | |
| if (mat) { | |
| dest[M4_00] = mat[M4_00]; | |
| dest[M4_01] = mat[M4_01]; | |
| dest[M4_02] = mat[M4_02]; | |
| dest[M4_03] = mat[M4_03]; | |
| dest[M4_10] = mat[M4_10]; | |
| dest[M4_11] = mat[M4_11]; | |
| dest[M4_12] = mat[M4_12]; | |
| dest[M4_13] = mat[M4_13]; | |
| dest[M4_20] = mat[M4_20]; | |
| dest[M4_21] = mat[M4_21]; | |
| dest[M4_22] = mat[M4_22]; | |
| dest[M4_23] = mat[M4_23]; | |
| dest[M4_30] = mat[M4_30]; | |
| dest[M4_31] = mat[M4_31]; | |
| dest[M4_32] = mat[M4_32]; | |
| dest[M4_33] = mat[M4_33]; | |
| } | |
| return dest; | |
| } | |
| void mat4_free(mat4_t mat) | |
| { | |
| free(mat); | |
| } | |
| mat4_t mat4_set(mat4_t mat, mat4_t dest) | |
| { | |
| dest[M4_00] = mat[M4_00]; | |
| dest[M4_01] = mat[M4_01]; | |
| dest[M4_02] = mat[M4_02]; | |
| dest[M4_03] = mat[M4_03]; | |
| dest[M4_10] = mat[M4_10]; | |
| dest[M4_11] = mat[M4_11]; | |
| dest[M4_12] = mat[M4_12]; | |
| dest[M4_13] = mat[M4_13]; | |
| dest[M4_20] = mat[M4_20]; | |
| dest[M4_21] = mat[M4_21]; | |
| dest[M4_22] = mat[M4_22]; | |
| dest[M4_23] = mat[M4_23]; | |
| dest[M4_30] = mat[M4_30]; | |
| dest[M4_31] = mat[M4_31]; | |
| dest[M4_32] = mat[M4_32]; | |
| dest[M4_33] = mat[M4_33]; | |
| return dest; | |
| } | |
| mat4_t mat4_identity(mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat4_create(NULL); | |
| } | |
| dest[M4_00] = 1; | |
| dest[M4_01] = 0; | |
| dest[M4_02] = 0; | |
| dest[M4_03] = 0; | |
| dest[M4_10] = 0; | |
| dest[M4_11] = 1; | |
| dest[M4_12] = 0; | |
| dest[M4_13] = 0; | |
| dest[M4_20] = 0; | |
| dest[M4_21] = 0; | |
| dest[M4_22] = 1; | |
| dest[M4_23] = 0; | |
| dest[M4_30] = 0; | |
| dest[M4_31] = 0; | |
| dest[M4_32] = 0; | |
| dest[M4_33] = 1; | |
| return dest; | |
| } | |
| mat4_t mat4_transpose(mat4_t mat, mat4_t dest) | |
| { | |
| // If we are transposing ourselves we can skip a few steps but have to cache some values | |
| if (!dest || mat == dest) { | |
| double a01 = mat[M4_01]; | |
| double a02 = mat[M4_02]; | |
| double a03 = mat[M4_03]; | |
| double a12 = mat[M4_12]; | |
| double a13 = mat[M4_13]; | |
| double a23 = mat[M4_23]; | |
| mat[M4_01] = mat[M4_10]; | |
| mat[M4_02] = mat[M4_20]; | |
| mat[M4_03] = mat[M4_30]; | |
| mat[M4_10] = a01; | |
| mat[M4_12] = mat[M4_21]; | |
| mat[M4_13] = mat[M4_31]; | |
| mat[M4_20] = a02; | |
| mat[M4_21] = a12; | |
| mat[M4_23] = mat[M4_32]; | |
| mat[M4_30] = a03; | |
| mat[M4_31] = a13; | |
| mat[M4_32] = a23; | |
| return mat; | |
| } | |
| dest[M4_00] = mat[M4_00]; | |
| dest[M4_01] = mat[M4_10]; | |
| dest[M4_02] = mat[M4_20]; | |
| dest[M4_03] = mat[M4_30]; | |
| dest[M4_10] = mat[M4_01]; | |
| dest[M4_11] = mat[M4_11]; | |
| dest[M4_12] = mat[M4_21]; | |
| dest[M4_13] = mat[M4_31]; | |
| dest[M4_20] = mat[M4_02]; | |
| dest[M4_21] = mat[M4_12]; | |
| dest[M4_22] = mat[M4_22]; | |
| dest[M4_23] = mat[M4_32]; | |
| dest[M4_30] = mat[M4_03]; | |
| dest[M4_31] = mat[M4_13]; | |
| dest[M4_32] = mat[M4_23]; | |
| dest[M4_33] = mat[M4_33]; | |
| return dest; | |
| } | |
| double mat4_determinant(mat4_t mat) | |
| { | |
| // Cache the matrix values (makes for huge speed increases!) | |
| double a00 = mat[M4_00]; | |
| double a01 = mat[M4_01]; | |
| double a02 = mat[M4_02]; | |
| double a03 = mat[M4_03]; | |
| double a10 = mat[M4_10]; | |
| double a11 = mat[M4_11]; | |
| double a12 = mat[M4_12]; | |
| double a13 = mat[M4_13]; | |
| double a20 = mat[M4_20]; | |
| double a21 = mat[M4_21]; | |
| double a22 = mat[M4_22]; | |
| double a23 = mat[M4_23]; | |
| double a30 = mat[M4_30]; | |
| double a31 = mat[M4_31]; | |
| double a32 = mat[M4_32]; | |
| double a33 = mat[M4_33]; | |
| return (a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 + | |
| a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 + | |
| a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 + | |
| a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 + | |
| a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 + | |
| a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33); | |
| } | |
| mat4_t mat4_inverse(mat4_t mat, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat; | |
| } | |
| // Cache the matrix values (makes for huge speed increases!) | |
| double a00 = mat[M4_00]; | |
| double a01 = mat[M4_01]; | |
| double a02 = mat[M4_02]; | |
| double a03 = mat[M4_03]; | |
| double a10 = mat[M4_10]; | |
| double a11 = mat[M4_11]; | |
| double a12 = mat[M4_12]; | |
| double a13 = mat[M4_13]; | |
| double a20 = mat[M4_20]; | |
| double a21 = mat[M4_21]; | |
| double a22 = mat[M4_22]; | |
| double a23 = mat[M4_23]; | |
| double a30 = mat[M4_30]; | |
| double a31 = mat[M4_31]; | |
| double a32 = mat[M4_32]; | |
| double a33 = mat[M4_33]; | |
| double b00 = a00 * a11 - a01 * a10; | |
| double b01 = a00 * a12 - a02 * a10; | |
| double b02 = a00 * a13 - a03 * a10; | |
| double b03 = a01 * a12 - a02 * a11; | |
| double b04 = a01 * a13 - a03 * a11; | |
| double b05 = a02 * a13 - a03 * a12; | |
| double b06 = a20 * a31 - a21 * a30; | |
| double b07 = a20 * a32 - a22 * a30; | |
| double b08 = a20 * a33 - a23 * a30; | |
| double b09 = a21 * a32 - a22 * a31; | |
| double b10 = a21 * a33 - a23 * a31; | |
| double b11 = a22 * a33 - a23 * a32; | |
| double d = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; | |
| double inv_det; | |
| // Calculate the determinant | |
| if (!d) { | |
| return NULL; | |
| } | |
| inv_det = 1 / d; | |
| dest[M4_00] = (a11 * b11 - a12 * b10 + a13 * b09) * inv_det; | |
| dest[M4_01] = (-a01 * b11 + a02 * b10 - a03 * b09) * inv_det; | |
| dest[M4_02] = (a31 * b05 - a32 * b04 + a33 * b03) * inv_det; | |
| dest[M4_03] = (-a21 * b05 + a22 * b04 - a23 * b03) * inv_det; | |
| dest[M4_10] = (-a10 * b11 + a12 * b08 - a13 * b07) * inv_det; | |
| dest[M4_11] = (a00 * b11 - a02 * b08 + a03 * b07) * inv_det; | |
| dest[M4_12] = (-a30 * b05 + a32 * b02 - a33 * b01) * inv_det; | |
| dest[M4_13] = (a20 * b05 - a22 * b02 + a23 * b01) * inv_det; | |
| dest[M4_20] = (a10 * b10 - a11 * b08 + a13 * b06) * inv_det; | |
| dest[M4_21] = (-a00 * b10 + a01 * b08 - a03 * b06) * inv_det; | |
| dest[M4_22] = (a30 * b04 - a31 * b02 + a33 * b00) * inv_det; | |
| dest[M4_23] = (-a20 * b04 + a21 * b02 - a23 * b00) * inv_det; | |
| dest[M4_30] = (-a10 * b09 + a11 * b07 - a12 * b06) * inv_det; | |
| dest[M4_31] = (a00 * b09 - a01 * b07 + a02 * b06) * inv_det; | |
| dest[M4_32] = (-a30 * b03 + a31 * b01 - a32 * b00) * inv_det; | |
| dest[M4_33] = (a20 * b03 - a21 * b01 + a22 * b00) * inv_det; | |
| return dest; | |
| } | |
| mat4_t mat4_toRotationMat(mat4_t mat, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat4_create(NULL); | |
| } | |
| dest[M4_00] = mat[M4_00]; | |
| dest[M4_01] = mat[M4_01]; | |
| dest[M4_02] = mat[M4_02]; | |
| dest[M4_03] = mat[M4_03]; | |
| dest[M4_10] = mat[M4_10]; | |
| dest[M4_11] = mat[M4_11]; | |
| dest[M4_12] = mat[M4_12]; | |
| dest[M4_13] = mat[M4_13]; | |
| dest[M4_20] = mat[M4_20]; | |
| dest[M4_21] = mat[M4_21]; | |
| dest[M4_22] = mat[M4_22]; | |
| dest[M4_23] = mat[M4_23]; | |
| dest[M4_30] = 0; | |
| dest[M4_31] = 0; | |
| dest[M4_32] = 0; | |
| dest[M4_33] = 1; | |
| return dest; | |
| } | |
| mat3_t mat4_to_mat3(mat4_t mat, mat3_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat3_create(NULL); | |
| } | |
| dest[M4_00] = mat[M4_00]; | |
| dest[M4_01] = mat[M4_01]; | |
| dest[M4_02] = mat[M4_02]; | |
| dest[M4_03] = mat[M4_10]; | |
| dest[M4_10] = mat[M4_11]; | |
| dest[M4_11] = mat[M4_12]; | |
| dest[M4_12] = mat[M4_20]; | |
| dest[M4_13] = mat[M4_21]; | |
| dest[M4_20] = mat[M4_22]; | |
| return dest; | |
| } | |
| mat3_t mat4_to_inverse_mat3(mat4_t mat, mat3_t dest) | |
| { | |
| // Cache the matrix values (makes for huge speed increases!) | |
| double a00 = mat[M4_00]; | |
| double a01 = mat[M4_01]; | |
| double a02 = mat[M4_02]; | |
| double a10 = mat[M4_10]; | |
| double a11 = mat[M4_11]; | |
| double a12 = mat[M4_12]; | |
| double a20 = mat[M4_20]; | |
| double a21 = mat[M4_21]; | |
| double a22 = mat[M4_22]; | |
| double b01 = a22 * a11 - a12 * a21; | |
| double b11 = -a22 * a10 + a12 * a20; | |
| double b21 = a21 * a10 - a11 * a20; | |
| double d = a00 * b01 + a01 * b11 + a02 * b21; | |
| double id; | |
| if (!d) { | |
| return NULL; | |
| } | |
| id = 1 / d; | |
| if (!dest) { | |
| dest = mat3_create(NULL); | |
| } | |
| dest[M4_00] = b01 * id; | |
| dest[M4_01] = (-a22 * a01 + a02 * a21) * id; | |
| dest[M4_02] = (a12 * a01 - a02 * a11) * id; | |
| dest[M4_03] = b11 * id; | |
| dest[M4_10] = (a22 * a00 - a02 * a20) * id; | |
| dest[M4_11] = (-a12 * a00 + a02 * a10) * id; | |
| dest[M4_12] = b21 * id; | |
| dest[M4_13] = (-a21 * a00 + a01 * a20) * id; | |
| dest[M4_20] = (a11 * a00 - a01 * a10) * id; | |
| return dest; | |
| } | |
| mat4_t mat4_multiply(mat4_t mat, mat4_t mat2, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat; | |
| } | |
| // Cache the matrix values (makes for huge speed increases!) | |
| double a00 = mat[M4_00]; | |
| double a01 = mat[M4_01]; | |
| double a02 = mat[M4_02]; | |
| double a03 = mat[M4_03]; | |
| double a10 = mat[M4_10]; | |
| double a11 = mat[M4_11]; | |
| double a12 = mat[M4_12]; | |
| double a13 = mat[M4_13]; | |
| double a20 = mat[M4_20]; | |
| double a21 = mat[M4_21]; | |
| double a22 = mat[M4_22]; | |
| double a23 = mat[M4_23]; | |
| double a30 = mat[M4_30]; | |
| double a31 = mat[M4_31]; | |
| double a32 = mat[M4_32]; | |
| double a33 = mat[M4_33]; | |
| double b00 = mat2[M4_00]; | |
| double b01 = mat2[M4_01]; | |
| double b02 = mat2[M4_02]; | |
| double b03 = mat2[M4_03]; | |
| double b10 = mat2[M4_10]; | |
| double b11 = mat2[M4_11]; | |
| double b12 = mat2[M4_12]; | |
| double b13 = mat2[M4_13]; | |
| double b20 = mat2[M4_20]; | |
| double b21 = mat2[M4_21]; | |
| double b22 = mat2[M4_22]; | |
| double b23 = mat2[M4_23]; | |
| double b30 = mat2[M4_30]; | |
| double b31 = mat2[M4_31]; | |
| double b32 = mat2[M4_32]; | |
| double b33 = mat2[M4_33]; | |
| dest[M4_00] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30; | |
| dest[M4_01] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31; | |
| dest[M4_02] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32; | |
| dest[M4_03] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33; | |
| dest[M4_10] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30; | |
| dest[M4_11] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31; | |
| dest[M4_12] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32; | |
| dest[M4_13] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33; | |
| dest[M4_20] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30; | |
| dest[M4_21] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31; | |
| dest[M4_22] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32; | |
| dest[M4_23] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33; | |
| dest[M4_30] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30; | |
| dest[M4_31] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31; | |
| dest[M4_32] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32; | |
| dest[M4_33] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33; | |
| return dest; | |
| } | |
| mat4_t mat4_multiply_vec3(mat4_t mat, vec3_t vec, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double x = vec[0], y = vec[1], z = vec[2]; | |
| dest[M4_00] = mat[M4_00] * x + mat[M4_10] * y + mat[M4_20] * z + mat[M4_30]; | |
| dest[M4_01] = mat[M4_01] * x + mat[M4_11] * y + mat[M4_21] * z + mat[M4_31]; | |
| dest[M4_02] = mat[M4_02] * x + mat[M4_12] * y + mat[M4_22] * z + mat[M4_32]; | |
| return dest; | |
| } | |
| mat4_t mat4_multiply_vec4(mat4_t mat, vec4_t vec, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double x = vec[0]; | |
| double y = vec[1]; | |
| double z = vec[2]; | |
| double w = vec[4]; | |
| dest[M4_00] = mat[M4_00] * x + mat[M4_10] * y + mat[M4_20] * z + mat[M4_30] * w; | |
| dest[M4_01] = mat[M4_01] * x + mat[M4_11] * y + mat[M4_21] * z + mat[M4_31] * w; | |
| dest[M4_02] = mat[M4_02] * x + mat[M4_12] * y + mat[M4_22] * z + mat[M4_32] * w; | |
| dest[M4_03] = mat[M4_03] * x + mat[M4_13] * y + mat[M4_23] * z + mat[M4_33] * w; | |
| return dest; | |
| } | |
| mat4_t mat4_translate(mat4_t mat, vec3_t vec, mat4_t dest) | |
| { | |
| double x = vec[0]; | |
| double y = vec[1]; | |
| double z = vec[2]; | |
| double a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; | |
| if (!dest || mat == dest) { | |
| mat[M4_30] = mat[M4_00] * x + mat[M4_10] * y + mat[M4_20] * z + mat[M4_30]; | |
| mat[M4_31] = mat[M4_01] * x + mat[M4_11] * y + mat[M4_21] * z + mat[M4_31]; | |
| mat[M4_32] = mat[M4_02] * x + mat[M4_12] * y + mat[M4_22] * z + mat[M4_32]; | |
| mat[M4_33] = mat[M4_03] * x + mat[M4_13] * y + mat[M4_23] * z + mat[M4_33]; | |
| return mat; | |
| } | |
| a00 = mat[M4_00]; | |
| a01 = mat[M4_01]; | |
| a02 = mat[M4_02]; | |
| a03 = mat[M4_03]; | |
| a10 = mat[M4_10]; | |
| a11 = mat[M4_11]; | |
| a12 = mat[M4_12]; | |
| a13 = mat[M4_13]; | |
| a20 = mat[M4_20]; | |
| a21 = mat[M4_21]; | |
| a22 = mat[M4_22]; | |
| a23 = mat[M4_23]; | |
| dest[M4_00] = a00; | |
| dest[M4_01] = a01; | |
| dest[M4_02] = a02; | |
| dest[M4_03] = a03; | |
| dest[M4_10] = a10; | |
| dest[M4_11] = a11; | |
| dest[M4_12] = a12; | |
| dest[M4_13] = a13; | |
| dest[M4_20] = a20; | |
| dest[M4_21] = a21; | |
| dest[M4_22] = a22; | |
| dest[M4_23] = a23; | |
| dest[M4_30] = a00 * x + a10 * y + a20 * z + mat[M4_30]; | |
| dest[M4_31] = a01 * x + a11 * y + a21 * z + mat[M4_31]; | |
| dest[M4_32] = a02 * x + a12 * y + a22 * z + mat[M4_32]; | |
| dest[M4_33] = a03 * x + a13 * y + a23 * z + mat[M4_33]; | |
| return dest; | |
| } | |
| mat4_t mat4_scale(mat4_t mat, vec3_t vec, mat4_t dest) | |
| { | |
| double x = vec[0]; | |
| double y = vec[1]; | |
| double z = vec[2]; | |
| if (!dest || mat == dest) { | |
| mat[M4_00] *= x; | |
| mat[M4_01] *= x; | |
| mat[M4_02] *= x; | |
| mat[M4_03] *= x; | |
| mat[M4_10] *= y; | |
| mat[M4_11] *= y; | |
| mat[M4_12] *= y; | |
| mat[M4_13] *= y; | |
| mat[M4_20] *= z; | |
| mat[M4_21] *= z; | |
| mat[M4_22] *= z; | |
| mat[M4_23] *= z; | |
| return mat; | |
| } | |
| dest[M4_00] = mat[M4_00] * x; | |
| dest[M4_01] = mat[M4_01] * x; | |
| dest[M4_02] = mat[M4_02] * x; | |
| dest[M4_03] = mat[M4_03] * x; | |
| dest[M4_10] = mat[M4_10] * y; | |
| dest[M4_11] = mat[M4_11] * y; | |
| dest[M4_12] = mat[M4_12] * y; | |
| dest[M4_13] = mat[M4_13] * y; | |
| dest[M4_20] = mat[M4_20] * z; | |
| dest[M4_21] = mat[M4_21] * z; | |
| dest[M4_22] = mat[M4_22] * z; | |
| dest[M4_23] = mat[M4_23] * z; | |
| dest[M4_30] = mat[M4_30]; | |
| dest[M4_31] = mat[M4_31]; | |
| dest[M4_32] = mat[M4_32]; | |
| dest[M4_33] = mat[M4_33]; | |
| return dest; | |
| } | |
| mat4_t mat4_rotate(mat4_t mat, double angle, vec3_t axis, mat4_t dest) | |
| { | |
| double a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; | |
| double b00, b01, b02, b10, b11, b12, b20, b21, b22; | |
| double x = axis[M4_00]; | |
| double y = axis[M4_01]; | |
| double z = axis[M4_02]; | |
| double len = sqrt(x * x + y * y + z * z); | |
| double s, c, t; | |
| if (!len) { | |
| return NULL; | |
| } | |
| if (len != 1) { | |
| len = 1 / len; | |
| x *= len; | |
| y *= len; | |
| z *= len; | |
| } | |
| s = sin(angle); | |
| c = cos(angle); | |
| t = 1 - c; | |
| a00 = mat[M4_00]; | |
| a01 = mat[M4_01]; | |
| a02 = mat[M4_02]; | |
| a03 = mat[M4_03]; | |
| a10 = mat[M4_10]; | |
| a11 = mat[M4_11]; | |
| a12 = mat[M4_12]; | |
| a13 = mat[M4_13]; | |
| a20 = mat[M4_20]; | |
| a21 = mat[M4_21]; | |
| a22 = mat[M4_22]; | |
| a23 = mat[M4_23]; | |
| // Construct the elements of the rotation matrix | |
| b00 = x * x * t + c; | |
| b01 = y * x * t + z * s; | |
| b02 = z * x * t - y * s; | |
| b10 = x * y * t - z * s; | |
| b11 = y * y * t + c; | |
| b12 = z * y * t + x * s; | |
| b20 = x * z * t + y * s; | |
| b21 = y * z * t - x * s; | |
| b22 = z * z * t + c; | |
| if (!dest) { | |
| dest = mat; | |
| } else if (mat != dest) { // If the source and destination differ, copy the unchanged last row | |
| dest[M4_30] = mat[M4_30]; | |
| dest[M4_31] = mat[M4_31]; | |
| dest[M4_32] = mat[M4_32]; | |
| dest[M4_33] = mat[M4_33]; | |
| } | |
| // Perform rotation-specific matrix multiplication | |
| dest[M4_00] = a00 * b00 + a10 * b01 + a20 * b02; | |
| dest[M4_01] = a01 * b00 + a11 * b01 + a21 * b02; | |
| dest[M4_02] = a02 * b00 + a12 * b01 + a22 * b02; | |
| dest[M4_03] = a03 * b00 + a13 * b01 + a23 * b02; | |
| dest[M4_10] = a00 * b10 + a10 * b11 + a20 * b12; | |
| dest[M4_11] = a01 * b10 + a11 * b11 + a21 * b12; | |
| dest[M4_12] = a02 * b10 + a12 * b11 + a22 * b12; | |
| dest[M4_13] = a03 * b10 + a13 * b11 + a23 * b12; | |
| dest[M4_20] = a00 * b20 + a10 * b21 + a20 * b22; | |
| dest[M4_21] = a01 * b20 + a11 * b21 + a21 * b22; | |
| dest[M4_22] = a02 * b20 + a12 * b21 + a22 * b22; | |
| dest[M4_23] = a03 * b20 + a13 * b21 + a23 * b22; | |
| return dest; | |
| } | |
| mat4_t mat4_rotate_x(mat4_t mat, double angle, mat4_t dest) | |
| { | |
| double s = sin(angle); | |
| double c = cos(angle); | |
| double a10 = mat[M4_10]; | |
| double a11 = mat[M4_11]; | |
| double a12 = mat[M4_12]; | |
| double a13 = mat[M4_13]; | |
| double a20 = mat[M4_20]; | |
| double a21 = mat[M4_21]; | |
| double a22 = mat[M4_22]; | |
| double a23 = mat[M4_23]; | |
| if (!dest) { | |
| dest = mat; | |
| } else if (mat != dest) { // If the source and destination differ, copy the unchanged rows | |
| dest[M4_00] = mat[M4_00]; | |
| dest[M4_01] = mat[M4_01]; | |
| dest[M4_02] = mat[M4_02]; | |
| dest[M4_03] = mat[M4_03]; | |
| dest[M4_30] = mat[M4_30]; | |
| dest[M4_31] = mat[M4_31]; | |
| dest[M4_32] = mat[M4_32]; | |
| dest[M4_33] = mat[M4_33]; | |
| } | |
| // Perform axis-specific matrix multiplication | |
| dest[M4_10] = a10 * c + a20 * s; | |
| dest[M4_11] = a11 * c + a21 * s; | |
| dest[M4_12] = a12 * c + a22 * s; | |
| dest[M4_13] = a13 * c + a23 * s; | |
| dest[M4_20] = a10 * -s + a20 * c; | |
| dest[M4_21] = a11 * -s + a21 * c; | |
| dest[M4_22] = a12 * -s + a22 * c; | |
| dest[M4_23] = a13 * -s + a23 * c; | |
| return dest; | |
| } | |
| mat4_t mat4_rotate_y(mat4_t mat, double angle, mat4_t dest) | |
| { | |
| double s = sin(angle); | |
| double c = cos(angle); | |
| double a00 = mat[M4_00]; | |
| double a01 = mat[M4_01]; | |
| double a02 = mat[M4_02]; | |
| double a03 = mat[M4_03]; | |
| double a20 = mat[M4_20]; | |
| double a21 = mat[M4_21]; | |
| double a22 = mat[M4_22]; | |
| double a23 = mat[M4_23]; | |
| if (!dest) { | |
| dest = mat; | |
| } else if (mat != dest) { // If the source and destination differ, copy the unchanged rows | |
| dest[M4_10] = mat[M4_10]; | |
| dest[M4_11] = mat[M4_11]; | |
| dest[M4_12] = mat[M4_12]; | |
| dest[M4_13] = mat[M4_13]; | |
| dest[M4_30] = mat[M4_30]; | |
| dest[M4_31] = mat[M4_31]; | |
| dest[M4_32] = mat[M4_32]; | |
| dest[M4_33] = mat[M4_33]; | |
| } | |
| // Perform axis-specific matrix multiplication | |
| dest[M4_00] = a00 * c + a20 * -s; | |
| dest[M4_01] = a01 * c + a21 * -s; | |
| dest[M4_02] = a02 * c + a22 * -s; | |
| dest[M4_03] = a03 * c + a23 * -s; | |
| dest[M4_20] = a00 * s + a20 * c; | |
| dest[M4_21] = a01 * s + a21 * c; | |
| dest[M4_22] = a02 * s + a22 * c; | |
| dest[M4_23] = a03 * s + a23 * c; | |
| return dest; | |
| } | |
| mat4_t mat4_rotate_z(mat4_t mat, double angle, mat4_t dest) | |
| { | |
| double s = sin(angle); | |
| double c = cos(angle); | |
| double a00 = mat[M4_00]; | |
| double a01 = mat[M4_01]; | |
| double a02 = mat[M4_02]; | |
| double a03 = mat[M4_03]; | |
| double a10 = mat[M4_10]; | |
| double a11 = mat[M4_11]; | |
| double a12 = mat[M4_12]; | |
| double a13 = mat[M4_13]; | |
| if (!dest) { | |
| dest = mat; | |
| } else if (mat != dest) { // If the source and destination differ, copy the unchanged last row | |
| dest[M4_20] = mat[M4_20]; | |
| dest[M4_21] = mat[M4_21]; | |
| dest[M4_22] = mat[M4_22]; | |
| dest[M4_23] = mat[M4_23]; | |
| dest[M4_30] = mat[M4_30]; | |
| dest[M4_31] = mat[M4_31]; | |
| dest[M4_32] = mat[M4_32]; | |
| dest[M4_33] = mat[M4_33]; | |
| } | |
| // Perform axis-specific matrix multiplication | |
| dest[M4_00] = a00 * c + a10 * s; | |
| dest[M4_01] = a01 * c + a11 * s; | |
| dest[M4_02] = a02 * c + a12 * s; | |
| dest[M4_03] = a03 * c + a13 * s; | |
| dest[M4_10] = a00 * -s + a10 * c; | |
| dest[M4_11] = a01 * -s + a11 * c; | |
| dest[M4_12] = a02 * -s + a12 * c; | |
| dest[M4_13] = a03 * -s + a13 * c; | |
| return dest; | |
| } | |
| mat4_t mat4_frustum(double left, double right, double bottom, double top, double near, double far, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat4_create(NULL); | |
| } | |
| double rl = (right - left); | |
| double tb = (top - bottom); | |
| double fn = (far - near); | |
| dest[M4_00] = (near * 2) / rl; | |
| dest[M4_01] = 0; | |
| dest[M4_02] = 0; | |
| dest[M4_03] = 0; | |
| dest[M4_10] = 0; | |
| dest[M4_11] = (near * 2) / tb; | |
| dest[M4_12] = 0; | |
| dest[M4_13] = 0; | |
| dest[M4_20] = (right + left) / rl; | |
| dest[M4_21] = (top + bottom) / tb; | |
| dest[M4_22] = -(far + near) / fn; | |
| dest[M4_23] = -1; | |
| dest[M4_30] = 0; | |
| dest[M4_31] = 0; | |
| dest[M4_32] = -(far * near * 2) / fn; | |
| dest[M4_33] = 0; | |
| return dest; | |
| } | |
| mat4_t mat4_perspective(double fovy, double aspect, double near, double far, mat4_t dest) | |
| { | |
| double top = near * tan(fovy * M_PI / 360.0); | |
| double right = top * aspect; | |
| return mat4_frustum(-right, right, -top, top, near, far, dest); | |
| } | |
| mat4_t mat4_ortho(double left, double right, double bottom, double top, double near, double far, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat4_create(NULL); | |
| } | |
| double rl = (right - left); | |
| double tb = (top - bottom); | |
| double fn = (far - near); | |
| dest[M4_00] = 2 / rl; | |
| dest[M4_01] = 0; | |
| dest[M4_02] = 0; | |
| dest[M4_03] = 0; | |
| dest[M4_10] = 0; | |
| dest[M4_11] = 2 / tb; | |
| dest[M4_12] = 0; | |
| dest[M4_13] = 0; | |
| dest[M4_20] = 0; | |
| dest[M4_21] = 0; | |
| dest[M4_22] = -2 / fn; | |
| dest[M4_23] = 0; | |
| dest[M4_30] = -(left + right) / rl; | |
| dest[M4_31] = -(top + bottom) / tb; | |
| dest[M4_32] = -(far + near) / fn; | |
| dest[M4_33] = 1; | |
| return dest; | |
| } | |
| mat4_t mat4_look_at(vec3_t eye, vec3_t center, vec3_t up, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat4_create(NULL); | |
| } | |
| double x0, x1, x2, y0, y1, y2, z0, z1, z2; | |
| double len; | |
| double eyex = eye[0]; | |
| double eyey = eye[1]; | |
| double eyez = eye[2]; | |
| double upx = up[0]; | |
| double upy = up[1]; | |
| double upz = up[2]; | |
| double centerx = center[0]; | |
| double centery = center[1]; | |
| double centerz = center[2]; | |
| if (eyex == centerx && eyey == centery && eyez == centerz) { | |
| return mat4_identity(dest); | |
| } | |
| //vec3.direction(eye, center, z); | |
| z0 = eyex - centerx; | |
| z1 = eyey - centery; | |
| z2 = eyez - centerz; | |
| // normalize (no check needed for 0 because of early return) | |
| len = 1 / sqrt(z0 * z0 + z1 * z1 + z2 * z2); | |
| z0 *= len; | |
| z1 *= len; | |
| z2 *= len; | |
| //vec3.normalize(vec3.cross(up, z, x)); | |
| x0 = upy * z2 - upz * z1; | |
| x1 = upz * z0 - upx * z2; | |
| x2 = upx * z1 - upy * z0; | |
| len = sqrt(x0 * x0 + x1 * x1 + x2 * x2); | |
| if (!len) { | |
| x0 = 0; | |
| x1 = 0; | |
| x2 = 0; | |
| } else { | |
| len = 1 / len; | |
| x0 *= len; | |
| x1 *= len; | |
| x2 *= len; | |
| } | |
| //vec3.normalize(vec3.cross(z, x, y)); | |
| y0 = z1 * x2 - z2 * x1; | |
| y1 = z2 * x0 - z0 * x2; | |
| y2 = z0 * x1 - z1 * x0; | |
| len = sqrt(y0 * y0 + y1 * y1 + y2 * y2); | |
| if (!len) { | |
| y0 = 0; | |
| y1 = 0; | |
| y2 = 0; | |
| } else { | |
| len = 1 / len; | |
| y0 *= len; | |
| y1 *= len; | |
| y2 *= len; | |
| } | |
| dest[M4_00] = x0; | |
| dest[M4_01] = y0; | |
| dest[M4_02] = z0; | |
| dest[M4_03] = 0; | |
| dest[M4_10] = x1; | |
| dest[M4_11] = y1; | |
| dest[M4_12] = z1; | |
| dest[M4_13] = 0; | |
| dest[M4_20] = x2; | |
| dest[M4_21] = y2; | |
| dest[M4_22] = z2; | |
| dest[M4_23] = 0; | |
| dest[M4_30] = -(x0 * eyex + x1 * eyey + x2 * eyez); | |
| dest[M4_31] = -(y0 * eyex + y1 * eyey + y2 * eyez); | |
| dest[M4_32] = -(z0 * eyex + z1 * eyey + z2 * eyez); | |
| dest[M4_33] = 1; | |
| return dest; | |
| } | |
| mat4_t mat4_from_rotation_translation(quat_t quat, vec3_t vec, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat4_create(NULL); | |
| } | |
| // Quaternion math | |
| double x = quat[0]; | |
| double y = quat[1]; | |
| double z = quat[2]; | |
| double w = quat[3]; | |
| double x2 = x + x; | |
| double y2 = y + y; | |
| double z2 = z + z; | |
| double xx = x * x2; | |
| double xy = x * y2; | |
| double xz = x * z2; | |
| double yy = y * y2; | |
| double yz = y * z2; | |
| double zz = z * z2; | |
| double wx = w * x2; | |
| double wy = w * y2; | |
| double wz = w * z2; | |
| dest[M4_00] = 1 - (yy + zz); | |
| dest[M4_01] = xy + wz; | |
| dest[M4_02] = xz - wy; | |
| dest[M4_03] = 0; | |
| dest[M4_10] = xy - wz; | |
| dest[M4_11] = 1 - (xx + zz); | |
| dest[M4_12] = yz + wx; | |
| dest[M4_13] = 0; | |
| dest[M4_20] = xz + wy; | |
| dest[M4_21] = yz - wx; | |
| dest[M4_22] = 1 - (xx + yy); | |
| dest[M4_23] = 0; | |
| dest[M4_30] = vec[0]; | |
| dest[M4_31] = vec[1]; | |
| dest[M4_32] = vec[2]; | |
| dest[M4_33] = 1; | |
| return dest; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _MAT4_H | |
| #define _MAT4_H | |
| typedef double *mat4_t; | |
| typedef enum | |
| { | |
| M4_00 = 0, | |
| M4_01 = 1, | |
| M4_02 = 2, | |
| M4_03 = 3, | |
| M4_10 = 4, | |
| M4_11 = 5, | |
| M4_12 = 6, | |
| M4_13 = 7, | |
| M4_20 = 8, | |
| M4_21 = 9, | |
| M4_22 = 10, | |
| M4_23 = 11, | |
| M4_30 = 12, | |
| M4_31 = 13, | |
| M4_32 = 14, | |
| M4_33 = 15 | |
| } mat4_pos; | |
| #include "vec3.h" | |
| #include "mat3.h" | |
| #include "vec4.h" | |
| #include "quat.h" | |
| #include "common.h" | |
| /* | |
| * mat4_t - 4x4 Matrix | |
| */ | |
| /* | |
| * mat4_create | |
| * Creates a new instance of a mat4_t | |
| * | |
| * Params: | |
| * mat - Optional, mat4_t containing values to initialize with | |
| * | |
| * Returns: | |
| * New mat4 | |
| */ | |
| mat4_t mat4_create(mat4_t mat); | |
| void mat4_free(mat4_t mat); | |
| /* | |
| * mat4_set | |
| * Copies the values of one mat4_t to another | |
| * | |
| * Params: | |
| * mat - mat4_t containing values to copy | |
| * dest - mat4_t receiving copied values | |
| * | |
| * Returns: | |
| * dest | |
| */ | |
| mat4_t mat4_set(mat4_t mat, mat4_t dest); | |
| /* | |
| * mat4_identity | |
| * Sets a mat4_t to an identity matrix | |
| * | |
| * Params: | |
| * dest - mat4_t to set | |
| * | |
| * Returns: | |
| * dest | |
| */ | |
| mat4_t mat4_identity(mat4_t dest); | |
| /* | |
| * mat4_transpose | |
| * Transposes a mat4_t (flips the values over the diagonal) | |
| * | |
| * Params: | |
| * mat - mat4_t to transpose | |
| * dest - Optional, mat4_t receiving transposed values. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest is specified, mat otherwise | |
| */ | |
| mat4_t mat4_transpose(mat4_t mat, mat4_t dest); | |
| /* | |
| * mat4_determinant | |
| * Calculates the determinant of a mat4 | |
| * | |
| * Params: | |
| * mat - mat4_t to calculate determinant of | |
| * | |
| * Returns: | |
| * determinant of mat | |
| */ | |
| double mat4_determinant(mat4_t mat); | |
| /* | |
| * mat4_inverse | |
| * Calculates the inverse matrix of a mat4 | |
| * | |
| * Params: | |
| * mat - mat4_t to calculate inverse of | |
| * dest - Optional, mat4_t receiving inverse matrix. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest is specified, mat otherwise, NULL if matrix cannot be inverted | |
| */ | |
| mat4_t mat4_inverse(mat4_t mat, mat4_t dest); | |
| /* | |
| * mat4_toRotationMat | |
| * Copies the upper 3x3 elements of a mat4_t into another mat4 | |
| * | |
| * Params: | |
| * mat - mat4_t containing values to copy | |
| * dest - Optional, mat4_t receiving copied values | |
| * | |
| * Returns: | |
| * dest is specified, a new mat4_t otherwise | |
| */ | |
| mat4_t mat4_to_rotation_mat(mat4_t mat, mat4_t dest); | |
| /* | |
| * mat4_to_mat3 | |
| * Copies the upper 3x3 elements of a mat4_t into a mat3 | |
| * | |
| * Params: | |
| * mat - mat4_t containing values to copy | |
| * dest - Optional, mat3_t receiving copied values | |
| * | |
| * Returns: | |
| * dest is specified, a new mat3_t otherwise | |
| */ | |
| mat3_t mat4_to_mat3(mat4_t mat, mat3_t dest); | |
| /* | |
| * mat4_to_inverse_mat3 | |
| * Calculates the inverse of the upper 3x3 elements of a mat4_t and copies the result into a mat3 | |
| * The resulting matrix is useful for calculating transformed normals | |
| * | |
| * Params: | |
| * mat - mat4_t containing values to invert and copy | |
| * dest - Optional, mat3_t receiving values | |
| * | |
| * Returns: | |
| * dest is specified, a new mat3_t otherwise, NULL if the matrix cannot be inverted | |
| */ | |
| mat3_t mat4_to_inverse_mat3(mat4_t mat, mat3_t dest); | |
| /* | |
| * mat4_multiply | |
| * Performs a matrix multiplication | |
| * | |
| * Params: | |
| * mat - mat4, first operand | |
| * mat2 - mat4, second operand | |
| * dest - Optional, mat4_t receiving operation result. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest if not NULL, mat otherwise | |
| */ | |
| mat4_t mat4_multiply(mat4_t mat, mat4_t mat2, mat4_t dest); | |
| /* | |
| * mat4_multiply_vec3 | |
| * Transforms a vec3_t with the given matrix | |
| * 4th vector component is implicitly '1' | |
| * | |
| * Params: | |
| * mat - mat4_t to transform the vector with | |
| * vec - vec3_t to transform | |
| * dest - Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * Returns: | |
| * dest if not NULL, vec otherwise | |
| */ | |
| mat4_t mat4_multiply_vec3(mat4_t mat, vec3_t vec, mat4_t dest); | |
| /* | |
| * mat4_multiply_vec4 | |
| * Transforms a vec4 with the given matrix | |
| * | |
| * Params: | |
| * mat - mat4_t to transform the vector with | |
| * vec - vec4 to transform | |
| * dest - Optional, vec4 receiving operation result. If NULL, result is written to vec | |
| * | |
| * Returns: | |
| * dest if not NULL, vec otherwise | |
| */ | |
| mat4_t mat4_multiply_vec4(mat4_t mat, vec4_t vec, mat4_t dest); | |
| /* | |
| * mat4_translate | |
| * Translates a matrix by the given vector | |
| * | |
| * Params: | |
| * mat - mat4_t to translate | |
| * vec - vec3_t specifying the translation | |
| * dest - Optional, mat4_t receiving operation result. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest if not NULL, mat otherwise | |
| */ | |
| mat4_t mat4_translate(mat4_t mat, vec3_t vec, mat4_t dest); | |
| /* | |
| * mat4_scale | |
| * Scales a matrix by the given vector | |
| * | |
| * Params: | |
| * mat - mat4_t to scale | |
| * vec - vec3_t specifying the scale for each axis | |
| * dest - Optional, mat4_t receiving operation result. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest if not NULL, mat otherwise | |
| */ | |
| mat4_t mat4_scale(mat4_t mat, vec3_t vec, mat4_t dest); | |
| /* | |
| * mat4_rotate | |
| * Rotates a matrix by the given angle around the specified axis | |
| * If rotating around a primary axis (X,Y,Z) one of the specialized rotation functions should be used instead for performance | |
| * | |
| * Params: | |
| * mat - mat4_t to rotate | |
| * angle - angle (in radians) to rotate | |
| * axis - vec3_t representing the axis to rotate around | |
| * dest - Optional, mat4_t receiving operation result. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest if not NULL, mat otherwise | |
| */ | |
| mat4_t mat4_rotate(mat4_t mat, double angle, vec3_t axis, mat4_t dest); | |
| /* | |
| * mat4_rotate_x | |
| * Rotates a matrix by the given angle around the X axis | |
| * | |
| * Params: | |
| * mat - mat4_t to rotate | |
| * angle - angle (in radians) to rotate | |
| * dest - Optional, mat4_t receiving operation result. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest if not NULL, mat otherwise | |
| */ | |
| mat4_t mat4_rotate_x(mat4_t mat, double angle, mat4_t dest); | |
| /* | |
| * mat4_rotate_y | |
| * Rotates a matrix by the given angle around the Y axis | |
| * | |
| * Params: | |
| * mat - mat4_t to rotate | |
| * angle - angle (in radians) to rotate | |
| * dest - Optional, mat4_t receiving operation result. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest if not NULL, mat otherwise | |
| */ | |
| mat4_t mat4_rotate_y(mat4_t mat, double angle, mat4_t dest); | |
| /* | |
| * mat4_rotate_z | |
| * Rotates a matrix by the given angle around the Z axis | |
| * | |
| * Params: | |
| * mat - mat4_t to rotate | |
| * angle - angle (in radians) to rotate | |
| * dest - Optional, mat4_t receiving operation result. If NULL, result is written to mat | |
| * | |
| * Returns: | |
| * dest if not NULL, mat otherwise | |
| */ | |
| mat4_t mat4_rotate_z(mat4_t mat, double angle, mat4_t dest); | |
| /* | |
| * mat4_frustum | |
| * Generates a frustum matrix with the given bounds | |
| * | |
| * Params: | |
| * left, right - scalar, left and right bounds of the frustum | |
| * bottom, top - scalar, bottom and top bounds of the frustum | |
| * near, far - scalar, near and far bounds of the frustum | |
| * dest - Optional, mat4_t frustum matrix will be written into | |
| * | |
| * Returns: | |
| * dest if not NULL, a new mat4_t otherwise | |
| */ | |
| mat4_t mat4_frustum(double left, double right, double bottom, double top, double near, double far, mat4_t dest); | |
| /* | |
| * mat4_perspective | |
| * Generates a perspective projection matrix with the given bounds | |
| * | |
| * Params: | |
| * fovy - scalar, vertical field of view | |
| * aspect - scalar, aspect ratio. typically viewport width/height | |
| * near, far - scalar, near and far bounds of the frustum | |
| * dest - Optional, mat4_t frustum matrix will be written into | |
| * | |
| * Returns: | |
| * dest if not NULL, a new mat4_t otherwise | |
| */ | |
| mat4_t mat4_perspective(double fovy, double aspect, double near, double far, mat4_t dest); | |
| /* | |
| * mat4_ortho | |
| * Generates a orthogonal projection matrix with the given bounds | |
| * | |
| * Params: | |
| * left, right - scalar, left and right bounds of the frustum | |
| * bottom, top - scalar, bottom and top bounds of the frustum | |
| * near, far - scalar, near and far bounds of the frustum | |
| * dest - Optional, mat4_t frustum matrix will be written into | |
| * | |
| * Returns: | |
| * dest if not NULL, a new mat4_t otherwise | |
| */ | |
| mat4_t mat4_ortho(double left, double right, double bottom, double top, double near, double far, mat4_t dest); | |
| /* | |
| * mat4_look_at | |
| * Generates a look-at matrix with the given eye position, focal point, and up axis | |
| * | |
| * Params: | |
| * eye - vec3, position of the viewer | |
| * center - vec3, point the viewer is looking at | |
| * up - vec3_t pointing "up" | |
| * dest - Optional, mat4_t frustum matrix will be written into | |
| * | |
| * Returns: | |
| * dest if not NULL, a new mat4_t otherwise | |
| */ | |
| mat4_t mat4_look_at(vec3_t eye, vec3_t center, vec3_t up, mat4_t dest); | |
| /* | |
| * mat4_from_rotation_translation | |
| * Creates a matrix from a quaternion rotation and vector translation | |
| * This is equivalent to (but much faster than): | |
| * | |
| * mat4_identity(dest); | |
| * mat4_translate(dest, vec); | |
| * mat4_t quatMat = mat4_create(); | |
| * quat_to_mat4(quat, quatMat); | |
| * mat4_multiply(dest, quatMat); | |
| * | |
| * Params: | |
| * quat - quat specifying the rotation by | |
| * vec - vec3_t specifying the translation | |
| * dest - Optional, mat4_t receiving operation result. If NULL, result is written to a new mat4 | |
| * | |
| * Returns: | |
| * dest if not NULL, a new mat4_t otherwise | |
| */ | |
| mat4_t mat4_from_rotation_translation(quat_t quat, vec3_t vec, mat4_t dest); | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <math.h> | |
| #include "quat.h" | |
| quat_t quat_create(quat_t quat) | |
| { | |
| quat_t dest = calloc(4, sizeof(double_t)); | |
| if (quat) { | |
| dest[0] = quat[0]; | |
| dest[1] = quat[1]; | |
| dest[2] = quat[2]; | |
| dest[3] = quat[3]; | |
| } | |
| return dest; | |
| } | |
| void quat_free(quat_t *quat) | |
| { | |
| free(quat); | |
| } | |
| quat_t quat_set(quat_t quat, quat_t dest) | |
| { | |
| dest[0] = quat[0]; | |
| dest[1] = quat[1]; | |
| dest[2] = quat[2]; | |
| dest[3] = quat[3]; | |
| return dest; | |
| } | |
| quat_t quat_calculate_w(quat_t quat, quat_t dest) | |
| { | |
| double x = quat[0]; | |
| double y = quat[1]; | |
| double z = quat[2]; | |
| if (!dest || quat == dest) { | |
| quat[3] = -sqrt(fabs(1.0 - x * x - y * y - z * z)); | |
| return quat; | |
| } | |
| dest[0] = x; | |
| dest[1] = y; | |
| dest[2] = z; | |
| dest[3] = -sqrt(fabs(1.0 - x * x - y * y - z * z)); | |
| return dest; | |
| } | |
| double quat_dot(quat_t quat, quat_t quat2) | |
| { | |
| return quat[0] * quat2[0] + quat[1] * quat2[1] + quat[2] * quat2[2] + quat[3] * quat2[3]; | |
| } | |
| quat_t quat_inverse(quat_t quat, quat_t dest) | |
| { | |
| double dot = quat_dot(quat, quat), invDot = 1.0 / dot; | |
| if (!dest || quat == dest) { | |
| quat[0] *= -invDot; | |
| quat[1] *= -invDot; | |
| quat[2] *= -invDot; | |
| quat[3] *= invDot; | |
| return quat; | |
| } | |
| dest[0] = -quat[0] * invDot; | |
| dest[1] = -quat[1] * invDot; | |
| dest[2] = -quat[2] * invDot; | |
| dest[3] = quat[3] * invDot; | |
| return dest; | |
| } | |
| quat_t quat_conjugate(quat_t quat, quat_t dest) | |
| { | |
| if (!dest || quat == dest) { | |
| quat[0] *= -1; | |
| quat[1] *= -1; | |
| quat[2] *= -1; | |
| return quat; | |
| } | |
| dest[0] = -quat[0]; | |
| dest[1] = -quat[1]; | |
| dest[2] = -quat[2]; | |
| dest[3] = quat[3]; | |
| return dest; | |
| } | |
| double quat_length(quat_t quat) | |
| { | |
| double x = quat[0]; | |
| double y = quat[1]; | |
| double z = quat[2]; | |
| double w = quat[3]; | |
| return sqrt(x * x + y * y + z * z + w * w); | |
| } | |
| quat_t quat_normalize(quat_t quat, quat_t dest) | |
| { | |
| if (!dest) { | |
| dest = quat; | |
| } | |
| double x = quat[0], y = quat[1], z = quat[2], w = quat[3], len = sqrt(x * x + y * y + z * z + w * w); | |
| if (len == 0) { | |
| dest[0] = 0; | |
| dest[1] = 0; | |
| dest[2] = 0; | |
| dest[3] = 0; | |
| return dest; | |
| } | |
| len = 1 / len; | |
| dest[0] = x * len; | |
| dest[1] = y * len; | |
| dest[2] = z * len; | |
| dest[3] = w * len; | |
| return dest; | |
| } | |
| quat_t quat_multiply(quat_t quat, quat_t quat2, quat_t dest) | |
| { | |
| if (!dest) { | |
| dest = quat; | |
| } | |
| double qax = quat[0]; | |
| double qay = quat[1]; | |
| double qaz = quat[2]; | |
| double qaw = quat[3]; | |
| double qbx = quat2[0]; | |
| double qby = quat2[1]; | |
| double qbz = quat2[2]; | |
| double qbw = quat2[3]; | |
| dest[0] = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; | |
| dest[1] = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; | |
| dest[2] = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; | |
| dest[3] = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; | |
| return dest; | |
| } | |
| quat_t quat_multiply_vec3(quat_t quat, vec3_t vec, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double x = vec[0]; | |
| double y = vec[1]; | |
| double z = vec[2]; | |
| double qx = quat[0]; | |
| double qy = quat[1]; | |
| double qz = quat[2]; | |
| double qw = quat[3]; | |
| // calculate quat * vec | |
| double ix = qw * x + qy * z - qz * y; | |
| double iy = qw * y + qz * x - qx * z; | |
| double iz = qw * z + qx * y - qy * x; | |
| double iw = -qx * x - qy * y - qz * z; | |
| // calculate result * inverse quat | |
| dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; | |
| dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; | |
| dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; | |
| return dest; | |
| } | |
| mat3_t quat_to_mat3(quat_t quat, mat3_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat3_create(NULL); | |
| } | |
| double x = quat[0]; | |
| double y = quat[1]; | |
| double z = quat[2]; | |
| double w = quat[3]; | |
| double x2 = x + x; | |
| double y2 = y + y; | |
| double z2 = z + z; | |
| double xx = x * x2; | |
| double xy = x * y2; | |
| double xz = x * z2; | |
| double yy = y * y2; | |
| double yz = y * z2; | |
| double zz = z * z2; | |
| double wx = w * x2; | |
| double wy = w * y2; | |
| double wz = w * z2; | |
| dest[0] = 1 - (yy + zz); | |
| dest[1] = xy + wz; | |
| dest[2] = xz - wy; | |
| dest[3] = xy - wz; | |
| dest[4] = 1 - (xx + zz); | |
| dest[5] = yz + wx; | |
| dest[6] = xz + wy; | |
| dest[7] = yz - wx; | |
| dest[8] = 1 - (xx + yy); | |
| return dest; | |
| } | |
| quat_t quat_to_mat4(quat_t quat, mat4_t dest) | |
| { | |
| if (!dest) { | |
| dest = mat4_create(NULL); | |
| } | |
| double x = quat[0]; | |
| double y = quat[1]; | |
| double z = quat[2]; | |
| double w = quat[3]; | |
| double x2 = x + x; | |
| double y2 = y + y; | |
| double z2 = z + z; | |
| double xx = x * x2; | |
| double xy = x * y2; | |
| double xz = x * z2; | |
| double yy = y * y2; | |
| double yz = y * z2; | |
| double zz = z * z2; | |
| double wx = w * x2; | |
| double wy = w * y2; | |
| double wz = w * z2; | |
| dest[0] = 1 - (yy + zz); | |
| dest[1] = xy + wz; | |
| dest[2] = xz - wy; | |
| dest[3] = 0; | |
| dest[4] = xy - wz; | |
| dest[5] = 1 - (xx + zz); | |
| dest[6] = yz + wx; | |
| dest[7] = 0; | |
| dest[8] = xz + wy; | |
| dest[9] = yz - wx; | |
| dest[10] = 1 - (xx + yy); | |
| dest[11] = 0; | |
| dest[12] = 0; | |
| dest[13] = 0; | |
| dest[14] = 0; | |
| dest[15] = 1; | |
| return dest; | |
| } | |
| quat_t quat_slerp(quat_t quat, quat_t quat2, double slerp, quat_t dest) | |
| { | |
| if (!dest) { | |
| dest = quat; | |
| } | |
| double cosHalfTheta = quat[0] * quat2[0] + quat[1] * quat2[1] + quat[2] * quat2[2] + quat[3] * quat2[3]; | |
| double halfTheta, sinHalfTheta, ratioA, ratioB; | |
| if (fabs(cosHalfTheta) >= 1.0) { | |
| if (dest != quat) { | |
| dest[0] = quat[0]; | |
| dest[1] = quat[1]; | |
| dest[2] = quat[2]; | |
| dest[3] = quat[3]; | |
| } | |
| return dest; | |
| } | |
| halfTheta = acos(cosHalfTheta); | |
| sinHalfTheta = sqrt(1.0 - cosHalfTheta * cosHalfTheta); | |
| if (fabs(sinHalfTheta) < 0.001) { | |
| dest[0] = (quat[0] * 0.5 + quat2[0] * 0.5); | |
| dest[1] = (quat[1] * 0.5 + quat2[1] * 0.5); | |
| dest[2] = (quat[2] * 0.5 + quat2[2] * 0.5); | |
| dest[3] = (quat[3] * 0.5 + quat2[3] * 0.5); | |
| return dest; | |
| } | |
| ratioA = sin((1 - slerp) * halfTheta) / sinHalfTheta; | |
| ratioB = sin(slerp * halfTheta) / sinHalfTheta; | |
| dest[0] = (quat[0] * ratioA + quat2[0] * ratioB); | |
| dest[1] = (quat[1] * ratioA + quat2[1] * ratioB); | |
| dest[2] = (quat[2] * ratioA + quat2[2] * ratioB); | |
| dest[3] = (quat[3] * ratioA + quat2[3] * ratioB); | |
| return dest; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _QUAT_H | |
| #define _QUAT_H | |
| typedef double *quat_t; | |
| #include "mat4.h" | |
| #include "mat3.h" | |
| #include "common.h" | |
| /* | |
| * quat - Quaternions | |
| */ | |
| /* | |
| * quat_create | |
| * Creates a new instance of a quat_t | |
| * | |
| * Params: | |
| * quat - Optional, quat_t containing values to initialize with | |
| * | |
| * Returns: | |
| * New quat_t | |
| */ | |
| quat_t quat_create(quat_t quat); | |
| void quat_free(quat_t *quat); | |
| /* | |
| * quat_set | |
| * Copies the values of one quat_t to another | |
| * | |
| * Params: | |
| * quat - quat_t containing values to copy | |
| * dest - quat_t receiving copied values | |
| * | |
| * Returns: | |
| * dest | |
| */ | |
| quat_t quat_set(quat_t quat, quat_t dest); | |
| /* | |
| * quat_calculate_w | |
| * Calculates the W component of a quat_t from the X, Y, and Z components. | |
| * Assumes that quaternion is 1 unit in length. | |
| * Any existing W component will be ignored. | |
| * | |
| * Params: | |
| * quat - quat_t to calculate W component of | |
| * dest - Optional, quat_t receiving calculated values. If NULL, result is written to quat | |
| * | |
| * Returns: | |
| * dest if not NULL, quat otherwise | |
| */ | |
| quat_t quat_calculate_w(quat_t quat, quat_t dest); | |
| /** | |
| * quat_dot | |
| * Calculates the dot product of two quaternions | |
| * | |
| * @param {quat4} quat First operand | |
| * @param {quat4} quat2 Second operand | |
| * | |
| * @return {number} Dot product of quat and quat2 | |
| */ | |
| double quat_dot(quat_t quat, quat_t quat2); | |
| /* | |
| * quat_inverse | |
| * Calculates the inverse of a quat_t | |
| * | |
| * Params: | |
| * quat - quat_t to calculate inverse of | |
| * dest - Optional, quat_t receiving inverse values. If NULL, result is written to quat | |
| * | |
| * Returns: | |
| * dest if not NULL, quat otherwise | |
| */ | |
| quat_t quat_inverse(quat_t quat, quat_t dest); | |
| /* | |
| * quat_conjugate | |
| * Calculates the conjugate of a quat_t | |
| * | |
| * Params: | |
| * quat - quat_t to calculate conjugate of | |
| * dest - Optional, quat_t receiving conjugate values. If NULL, result is written to quat | |
| * | |
| * Returns: | |
| * dest if not NULL, quat otherwise | |
| */ | |
| quat_t quat_conjugate(quat_t quat, quat_t dest); | |
| /* | |
| * quat_length | |
| * Calculates the length of a quat_t | |
| * | |
| * Params: | |
| * quat - quat_t to calculate length of | |
| * | |
| * Returns: | |
| * Length of quat | |
| */ | |
| double quat_length(quat_t quat); | |
| /* | |
| * quat_normalize | |
| * Generates a unit quaternion of the same direction as the provided quat_t | |
| * If quaternion length is 0, returns [0, 0, 0, 0] | |
| * | |
| * Params: | |
| * quat - quat_t to normalize | |
| * dest - Optional, quat_ receiving operation result. If NULL, result is written to quat | |
| * | |
| * Returns: | |
| * dest if not NULL, quat otherwise | |
| */ | |
| quat_t quat_normalize(quat_t quat, quat_t dest); | |
| /* | |
| * quat_multiply | |
| * Performs a quaternion multiplication | |
| * | |
| * Params: | |
| * quat - quat_t, first operand | |
| * quat2 - quat_t, second operand | |
| * dest - Optional, quat_t receiving operation result. If NULL, result is written to quat | |
| * | |
| * Returns: | |
| * dest if not NULL, quat otherwise | |
| */ | |
| quat_t quat_multiply(quat_t quat, quat_t quat2, quat_t dest); | |
| /* | |
| * quat_multiply_vec3 | |
| * Transforms a vec3_t with the given quaternion | |
| * | |
| * Params: | |
| * quat - quat_t to transform the vector with | |
| * vec - vec3_t to transform | |
| * dest - Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * Returns: | |
| * dest if not NULL, vec otherwise | |
| */ | |
| quat_t quat_multiply_vec3(quat_t quat, vec3_t vec, vec3_t dest); | |
| /* | |
| * quat_to_mat3 | |
| * Calculates a 3x3 matrix from the given quat_t | |
| * | |
| * Params: | |
| * quat - quat_t to create matrix from | |
| * dest - Optional, mat3_t receiving operation result | |
| * | |
| * Returns: | |
| * dest if not NULL, a new mat3_t otherwise | |
| */ | |
| mat3_t quat_to_mat3(quat_t quat, mat3_t dest); | |
| /* | |
| * quat_to_mat4 | |
| * Calculates a 4x4 matrix from the given quat_t | |
| * | |
| * Params: | |
| * quat - quat_t to create matrix from | |
| * dest - Optional, mat4_t receiving operation result | |
| * | |
| * Returns: | |
| * dest if not NULL, a new mat4_t otherwise | |
| */ | |
| quat_t quat_to_mat4(quat_t quat, mat4_t dest); | |
| /* | |
| * quat_slerp | |
| * Performs a spherical linear interpolation between two quat_t | |
| * | |
| * Params: | |
| * quat - quat_t, first quaternion | |
| * quat2 - quat_t, second quaternion | |
| * slerp - interpolation amount between the two inputs | |
| * dest - Optional, quat_t receiving operation result. If NULL, result is written to quat | |
| * | |
| * Returns: | |
| * dest if not NULL, quat otherwise | |
| */ | |
| quat_t quat_slerp(quat_t quat, quat_t quat2, double slerp, quat_t dest); | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <math.h> | |
| #include "common.h" | |
| #include "vec2.h" | |
| vec2_t vec2_create(vec2_t vec) | |
| { | |
| vec2_t dest = calloc(2, sizeof(double_t)); | |
| if (!dest) { | |
| return NULL; | |
| } | |
| if (vec) { | |
| dest[VX] = vec[VX]; | |
| dest[VY] = vec[VY]; | |
| } else { | |
| dest[VX] = 0; | |
| dest[VY] = 0; | |
| } | |
| return dest; | |
| } | |
| void vec2_free(vec2_t vec) | |
| { | |
| free(vec); | |
| } | |
| void vec2_set(vec2_t vec, vec2_t dest) | |
| { | |
| dest[VX] = vec[VX]; | |
| dest[VY] = vec[VY]; | |
| } | |
| void vec2_add(vec2_t vec, vec2_t vec2, vec2_t dest) | |
| { | |
| if (!dest || vec == dest) { | |
| vec[VX] += vec2[VX]; | |
| vec[VY] += vec2[VY]; | |
| return; | |
| } | |
| dest[VX] = vec[VX] + vec2[VX]; | |
| dest[VY] = vec[VY] + vec2[VY]; | |
| } | |
| void vec2_subtract(vec2_t vec, vec2_t vec2, vec2_t dest) | |
| { | |
| if (!dest || vec == dest) { | |
| vec[VX] -= vec2[VX]; | |
| vec[VY] -= vec2[VY]; | |
| return; | |
| } | |
| dest[VX] = vec[VX] - vec2[VX]; | |
| dest[VY] = vec[VY] - vec2[VY]; | |
| return; | |
| } | |
| void vec2_multiply(vec2_t vec, vec2_t vec2, vec2_t dest) | |
| { | |
| if (!dest || vec == dest) { | |
| vec[VX] *= vec2[VX]; | |
| vec[VY] *= vec2[VY]; | |
| return; | |
| } | |
| dest[VX] = vec[VX] * vec2[VX]; | |
| dest[VY] = vec[VY] * vec2[VY]; | |
| } | |
| void vec2_negate(vec2_t vec, vec2_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| dest[VX] = -vec[VX]; | |
| dest[VY] = -vec[VY]; | |
| } | |
| void vec2_scale(vec2_t vec, double scalar, vec2_t dest) | |
| { | |
| if (!dest || vec == dest) { | |
| vec[VX] *= scalar; | |
| vec[VY] *= scalar; | |
| return; | |
| } | |
| dest[VX] = vec[VX] * scalar; | |
| dest[VY] = vec[VY] * scalar; | |
| } | |
| void vec2_normalize(vec2_t vec, vec2_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| double len = sqrt(square(x) + square(y)); | |
| if (!len) { | |
| dest[VX] = 0; | |
| dest[VY] = 0; | |
| return; | |
| } else if (len == 1) { | |
| dest[VX] = x; | |
| dest[VY] = y; | |
| return; | |
| } | |
| len = 1 / len; | |
| dest[VX] = x * len; | |
| dest[VY] = y * len; | |
| } | |
| double vec2_cross(vec2_t vec, vec2_t vec2) | |
| { | |
| return vec[VX] * vec2[VY] - vec[VY] * vec2[VX]; | |
| } | |
| double vec2_length(vec2_t vec) | |
| { | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| return sqrt(square(x) + square(y)); | |
| } | |
| double vec2_dot(vec2_t vec, vec2_t vec2) | |
| { | |
| return vec[VX] * vec2[VX] + vec[VY] * vec2[VY]; | |
| } | |
| void vec2_direction(vec2_t vec, vec2_t vec2, vec2_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double x = vec[VX] - vec2[VX]; | |
| double y = vec[VY] - vec2[VY]; | |
| double len = sqrt(square(x) + square(y)); | |
| if (!len) { | |
| dest[VX] = 0; | |
| dest[VY] = 0; | |
| return; | |
| } | |
| len = 1 / len; | |
| dest[VX] = x * len; | |
| dest[VY] = y * len; | |
| } | |
| void vec2_lerp(vec2_t vec, vec2_t vec2, double lerp, vec2_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| dest[VX] = vec[VX] + lerp * (vec2[VX] - vec[VX]); | |
| dest[VY] = vec[VY] + lerp * (vec2[VY] - vec[VY]); | |
| } | |
| double vec2_dist(vec2_t vec, vec2_t vec2) | |
| { | |
| double x = vec2[VX] - vec[VX]; | |
| double y = vec2[VY] - vec[VY]; | |
| return sqrt(square(x) + square(y)); | |
| } | |
| void vec2_rotate(vec2_t vec, double rad, vec2_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| dest[VX] = (cos(rad) * vec[VX]) - (sin(rad) * vec[VY]); | |
| dest[VY] = (sin(rad) * vec[VX]) - (cos(rad) * vec[VY]); | |
| } | |
| double vec2_angle(vec2_t vec) | |
| { | |
| return atan2(vec[VY], vec[VX]); | |
| } | |
| void vec2_zero(vec2_t vec) | |
| { | |
| vec[VX] = 0; | |
| vec[VY] = 0; | |
| } | |
| void vec2_translate(vec2_t vec, double dx, double dy) | |
| { | |
| vec[VX] += dx; | |
| vec[VY] += dy; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _VEC3_H | |
| #define _VEC3_H | |
| /** | |
| * vec2_t - 2 Dimensional Vector | |
| */ | |
| typedef double *vec2_t; | |
| #include "common.h" | |
| /** | |
| * Creates a new instance of a vec2_t | |
| * | |
| * @param vec | |
| * Optional, vec2_t containing values to initialize with. If NULL, the | |
| * vector will be initialized with zeroes. | |
| * | |
| * @return New vec | |
| */ | |
| vec2_t vec2_create(vec2_t vec); | |
| /** | |
| * Frees a vec2_t instance | |
| * | |
| * @param vec | |
| * Vector to free | |
| */ | |
| void vec2_free(vec2_t vec); | |
| /** | |
| * Copies the values of one vec2_t to another | |
| * | |
| * @param vec | |
| * vec2_t containing values to copy | |
| * @param dest | |
| * vec2_t receiving copied values | |
| * | |
| * @return dest | |
| */ | |
| void vec2_set(vec2_t vec, vec2_t dest); | |
| /** | |
| * Performs a vector addition | |
| * | |
| * @param vec | |
| * first operand | |
| * @param vec2 | |
| * second operand | |
| * @param dest | |
| * Optional, vec2_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec2_add(vec2_t vec, vec2_t vec2, vec2_t dest); | |
| /** | |
| * Performs a vector subtraction | |
| * | |
| * @param vec | |
| * first operand | |
| * @param vec2 | |
| * second operand | |
| * @param dest | |
| * Optional, vec2_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec2_subtract(vec2_t vec, vec2_t vec2, vec2_t dest); | |
| /** | |
| * Performs a vector multiplication | |
| * | |
| * @param vec | |
| * first operand | |
| * @param vec2 | |
| * second operand | |
| * @param dest | |
| * Optional, vec2_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec2_multiply(vec2_t vec, vec2_t vec2, vec2_t dest); | |
| /** | |
| * Negates the components of a vec | |
| * | |
| * @param vec | |
| * vec2_t to negate | |
| * @param dest | |
| * Optional, vec2_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec2_negate(vec2_t vec, vec2_t dest); | |
| /** | |
| * Multiplies the components of a vec2_t by a scalar value | |
| * | |
| * @param vec | |
| * vec2_t to scale | |
| * @param val | |
| * Numeric value to scale by | |
| * @param dest | |
| * Optional, vec2_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec2_scale(vec2_t vec, double scalar, vec2_t dest); | |
| /** | |
| * Generates a unit vector of the same direction as the provided vec | |
| * If vector length is 0, returns [0, 0, 0] | |
| * | |
| * @param vec | |
| * vec2_t to normalize | |
| * @param dest | |
| * Optional, vec2_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec2_normalize(vec2_t vec, vec2_t dest); | |
| /** | |
| * Generates the cross product of two vecs | |
| * | |
| * @param vec | |
| * first operand | |
| * @param vec2 | |
| * second operand | |
| * | |
| * @return the cross product of both vectors | |
| */ | |
| double vec2_cross(vec2_t vec, vec2_t vec2); | |
| /** | |
| * Caclulates the length of a vec | |
| * | |
| * vec - vec2_t to calculate length of | |
| * | |
| * @return Length of vec | |
| */ | |
| double vec2_length(vec2_t vec); | |
| /** | |
| * Caclulates the dot product of two vecs | |
| * | |
| * @param vec | |
| * first operand | |
| * @param vec2 | |
| * second operand | |
| * | |
| * @return Dot product of vec and vec2 | |
| */ | |
| double vec2_dot(vec2_t vec, vec2_t vec2); | |
| /** | |
| * Generates a unit vector pointing from one vector to another | |
| * | |
| * @param vec | |
| * origin vec | |
| * @param vec2 | |
| * t to point to | |
| * @param dest | |
| * Optional, vec2_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec2_direction(vec2_t vec, vec2_t vec2, vec2_t dest); | |
| /** | |
| * Performs a linear interpolation between two vec | |
| * | |
| * @param vec | |
| * first vector | |
| * @param vec2 | |
| * second vector | |
| * @param lerp | |
| * interpolation amount between the two inputs | |
| * @param dest | |
| * Optional, vec2_t receiving operation result. If NULL, result is written | |
| * to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec2_lerp(vec2_t vec, vec2_t vec2, double lerp, vec2_t dest); | |
| /** | |
| * Calculates the euclidian distance between two vec | |
| * | |
| * @param vec | |
| * first vector | |
| * @param vec2 | |
| * second vector | |
| * | |
| * @return distance between vec and vec2 | |
| */ | |
| double vec2_dist(vec2_t vec, vec2_t vec2); | |
| void vec2_rotate(vec2_t vec, double rad, vec2_t dest); | |
| double vec2_angle(vec2_t vec); | |
| void vec2_zero(vec2_t vec); | |
| void vec2_translate(vec2_t vec, double dx, double dy); | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <math.h> | |
| #include "vec3.h" | |
| #include "common.h" | |
| vec3_t vec3_create(vec3_t vec) | |
| { | |
| vec3_t dest = calloc(3, sizeof(double_t)); | |
| if (vec) { | |
| dest[VX] = vec[VX]; | |
| dest[VY] = vec[VY]; | |
| dest[VZ] = vec[VZ]; | |
| } else { | |
| dest[VX] = 0; | |
| dest[VY] = 0; | |
| dest[VZ] = 0; | |
| } | |
| return dest; | |
| } | |
| void vec3_free(vec3_t vec) | |
| { | |
| free(vec); | |
| } | |
| void vec3_set(vec3_t vec, vec3_t dest) | |
| { | |
| dest[VX] = vec[VX]; | |
| dest[VY] = vec[VY]; | |
| dest[VZ] = vec[VZ]; | |
| } | |
| void vec3_add(vec3_t vec, vec3_t other, vec3_t dest) | |
| { | |
| if (!dest || vec == dest) { | |
| vec[VX] += other[VX]; | |
| vec[VY] += other[VY]; | |
| vec[VZ] += other[VZ]; | |
| return; | |
| } | |
| dest[VX] = vec[VX] + other[VX]; | |
| dest[VY] = vec[VY] + other[VY]; | |
| dest[VZ] = vec[VZ] + other[VZ]; | |
| } | |
| void vec3_subtract(vec3_t vec, vec3_t other, vec3_t dest) | |
| { | |
| if (!dest || vec == dest) { | |
| vec[VX] -= other[VX]; | |
| vec[VY] -= other[VY]; | |
| vec[VZ] -= other[VZ]; | |
| return; | |
| } | |
| dest[VX] = vec[VX] - other[VX]; | |
| dest[VY] = vec[VY] - other[VY]; | |
| dest[VZ] = vec[VZ] - other[VZ]; | |
| } | |
| void vec3_multiply(vec3_t vec, vec3_t other, vec3_t dest) | |
| { | |
| if (!dest || vec == dest) { | |
| vec[VX] *= other[VX]; | |
| vec[VY] *= other[VY]; | |
| vec[VZ] *= other[VZ]; | |
| return; | |
| } | |
| dest[VX] = vec[VX] * other[VX]; | |
| dest[VY] = vec[VY] * other[VY]; | |
| dest[VZ] = vec[VZ] * other[VZ]; | |
| } | |
| void vec3_negate(vec3_t vec, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| dest[VX] = -vec[VX]; | |
| dest[VY] = -vec[VY]; | |
| dest[VZ] = -vec[VZ]; | |
| } | |
| void vec3_scale(vec3_t vec, double val, vec3_t dest) | |
| { | |
| if (!dest || vec == dest) { | |
| vec[VX] *= val; | |
| vec[VY] *= val; | |
| vec[VZ] *= val; | |
| return; | |
| } | |
| dest[VX] = vec[VX] * val; | |
| dest[VY] = vec[VY] * val; | |
| dest[VZ] = vec[VZ] * val; | |
| return; | |
| } | |
| void vec3_normalize(vec3_t vec, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| double z = vec[VZ]; | |
| double len = sqrt(square(x) + square(y) + square(z)); | |
| if (!len) { | |
| dest[VX] = 0; | |
| dest[VY] = 0; | |
| dest[VZ] = 0; | |
| return; | |
| } else if (len == 1) { | |
| dest[VX] = x; | |
| dest[VY] = y; | |
| dest[VZ] = z; | |
| return; | |
| } | |
| len = 1 / len; | |
| dest[VX] = x * len; | |
| dest[VY] = y * len; | |
| dest[VZ] = z * len; | |
| } | |
| void vec3_cross(vec3_t vec, vec3_t other, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| double z = vec[VZ]; | |
| double x2 = other[VX]; | |
| double y2 = other[VY]; | |
| double z2 = other[VZ]; | |
| dest[VX] = y * z2 - z * y2; | |
| dest[VY] = z * x2 - x * z2; | |
| dest[VZ] = x * y2 - y * x2; | |
| } | |
| double vec3_length(vec3_t vec) | |
| { | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| double z = vec[VZ]; | |
| return sqrt(square(x) + square(y) + square(z)); | |
| } | |
| double vec3_dot(vec3_t vec, vec3_t other) | |
| { | |
| return vec[VX] * other[VX] + vec[VY] * other[VY] + vec[VZ] * other[VZ]; | |
| } | |
| void vec3_direction(vec3_t vec, vec3_t other, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double x = vec[VX] - other[VX]; | |
| double y = vec[VY] - other[VY]; | |
| double z = vec[VZ] - other[VZ]; | |
| double len = sqrt(square(x) + square(y) + square(z)); | |
| if (!len) { | |
| dest[VX] = 0; | |
| dest[VY] = 0; | |
| dest[VZ] = 0; | |
| return; | |
| } | |
| len = 1 / len; | |
| dest[VX] = x * len; | |
| dest[VY] = y * len; | |
| dest[VZ] = z * len; | |
| } | |
| void vec3_lerp(vec3_t vec, vec3_t vec2, double lerp, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| dest[VX] = vec[VX] + lerp * (vec2[VX] - vec[VX]); | |
| dest[VY] = vec[VY] + lerp * (vec2[VY] - vec[VY]); | |
| dest[VZ] = vec[VZ] + lerp * (vec2[VZ] - vec[VZ]); | |
| } | |
| double vec3_dist(vec3_t vec, vec3_t other) | |
| { | |
| double x = other[VX] - vec[VX]; | |
| double y = other[VY] - vec[VY]; | |
| double z = other[VZ] - vec[VZ]; | |
| return sqrt(square(x) + square(y) + square(z)); | |
| } | |
| int vec3_identical(vec3_t vec, vec3_t other) | |
| { | |
| return (vec[VX] == other[VX]) && (vec[VY] == other[VY]) && (vec[VZ] == other[VZ]); | |
| } | |
| /** | |
| * Left-multiplies the vector by the given mat3_t | |
| * | |
| * @param vec | |
| * The base vector | |
| * @param mat | |
| * The matrix to multiply by | |
| * @param dest | |
| * Optional, the destination vector | |
| */ | |
| void vec3_left_mul_mat3(vec3_t vec, mat3_t mat, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double a00 = mat[0]; | |
| double a01 = mat[3]; | |
| double a02 = mat[6]; | |
| double a10 = mat[1]; | |
| double a11 = mat[4]; | |
| double a12 = mat[7]; | |
| double a20 = mat[2]; | |
| double a21 = mat[5]; | |
| double a22 = mat[8]; | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| double z = vec[VZ]; | |
| dest[VX] = x * a00 + y * a01 + z * a02; | |
| dest[VY] = x * a10 + y * a11 + z * a12; | |
| dest[VZ] = x * a20 + y * a21 + z * a22; | |
| } | |
| /** | |
| * Multiplies the vector by the transpose of the given matrix. | |
| * | |
| * @param vec | |
| * The base vector | |
| * @param mat | |
| * The matrix to multiply by | |
| * @param dest | |
| * Optional, the destination vector | |
| */ | |
| void vec3_tra_mul_mat3(vec3_t vec, mat3_t mat, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double a00 = mat[0]; | |
| double a01 = mat[3]; | |
| double a02 = mat[6]; | |
| double a10 = mat[1]; | |
| double a11 = mat[4]; | |
| double a12 = mat[7]; | |
| double a20 = mat[2]; | |
| double a21 = mat[5]; | |
| double a22 = mat[8]; | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| double z = vec[VZ]; | |
| dest[VX] = x * a00 + y * a10 + z * a20; | |
| dest[VY] = x * a01 + y * a11 + z * a21; | |
| dest[VZ] = x * a02 + y * a12 + z * a22; | |
| } | |
| /** | |
| * Left-multiplies the vector by the given matrix, assuming the | |
| * fourth (w) component of the vector is 1. | |
| * | |
| * @param vec | |
| * The base vector | |
| * @param mat | |
| * The matrix to multiply by | |
| * @param dest | |
| * Optional, the destination vector. If not specified, the first | |
| * vec will be the destination. | |
| */ | |
| void vec3_left_mul_mat4(vec3_t vec, mat4_t mat, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double a00 = mat[0]; | |
| double a01 = mat[4]; | |
| double a02 = mat[8]; | |
| double a03 = mat[12]; | |
| double a10 = mat[1]; | |
| double a11 = mat[5]; | |
| double a12 = mat[9]; | |
| double a13 = mat[13]; | |
| double a20 = mat[2]; | |
| double a21 = mat[6]; | |
| double a22 = mat[10]; | |
| double a23 = mat[14]; | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| double z = vec[VZ]; | |
| dest[VX] = x * a00 + y * a01 + z * a02 + a03; | |
| dest[VY] = x * a10 + y * a11 + z * a12 + a13; | |
| dest[VZ] = x * a20 + y * a21 + z * a22 + a23; | |
| } | |
| /** | |
| * Multiplies the vector by the transpose of the given matrix, assuming the | |
| * fourth (w) component of the vector is 1. | |
| * | |
| * @param vec | |
| * The base vector | |
| * @param mat | |
| * The matrix to multiply by | |
| * @param dest | |
| * Optional, the destination vector. If not specified, the first | |
| * vec will be the destination. | |
| */ | |
| void vec3_tra_mul_mat4(vec3_t vec, mat4_t mat, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| double a00 = mat[0]; | |
| double a01 = mat[4]; | |
| double a02 = mat[8]; | |
| double a10 = mat[1]; | |
| double a11 = mat[5]; | |
| double a12 = mat[9]; | |
| double a20 = mat[2]; | |
| double a21 = mat[6]; | |
| double a22 = mat[10]; | |
| double a30 = mat[3]; | |
| double a31 = mat[7]; | |
| double a32 = mat[11]; | |
| double x = vec[VX]; | |
| double y = vec[VY]; | |
| double z = vec[VZ]; | |
| dest[VX] = x * a00 + y * a10 + z * a20 + a30; | |
| dest[VY] = x * a01 + y * a11 + z * a21 + a31; | |
| dest[VZ] = x * a02 + y * a12 + z * a22 + a32; | |
| } | |
| void vec3_zero(vec3_t vec) | |
| { | |
| vec[VX] = 0; | |
| vec[VY] = 0; | |
| vec[VZ] = 0; | |
| } | |
| vec3_t vec3_unproject(vec3_t vec, mat4_t view, mat4_t proj, vec4_t viewport, vec3_t dest) | |
| { | |
| if (!dest) { | |
| dest = vec; | |
| } | |
| mat4_t m = mat4_create(NULL); | |
| double *v = malloc(sizeof(double) * 4); | |
| v[VX] = (vec[VX] - viewport[0]) * 2.0 / viewport[2] - 1.0; | |
| v[VY] = (vec[VY] - viewport[1]) * 2.0 / viewport[3] - 1.0; | |
| v[VZ] = 2.0 * vec[VZ] - 1.0; | |
| v[VU] = 1.0; | |
| mat4_multiply(proj, view, m); | |
| if (!mat4_inverse(m, NULL)) { | |
| return NULL; | |
| } | |
| mat4_multiply_vec4(m, v, NULL); | |
| if (v[VU] == 0.0) { | |
| return NULL; | |
| } | |
| dest[VX] = v[VX] / v[VU]; | |
| dest[VY] = v[VY] / v[VU]; | |
| dest[VZ] = v[VZ] / v[VU]; | |
| return dest; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _VEC3_H | |
| #define _VEC3_H | |
| /** | |
| * vec3_t - 3 Dimensional Vector | |
| */ | |
| typedef double *vec3_t; | |
| #include "mat4.h" | |
| #include "mat3.h" | |
| #include "vec4.h" | |
| #include "common.h" | |
| /* | |
| * vec3_create | |
| * Creates a new instance of a vec3_t | |
| * | |
| * Params: | |
| * vec - Optional, vec3_t containing values to initialize with. If NULL, the | |
| * vector will be initialized with zeroes. | |
| * | |
| * Returns: | |
| * New vec3 | |
| */ | |
| vec3_t vec3_create(vec3_t vec); | |
| /** | |
| * Frees a vec3_t instance | |
| * | |
| * @param vec | |
| * Vector to free | |
| */ | |
| void vec3_free(vec3_t vec); | |
| /** | |
| * Copies the values of one vec3_t to another | |
| * | |
| * @param vec | |
| * containing values to copy | |
| * @param dest | |
| * receiving copied values | |
| * | |
| * @return dest | |
| */ | |
| void vec3_set(vec3_t vec, vec3_t dest); | |
| /** | |
| * Performs a vector addition | |
| * | |
| * @param vec | |
| * first operand | |
| * @param vec2 | |
| * second operand | |
| * @param dest | |
| * Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_add(vec3_t vec, vec3_t other, vec3_t dest); | |
| /** | |
| * Performs a vector subtraction | |
| * | |
| * @param vec | |
| * vec3, first operand | |
| * @param vec2 | |
| * vec3, second operand | |
| * @param dest | |
| * Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_subtract(vec3_t vec, vec3_t other, vec3_t dest); | |
| /** | |
| * Performs a vector multiplication | |
| * | |
| * @param vec | |
| * first operand | |
| * @param vec2 | |
| * second operand | |
| * @param dest | |
| * Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_multiply(vec3_t vec, vec3_t other, vec3_t dest); | |
| /** | |
| * Negates the components of a vec3 | |
| * | |
| * @param vec | |
| * vec3_t to negate | |
| * @param dest | |
| * Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_negate(vec3_t vec, vec3_t dest); | |
| /** | |
| * Multiplies the components of a vec3_t by a scalar value | |
| * | |
| * @param vec | |
| * vec3_t to scale | |
| * @param val | |
| * Numeric value to scale by | |
| * @param dest | |
| * Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_scale(vec3_t vec, double val, vec3_t dest); | |
| /** | |
| * Generates a unit vector of the same direction as the provided vec3 | |
| * If vector length is 0, returns [0, 0, 0] | |
| * | |
| * @param vec | |
| * vec3_t to normalize | |
| * @param dest | |
| * Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_normalize(vec3_t vec, vec3_t dest); | |
| /** | |
| * Generates the cross product of two vec3s | |
| * | |
| * @param vec | |
| * vec3, first operand | |
| * @param vec2 | |
| * vec3, second operand | |
| * @param dest | |
| * Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_cross(vec3_t vec, vec3_t other, vec3_t dest); | |
| /** | |
| * Calculates the length of a vec3 | |
| * | |
| * @param vec | |
| * to calculate length of | |
| * | |
| * @return Length of vec | |
| */ | |
| double vec3_length(vec3_t vec); | |
| /** | |
| * Calculates the dot product of two vec3s | |
| * | |
| * @param vec - vec3, first operand | |
| * @param vec2 - vec3, second operand | |
| * | |
| * @return Dot product of vec and vec2 | |
| */ | |
| double vec3_dot(vec3_t vec, vec3_t other); | |
| /** | |
| * Generates a unit vector pointing from one vector to another | |
| * | |
| * @param vec | |
| * origin vec3 | |
| * @param vec2 | |
| * vec3_t to point to | |
| * @param dest | |
| * Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_direction(vec3_t vec, vec3_t other, vec3_t dest); | |
| /** | |
| * Performs a linear interpolation between two vec3 | |
| * | |
| * @param vec - vec3, first vector | |
| * @param vec2 - vec3, second vector | |
| * @param lerp - interpolation amount between the two inputs | |
| * @param dest - Optional, vec3_t receiving operation result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| void vec3_lerp(vec3_t vec, vec3_t vec2, double lerp, vec3_t dest); | |
| /** | |
| * Calculates the euclidian distance between two vec3 | |
| * | |
| * Params: | |
| * vec - vec3, first vector | |
| * vec2 - vec3, second vector | |
| * | |
| * distance between vec and vec2 | |
| */ | |
| double vec3_dist(vec3_t vec, vec3_t other); | |
| /** | |
| * Projects the specified vec3_t from screen space into object space. | |
| * | |
| * Based on Mesa gluUnProject implementation | |
| * | |
| * @see http://webcvs.freedesktop.org/mesa/Mesa/src/glu/mesa/project.c?revision=1.4&view=markup | |
| * | |
| * @param vec | |
| * screen-space vector to project | |
| * @param view | |
| * View matrix | |
| * @param proj | |
| * Projection matrix | |
| * @param viewport | |
| * Viewport as given to gl.viewport [x, y, width, height] | |
| * @param dest | |
| * Optional, vec3_t receiving unprojected result. If NULL, result is written to vec | |
| * | |
| * @return dest if not NULL, vec otherwise | |
| */ | |
| vec3_t vec3_unproject(vec3_t vec, mat4_t view, mat4_t proj, vec4_t viewport, vec3_t dest); | |
| /** | |
| * Left-multiplies the vector by the given mat3_t | |
| * | |
| * @param vec | |
| * The base vector | |
| * @param mat | |
| * The matrix to multiply by | |
| * @param dest | |
| * Optional, the destination vector | |
| */ | |
| void vec3_left_mul_mat3(vec3_t vec, mat3_t mat, vec3_t dest); | |
| /** | |
| * Multiplies the vector by the transpose of the given matrix. | |
| * | |
| * @param vec | |
| * The base vector | |
| * @param mat | |
| * The matrix to multiply by | |
| * @param dest | |
| * Optional, the destination vector | |
| */ | |
| void vec3_tra_mul_mat3(vec3_t vec, mat3_t mat, vec3_t dest); | |
| /** | |
| * Left-multiplies the vector by the given matrix, assuming the | |
| * fourth (w) component of the vector is 1. | |
| * | |
| * @param vec | |
| * The base vector | |
| * @param mat | |
| * The matrix to multiply by | |
| * @param dest | |
| * Optional, the destination vector. If not specified, the first | |
| * vec will be the destination. | |
| */ | |
| void vec3_left_mul_mat4(vec3_t vec, mat4_t mat, vec3_t dest); | |
| /** | |
| * Multiplies the vector by the transpose of the given matrix, assuming the | |
| * fourth (w) component of the vector is 1. | |
| * | |
| * @param vec | |
| * The base vector | |
| * @param mat | |
| * The matrix to multiply by | |
| * @param dest | |
| * Optional, the destination vector. If not specified, the first | |
| * vec will be the destination. | |
| */ | |
| void vec3_tra_mul_mat4(vec3_t vec, mat4_t mat, vec3_t dest); | |
| void vec3_zero(vec3_t vec); | |
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdlib.h> | |
| #include <math.h> | |
| #include "vec4.h" | |
| vec4_t vec4_create(vec4_t vec) | |
| { | |
| vec4_t dest = calloc(4, sizeof(double_t)); | |
| if (vec) { | |
| dest[0] = vec[0]; | |
| dest[1] = vec[1]; | |
| dest[2] = vec[2]; | |
| dest[3] = vec[3]; | |
| } else { | |
| dest[0] = 0; | |
| dest[1] = 0; | |
| dest[2] = 0; | |
| dest[3] = 0; | |
| } | |
| return dest; | |
| } | |
| void vec4_free(vec4_t vec) | |
| { | |
| free(vec); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _VEC4_H | |
| #define _VEC4_H | |
| typedef double *vec4_t; | |
| vec4_t vec4_create(vec4_t vec); | |
| void vec4_free(vec4_t vec); | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment