66 template <
unsigned rows,
unsigned cols>
70 using array_type = std::array<scalar_type, mat_rows * mat_cols>;
77 constexpr Matrix() noexcept = default;
110 template <
unsigned rows,
unsigned cols>
112 for (
size_t r { 0 }; r < rows && r <
mat_rows; ++r)
152 std::array<scalar_type, mat_rows * mat_cols> data { };
181 consteval size_t size() const noexcept {
197 constexpr auto end() noexcept {
213 constexpr auto cend() const noexcept {
246 constexpr std::span<const scalar_type>
row(
size_t row)
const noexcept {
257 constexpr std::span<scalar_type>
row(
size_t row)
noexcept {
272 constexpr std::array<scalar_type, mat_cols>
column(
size_t col)
const noexcept {
275 return m_elements | std::views::drop(col) | std::views::stride(
mat_cols) | std::ranges::to<std::array<scalar_type, mat_cols>>();
278#ifdef __cpp_multidimensional_subscript
285 constexpr scalar_type operator[](
size_t row,
size_t col)
const noexcept {
286 return this->at(row, col);
295 constexpr scalar_type& operator[](
size_t row,
size_t col)
noexcept {
296 return this->at(row, col);
306 return this->
at(position.first, position.second);
315 return this->
at(position.first, position.second);
318#ifdef __cpp_lib_mdspan
322 constexpr operator std::mdspan<const scalar_type, std::extents<std::size_t, mat_rows, mat_cols>>()
const noexcept {
323 return std::mdspan<const scalar_type, std::extents<std::size_t, mat_rows, mat_cols>>(m_elements.data());
329 constexpr operator std::mdspan<scalar_type, std::extents<std::size_t, mat_rows, mat_cols>>()
noexcept {
330 return std::mdspan<scalar_type, std::extents<std::size_t, mat_rows, mat_cols>>(m_elements.data());
337 constexpr operator std::array<T, mat_rows * mat_cols>() const noexcept {
344 constexpr operator std::vector<T>() const noexcept {
351 constexpr operator std::span<const scalar_type>() const noexcept {
358 constexpr operator std::span<scalar_type>() noexcept {
371 std::array<scalar_type, mat_cols * mat_rows> data { };
392#ifdef LITEFX_BUILD_WITH_GLM
399 constexpr Matrix(
const glm::mat<mat_cols, mat_rows, scalar_type>& mat)
noexcept {
400 for (
int r { 0 }; r < mat_rows; ++r)
401 for (
int c { 0 }; c < mat_cols; ++c)
402 m_elements[r * mat_cols + c] = mat[c][r];
409 constexpr Matrix(glm::mat<mat_cols, mat_rows, scalar_type>&& mat)
noexcept {
410 for (
size_t r { 0 }; r < mat_rows; ++r)
411 for (
size_t c { 0 }; c < mat_cols; ++c)
412 m_elements[r * mat_cols + c] = std::move(mat[c][r]);
419 template <
unsigned rows,
unsigned cols>
420 constexpr operator glm::mat<cols, rows, scalar_type>() const noexcept requires (mat_rows >= rows && mat_cols >= cols) {
421 std::array<scalar_type, static_cast<size_t>(cols * rows)> data;
422 glm::mat<cols, rows, scalar_type> mat;
424 for (
size_t c { 0 }; c < cols; ++c)
425 for (
size_t r { 0 }; r < rows; ++r)
426 data[c * mat_rows + r] = this->at(r, c);
428 std::memcpy(&mat, data.data(), data.size() *
sizeof(scalar_type));
436 constexpr operator glm::mat<2, 2, scalar_type>() const noexcept requires (mat_rows >= 2 && mat_cols >= 2) {
437 return glm::mat<2, 2, scalar_type>(at(0, 0), at(1, 0), at(0, 1), at(1, 1));
444 constexpr operator glm::mat<2, 3, scalar_type>() const noexcept requires (mat_rows >= 3 && mat_cols >= 2) {
445 return glm::mat<2, 3, scalar_type>(at(0, 0), at(1, 0), at(2, 0), at(0, 1), at(1, 1), at(2, 1));
452 constexpr operator glm::mat<2, 4, scalar_type>() const noexcept requires (mat_rows >= 4 && mat_cols >= 2) {
453 return glm::mat<2, 4, scalar_type>(at(0, 0), at(1, 0), at(2, 0), at(3, 0), at(0, 1), at(1, 1), at(2, 1), at(3, 1));
460 constexpr operator glm::mat<3, 2, scalar_type>() const noexcept requires (mat_rows >= 2 && mat_cols >= 3) {
461 return glm::mat<3, 2, scalar_type>(at(0, 0), at(1, 0), at(0, 1), at(1, 1), at(0, 2), at(1, 2));
468 constexpr operator glm::mat<4, 2, scalar_type>() const noexcept requires (mat_rows >= 2 && mat_cols >= 4) {
469 return glm::mat<4, 2, scalar_type>(at(0, 0), at(1, 0), at(0, 1), at(1, 1), at(0, 2), at(1, 2), at(0, 3), at(1, 3));
476 constexpr operator glm::mat<3, 3, scalar_type>() const noexcept requires (mat_rows >= 3 && mat_cols >= 3) {
477 return glm::mat<3, 3, scalar_type>(at(0, 0), at(1, 0), at(2, 0), at(0, 1), at(1, 1), at(2, 1), at(0, 2), at(1, 2), at(2, 2));
484 constexpr operator glm::mat<3, 4, scalar_type>() const noexcept requires (mat_rows >= 4 && mat_cols >= 3) {
485 return glm::mat<3, 4, scalar_type>(at(0, 0), at(1, 0), at(2, 0), at(3, 0), at(0, 1), at(1, 1), at(2, 1), at(3, 1), at(0, 2), at(1, 2), at(2, 2), at(3, 2));
492 constexpr operator glm::mat<4, 3, scalar_type>() const noexcept requires (mat_rows >= 3 && mat_cols >= 4) {
493 return glm::mat<4, 3, scalar_type>(at(0, 0), at(1, 0), at(2, 0), at(0, 1), at(1, 1), at(2, 1), at(0, 2), at(1, 2), at(2, 2), at(0, 3), at(1, 3), at(2, 3));
500 constexpr operator glm::mat<4, 4, scalar_type>() const noexcept requires (mat_rows >= 4 && mat_cols >= 4) {
501 return glm::mat<4, 4, scalar_type>(at(0, 0), at(1, 0), at(2, 0), at(3, 0), at(0, 1), at(1, 1), at(2, 1), at(3, 1), at(0, 2), at(1, 2), at(2, 2), at(3, 2), at(0, 3), at(1, 3), at(2, 3), at(3, 3));
505#ifdef LITEFX_BUILD_WITH_DIRECTX_MATH
511 constexpr Matrix(
const DirectX::XMFLOAT3X3& mat)
noexcept {
512 for (
int r { 0 }; r < 3; ++r)
513 for (
int c { 0 }; c < 3; ++c)
514 at(r, c) = mat(r, c);
521 constexpr Matrix(
const DirectX::XMFLOAT4X3& mat)
noexcept {
522 for (
int r { 0 }; r < 4; ++r)
523 for (
int c { 0 }; c < 3; ++c)
524 at(r, c) = mat(r, c);
531 constexpr Matrix(
const DirectX::XMFLOAT3X4& mat)
noexcept {
532 for (
int r { 0 }; r < 3; ++r)
533 for (
int c { 0 }; c < 4; ++c)
534 at(r, c) = mat(r, c);
541 constexpr Matrix(
const DirectX::XMFLOAT4X4& mat)
noexcept {
542 for (
int r { 0 }; r < 4; ++r)
543 for (
int c { 0 }; c < 4; ++c)
544 at(r, c) = mat(r, c);
551 constexpr operator DirectX::XMMATRIX() const noexcept requires ((mat_rows == 3 || mat_rows == 4) && (mat_cols == 3 || mat_cols == 4) && std::convertible_to<scalar_type,
float>) {
552 if constexpr (mat_rows == 3 && mat_cols == 3)
554 DirectX::XMFLOAT3X3 mat =
static_cast<DirectX::XMFLOAT3X3
>(*this);
555 return DirectX::XMLoadFloat3x3(&mat);
557 else if constexpr (mat_rows == 3 && mat_cols == 4)
559 DirectX::XMFLOAT3X4 mat =
static_cast<DirectX::XMFLOAT3X4
>(*this);
560 return DirectX::XMLoadFloat3x4(&mat);
562 else if constexpr (mat_rows == 4 && mat_cols == 3)
564 DirectX::XMFLOAT4X3 mat =
static_cast<DirectX::XMFLOAT4X3
>(*this);
565 return DirectX::XMLoadFloat4x3(&mat);
567 if constexpr (mat_rows == 4 && mat_cols == 4)
569 DirectX::XMFLOAT4X4 mat =
static_cast<DirectX::XMFLOAT4X4
>(*this);
570 return DirectX::XMLoadFloat4x4(&mat);
580 constexpr operator DirectX::XMFLOAT3X3() const noexcept requires (mat_rows >= 3 && mat_cols >= 3 && std::convertible_to<scalar_type,
float>) {
581 return DirectX::XMFLOAT3X3(at(0, 0), at(0, 1), at(0, 2), at(1, 0), at(1, 2), at(2, 0), at(2, 1), at(2, 2));
588 constexpr operator DirectX::XMFLOAT4X3() const noexcept requires (mat_rows >= 4 && mat_cols >= 3 && std::convertible_to<scalar_type,
float>) {
589 return DirectX::XMFLOAT4X3(at(0, 0), at(0, 1), at(0, 2), at(1, 0), at(1, 2), at(2, 0), at(2, 1), at(2, 2), at(3, 0), at(3, 1), at(3, 2));
596 constexpr operator DirectX::XMFLOAT3X4() const noexcept requires (mat_rows >= 3 && mat_cols >= 4 && std::convertible_to<scalar_type,
float>) {
597 return DirectX::XMFLOAT3X4(at(0, 0), at(0, 1), at(0, 2), at(0, 3), at(1, 0), at(1, 2), at(1, 3), at(2, 0), at(2, 1), at(2, 2), at(2, 3));
604 constexpr operator DirectX::XMFLOAT4X4() const noexcept requires (mat_rows >= 4 && mat_cols >= 4 && std::convertible_to<scalar_type,
float>) {
605 return DirectX::XMFLOAT4X4(at(0, 0), at(0, 1), at(0, 2), at(0, 3), at(1, 0), at(1, 2), at(1, 3), at(2, 0), at(2, 1), at(2, 2), at(2, 3), at(3, 0), at(3, 1), at(3, 2), at(3, 3));