Techneck/code/source-c/utility/matrix.c

170 lines
5.0 KiB
C

#include <utility/math.h>
#include <math.h>
tc_mat4f_s tc_mat4f_zero()
{
tc_mat4f_s matrix;
matrix.values[0][0] = 0.0f;
matrix.values[0][1] = 0.0f;
matrix.values[0][2] = 0.0f;
matrix.values[0][3] = 0.0f;
matrix.values[1][0] = 0.0f;
matrix.values[1][1] = 0.0f;
matrix.values[1][2] = 0.0f;
matrix.values[1][3] = 0.0f;
matrix.values[2][0] = 0.0f;
matrix.values[2][1] = 0.0f;
matrix.values[2][2] = 0.0f;
matrix.values[2][3] = 0.0f;
matrix.values[3][0] = 0.0f;
matrix.values[3][1] = 0.0f;
matrix.values[3][2] = 0.0f;
matrix.values[3][3] = 0.0f;
return matrix;
}
tc_mat4f_s tc_mat4f_identity()
{
tc_mat4f_s matrix;
matrix.values[0][0] = 1.0f;
matrix.values[0][1] = 0.0f;
matrix.values[0][2] = 0.0f;
matrix.values[0][3] = 0.0f;
matrix.values[1][0] = 0.0f;
matrix.values[1][1] = 1.0f;
matrix.values[1][2] = 0.0f;
matrix.values[1][3] = 0.0f;
matrix.values[2][0] = 0.0f;
matrix.values[2][1] = 0.0f;
matrix.values[2][2] = 1.0f;
matrix.values[2][3] = 0.0f;
matrix.values[3][0] = 0.0f;
matrix.values[3][1] = 0.0f;
matrix.values[3][2] = 0.0f;
matrix.values[3][3] = 1.0f;
return matrix;
}
tc_mat3f_s tc_mat3f_identity()
{
tc_mat3f_s matrix;
matrix.values[0][0] = 1.0f;
matrix.values[0][1] = 0.0f;
matrix.values[0][2] = 0.0f;
matrix.values[1][0] = 0.0f;
matrix.values[1][1] = 1.0f;
matrix.values[1][2] = 0.0f;
matrix.values[2][0] = 0.0f;
matrix.values[2][1] = 0.0f;
matrix.values[2][2] = 1.0f;
return matrix;
}
tc_mat4f_s tc_mat4f_multiply(tc_mat4f_s first, tc_mat4f_s second)
{
tc_mat4f_s result;
u32_t k, r, c;
for(c = 0; c < 4; ++c)
{
for(r = 0; r < 4; ++r)
{
result.values[c][r] = 0.f;
for(k=0; k<4; ++k)
{
result.values[c][r] += first.values[k][r] * second.values[c][k];
}
}
}
return result;
}
tc_mat4f_s tc_mat4_rotate_x(tc_mat4f_s matrix, float radians)
{
tc_mat4f_s rotation = tc_mat4f_identity();
rotation.values[1][1] = cosf(radians);
rotation.values[1][2] = -sinf(radians);
rotation.values[2][1] = sinf(radians);
rotation.values[2][2] = cosf(radians);
return tc_mat4f_multiply(matrix, rotation);
}
tc_mat4f_s tc_mat4_rotate_y(tc_mat4f_s matrix, float radians)
{
tc_mat4f_s rotation = tc_mat4f_identity();
rotation.values[0][0] = cosf(radians);
rotation.values[0][2] = sinf(radians);
rotation.values[2][0] = -sinf(radians);
rotation.values[2][2] = cosf(radians);
return tc_mat4f_multiply(matrix, rotation);
}
tc_mat4f_s tc_mat4_rotate_z(tc_mat4f_s matrix, float radians)
{
tc_mat4f_s rotation = tc_mat4f_identity();
rotation.values[0][0] = cosf(radians);
rotation.values[0][1] = -sinf(radians);
rotation.values[1][0] = sinf(radians);
rotation.values[1][1] = cosf(radians);
return tc_mat4f_multiply(matrix, rotation);
}
tc_mat4f_s tc_mat4f_translate(tc_mat4f_s matrix, tc_vec3f_s translation)
{
matrix.values[0][3] += translation.x;
matrix.values[1][3] += translation.y;
matrix.values[2][3] += translation.z;
return matrix;
}
tc_mat3f_s tc_mat3f_translate(tc_mat3f_s matrix, tc_vec3f_s translation)
{
matrix.values[0][2] += translation.x;
matrix.values[1][2] += translation.y;
matrix.values[2][2] += translation.z;
return matrix;
}
tc_mat4f_s tc_mat4f_perspective(float fov, float aspect_ratio, float near, float far)
{
float range = tanf(fov / 2) * near;
float scale_x = (2 * near) / (range * aspect_ratio * 2);
float scale_y = near / range;
float scale_z = -(far + near) / (far - near);
float position_z = -(2 * far * near) / (far - near);
tc_mat4f_s matrix = tc_mat4f_zero();
matrix.values[0][0] = scale_x;
matrix.values[1][1] = scale_y;
matrix.values[2][2] = scale_z;
matrix.values[3][2] = -1.0f;
matrix.values[2][3] = position_z;
return matrix;
}