MXVK Vulkan Framework 0.35.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
mxvk::Mat4D Class Reference

Four-by-four homogeneous transform matrix. More...

#include <mxvk/include/mxvk/mxvk_math.h>

Public Member Functions

void BuildXYZ (float theta_x, float theta_y, float theta_z)
 Build an XYZ Euler rotation matrix from angles in degrees.
void BuildXYZ (float theta_x, float theta_y, float theta_z)
 Build an XYZ Euler rotation matrix from angles in degrees.
bool Inverse (Mat4D &out) const
 Compute the inverse matrix using Gauss-Jordan elimination.
bool Inverse (Mat4D &out) const
 Compute the inverse matrix.
void LoadIdentity ()
 Set this matrix to the identity matrix.
void LoadIdentity ()
 Set this matrix to the identity matrix.
 Mat4D ()=default
 Construct a zero-initialized matrix.
 Mat4D ()=default
 Construct a zero-initialized matrix.
 Mat4D (float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
 Construct from explicit row-major elements.
 Mat4D (float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
 Construct from explicit row-major elements.
vec3D MulVec (const vec3D &in) const
 Transform a 3D point by this matrix using W = 1.
vec3D MulVec (const vec3D &in) const
 Transform a 3D point by this matrix using W = 1.
void MulVec (const vec3D &in, vec3D &out) const
 Transform a 3D point and write the result to out.
void MulVec (const vec3D &in, vec3D &out) const
 Transform a 3D point and write the result to out.
vec4D MulVec (const vec4D &in) const
 Transform a homogeneous 4D vector by this matrix.
vec4D MulVec (const vec4D &in) const
 Transform a homogeneous 4D vector by this matrix.
void MulVec (const vec4D &in, vec4D &out) const
 Transform a homogeneous 4D vector and write the result to out.
void MulVec (const vec4D &in, vec4D &out) const
 Transform a homogeneous 4D vector and write the result to out.
void MulVec (std::span< const vec4D > input, std::span< vec4D > output) const
 Transform a batch of homogeneous 4D vectors.
void MulVec (std::span< const vec4D > input, std::span< vec4D > output) const
 Transform a batch of homogeneous 4D vectors.
Mat4D operator* (const Mat4D &m) const
 Multiply two 4x4 matrices.
Mat4D operator* (const Mat4D &m) const
 Multiply two 4x4 matrices.
Mat4D & operator*= (const Mat4D &m)
 Multiply this matrix by another matrix in place.
Mat4D & operator*= (const Mat4D &m)
 Multiply this matrix by another matrix in place.
Mat4D operator+ (const Mat4D &m) const
 Add two matrices component-wise.
Mat4D operator+ (const Mat4D &m) const
 Add two matrices component-wise.
void Set (float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
 Set all matrix elements in row-major order.
void Set (float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
 Set all matrix elements in row-major order.

Public Attributes

float mat [4][4] {}
 Matrix elements indexed as row, column.

Detailed Description

Four-by-four homogeneous transform matrix.

Definition at line 706 of file mxvk_math.h.

Constructor & Destructor Documentation

◆ Mat4D() [1/4]

mxvk::Mat4D::Mat4D ( )
default

Construct a zero-initialized matrix.

◆ Mat4D() [2/4]

mxvk::Mat4D::Mat4D ( float m00,
float m01,
float m02,
float m03,
float m10,
float m11,
float m12,
float m13,
float m20,
float m21,
float m22,
float m23,
float m30,
float m31,
float m32,
float m33 )
inline

Construct from explicit row-major elements.

Definition at line 715 of file mxvk_math.h.

715{ Set(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33); }
void Set(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33)
Set all matrix elements in row-major order.
Definition mxvk_math.h:718

◆ Mat4D() [3/4]

mxvk::Mat4D::Mat4D ( )
default

Construct a zero-initialized matrix.

◆ Mat4D() [4/4]

mxvk::Mat4D::Mat4D ( float m00,
float m01,
float m02,
float m03,
float m10,
float m11,
float m12,
float m13,
float m20,
float m21,
float m22,
float m23,
float m30,
float m31,
float m32,
float m33 )
inline

Construct from explicit row-major elements.

Definition at line 729 of file mxvk_math_eigen.hpp.

729{ Set(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33); }

Member Function Documentation

◆ BuildXYZ() [1/2]

void mxvk::Mat4D::BuildXYZ ( float theta_x,
float theta_y,
float theta_z )
inline

Build an XYZ Euler rotation matrix from angles in degrees.

Definition at line 859 of file mxvk_math.h.

859 {
860 const float cx = std::cos(deg2rad(theta_x));
861 const float sx = std::sin(deg2rad(theta_x));
862 const float cy = std::cos(deg2rad(theta_y));
863 const float sy = std::sin(deg2rad(theta_y));
864 const float cz = std::cos(deg2rad(theta_z));
865 const float sz = std::sin(deg2rad(theta_z));
866
867 Mat4D mx(1, 0, 0, 0, 0, cx, sx, 0, 0, -sx, cx, 0, 0, 0, 0, 1);
868 Mat4D my(cy, 0, -sy, 0, 0, 1, 0, 0, sy, 0, cy, 0, 0, 0, 0, 1);
869 Mat4D mz(cz, sz, 0, 0, -sz, cz, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
870 *this = mx * my * mz;
871 }
Mat4D()=default
Construct a zero-initialized matrix.
float deg2rad(float ang)
Convert degrees to radians.
Definition mxvk_math.h:109

◆ BuildXYZ() [2/2]

void mxvk::Mat4D::BuildXYZ ( float theta_x,
float theta_y,
float theta_z )
inline

Build an XYZ Euler rotation matrix from angles in degrees.

Definition at line 809 of file mxvk_math_eigen.hpp.

809 {
810 const float cx = std::cos(deg2rad(theta_x));
811 const float sx = std::sin(deg2rad(theta_x));
812 const float cy = std::cos(deg2rad(theta_y));
813 const float sy = std::sin(deg2rad(theta_y));
814 const float cz = std::cos(deg2rad(theta_z));
815 const float sz = std::sin(deg2rad(theta_z));
816
817 Mat4D mx(1, 0, 0, 0, 0, cx, sx, 0, 0, -sx, cx, 0, 0, 0, 0, 1);
818 Mat4D my(cy, 0, -sy, 0, 0, 1, 0, 0, sy, 0, cy, 0, 0, 0, 0, 1);
819 Mat4D mz(cz, sz, 0, 0, -sz, cz, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
820 *this = mx * my * mz;
821 }

◆ Inverse() [1/2]

bool mxvk::Mat4D::Inverse ( Mat4D & out) const
inline

Compute the inverse matrix using Gauss-Jordan elimination.

Parameters
outReceives the inverse on success.
Returns
True when the matrix is invertible.

Definition at line 811 of file mxvk_math.h.

811 {
812 float a[4][8]{};
813 for (int r = 0; r < 4; ++r) {
814 for (int c = 0; c < 4; ++c) {
815 a[r][c] = mat[r][c];
816 }
817 a[r][r + 4] = 1.0f;
818 }
819
820 for (int c = 0; c < 4; ++c) {
821 int pivot = c;
822 for (int r = c + 1; r < 4; ++r) {
823 if (std::fabs(a[r][c]) > std::fabs(a[pivot][c])) {
824 pivot = r;
825 }
826 }
827 if (std::fabs(a[pivot][c]) <= EPSILON) {
828 return false;
829 }
830 if (pivot != c) {
831 for (int k = 0; k < 8; ++k) {
832 std::swap(a[c][k], a[pivot][k]);
833 }
834 }
835 const float inv_pivot = 1.0f / a[c][c];
836 for (int k = 0; k < 8; ++k) {
837 a[c][k] *= inv_pivot;
838 }
839 for (int r = 0; r < 4; ++r) {
840 if (r == c) {
841 continue;
842 }
843 const float factor = a[r][c];
844 for (int k = 0; k < 8; ++k) {
845 a[r][k] -= factor * a[c][k];
846 }
847 }
848 }
849
850 for (int r = 0; r < 4; ++r) {
851 for (int c = 0; c < 4; ++c) {
852 out.mat[r][c] = a[r][c + 4];
853 }
854 }
855 return true;
856 }
float mat[4][4]
Matrix elements indexed as row, column.
Definition mxvk_math.h:709
constexpr float EPSILON
Default tolerance used for floating-point singularity and zero-length checks.
Definition mxvk_math.h:37

◆ Inverse() [2/2]

bool mxvk::Mat4D::Inverse ( Mat4D & out) const
inline

Compute the inverse matrix.

Parameters
outReceives the inverse on success.
Returns
True when the matrix is invertible.

Definition at line 798 of file mxvk_math_eigen.hpp.

798 {
799 Eigen::FullPivLU<EigenMatrix> decomposition(ToEigen());
800 decomposition.setThreshold(EPSILON);
801 if (!decomposition.isInvertible()) {
802 return false;
803 }
804 out = FromEigen(decomposition.inverse());
805 return true;
806 }

◆ LoadIdentity() [1/2]

void mxvk::Mat4D::LoadIdentity ( )
inline

Set this matrix to the identity matrix.

Definition at line 738 of file mxvk_math.h.

738{ Set(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); }

◆ LoadIdentity() [2/2]

void mxvk::Mat4D::LoadIdentity ( )
inline

Set this matrix to the identity matrix.

Definition at line 735 of file mxvk_math_eigen.hpp.

735{ ToEigen().setIdentity(); }

◆ MulVec() [1/10]

vec3D mxvk::Mat4D::MulVec ( const vec3D & in) const
inlinenodiscard

Transform a 3D point by this matrix using W = 1.

Definition at line 798 of file mxvk_math.h.

798 {
799 const vec4D r = MulVec(vec4D(in.x, in.y, in.z, 1.0f));
800 return {r.x, r.y, r.z};
801 }
vec4D MulVec(const vec4D &in) const
Transform a homogeneous 4D vector by this matrix.
Definition mxvk_math.h:771
constexpr vec4D()
Construct the homogeneous origin.
Definition mxvk_math.h:378

◆ MulVec() [2/10]

vec3D mxvk::Mat4D::MulVec ( const vec3D & in) const
inlinenodiscard

Transform a 3D point by this matrix using W = 1.

Definition at line 785 of file mxvk_math_eigen.hpp.

785 {
786 const vec4D r = MulVec(vec4D(in.x, in.y, in.z, 1.0f));
787 return {r.x, r.y, r.z};
788 }

◆ MulVec() [3/10]

void mxvk::Mat4D::MulVec ( const vec3D & in,
vec3D & out ) const
inline

Transform a 3D point and write the result to out.

Definition at line 804 of file mxvk_math.h.

804{ out = MulVec(in); }

◆ MulVec() [4/10]

void mxvk::Mat4D::MulVec ( const vec3D & in,
vec3D & out ) const
inline

Transform a 3D point and write the result to out.

Definition at line 791 of file mxvk_math_eigen.hpp.

791{ out = MulVec(in); }

◆ MulVec() [5/10]

vec4D mxvk::Mat4D::MulVec ( const vec4D & in) const
inlinenodiscard

Transform a homogeneous 4D vector by this matrix.

Definition at line 771 of file mxvk_math.h.

771 {
772 vec4D out(0.0f, 0.0f, 0.0f, 0.0f);
773 out.x = in.x * mat[0][0] + in.y * mat[1][0] + in.z * mat[2][0] + in.w * mat[3][0];
774 out.y = in.x * mat[0][1] + in.y * mat[1][1] + in.z * mat[2][1] + in.w * mat[3][1];
775 out.z = in.x * mat[0][2] + in.y * mat[1][2] + in.z * mat[2][2] + in.w * mat[3][2];
776 out.w = in.x * mat[0][3] + in.y * mat[1][3] + in.z * mat[2][3] + in.w * mat[3][3];
777 return out;
778 }

◆ MulVec() [6/10]

vec4D mxvk::Mat4D::MulVec ( const vec4D & in) const
inlinenodiscard

Transform a homogeneous 4D vector by this matrix.

Definition at line 750 of file mxvk_math_eigen.hpp.

750 {
751 const Eigen::Vector4f result = ToEigen().transpose() * Eigen::Vector4f(in.x, in.y, in.z, in.w);
752 return {result.x(), result.y(), result.z(), result.w()};
753 }

◆ MulVec() [7/10]

void mxvk::Mat4D::MulVec ( const vec4D & in,
vec4D & out ) const
inline

Transform a homogeneous 4D vector and write the result to out.

Definition at line 781 of file mxvk_math.h.

781{ out = MulVec(in); }

◆ MulVec() [8/10]

void mxvk::Mat4D::MulVec ( const vec4D & in,
vec4D & out ) const
inline

Transform a homogeneous 4D vector and write the result to out.

Definition at line 756 of file mxvk_math_eigen.hpp.

756{ out = MulVec(in); }

◆ MulVec() [9/10]

void mxvk::Mat4D::MulVec ( std::span< const vec4D > input,
std::span< vec4D > output ) const
inline

Transform a batch of homogeneous 4D vectors.

Parameters
inputSource vectors.
outputDestination vectors, with the same size as input.

Definition at line 788 of file mxvk_math.h.

788 {
789 if (input.size() != output.size()) {
790 throw std::invalid_argument("Mat4D::MulVec batch spans must have equal sizes");
791 }
792 for (std::size_t index = 0; index < input.size(); ++index) {
793 output[index] = MulVec(input[index]);
794 }
795 }

◆ MulVec() [10/10]

void mxvk::Mat4D::MulVec ( std::span< const vec4D > input,
std::span< vec4D > output ) const
inline

Transform a batch of homogeneous 4D vectors.

Parameters
inputSource vectors.
outputDestination vectors, with the same size as input.

Processing the vectors as a 4xN matrix lets Eigen use packetized SIMD across the complete batch instead of evaluating one small expression per vertex.

Definition at line 767 of file mxvk_math_eigen.hpp.

767 {
768 if (input.size() != output.size()) {
769 throw std::invalid_argument("Mat4D::MulVec batch spans must have equal sizes");
770 }
771 if (input.empty()) {
772 return;
773 }
774
775 static_assert(std::is_standard_layout_v<vec4D>);
776 static_assert(sizeof(vec4D) == sizeof(float) * 4);
777 using VertexMatrix = Eigen::Matrix<float, 4, Eigen::Dynamic, Eigen::ColMajor>;
778 const Eigen::Index vertex_count = static_cast<Eigen::Index>(input.size());
779 const Eigen::Map<const VertexMatrix, Eigen::Unaligned> input_matrix(&input.front().x, 4, vertex_count);
780 Eigen::Map<VertexMatrix, Eigen::Unaligned> output_matrix(&output.front().x, 4, vertex_count);
781 output_matrix.noalias() = ToEigen().transpose() * input_matrix;
782 }

◆ operator*() [1/2]

Mat4D mxvk::Mat4D::operator* ( const Mat4D & m) const
inlinenodiscard

Multiply two 4x4 matrices.

Definition at line 752 of file mxvk_math.h.

752 {
753 Mat4D out;
754 for (int r = 0; r < 4; ++r) {
755 for (int c = 0; c < 4; ++c) {
756 for (int k = 0; k < 4; ++k) {
757 out.mat[r][c] += mat[r][k] * m.mat[k][c];
758 }
759 }
760 }
761 return out;
762 }

◆ operator*() [2/2]

Mat4D mxvk::Mat4D::operator* ( const Mat4D & m) const
inlinenodiscard

Multiply two 4x4 matrices.

Definition at line 741 of file mxvk_math_eigen.hpp.

741{ return FromEigen(ToEigen() * m.ToEigen()); }

◆ operator*=() [1/2]

Mat4D & mxvk::Mat4D::operator*= ( const Mat4D & m)
inline

Multiply this matrix by another matrix in place.

Definition at line 765 of file mxvk_math.h.

765 {
766 *this = *this * m;
767 return *this;
768 }

◆ operator*=() [2/2]

Mat4D & mxvk::Mat4D::operator*= ( const Mat4D & m)
inline

Multiply this matrix by another matrix in place.

Definition at line 744 of file mxvk_math_eigen.hpp.

744 {
745 *this = *this * m;
746 return *this;
747 }

◆ operator+() [1/2]

Mat4D mxvk::Mat4D::operator+ ( const Mat4D & m) const
inlinenodiscard

Add two matrices component-wise.

Definition at line 741 of file mxvk_math.h.

741 {
742 Mat4D out;
743 for (int r = 0; r < 4; ++r) {
744 for (int c = 0; c < 4; ++c) {
745 out.mat[r][c] = mat[r][c] + m.mat[r][c];
746 }
747 }
748 return out;
749 }

◆ operator+() [2/2]

Mat4D mxvk::Mat4D::operator+ ( const Mat4D & m) const
inlinenodiscard

Add two matrices component-wise.

Definition at line 738 of file mxvk_math_eigen.hpp.

738{ return FromEigen(ToEigen() + m.ToEigen()); }

◆ Set() [1/2]

void mxvk::Mat4D::Set ( float m00,
float m01,
float m02,
float m03,
float m10,
float m11,
float m12,
float m13,
float m20,
float m21,
float m22,
float m23,
float m30,
float m31,
float m32,
float m33 )
inline

Set all matrix elements in row-major order.

Definition at line 718 of file mxvk_math.h.

718 {
719 mat[0][0] = m00;
720 mat[0][1] = m01;
721 mat[0][2] = m02;
722 mat[0][3] = m03;
723 mat[1][0] = m10;
724 mat[1][1] = m11;
725 mat[1][2] = m12;
726 mat[1][3] = m13;
727 mat[2][0] = m20;
728 mat[2][1] = m21;
729 mat[2][2] = m22;
730 mat[2][3] = m23;
731 mat[3][0] = m30;
732 mat[3][1] = m31;
733 mat[3][2] = m32;
734 mat[3][3] = m33;
735 }

◆ Set() [2/2]

void mxvk::Mat4D::Set ( float m00,
float m01,
float m02,
float m03,
float m10,
float m11,
float m12,
float m13,
float m20,
float m21,
float m22,
float m23,
float m30,
float m31,
float m32,
float m33 )
inline

Set all matrix elements in row-major order.

Definition at line 732 of file mxvk_math_eigen.hpp.

732{ ToEigen() << m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33; }

Member Data Documentation

◆ mat

float mxvk::Mat4D::mat {}

Matrix elements indexed as row, column.

Definition at line 709 of file mxvk_math.h.


The documentation for this class was generated from the following files: