#include "matrix4x4.h"
#include "../util/util.h"
#include <SDL2/SDL.h>
void mat4_identity(mat4_t *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;
}
mat4_t mat4_mul(const mat4_t* a, const mat4_t* b)
{
int i, j, k;
GLfloat sum = 0.0f;
mat4_t 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_t mat4_translate(const vec3_t *a)
{
mat4_t 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_t mat4_scale(GLfloat x, GLfloat y, GLfloat z)
{
mat4_t 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_t mat4_rotate(GLfloat degrees, const vec3_t* a)
{
mat4_t 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_t mat4_rotate_x(GLfloat degrees)
{
mat4_t 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_t mat4_rotate_y(GLfloat degrees)
{
mat4_t 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_t mat4_rotate_z(GLfloat degrees)
{
mat4_t 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_t mat4_perspective(GLfloat fov, GLfloat aspect, GLfloat zNear, GLfloat zFar)
{
mat4_t 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_t
mat4_orthographic(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top)
{
mat4_t 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] = -1.0f;
a.data[0 + 3 * 4] = (left + right) / (left - right);
a.data[1 + 3 * 4] = (bottom + top) / (bottom - top);
return a;
}
mat4_t mat4_lookAt(vec3_t* eye, vec3_t* center, vec3_t* up)
{
vec3_t temp = vec3_sub(center, eye);
vec3_t f = vec3_normalize(&temp);
vec3_t u = vec3_normalize(up);
temp = vec3_cross_mul(&f, &u);
vec3_t s = vec3_normalize(&temp);
u = vec3_cross_mul(&s, &f);
mat4_t 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_t mat4_mul_vec3(const mat4_t* a, const vec3_t* b)
{
vec3_t 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;
}