module; #include #include #include #include #include #include #include export module Crafter.Math:MatrixCollumMajor; import :BasicTypes; import :Vector; import :Misc; namespace Crafter { export template class MatrixCollumMajor { public: T m[CollumSize*Repeats][RowSize]; MatrixCollumMajor() = default; MatrixCollumMajor( float x0, float y0, float z0, float w0, float x1, float y1, float z1, float w1, float x2, float y2, float z2, float w2, float x3, float y3, float z3, float w3 ) requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as) { m[0][0] = x0; m[0][1] = x1; m[0][2] = x2; m[0][3] = x3; m[1][0] = y0; m[1][1] = y1; m[1][2] = y2; m[1][3] = y3; m[2][0] = z0; m[2][1] = z1; m[2][2] = z2; m[2][3] = z3; m[3][0] = w0; m[3][1] = w1; m[3][2] = w2; m[3][3] = w3; } Vector operator*(Vector b) const requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as) { return Vector( b.x * m[0][0] + b.y * m[0][1] + b.z * m[0][2] + m[0][3], b.x * m[1][0] + b.y * m[1][1] + b.z * m[1][2] + m[1][3], b.x * m[2][0] + b.y * m[2][1] + b.z * m[2][2] + m[2][3] ); } MatrixCollumMajor operator*(MatrixCollumMajor b) const requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as) { MatrixCollumMajor result; result.m[0][0] = b.m[0][0] * m[0][0] + b.m[1][0] * m[0][1] + b.m[2][0] * m[0][2] + b.m[3][0] * m[0][3]; result.m[0][1] = b.m[0][1] * m[0][0] + b.m[1][1] * m[0][1] + b.m[2][1] * m[0][2] + b.m[3][1] * m[0][3]; result.m[0][2] = b.m[0][2] * m[0][0] + b.m[1][2] * m[0][1] + b.m[2][2] * m[0][2] + b.m[3][2] * m[0][3]; result.m[0][3] = b.m[0][3] * m[0][0] + b.m[1][3] * m[0][1] + b.m[2][3] * m[0][2] + b.m[3][3] * m[0][3]; result.m[1][0] = b.m[0][0] * m[1][0] + b.m[1][0] * m[1][1] + b.m[2][0] * m[1][2] + b.m[3][0] * m[1][3]; result.m[1][1] = b.m[0][1] * m[1][0] + b.m[1][1] * m[1][1] + b.m[2][1] * m[1][2] + b.m[3][1] * m[1][3]; result.m[1][2] = b.m[0][2] * m[1][0] + b.m[1][2] * m[1][1] + b.m[2][2] * m[1][2] + b.m[3][2] * m[1][3]; result.m[1][3] = b.m[0][3] * m[1][0] + b.m[1][3] * m[1][1] + b.m[2][3] * m[1][2] + b.m[3][3] * m[1][3]; result.m[2][0] = b.m[0][0] * m[2][0] + b.m[1][0] * m[2][1] + b.m[2][0] * m[2][2] + b.m[3][0] * m[2][3]; result.m[2][1] = b.m[0][1] * m[2][0] + b.m[1][1] * m[2][1] + b.m[2][1] * m[2][2] + b.m[3][1] * m[2][3]; result.m[2][2] = b.m[0][2] * m[2][0] + b.m[1][2] * m[2][1] + b.m[2][2] * m[2][2] + b.m[3][2] * m[2][3]; result.m[2][3] = b.m[0][3] * m[2][0] + b.m[1][3] * m[2][1] + b.m[2][3] * m[2][2] + b.m[3][3] * m[2][3]; result.m[3][0] = b.m[0][0] * m[3][0] + b.m[1][0] * m[3][1] + b.m[2][0] * m[3][2] + b.m[3][0] * m[3][3]; result.m[3][1] = b.m[0][1] * m[3][0] + b.m[1][1] * m[3][1] + b.m[2][1] * m[3][2] + b.m[3][1] * m[3][3]; result.m[3][2] = b.m[0][2] * m[3][0] + b.m[1][2] * m[3][1] + b.m[2][2] * m[3][2] + b.m[3][2] * m[3][3]; result.m[3][3] = b.m[0][3] * m[3][0] + b.m[1][3] * m[3][1] + b.m[2][3] * m[3][2] + b.m[3][3] * m[3][3]; return result; } static MatrixCollumMajor Perspective(float fovAngleY, float aspectRatio, float nearZ, float farZ) requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as) { MatrixCollumMajor result; float SinFov; float CosFov; XMScalarSinCos(&SinFov, &CosFov, 0.5f * fovAngleY); float Height = CosFov / SinFov; float Width = Height / aspectRatio; float fRange = farZ / (nearZ - farZ); result.m[0][0] = Width; result.m[1][0] = 0.0f; result.m[2][0] = 0.0f; result.m[3][0] = 0.0f; result.m[0][1] = 0.0f; result.m[1][1] = Height; result.m[2][1] = 0.0f; result.m[3][1] = 0.0f; result.m[0][2] = 0.0f; result.m[1][2] = 0.0f; result.m[2][2] = fRange; result.m[3][2] = -1.0f; result.m[0][3] = 0.0f; result.m[1][3] = 0.0f; result.m[2][3] = fRange * nearZ; result.m[3][3] = 0.0f; return result; } static MatrixCollumMajor Identity() requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as) { return MatrixCollumMajor( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); } static MatrixCollumMajor Scaling(float x, float y, float z) requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as) { return MatrixCollumMajor( x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 ); } static MatrixCollumMajor Translation(float x, float y, float z) requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as) { return MatrixCollumMajor( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 ); } static MatrixCollumMajor Rotation(float Pitch, float Yaw, float Roll) requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as) { float cp = cosf(Pitch); float sp = sinf(Pitch); float cy = cosf(Yaw); float sy = sinf(Yaw); float cr = cosf(Roll); float sr = sinf(Roll); MatrixCollumMajor M; M.m[0][0] = cr * cy + sr * sp * sy; M.m[1][0] = sr * cp; M.m[2][0] = sr * sp * cy - cr * sy; M.m[3][0] = 0.0f; M.m[0][1] = cr * sp * sy - sr * cy; M.m[1][1] = cr * cp; M.m[2][1] = sr * sy + cr * sp * cy; M.m[3][1] = 0.0f; M.m[0][2] = cp * sy; M.m[1][2] = -sp; M.m[2][2] = cp * cy; M.m[3][2] = 0.0f; M.m[0][3] = 0.0f; M.m[1][3] = 0.0f; M.m[2][3] = 0.0f; M.m[3][3] = 1.0f; return M; } }; } template <> struct std::formatter> : std::formatter { auto format(const Crafter::MatrixCollumMajor& obj, format_context& ctx) const { return std::formatter::format(std::format("{{{}, {}, {}, {}\n{}, {}, {}, {}\n{}, {}, {}, {}\n{}, {}, {}, {}}}", obj.m[0][0], obj.m[1][0], obj.m[2][0], obj.m[3][0], obj.m[0][1], obj.m[1][1], obj.m[2][1], obj.m[3][1], obj.m[0][2], obj.m[1][2], obj.m[2][2], obj.m[3][2], obj.m[0][3], obj.m[1][3], obj.m[2][3], obj.m[3][3] ), ctx); } };