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