diff --git a/lib/std/math/math.c3 b/lib/std/math/math.c3 index c93b1e893..12017be8a 100644 --- a/lib/std/math/math.c3 +++ b/lib/std/math/math.c3 @@ -105,9 +105,13 @@ define matrix4_ortho = matrix::ortho; define matrix4_perspective = matrix::perspective; define matrix4f_ortho = matrix::ortho; define matrix4f_perspective = matrix::perspective; -macro Matrix4 matrix4_indentity() => { .m = { [0] = 1, [5] = 1, [10] = 1, [15] = 1 } }; -macro Matrix3 matrix3_indentity() => { .m = { [0] = 1, [4] = 1, [8] = 1 } }; -macro Matrix2 matrix2_indentity() => { .m = { [0] = 1, [3] = 1 } }; + +define MATRIX2_IDENTITY = matrix::IDENTITY2; +define MATRIX2F_IDENTITY = matrix::IDENTITY2; +define MATRIX3_IDENTITY = matrix::IDENTITY3; +define MATRIX3F_IDENTITY = matrix::IDENTITY3; +define MATRIX4_IDENTITY = matrix::IDENTITY4; +define MATRIX4F_IDENTITY = matrix::IDENTITY4; /** * @require types::is_numerical($typeof(x)) `The input must be a numerical value or numerical vector` diff --git a/lib/std/math/math.matrix.c3 b/lib/std/math/math.matrix.c3 index 282ab02c2..e9767fa2b 100644 --- a/lib/std/math/math.matrix.c3 +++ b/lib/std/math/math.matrix.c3 @@ -411,6 +411,9 @@ fn Matrix4x4 perspective(Real fov, Real aspect_ratio, Real near, Real far) }; } +const Matrix2x2 IDENTITY2 = { .m = { [0] = 1, [3] = 1 } }; +const Matrix3x3 IDENTITY3 = { .m = { [0] = 1, [4] = 1, [8] = 1 } }; +const Matrix4x4 IDENTITY4 = { .m = { [0] = 1, [5] = 1, [10] = 1, [15] = 1 } }; macro matrix_component_mul(mat, val) @private { diff --git a/lib/std/math/math_quaternion.c3 b/lib/std/math/math_quaternion.c3 index 1ed0f9ecd..73dbc8178 100644 --- a/lib/std/math/math_quaternion.c3 +++ b/lib/std/math/math_quaternion.c3 @@ -18,6 +18,8 @@ macro Quaternion Quaternion.scale(Quaternion a, Real s) => Quaternion { .v = a.v macro Quaternion Quaternion.normalize(Quaternion q) => { .v = q.v.normalize() }; macro Real Quaternion.length(Quaternion q) => q.v.length(); macro Quaternion Quaternion.lerp(Quaternion q1, Quaternion q2, Real amount) => { .v = q1.v.lerp(q2.v, amount) }; +macro Matrix4f Quaternion.to_matrixf(Quaternion* q) => into_matrix(q, Matrix4f); +macro Matrix4 Quaternion.to_matrix(Quaternion* q) => into_matrix(q, Matrix4); fn Quaternion Quaternion.nlerp(Quaternion q1, Quaternion q2, Real amount) => { .v = q1.v.lerp(q2.v, amount).normalize() }; fn Quaternion Quaternion.invert(Quaternion q) @@ -65,4 +67,32 @@ fn Quaternion Quaternion.mul(Quaternion a, Quaternion b) a.l * b.l - a.i * b.i - a.j * a.j - a.k * a.k }; } +macro into_matrix(Quaternion* q, $Type) @private +{ + $Type result = { .m = { [0] = 1, [5] = 1, [10] = 1, [15] = 1 } }; + Quaternion norm = q.normalize(); + var ii = norm.i*norm.i; + var jj = norm.j*norm.j; + var kk = norm.k*norm.k; + var ik = norm.i*norm.k; + var ij = norm.i*q.j; + var jk = norm.j*norm.k; + var li = norm.l*norm.i; + var lj = norm.l*norm.j; + var lk = norm.l*norm.k; + + result.m00 = 1 - 2*(jj + kk); + result.m01 = 2*(ik + lk); + result.m02 = 2*(ij - lj); + + result.m10 = 2*(ij - lk); + result.m11 = 1 - 2*(ii + kk); + result.m12 = 2*(jk + li); + + result.m20 = 2*(ik + lj); + result.m21 = 2*(jk - li); + result.m22 = 1 - 2*(ii + jj); + + return result; +} \ No newline at end of file diff --git a/test/unit/stdlib/math/matrix.c3 b/test/unit/stdlib/math/matrix.c3 index a0787a6a8..c086b2ae9 100644 --- a/test/unit/stdlib/math/matrix.c3 +++ b/test/unit/stdlib/math/matrix.c3 @@ -1,10 +1,12 @@ module math_matrix @test; import std::math; + + fn void test_mat4() { {| - Matrix4 mat = math::matrix4_indentity(); + Matrix4 mat = MATRIX4_IDENTITY; Matrix4 mat2 = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; Matrix4 calc = mat.mul(mat2); assert(calc.m == mat.m);