libs/base/src/base/mat4.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "base/vec3.h" | ||
| 4 | #include "base/vec4.h" | ||
| 5 | #include "base/angle.h" | ||
| 6 | #include "base/axisangle.h" | ||
| 7 | |||
| 8 | |||
| 9 | namespace eu | ||
| 10 | { | ||
| 11 | /** \addtogroup math | ||
| 12 | * @{ | ||
| 13 | */ | ||
| 14 | |||
| 15 | struct Q; | ||
| 16 | |||
| 17 | /// 4x4 matrix | ||
| 18 | struct m4 | ||
| 19 | { | ||
| 20 | /// Create a new matrix from column major format. | ||
| 21 | [[nodiscard]] static m4 from_col_major( | ||
| 22 | float t00, float t01, float t02, float t03, | ||
| 23 | float t10, float t11, float t12, float t13, | ||
| 24 | float t20, float t21, float t22, float t23, | ||
| 25 | float t30, float t31, float t32, float t33); | ||
| 26 | |||
| 27 | /// Create a new matrix from row major format. | ||
| 28 | 28 | [[nodiscard]] constexpr static m4 from_row_major( | |
| 29 | float t00, float t10, float t20, float t30, | ||
| 30 | float t01, float t11, float t21, float t31, | ||
| 31 | float t02, float t12, float t22, float t32, | ||
| 32 | float t03, float t13, float t23, float t33) | ||
| 33 | { | ||
| 34 | return { | ||
| 35 | t00, t01, t02, t03, | ||
| 36 | t10, t11, t12, t13, | ||
| 37 | t20, t21, t22, t23, | ||
| 38 | 28 | t30, t31, t32, t33}; | |
| 39 | } | ||
| 40 | |||
| 41 | /// Create a matrix from the major, aka the diagonal. | ||
| 42 | /// @see from_scalar | ||
| 43 | [[nodiscard]] static m4 from_major(const v4 &major); | ||
| 44 | |||
| 45 | /// Create a matrix from a single scalar. | ||
| 46 | /// @see from_major | ||
| 47 | [[nodiscard]] constexpr static m4 from_scalar(float scalar) | ||
| 48 | { | ||
| 49 | const float z = 0; | ||
| 50 | return from_row_major( | ||
| 51 | scalar, z, z, z, | ||
| 52 | z, scalar, z, z, | ||
| 53 | z, z, scalar, z, | ||
| 54 | z, z, z, scalar); | ||
| 55 | } | ||
| 56 | |||
| 57 | /// Create a translation matrix. | ||
| 58 | [[nodiscard]] static m4 from_translation(const v3 &v); | ||
| 59 | |||
| 60 | /// Create a rotation matrix, around the X axis. | ||
| 61 | [[nodiscard]] static m4 from_rot_x(const An &a); | ||
| 62 | |||
| 63 | /// Create a rotation matrix, around the Y axis. | ||
| 64 | [[nodiscard]] static m4 from_rot_y(const An &a); | ||
| 65 | |||
| 66 | /// Create a rotation matrix, around the Z axis. | ||
| 67 | [[nodiscard]] static m4 from_rot_z(const An &a); | ||
| 68 | |||
| 69 | /// Create a rotation matrix, from an axis angle. | ||
| 70 | [[nodiscard]] static m4 from(const AA &aa); | ||
| 71 | |||
| 72 | /// Create a rotation matrix, from a quaternion. | ||
| 73 | [[nodiscard]] static std::optional<m4> from(const Q& q); | ||
| 74 | |||
| 75 | /// Create an orthographic projection matrix. | ||
| 76 | /// Also known as a `clip_from_view` transformation. | ||
| 77 | /// Clip Space is in OpenGL NDC (-1 to +1) z range. | ||
| 78 | /// @param l the left side | ||
| 79 | /// @param r the right side | ||
| 80 | /// @param t the up side | ||
| 81 | /// @param b the down side | ||
| 82 | /// @param n near | ||
| 83 | /// @param f far | ||
| 84 | [[nodiscard]] static m4 create_ortho_lrud(float l, float r, float t, float b, float n, float f); | ||
| 85 | |||
| 86 | /// Create a perspective projection matrix. | ||
| 87 | [[nodiscard]] static m4 create_perspective(const An &fov, float aspect_ratio, float near, float far); | ||
| 88 | |||
| 89 | /// Get a direct pointer to the data in column major format, for API integration. | ||
| 90 | float *get_column_major_data_ptr(); | ||
| 91 | |||
| 92 | /// Get a direct pointer to the const data in column major format, for API integration. | ||
| 93 | [[nodiscard]] const float* get_column_major_data_ptr() const; | ||
| 94 | |||
| 95 | /// Invert the current matrix. | ||
| 96 | /// @see get_inverted | ||
| 97 | bool invert(); | ||
| 98 | |||
| 99 | /// Return the inverted matrix | ||
| 100 | /// @see invert | ||
| 101 | [[nodiscard]] m4 get_inverted() const; | ||
| 102 | |||
| 103 | /// Return a single value given a row and column. | ||
| 104 | [[nodiscard]] float get(int row, int col) const; | ||
| 105 | |||
| 106 | /// Get a transformed vec4. | ||
| 107 | [[nodiscard]] v4 get_transformed(const v4 &p) const; | ||
| 108 | |||
| 109 | /// Get a transformed vec3 assuming it's a point | ||
| 110 | [[nodiscard]] v3 get_transformed_point(const v3 &p) const; | ||
| 111 | |||
| 112 | /// Get a transformed vec3, assuming it's a normal vector | ||
| 113 | [[nodiscard]] v3 get_transformed_vec(const v3 &p) const; | ||
| 114 | |||
| 115 | /// Get a transformed unit3 | ||
| 116 | [[nodiscard]] n3 get_transformed_vec(const n3 &p) const; | ||
| 117 | |||
| 118 | /// Get a row as a vec4. | ||
| 119 | [[nodiscard]] v4 get_row(int r) const; | ||
| 120 | |||
| 121 | /// Get a column as vec4. | ||
| 122 | [[nodiscard]] v4 get_column(int c) const; | ||
| 123 | |||
| 124 | /// Combine this with a translation matrix. | ||
| 125 | [[nodiscard]] m4 get_translated(const v3 &t) const; | ||
| 126 | |||
| 127 | /// Combine this with a rotation matrix. | ||
| 128 | [[nodiscard]] m4 get_rotated(const AA &aa) const; | ||
| 129 | |||
| 130 | /// Get the current translation of the transformation matrix. | ||
| 131 | [[nodiscard]] v3 get_translation() const; | ||
| 132 | |||
| 133 | /// Get the major vector. | ||
| 134 | [[nodiscard]] v4 get_major() const; | ||
| 135 | |||
| 136 | /// Get the local X axis. | ||
| 137 | [[nodiscard]] n3 get_x_axis() const; | ||
| 138 | |||
| 139 | /// Get the local Y axis. | ||
| 140 | [[nodiscard]] n3 get_y_axis() const; | ||
| 141 | |||
| 142 | /// Get the local Z azis. | ||
| 143 | [[nodiscard]] n3 get_z_axis() const; | ||
| 144 | |||
| 145 | /// Gets the transpose of a matrix. | ||
| 146 | /// If the matrix is a rotation matrix, then the transpose is guaranteed to be the inverse of the matrix. | ||
| 147 | [[nodiscard]] m4 get_transposed() const; | ||
| 148 | |||
| 149 | |||
| 150 | void operator+=(const m4 &rhs); | ||
| 151 | void operator-=(const m4 &rhs); | ||
| 152 | |||
| 153 | private: | ||
| 154 | /// stored in column major | ||
| 155 | float data[16]; | ||
| 156 | |||
| 157 | m4() = default; | ||
| 158 | |||
| 159 | 41 | constexpr m4( | |
| 160 | float t00, float t01, float t02, float t03, | ||
| 161 | float t10, float t11, float t12, float t13, | ||
| 162 | float t20, float t21, float t22, float t23, | ||
| 163 | float t30, float t31, float t32, float t33) | ||
| 164 | 41 | : data{ | |
| 165 | t00, t01, t02, t03, | ||
| 166 | t10, t11, t12, t13, | ||
| 167 | t20, t21, t22, t23, | ||
| 168 | t30, t31, t32, t33} | ||
| 169 | { | ||
| 170 | 41 | } | |
| 171 | }; | ||
| 172 | |||
| 173 | /// The identity matrix. | ||
| 174 | constexpr m4 m4_identity = m4::from_scalar(1); | ||
| 175 | |||
| 176 | /// Convert a matrix to a string representation, prefer fmt. | ||
| 177 | std::string string_from(const m4 &m); | ||
| 178 | |||
| 179 | m4 operator+(const m4 &lhs, const m4 &rhs); | ||
| 180 | m4 operator-(const m4 &lhs, const m4 &rhs); | ||
| 181 | m4 operator*(const m4 &lhs, const m4 &rhs); | ||
| 182 | v4 operator*(const m4 &lhs, const v4 &rhs); | ||
| 183 | |||
| 184 | /** @}*/ | ||
| 185 | |||
| 186 | ADD_CATCH_FORMATTER_DEF(m4) | ||
| 187 | } | ||
| 188 | |||
| 189 | 2 | ADD_DEFAULT_FORMATTER(eu::m4, std::string, eu::string_from); | |
| 190 |