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