mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Matrix math cleanup (#2620)
* Cleanup inconsistent matrix math functions * Add more matrix unit tests
This commit is contained in:
@@ -13,6 +13,8 @@ alias matrix4_ortho @builtin = matrix::ortho {double};
|
||||
alias matrix4f_ortho @builtin = matrix::ortho {float};
|
||||
alias matrix4_perspective @builtin = matrix::perspective {double};
|
||||
alias matrix4f_perspective @builtin = matrix::perspective {float};
|
||||
alias matrix4_look_at @builtin = matrix::look_at {double};
|
||||
alias matrix4f_look_at @builtin = matrix::look_at {float};
|
||||
|
||||
alias MATRIX2_IDENTITY @builtin = matrix::IDENTITY2 {double};
|
||||
alias MATRIX2F_IDENTITY @builtin = matrix::IDENTITY2 {float};
|
||||
@@ -149,9 +151,9 @@ fn Matrix4x4 Matrix4x4.mul(Matrix4x4* self, Matrix4x4 b) @operator(*)
|
||||
};
|
||||
}
|
||||
|
||||
fn Matrix2x2 Matrix2x2.component_mul(&self, Real s) => matrix_component_mul(self, s);
|
||||
fn Matrix3x3 Matrix3x3.component_mul(&self, Real s) => matrix_component_mul(self, s);
|
||||
fn Matrix4x4 Matrix4x4.component_mul(&self, Real s) => matrix_component_mul(self, s);
|
||||
fn Matrix2x2 Matrix2x2.component_mul(&self, Real s) @operator(*) => matrix_component_mul(self, s);
|
||||
fn Matrix3x3 Matrix3x3.component_mul(&self, Real s) @operator(*) => matrix_component_mul(self, s);
|
||||
fn Matrix4x4 Matrix4x4.component_mul(&self, Real s) @operator(*) => matrix_component_mul(self, s);
|
||||
|
||||
fn Matrix2x2 Matrix2x2.add(&self, Matrix2x2 mat2) @operator(+) => matrix_add(self, mat2);
|
||||
fn Matrix3x3 Matrix3x3.add(&self, Matrix3x3 mat2) @operator(+) => matrix_add(self, mat2);
|
||||
@@ -384,9 +386,9 @@ fn Matrix4x4 Matrix4x4.rotate_z(&self, Real r)
|
||||
fn Matrix4x4 Matrix4x4.rotate_y(&self, Real r)
|
||||
{
|
||||
return self.mul({
|
||||
math::cos(r), 0, -math::sin(r), 0,
|
||||
math::cos(r), 0, math::sin(r), 0,
|
||||
0, 1, 0, 0,
|
||||
math::sin(r), 0, math::cos(r), 0,
|
||||
-math::sin(r), 0, math::cos(r), 0,
|
||||
0, 0, 0, 1,
|
||||
});
|
||||
}
|
||||
@@ -432,10 +434,10 @@ fn Matrix4x4 ortho(Real left, Real right, Real top, Real bottom, Real near, Real
|
||||
Real height = top - bottom;
|
||||
Real depth = far - near;
|
||||
return {
|
||||
2 / width, 0, 0, 0,
|
||||
0, 2 / height, 0, 0,
|
||||
0, 0, -2 / depth, 0,
|
||||
-(right + left) / width, -(top + bottom) / height, -(far + near) / depth, 1
|
||||
2 / width, 0, 0, -(right + left) / width,
|
||||
0, 2 / height, 0, -(top + bottom) / height,
|
||||
0, 0, -2 / depth, -(far + near) / depth,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,36 @@ fn void test_mat4_translate()
|
||||
assert(translated.m == mat.m);
|
||||
}
|
||||
|
||||
fn void test_mat4_translate_v()
|
||||
{
|
||||
Matrix4 mat = MATRIX4_IDENTITY.translate({1.0, 2.0, 3.0});
|
||||
assert(math::round_to_decimals(mat * (double[<4>]){ 10.0, 11.0, 12.0, 1.0}, 4) == {11.0, 13.0, 15.0, 1.0});
|
||||
}
|
||||
|
||||
fn void test_mat4_rotate()
|
||||
{
|
||||
Matrix4 rot_x = MATRIX4_IDENTITY.rotate_x(math::deg_to_rad(90));
|
||||
assert(math::round_to_decimals(rot_x * (double[<4>]){ 0.0, 1.0, 0.0, 1.0}, 4) == {0.0, 0.0, 1.0, 1.0});
|
||||
Matrix4f rot_xf = MATRIX4F_IDENTITY.rotate_x((float) math::deg_to_rad(90));
|
||||
assert(math::round_to_decimals(rot_xf * (float[<4>]){ 0.0, 1.0, 0.0, 1.0}, 4) == {0.0, 0.0, 1.0, 1.0});
|
||||
|
||||
Matrix4 rot_y = MATRIX4_IDENTITY.rotate_y(math::deg_to_rad(90));
|
||||
assert(math::round_to_decimals(rot_y * (double[<4>]){ 1.0, 0.0, 0.0, 1.0}, 4) == {0.0, 0.0, -1.0, 1.0});
|
||||
Matrix4f rot_yf = MATRIX4F_IDENTITY.rotate_y((float) math::deg_to_rad(90));
|
||||
assert(math::round_to_decimals(rot_yf * (float[<4>]){ 1.0, 0.0, 0.0, 1.0}, 4) == {0.0, 0.0, -1.0, 1.0});
|
||||
|
||||
Matrix4 rot_z = MATRIX4_IDENTITY.rotate_z(math::deg_to_rad(90));
|
||||
assert(math::round_to_decimals(rot_z * (double[<4>]){ 0.0, 1.0, 0.0, 1.0}, 4) == {-1.0, 0.0, 0.0, 1.0});
|
||||
Matrix4f rot_zf = MATRIX4F_IDENTITY.rotate_z((float) math::deg_to_rad(90));
|
||||
assert(math::round_to_decimals(rot_zf * (float[<4>]){ 0.0, 1.0, 0.0, 1.0}, 4) == {-1.0, 0.0, 0.0, 1.0});
|
||||
}
|
||||
|
||||
fn void test_mat4_scale()
|
||||
{
|
||||
Matrix4 scale = MATRIX4_IDENTITY.scale({2.0, 3.0, 4.0});
|
||||
assert(math::round_to_decimals(scale * (double[<4>]){ 10.0, 11.0, 12.0, 1.0}, 4) == {20.0, 33.0, 48.0, 1.0});
|
||||
}
|
||||
|
||||
fn void test_mat4_mul()
|
||||
{
|
||||
Matrix4 mat = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
@@ -22,6 +52,7 @@ fn void test_mat4_mul()
|
||||
assert(calc.m == value.m);
|
||||
assert(mat * mat2 == value);
|
||||
}
|
||||
|
||||
fn void test_mat4_lookat()
|
||||
{
|
||||
Matrix4 result = {
|
||||
@@ -85,6 +116,51 @@ fn void test_mat4_perspective()
|
||||
|
||||
assert(math::round_to_decimals((double[<16>])result.m, 4) == math::round_to_decimals((double[<16>])perspective.m, 4));
|
||||
assert(math::round_to_decimals((float[<16>])result_f.m, 4) == math::round_to_decimals((float[<16>])perspective_f.m, 4));
|
||||
|
||||
// Test the corners of the view frustum
|
||||
double top = math::tan(math::deg_to_rad(45) / 2);
|
||||
double right = math::tan(math::deg_to_rad(45) / 2) * 1.3;
|
||||
|
||||
assert(math::round_to_decimals(perspective * (double[<4>]) {-right * 0.1, -top * 0.1, -0.1, 1}, 4) == {-0.1, -0.1, -0.1, 0.1});
|
||||
assert(math::round_to_decimals(perspective * (double[<4>]) { right * 0.1, -top * 0.1, -0.1, 1}, 4) == { 0.1, -0.1, -0.1, 0.1});
|
||||
assert(math::round_to_decimals(perspective * (double[<4>]) {-right * 0.1, top * 0.1, -0.1, 1}, 4) == {-0.1, 0.1, -0.1, 0.1});
|
||||
assert(math::round_to_decimals(perspective * (double[<4>]) { right * 0.1, top * 0.1, -0.1, 1}, 4) == { 0.1, 0.1, -0.1, 0.1});
|
||||
assert(math::round_to_decimals(perspective * (double[<4>]) {-right * 1000, -top * 1000, -1000, 1}, 4) == {-1000, -1000, 1000, 1000});
|
||||
assert(math::round_to_decimals(perspective * (double[<4>]) { right * 1000, -top * 1000, -1000, 1}, 4) == { 1000, -1000, 1000, 1000});
|
||||
assert(math::round_to_decimals(perspective * (double[<4>]) {-right * 1000, top * 1000, -1000, 1}, 4) == {-1000, 1000, 1000, 1000});
|
||||
assert(math::round_to_decimals(perspective * (double[<4>]) { right * 1000, top * 1000, -1000, 1}, 4) == { 1000, 1000, 1000, 1000});
|
||||
}
|
||||
|
||||
fn void test_mat4_ortho()
|
||||
{
|
||||
Matrix4 result = {
|
||||
0.0025, 0, 0, -0.5,
|
||||
0, 0.005, 0, 0,
|
||||
0, 0, -0.05, -0.5,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
Matrix4f result_f = {
|
||||
0.0025, 0, 0, -0.5,
|
||||
0, 0.005, 0, 0,
|
||||
0, 0, -0.05, -0.5,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
Matrix4 ortho = matrix4_ortho(-200, 600, 200, -200, -10, 30);
|
||||
Matrix4f ortho_f = matrix4f_ortho(-200, 600, 200, -200, -10, 30);
|
||||
|
||||
assert(math::round_to_decimals((double[<16>])result.m, 4) == math::round_to_decimals((double[<16>])ortho.m, 4));
|
||||
assert(math::round_to_decimals((double[<16>])result_f.m, 4) == math::round_to_decimals((double[<16>])ortho_f.m, 4));
|
||||
|
||||
// Test the corners of the view space
|
||||
assert(math::round_to_decimals(ortho * (double[<4>]) {-200, -200, 10, 1}, 4) == {-1.0, -1.0, -1.0, 1.0});
|
||||
assert(math::round_to_decimals(ortho * (double[<4>]) { 600, -200, 10, 1}, 4) == { 1.0, -1.0, -1.0, 1.0});
|
||||
assert(math::round_to_decimals(ortho * (double[<4>]) {-200, 200, 10, 1}, 4) == {-1.0, 1.0, -1.0, 1.0});
|
||||
assert(math::round_to_decimals(ortho * (double[<4>]) { 600, 200, 10, 1}, 4) == { 1.0, 1.0, -1.0, 1.0});
|
||||
assert(math::round_to_decimals(ortho * (double[<4>]) {-200, -200, -30, 1}, 4) == {-1.0, -1.0, 1.0, 1.0});
|
||||
assert(math::round_to_decimals(ortho * (double[<4>]) { 600, -200, -30, 1}, 4) == { 1.0, -1.0, 1.0, 1.0});
|
||||
assert(math::round_to_decimals(ortho * (double[<4>]) {-200, 200, -30, 1}, 4) == {-1.0, 1.0, 1.0, 1.0});
|
||||
assert(math::round_to_decimals(ortho * (double[<4>]) { 600, 200, -30, 1}, 4) == { 1.0, 1.0, 1.0, 1.0});
|
||||
}
|
||||
|
||||
fn void test_mat3()
|
||||
|
||||
Reference in New Issue
Block a user