MXVK Vulkan Framework 0.24.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.
Mat4Doperator*= (const Mat4D &m)
 Multiply this matrix by another matrix in place.
Mat4Doperator*= (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 812 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 821 of file mxvk_math.h.

821 {
822 Set(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);
823 }
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:826

◆ 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 858 of file mxvk_math_eigen.hpp.

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

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 973 of file mxvk_math.h.

973 {
974 const float cx = std::cos(deg2rad(theta_x));
975 const float sx = std::sin(deg2rad(theta_x));
976 const float cy = std::cos(deg2rad(theta_y));
977 const float sy = std::sin(deg2rad(theta_y));
978 const float cz = std::cos(deg2rad(theta_z));
979 const float sz = std::sin(deg2rad(theta_z));
980
981 Mat4D mx(1, 0, 0, 0, 0, cx, sx, 0, 0, -sx, cx, 0, 0, 0, 0, 1);
982 Mat4D my(cy, 0, -sy, 0, 0, 1, 0, 0, sy, 0, cy, 0, 0, 0, 0, 1);
983 Mat4D mz(cz, sz, 0, 0, -sz, cz, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
984 *this = mx * my * mz;
985 }
Mat4D()=default
Construct a zero-initialized matrix.
float deg2rad(float ang)
Convert degrees to radians.
Definition mxvk_math.h:124

◆ 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 952 of file mxvk_math_eigen.hpp.

952 {
953 const float cx = std::cos(deg2rad(theta_x));
954 const float sx = std::sin(deg2rad(theta_x));
955 const float cy = std::cos(deg2rad(theta_y));
956 const float sy = std::sin(deg2rad(theta_y));
957 const float cz = std::cos(deg2rad(theta_z));
958 const float sz = std::sin(deg2rad(theta_z));
959
960 Mat4D mx(1, 0, 0, 0, 0, cx, sx, 0, 0, -sx, cx, 0, 0, 0, 0, 1);
961 Mat4D my(cy, 0, -sy, 0, 0, 1, 0, 0, sy, 0, cy, 0, 0, 0, 0, 1);
962 Mat4D mz(cz, sz, 0, 0, -sz, cz, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
963 *this = mx * my * mz;
964 }

◆ 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 925 of file mxvk_math.h.

925 {
926 float a[4][8]{};
927 for (int r = 0; r < 4; ++r) {
928 for (int c = 0; c < 4; ++c) {
929 a[r][c] = mat[r][c];
930 }
931 a[r][r + 4] = 1.0f;
932 }
933
934 for (int c = 0; c < 4; ++c) {
935 int pivot = c;
936 for (int r = c + 1; r < 4; ++r) {
937 if (std::fabs(a[r][c]) > std::fabs(a[pivot][c])) {
938 pivot = r;
939 }
940 }
941 if (std::fabs(a[pivot][c]) <= EPSILON) {
942 return false;
943 }
944 if (pivot != c) {
945 for (int k = 0; k < 8; ++k) {
946 std::swap(a[c][k], a[pivot][k]);
947 }
948 }
949 const float inv_pivot = 1.0f / a[c][c];
950 for (int k = 0; k < 8; ++k) {
951 a[c][k] *= inv_pivot;
952 }
953 for (int r = 0; r < 4; ++r) {
954 if (r == c) {
955 continue;
956 }
957 const float factor = a[r][c];
958 for (int k = 0; k < 8; ++k) {
959 a[r][k] -= factor * a[c][k];
960 }
961 }
962 }
963
964 for (int r = 0; r < 4; ++r) {
965 for (int c = 0; c < 4; ++c) {
966 out.mat[r][c] = a[r][c + 4];
967 }
968 }
969 return true;
970 }
float mat[4][4]
Matrix elements indexed as row, column.
Definition mxvk_math.h:815
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 941 of file mxvk_math_eigen.hpp.

941 {
942 Eigen::FullPivLU<EigenMatrix> decomposition(ToEigen());
943 decomposition.setThreshold(EPSILON);
944 if (!decomposition.isInvertible()) {
945 return false;
946 }
947 out = FromEigen(decomposition.inverse());
948 return true;
949 }

◆ LoadIdentity() [1/2]

void mxvk::Mat4D::LoadIdentity ( )
inline

Set this matrix to the identity matrix.

Definition at line 846 of file mxvk_math.h.

846 {
847 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);
848 }

◆ LoadIdentity() [2/2]

void mxvk::Mat4D::LoadIdentity ( )
inline

Set this matrix to the identity matrix.

Definition at line 868 of file mxvk_math_eigen.hpp.

868 {
869 ToEigen().setIdentity();
870 }

◆ 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 910 of file mxvk_math.h.

910 {
911 const vec4D r = MulVec(vec4D(in.x, in.y, in.z, 1.0f));
912 return {r.x, r.y, r.z};
913 }
vec4D MulVec(const vec4D &in) const
Transform a homogeneous 4D vector by this matrix.
Definition mxvk_math.h:881

◆ 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 926 of file mxvk_math_eigen.hpp.

926 {
927 const vec4D r = MulVec(vec4D(in.x, in.y, in.z, 1.0f));
928 return {r.x, r.y, r.z};
929 }

◆ 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 916 of file mxvk_math.h.

916 {
917 out = MulVec(in);
918 }

◆ 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 932 of file mxvk_math_eigen.hpp.

932 {
933 out = MulVec(in);
934 }

◆ MulVec() [5/10]

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

Transform a homogeneous 4D vector by this matrix.

Definition at line 881 of file mxvk_math.h.

881 {
882 vec4D out(0.0f, 0.0f, 0.0f, 0.0f);
883 out.x = in.x * mat[0][0] + in.y * mat[1][0] + in.z * mat[2][0] + in.w * mat[3][0];
884 out.y = in.x * mat[0][1] + in.y * mat[1][1] + in.z * mat[2][1] + in.w * mat[3][1];
885 out.z = in.x * mat[0][2] + in.y * mat[1][2] + in.z * mat[2][2] + in.w * mat[3][2];
886 out.w = in.x * mat[0][3] + in.y * mat[1][3] + in.z * mat[2][3] + in.w * mat[3][3];
887 return out;
888 }

◆ MulVec() [6/10]

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

Transform a homogeneous 4D vector by this matrix.

Definition at line 889 of file mxvk_math_eigen.hpp.

889 {
890 const Eigen::Vector4f result = ToEigen().transpose() * Eigen::Vector4f(in.x, in.y, in.z, in.w);
891 return {result.x(), result.y(), result.z(), result.w()};
892 }

◆ 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 891 of file mxvk_math.h.

891 {
892 out = MulVec(in);
893 }

◆ 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 895 of file mxvk_math_eigen.hpp.

895 {
896 out = MulVec(in);
897 }

◆ 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 900 of file mxvk_math.h.

900 {
901 if (input.size() != output.size()) {
902 throw std::invalid_argument("Mat4D::MulVec batch spans must have equal sizes");
903 }
904 for (std::size_t index = 0; index < input.size(); ++index) {
905 output[index] = MulVec(input[index]);
906 }
907 }

◆ 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 908 of file mxvk_math_eigen.hpp.

908 {
909 if (input.size() != output.size()) {
910 throw std::invalid_argument("Mat4D::MulVec batch spans must have equal sizes");
911 }
912 if (input.empty()) {
913 return;
914 }
915
916 static_assert(std::is_standard_layout_v<vec4D>);
917 static_assert(sizeof(vec4D) == sizeof(float) * 4);
918 using VertexMatrix = Eigen::Matrix<float, 4, Eigen::Dynamic, Eigen::ColMajor>;
919 const Eigen::Index vertex_count = static_cast<Eigen::Index>(input.size());
920 const Eigen::Map<const VertexMatrix, Eigen::Unaligned> input_matrix(&input.front().x, 4, vertex_count);
921 Eigen::Map<VertexMatrix, Eigen::Unaligned> output_matrix(&output.front().x, 4, vertex_count);
922 output_matrix.noalias() = ToEigen().transpose() * input_matrix;
923 }

◆ operator*() [1/2]

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

Multiply two 4x4 matrices.

Definition at line 862 of file mxvk_math.h.

862 {
863 Mat4D out;
864 for (int r = 0; r < 4; ++r) {
865 for (int c = 0; c < 4; ++c) {
866 for (int k = 0; k < 4; ++k) {
867 out.mat[r][c] += mat[r][k] * m.mat[k][c];
868 }
869 }
870 }
871 return out;
872 }

◆ operator*() [2/2]

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

Multiply two 4x4 matrices.

Definition at line 878 of file mxvk_math_eigen.hpp.

878 {
879 return FromEigen(ToEigen() * m.ToEigen());
880 }

◆ operator*=() [1/2]

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

Multiply this matrix by another matrix in place.

Definition at line 875 of file mxvk_math.h.

875 {
876 *this = *this * m;
877 return *this;
878 }

◆ operator*=() [2/2]

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

Multiply this matrix by another matrix in place.

Definition at line 883 of file mxvk_math_eigen.hpp.

883 {
884 *this = *this * m;
885 return *this;
886 }

◆ operator+() [1/2]

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

Add two matrices component-wise.

Definition at line 851 of file mxvk_math.h.

851 {
852 Mat4D out;
853 for (int r = 0; r < 4; ++r) {
854 for (int c = 0; c < 4; ++c) {
855 out.mat[r][c] = mat[r][c] + m.mat[r][c];
856 }
857 }
858 return out;
859 }

◆ operator+() [2/2]

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

Add two matrices component-wise.

Definition at line 873 of file mxvk_math_eigen.hpp.

873 {
874 return FromEigen(ToEigen() + m.ToEigen());
875 }

◆ 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 826 of file mxvk_math.h.

826 {
827 mat[0][0] = m00;
828 mat[0][1] = m01;
829 mat[0][2] = m02;
830 mat[0][3] = m03;
831 mat[1][0] = m10;
832 mat[1][1] = m11;
833 mat[1][2] = m12;
834 mat[1][3] = m13;
835 mat[2][0] = m20;
836 mat[2][1] = m21;
837 mat[2][2] = m22;
838 mat[2][3] = m23;
839 mat[3][0] = m30;
840 mat[3][1] = m31;
841 mat[3][2] = m32;
842 mat[3][3] = m33;
843 }

◆ 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 863 of file mxvk_math_eigen.hpp.

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

Member Data Documentation

◆ mat

float mxvk::Mat4D::mat {}

Matrix elements indexed as row, column.

Definition at line 815 of file mxvk_math.h.

815{};

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