diff options
| author | Thomas Guillermo Albers Raviola <thomas@thomaslabs.org> | 2026-01-16 23:02:32 +0100 |
|---|---|---|
| committer | Thomas Guillermo Albers Raviola <thomas@thomaslabs.org> | 2026-01-16 23:02:32 +0100 |
| commit | 6b8af9cf83851c075c6c9514b1deaa931c2b19a4 (patch) | |
| tree | 428986b49c32e21d3f7a3c2dfa41858ae0153209 /09-september/tomcat/math/matrix4x4.c | |
Initial commit
Diffstat (limited to '09-september/tomcat/math/matrix4x4.c')
| -rw-r--r-- | 09-september/tomcat/math/matrix4x4.c | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/09-september/tomcat/math/matrix4x4.c b/09-september/tomcat/math/matrix4x4.c new file mode 100644 index 0000000..d4bea71 --- /dev/null +++ b/09-september/tomcat/math/matrix4x4.c @@ -0,0 +1,326 @@ +#include "matrix4x4.h" +#include "../util/util.h" +#include <SDL2/SDL.h> + +void mat4_identity(Mat4 *a) +{ + int i; + for(i = 0; i < 4*4; i++) + { + a->data[i] = 0.0f; + } + a->data[0 + 0 * 4] = 1.0f; + a->data[1 + 1 * 4] = 1.0f; + a->data[2 + 2 * 4] = 1.0f; + a->data[3 + 3 * 4] = 1.0f; +} + +/** TODO: Preprocess these operation (1 + 1 * 4) -> 5 **/ +Mat4 mat4_inverse(const Mat4 *a) +{ + Mat4 inv; + int i; + + /** Remember that inverted matrix is (1/det) * cofactor(transposed) **/ + inv.data[0 + 0 * 4] = (a->data[1 + 1 * 4] * a->data[2 + 2 * 4] * a->data[3 + 3 * 4] + + a->data[2 + 1 * 4] * a->data[3 + 2 * 4] * a->data[1 + 3 * 4] + + a->data[3 + 1 * 4] * a->data[1 + 2 * 4] * a->data[2 + 3 * 4] - + a->data[1 + 3 * 4] * a->data[2 + 2 * 4] * a->data[3 + 1 * 4] - + a->data[2 + 3 * 4] * a->data[3 + 2 * 4] * a->data[1 + 1 * 4] - + a->data[3 + 3 * 4] * a->data[1 + 2 * 4] * a->data[2 + 1 * 4]); + + inv.data[0 + 1 * 4] = -(a->data[0 + 1 * 4] * a->data[2 + 2 * 4] * a->data[3 + 3 * 4] + + a->data[2 + 1 * 4] * a->data[3 + 2 * 4] * a->data[0 + 3 * 4] + + a->data[3 + 1 * 4] * a->data[0 + 2 * 4] * a->data[2 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[2 + 2 * 4] * a->data[3 + 1 * 4] - + a->data[2 + 3 * 4] * a->data[3 + 2 * 4] * a->data[0 + 1 * 4] - + a->data[3 + 3 * 4] * a->data[0 + 2 * 4] * a->data[2 + 1 * 4]); + + inv.data[0 + 2 * 4] = (a->data[0 + 1 * 4] * a->data[1 + 2 * 4] * a->data[3 + 3 * 4] + + a->data[1 + 1 * 4] * a->data[3 + 2 * 4] * a->data[0 + 3 * 4] + + a->data[3 + 1 * 4] * a->data[0 + 2 * 4] * a->data[1 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[1 + 2 * 4] * a->data[3 + 1 * 4] - + a->data[1 + 3 * 4] * a->data[3 + 2 * 4] * a->data[0 + 1 * 4] - + a->data[3 + 3 * 4] * a->data[0 + 2 * 4] * a->data[1 + 1 * 4]); + + inv.data[0 + 3 * 4] = -(a->data[0 + 1 * 4] * a->data[1 + 2 * 4] * a->data[2 + 3 * 4] + + a->data[1 + 1 * 4] * a->data[2 + 2 * 4] * a->data[0 + 3 * 4] + + a->data[2 + 1 * 4] * a->data[0 + 2 * 4] * a->data[1 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[1 + 2 * 4] * a->data[2 + 1 * 4] - + a->data[1 + 3 * 4] * a->data[2 + 2 * 4] * a->data[0 + 1 * 4] - + a->data[2 + 3 * 4] * a->data[0 + 2 * 4] * a->data[1 + 1 * 4]); + + inv.data[1 + 0 * 4] = -(a->data[1 + 0 * 4] * a->data[2 + 2 * 4] * a->data[3 + 3 * 4] + + a->data[2 + 0 * 4] * a->data[3 + 2 * 4] * a->data[1 + 3 * 4] + + a->data[3 + 0 * 4] * a->data[1 + 2 * 4] * a->data[2 + 3 * 4] - + a->data[1 + 3 * 4] * a->data[2 + 2 * 4] * a->data[3 + 0 * 4] - + a->data[2 + 3 * 4] * a->data[3 + 2 * 4] * a->data[1 + 0 * 4] - + a->data[3 + 3 * 4] * a->data[1 + 2 * 4] * a->data[2 + 0 * 4]); + + inv.data[1 + 1 * 4] = (a->data[0 + 0 * 4] * a->data[2 + 2 * 4] * a->data[3 + 3 * 4] + + a->data[2 + 0 * 4] * a->data[3 + 2 * 4] * a->data[0 + 3 * 4] + + a->data[3 + 0 * 4] * a->data[0 + 2 * 4] * a->data[2 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[2 + 2 * 4] * a->data[3 + 0 * 4] - + a->data[2 + 3 * 4] * a->data[3 + 2 * 4] * a->data[0 + 0 * 4] - + a->data[3 + 3 * 4] * a->data[0 + 2 * 4] * a->data[2 + 0 * 4]); + + inv.data[1 + 2 * 4] = -(a->data[0 + 0 * 4] * a->data[1 + 2 * 4] * a->data[3 + 3 * 4] + + a->data[1 + 0 * 4] * a->data[3 + 2 * 4] * a->data[0 + 3 * 4] + + a->data[3 + 0 * 4] * a->data[0 + 2 * 4] * a->data[1 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[1 + 2 * 4] * a->data[3 + 0 * 4] - + a->data[1 + 3 * 4] * a->data[3 + 2 * 4] * a->data[0 + 0 * 4] - + a->data[3 + 3 + 4] * a->data[0 + 2 * 4] * a->data[1 + 0 * 4]); + + inv.data[1 + 3 * 4] = (a->data[0 + 0 * 4] * a->data[1 + 2 * 4] * a->data[2 + 3 * 4] + + a->data[1 + 0 * 4] * a->data[2 + 2 * 4] * a->data[0 + 3 * 4] + + a->data[2 + 0 * 4] * a->data[0 + 2 * 4] * a->data[1 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[1 + 2 * 4] * a->data[2 + 0 * 4] - + a->data[1 + 3 * 4] * a->data[2 + 2 * 4] * a->data[0 + 0 * 4] - + a->data[2 + 3 * 4] * a->data[0 + 2 * 4] * a->data[1 + 0 * 4]); + + inv.data[2 + 0 * 4] = (a->data[1 + 0 * 4] * a->data[2 + 1 * 4] * a->data[3 + 3 * 4] + + a->data[2 + 0 * 4] * a->data[3 + 1 * 4] * a->data[1 + 3 * 4] + + a->data[3 + 0 * 4] * a->data[1 + 1 * 4] * a->data[2 + 3 * 4] - + a->data[1 + 3 * 4] * a->data[2 + 1 * 4] * a->data[3 + 0 * 4] - + a->data[2 + 3 * 4] * a->data[3 + 1 * 4] * a->data[1 + 0 * 4] - + a->data[3 + 3 * 4] * a->data[1 + 1 * 4] * a->data[2 + 0 * 4]); + + inv.data[2 + 1 * 4] = -(a->data[0 + 0 * 4] * a->data[2 + 1 * 4] * a->data[3 + 3 * 4] + + a->data[2 + 0 * 4] * a->data[3 + 1 * 4] * a->data[0 + 3 * 4] + + a->data[3 + 0 * 4] * a->data[0 + 1 * 4] * a->data[2 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[2 + 1 * 4] * a->data[3 + 0 * 4] - + a->data[2 + 3 * 4] * a->data[3 + 1 * 4] * a->data[0 + 0 * 4] - + a->data[3 + 3 * 4] * a->data[0 + 1 * 4] * a->data[2 + 0 * 4]); + + inv.data[2 + 2 * 4] = (a->data[0 + 0 * 4] * a->data[1 + 1 * 4] * a->data[3 + 3 * 4] + + a->data[1 + 0 * 4] * a->data[3 + 1 * 4] * a->data[0 + 3 * 4] + + a->data[3 + 0 * 4] * a->data[0 + 1 * 4] * a->data[1 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[1 + 1 * 4] * a->data[3 + 0 * 4] - + a->data[1 + 3 * 4] * a->data[3 + 1 * 4] * a->data[0 + 0 * 4] - + a->data[3 + 3 * 4] * a->data[0 + 1 * 4] * a->data[1 + 0 * 4]); + + inv.data[2 + 3 * 4] = -(a->data[0 + 0 * 4] * a->data[1 + 1 * 4] * a->data[2 + 3 * 4] + + a->data[1 + 0 * 4] * a->data[2 + 1 * 4] * a->data[0 + 3 * 4] + + a->data[2 + 0 * 4] * a->data[0 + 1 * 4] * a->data[1 + 3 * 4] - + a->data[0 + 3 * 4] * a->data[1 + 1 * 4] * a->data[2 + 0 * 4] - + a->data[1 + 3 * 4] * a->data[2 + 1 * 4] * a->data[0 + 0 * 4] - + a->data[2 + 3 * 4] * a->data[0 + 1 * 4] * a->data[1 + 0 * 4]); + + inv.data[3 + 0 * 4] = -(a->data[1 + 0 * 4] * a->data[2 + 1 * 4] * a->data[3 + 2 * 4] + + a->data[2 + 0 * 4] * a->data[3 + 1 * 4] * a->data[1 + 2 * 4] + + a->data[3 + 0 * 4] * a->data[1 + 1 * 4] * a->data[2 + 2 * 4] - + a->data[1 + 2 * 4] * a->data[2 + 1 * 4] * a->data[3 + 0 * 4] - + a->data[2 + 2 * 4] * a->data[3 + 1 * 4] * a->data[1 + 0 * 4] - + a->data[3 + 2 * 4] * a->data[1 + 1 * 4] * a->data[2 + 0 * 4]); + + inv.data[3 + 1 * 4] = (a->data[0 + 0 * 4] * a->data[2 + 1 * 4] * a->data[3 + 2 * 4] + + a->data[2 + 0 * 4] * a->data[3 + 1 * 4] * a->data[0 + 2 * 4] + + a->data[3 + 0 * 4] * a->data[0 + 1 * 4] * a->data[2 + 2 * 4] - + a->data[0 + 2 * 4] * a->data[2 + 1 * 4] * a->data[3 + 0 * 4] - + a->data[2 + 2 * 4] * a->data[3 + 1 * 4] * a->data[0 + 0 * 4] - + a->data[3 + 2 * 4] * a->data[0 + 1 * 4] * a->data[2 + 0 * 4]); + + inv.data[3 + 2 * 4] = -(a->data[0 + 0 * 4] * a->data[1 + 1 * 4] * a->data[3 + 2 * 4] + + a->data[1 + 0 * 4] * a->data[3 + 1 * 4] * a->data[0 + 2 * 4] + + a->data[3 + 0 * 4] * a->data[0 + 1 * 4] * a->data[1 + 2 * 4] - + a->data[0 + 2 * 4] * a->data[1 + 1 * 4] * a->data[3 + 0 * 4] - + a->data[1 + 2 * 4] * a->data[3 + 1 * 4] * a->data[0 + 0 * 4] - + a->data[3 + 2 * 4] * a->data[0 + 1 * 4] * a->data[1 + 0 * 4]); + + inv.data[3 + 3 * 4] = (a->data[0 + 0 * 4] * a->data[1 + 1 * 4] * a->data[2 + 2 * 4] + + a->data[1 + 0 * 4] * a->data[2 + 1 * 4] * a->data[0 + 2 * 4] + + a->data[2 + 0 * 4] * a->data[0 + 1 * 4] * a->data[1 + 2 * 4] - + a->data[0 + 2 * 4] * a->data[1 + 1 * 4] * a->data[2 + 0 * 4] - + a->data[1 + 2 * 4] * a->data[2 + 1 * 4] * a->data[0 + 0 * 4] - + a->data[2 + 2 * 4] * a->data[0 + 1 * 4] * a->data[1 + 0 * 4]); + + /** Remember that our matrix is already transposed and we also got the minors(inside each "inv" entry), + so we just use them. We use a->data[0 + 1 * 4] * inv.data[1 + 0 * 4] becouse inv.data is transposed **/ + float det = a->data[0 + 0 * 4] * inv.data[0 + 0 * 4] + a->data[0 + 1 * 4] * inv.data[1 + 0 * 4] + + a->data[0 + 2 * 4] * inv.data[2 + 0 * 4] + a->data[0 + 3 * 4] * inv.data[3 + 0 * 4]; + + if(det == 0.0f) + return *a; + + det = 1.0f / det; + + for(i = 0; i < 16; i++) + inv.data[i] *= det; + + return inv; +} + +Mat4 mat4_mul(const Mat4 *a, const Mat4 *b) +{ + int i, j, k; + GLfloat sum = 0.0f; + Mat4 c; + mat4_identity(&c); + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++){ + for(k = 0; k < 4; k++){ + sum += a->data[i + k * 4] * b->data[k + j * 4]; + } + c.data[i + j * 4] = sum; + sum = 0.0f; + } + + return c; +} + +Mat4 mat4_translate(const Vec3 *a) +{ + Mat4 b; + mat4_identity(&b); + b.data[0 + 3 * 4] = a->x; + b.data[1 + 3 * 4] = a->y; + b.data[2 + 3 * 4] = a->z; + return b; +} + +Mat4 mat4_scale(GLfloat x, GLfloat y, GLfloat z) +{ + Mat4 b; + mat4_identity(&b); + b.data[0 + 0 * 4] = x; + b.data[1 + 1 * 4] = y; + b.data[2 + 2 * 4] = z; + return b; +} + +Mat4 mat4_rotate(GLfloat degrees, const Vec3 *a) +{ + Mat4 b; + mat4_identity(&b); + GLfloat c = SDL_cosf(toRadians(degrees)), s = SDL_sinf(toRadians(degrees)), o = 1-c; + b.data[0 + 0 * 4] = a->x * a->x * o + c; + b.data[0 + 1 * 4] = a->x * a->y * o - a->z * s; + b.data[0 + 2 * 4] = a->x * a->z * o + a->y * s; + + b.data[1 + 0 * 4] = a->x * a->y * o + a->z * s; + b.data[1 + 1 * 4] = a->y * a->y * o + c; + b.data[1 + 2 * 4] = a->y * a->z * o - a->x * s; + + b.data[2 + 0 * 4] = a->x * a->z * o - a->y * s; + b.data[2 + 1 * 4] = a->y * a->z * o + a->x * s; + b.data[2 + 2 * 4] = a->z * a->z * o + c; + return b; +} + +Mat4 mat4_rotate_x(GLfloat degrees) +{ + Mat4 a; + mat4_identity(&a); + GLfloat c = SDL_cosf(toRadians(degrees)), s = SDL_sinf(toRadians(degrees)); + a.data[1 + 1 * 4] = c; + a.data[2 + 1 * 4] = s; + a.data[1 + 2 * 4] = -s; + a.data[2 + 2 * 4] = c; + return a; +} + +Mat4 mat4_rotate_y(GLfloat degrees) +{ + Mat4 a; + mat4_identity(&a); + GLfloat c = SDL_cosf(toRadians(degrees)), s = SDL_sinf(toRadians(degrees)); + a.data[0 + 0 * 4] = c; + a.data[2 + 0 * 4] = -s; + a.data[0 + 2 * 4] = s; + a.data[2 + 2 * 4] = c; + return a; +} + +Mat4 mat4_rotate_z(GLfloat degrees) +{ + Mat4 a; + mat4_identity(&a); + GLfloat c = SDL_cosf(toRadians(degrees)), s = SDL_sinf(toRadians(degrees)); + a.data[0 + 0 * 4] = c; + a.data[1 + 0 * 4] = s; + a.data[0 + 1 * 4] = -s; + a.data[1 + 1 * 4] = c; + return a; +} + +Mat4 mat4_perspective(GLfloat fov, GLfloat aspect, GLfloat zNear, GLfloat zFar) +{ + Mat4 a; + GLubyte i, j; + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++) + a.data[i + j * 4] = 0.0f; + fov = toRadians(fov); // To radians + + a.data[0 + 0 * 4] = ( (1.0f / SDL_tanf( fov/2.0f )) / aspect); + a.data[1 + 1 * 4] = (1.0f / SDL_tanf( fov/2.0f )); + a.data[2 + 2 * 4] = -( (zFar + zNear) / (zFar - zNear) ); + a.data[2 + 3 * 4] = -( ( 2.0f * zFar * zNear) / (zFar - zNear) ); + a.data[3 + 2 * 4] = -1.0f; + + return a; +} + +Mat4 +mat4_orthographic(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far) +{ + Mat4 a; + mat4_identity(&a); + a.data[0 + 0 * 4] = 2.0f / (right - left); + a.data[1 + 1 * 4] = 2.0f / (top - bottom); + a.data[2 + 2 * 4] = 2.0f / (near - far); + + a.data[0 + 3 * 4] = (left + right) / (left - right); + a.data[1 + 3 * 4] = (bottom + top) / (bottom - top); + a.data[2 + 3 * 4] = (far + near) / (far - near); + + return a; +} + +Mat4 mat4_lookAt(Vec3 *eye, Vec3 *center, Vec3 *up) +{ + Vec3 temp = vec3_sub(center, eye); + + Vec3 f = vec3_normalize(&temp); + Vec3 u = vec3_normalize(up); + temp = vec3_cross_mul(&f, &u); + Vec3 s = vec3_normalize(&temp); + u = vec3_cross_mul(&s, &f); + + Mat4 a; + mat4_identity(&a); + + a.data[0 + 0 * 4] = s.x;
+ a.data[0 + 1 * 4] = s.y;
+ a.data[0 + 2 * 4] = s.z;
+ a.data[1 + 0 * 4] = u.x;
+ a.data[1 + 1 * 4] = u.y;
+ a.data[1 + 2 * 4] = u.z;
+ a.data[2 + 0 * 4] =-f.x;
+ a.data[2 + 1 * 4] =-f.y;
+ a.data[2 + 2 * 4] =-f.z;
+ a.data[0 + 3 * 4] =-vec3_dot_mul(&s, eye);
+ a.data[1 + 3 * 4] =-vec3_dot_mul(&u, eye);
+ a.data[2 + 3 * 4] = vec3_dot_mul(&f, eye); +
+ return a; +} + +Vec3 mat4_mul_vec3(const Mat4 *a, const Vec3 *b) +{ + Vec3 c; + c.x = a->data[0 + 0 * 4] * b->x + a->data[0 + 1 * 4] * b->y + a->data[0 + 2 * 4] * b->z + a->data[0 + 3 * 4]; + c.y = a->data[1 + 0 * 4] * b->x + a->data[1 + 1 * 4] * b->y + a->data[1 + 2 * 4] * b->z + a->data[1 + 3 * 4]; + c.z = a->data[2 + 0 * 4] * b->x + a->data[2 + 1 * 4] * b->y + a->data[2 + 2 * 4] * b->z + a->data[2 + 3 * 4]; + return c; +} + +Vec4 mat4_mul_vec4(const Mat4 *a, const Vec4 *b) +{ + Vec4 c; + c.x = a->data[0 + 0 * 4] * b->x + a->data[0 + 1 * 4] * b->y + a->data[0 + 2 * 4] * b->z + a->data[0 + 3 * 4] * b->w; + c.y = a->data[1 + 0 * 4] * b->x + a->data[1 + 1 * 4] * b->y + a->data[1 + 2 * 4] * b->z + a->data[1 + 3 * 4] * b->w; + c.z = a->data[2 + 0 * 4] * b->x + a->data[2 + 1 * 4] * b->y + a->data[2 + 2 * 4] * b->z + a->data[2 + 3 * 4] * b->w; + c.w = a->data[3 + 0 * 4] * b->x + a->data[3 + 1 * 4] * b->y + a->data[3 + 2 * 4] * b->z + a->data[3 + 3 * 4] * b->w; + return c; +} |
