diff options
Diffstat (limited to 'src/maths.c')
-rw-r--r-- | src/maths.c | 142 |
1 files changed, 129 insertions, 13 deletions
diff --git a/src/maths.c b/src/maths.c index c1fab2a..3a7ecf1 100644 --- a/src/maths.c +++ b/src/maths.c @@ -1,27 +1,116 @@ #include <celeritas.h> vec3 vec3_create(f32 x, f32 y, f32 z) { return (vec3){ x, y, z }; } - vec3 vec3_add(vec3 u, vec3 v) { return (vec3){ .x = u.x + v.x, .y = u.y + v.y, .z = u.z + v.z }; } +vec3 vec3_sub(vec3 a, vec3 b) { return (vec3){ a.x - b.x, a.y - b.y, a.z - b.z }; } +vec3 vec3_mult(vec3 a, f32 s) { return (vec3){ a.x * s, a.y * s, a.z * s }; } +vec3 vec3_div(vec3 a, f32 s) { return (vec3){ a.x / s, a.y / s, a.z / s }; } + +f32 vec3_len_squared(vec3 a) { return (a.x * a.x) + (a.y * a.y) + (a.z * a.z); } +f32 vec3_len(vec3 a) { return sqrtf(vec3_len_squared(a)); } +vec3 vec3_negate(vec3 a) { return (vec3){ -a.x, -a.y, -a.z }; } + +vec3 vec3_normalise(vec3 a) { + f32 length = vec3_len(a); + return vec3_div(a, length); +} + +f32 vec3_dot(vec3 a, vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } + +vec3 vec3_cross(vec3 a, vec3 b) { + return (vec3){ .x = a.y * b.z - a.z * b.y, .y = a.z * b.x - a.x * b.z, .z = a.x * b.y - a.y * b.x }; +} vec4 vec4_create(f32 x, f32 y, f32 z, f32 w) { return (vec4){ x, y, z, w }; } +f32 quat_dot(quat a, quat b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } + +quat quat_normalise(quat a) { + f32 length = sqrtf(quat_dot(a, a)); // same as len squared + + return (quat){ a.x / length, a.y / length, a.z / length, a.w / length }; +} + +quat quat_from_axis_angle(vec3 axis, f32 angle, bool normalize) { + const f32 half_angle = 0.5f * angle; + f32 s = sinf(half_angle); + f32 c = cosf(half_angle); + + quat q = (quat){ s * axis.x, s * axis.y, s * axis.z, c }; + if (normalize) { + return quat_normalise(q); + } + return q; +} + mat4 mat4_ident() { return (mat4){ .data = { 1.0, 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.0 } }; } -mat4 mat4_mult(mat4 lhs, mat4 rhs) { +mat4 mat4_translation(vec3 position) { + mat4 out_matrix = mat4_ident(); + out_matrix.data[12] = position.x; + out_matrix.data[13] = position.y; + out_matrix.data[14] = position.z; + return out_matrix; +} + +mat4 mat4_scale(vec3 scale) { mat4 out_matrix = mat4_ident(); + out_matrix.data[0] = scale.x; + out_matrix.data[5] = scale.y; + out_matrix.data[10] = scale.z; + return out_matrix; +} + +// TODO: double check this +mat4 mat4_rotation(quat rotation) { + mat4 out_matrix = mat4_ident(); + quat n = quat_normalise(rotation); + + out_matrix.data[0] = 1.0f - 2.0f * n.y * n.y - 2.0f * n.z * n.z; + out_matrix.data[1] = 2.0f * n.x * n.y - 2.0f * n.z * n.w; + out_matrix.data[2] = 2.0f * n.x * n.z + 2.0f * n.y * n.w; + + out_matrix.data[4] = 2.0f * n.x * n.y + 2.0f * n.z * n.w; + out_matrix.data[5] = 1.0f - 2.0f * n.x * n.x - 2.0f * n.z * n.z; + out_matrix.data[6] = 2.0f * n.y * n.z - 2.0f * n.x * n.w; + + out_matrix.data[8] = 2.0f * n.x * n.z - 2.0f * n.y * n.w; + out_matrix.data[9] = 2.0f * n.y * n.z + 2.0f * n.x * n.w; + out_matrix.data[10] = 1.0f - 2.0f * n.x * n.x - 2.0f * n.y * n.y; + + return out_matrix; +} - const f32* m1_ptr = lhs.data; - const f32* m2_ptr = rhs.data; - f32* dst_ptr = out_matrix.data; +// mat4 mat4_mult(mat4 lhs, mat4 rhs) { +// mat4 out_matrix = mat4_ident(); - for (i32 i = 0; i < 4; ++i) { - for (i32 j = 0; j < 4; ++j) { - *dst_ptr = m1_ptr[0] * m2_ptr[0 + j] + m1_ptr[1] * m2_ptr[4 + j] + m1_ptr[2] * m2_ptr[8 + j] + - m1_ptr[3] * m2_ptr[12 + j]; - dst_ptr++; +// const f32* m1_ptr = lhs.data; +// const f32* m2_ptr = rhs.data; +// f32* dst_ptr = out_matrix.data; + +// for (i32 i = 0; i < 4; ++i) { +// for (i32 j = 0; j < 4; ++j) { +// *dst_ptr = m1_ptr[0] * m2_ptr[0 + j] + m1_ptr[1] * m2_ptr[4 + j] + m1_ptr[2] * m2_ptr[8 + j] + +// m1_ptr[3] * m2_ptr[12 + j]; +// dst_ptr++; +// } +// m1_ptr += 4; +// } + +// return out_matrix; +// } +mat4 mat4_mult(mat4 lhs, mat4 rhs) { + mat4 out_matrix = mat4_ident(); + + for (i32 row = 0; row < 4; row++) { + for (i32 col = 0; col < 4; col++) { + f32 sum = 0; + for (i32 i = 0; i < 4; i++) { + // column-major: first matrix columns × second matrix rows + sum += lhs.data[row + i * 4] * rhs.data[i + col * 4]; + } + out_matrix.data[row + col * 4] = sum; } - m1_ptr += 4; } return out_matrix; @@ -39,5 +128,32 @@ mat4 mat4_perspective(f32 fov_radians, f32 aspect_ratio, f32 near_z, f32 far_z) } mat4 mat4_look_at(vec3 position, vec3 target, vec3 up) { - // TODO -}
\ No newline at end of file + mat4 out_matrix; + vec3 z_axis; + z_axis.x = target.x - position.x; + z_axis.y = target.y - position.y; + z_axis.z = target.z - position.z; + + z_axis = vec3_normalise(z_axis); + vec3 x_axis = vec3_normalise(vec3_cross(z_axis, up)); + vec3 y_axis = vec3_cross(x_axis, z_axis); + + out_matrix.data[0] = x_axis.x; + out_matrix.data[1] = y_axis.x; + out_matrix.data[2] = -z_axis.x; + out_matrix.data[3] = 0; + out_matrix.data[4] = x_axis.y; + out_matrix.data[5] = y_axis.y; + out_matrix.data[6] = -z_axis.y; + out_matrix.data[7] = 0; + out_matrix.data[8] = x_axis.z; + out_matrix.data[9] = y_axis.z; + out_matrix.data[10] = -z_axis.z; + out_matrix.data[11] = 0; + out_matrix.data[12] = -vec3_dot(x_axis, position); + out_matrix.data[13] = -vec3_dot(y_axis, position); + out_matrix.data[14] = vec3_dot(z_axis, position); + out_matrix.data[15] = 1.0f; + + return out_matrix; +} |