16 #ifndef MATHFU_MATRIX_4X4_SIMD_H_
17 #define MATHFU_MATRIX_4X4_SIMD_H_
21 #ifdef MATHFU_COMPILE_WITH_SIMD
22 #include "vectorial/simd4x4f.h"
32 #ifdef MATHFU_COMPILE_WITH_SIMD
34 static const Vector<float, 4> kAffineWColumn(0.0f, 0.0f, 0.0f, 1.0f);
38 class Matrix<float, 4> {
42 inline Matrix<float, 4>(
const Matrix<float, 4>& m) {
43 data_.simd_matrix.x = m.
data_.simd_matrix.x;
44 data_.simd_matrix.y = m.
data_.simd_matrix.y;
45 data_.simd_matrix.z = m.
data_.simd_matrix.z;
46 data_.simd_matrix.w = m.
data_.simd_matrix.w;
49 explicit inline Matrix<float, 4>(
const float& s) {
50 simd4f v = simd4f_create(s, s, s, s);
51 data_.simd_matrix = simd4x4f_create(v, v, v, v);
54 inline Matrix<float, 4>(
const float& s00,
const float& s10,
const float& s20,
55 const float& s30,
const float& s01,
const float& s11,
56 const float& s21,
const float& s31,
const float& s02,
57 const float& s12,
const float& s22,
const float& s32,
58 const float& s03,
const float& s13,
const float& s23,
60 data_.simd_matrix = simd4x4f_create(
61 simd4f_create(s00, s10, s20, s30), simd4f_create(s01, s11, s21, s31),
62 simd4f_create(s02, s12, s22, s32), simd4f_create(s03, s13, s23, s33));
65 explicit inline Matrix<float, 4>(
const float* m) {
67 simd4x4f_create(simd4f_create(m[0], m[1], m[2], m[3]),
68 simd4f_create(m[4], m[5], m[6], m[7]),
69 simd4f_create(m[8], m[9], m[10], m[11]),
70 simd4f_create(m[12], m[13], m[14], m[15]));
73 inline Matrix<float, 4>(
const Vector<float, 4>& column0,
74 const Vector<float, 4>& column1,
75 const Vector<float, 4>& column2,
76 const Vector<float, 4>& column3) {
77 #if defined(MATHFU_COMPILE_WITH_PADDING)
78 data_.simd_matrix = simd4x4f_create(column0.data_.simd, column1.data_.simd,
79 column2.data_.simd, column3.data_.simd);
81 data_.simd_matrix = simd4x4f_create(
82 simd4f_create(column0[0], column0[1], column0[2], column0[3]),
83 simd4f_create(column1[0], column1[1], column1[2], column1[3]),
84 simd4f_create(column2[0], column2[1], column2[2], column2[3]),
85 simd4f_create(column3[0], column3[1], column3[2], column3[3]));
86 #endif // defined(MATHFU_COMPILE_WITH_PADDING)
89 explicit inline Matrix(
const VectorPacked<float, 4>*
const vectors) {
90 data_.simd_matrix.x = simd4f_uload4(vectors[0].data);
91 data_.simd_matrix.y = simd4f_uload4(vectors[1].data);
92 data_.simd_matrix.z = simd4f_uload4(vectors[2].data);
93 data_.simd_matrix.w = simd4f_uload4(vectors[3].data);
96 inline const float&
operator()(
const int i,
const int j)
const {
97 return FindElem(i, FindColumn(j));
100 inline float&
operator()(
const int i,
const int j) {
101 return FindElem(i, FindColumn(j));
104 inline const float&
operator()(
const int i)
const {
110 inline const float&
operator[](
const int i)
const {
111 const int col = i / 4;
112 const int row = i % 4;
113 return FindElem(row, FindColumn(col));
117 const int col = i / 4;
118 const int row = i % 4;
119 return FindElem(row, FindColumn(col));
122 inline void Pack(VectorPacked<float, 4>*
const vector)
const {
123 simd4f_ustore4(data_.simd_matrix.x, vector[0].data);
124 simd4f_ustore4(data_.simd_matrix.y, vector[1].data);
125 simd4f_ustore4(data_.simd_matrix.z, vector[2].data);
126 simd4f_ustore4(data_.simd_matrix.w, vector[3].data);
129 inline Matrix<float, 4>
operator-()
const {
130 Matrix<float, 4> m(0.f);
131 simd4x4f_sub(&m.data_.simd_matrix, &data_.simd_matrix,
132 &m.
data_.simd_matrix);
136 inline Matrix<float, 4>
operator+(
const Matrix<float, 4>& m)
const {
137 Matrix<float, 4> return_m;
138 simd4x4f_add(&data_.simd_matrix, &m.data_.simd_matrix,
139 &return_m.data_.simd_matrix);
143 inline Matrix<float, 4>
operator-(
const Matrix<float, 4>& m)
const {
144 Matrix<float, 4> return_m;
145 simd4x4f_sub(&data_.simd_matrix, &m.data_.simd_matrix,
146 &return_m.data_.simd_matrix);
150 inline Matrix<float, 4>
operator*(
const float& s)
const {
151 Matrix<float, 4> m(s);
152 simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix,
153 &m.
data_.simd_matrix);
157 inline Matrix<float, 4>
operator/(
const float& s)
const {
158 Matrix<float, 4> m(1 / s);
159 simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix,
160 &m.
data_.simd_matrix);
164 inline Vector<float, 3>
operator*(
const Vector<float, 3>& v)
const {
165 Vector<float, 3> return_v;
167 #ifdef MATHFU_COMPILE_WITH_PADDING
168 temp_v.simd = v.data_.simd;
169 temp_v.float_array[3] = 1;
170 simd4x4f_matrix_vector_mul(&data_.simd_matrix, &temp_v.simd,
171 &return_v.
data_.simd);
172 return_v *= (1 / return_v.data_.float_array[3]);
174 temp_v.simd = simd4f_create(v[0], v[1], v[2], 1.0f);
175 simd4x4f_matrix_vector_mul(&data_.simd_matrix, &temp_v.simd, &temp_v.simd);
176 simd4f_mul(temp_v.simd, simd4f_splat(temp_v.float_array[3]));
177 MATHFU_VECTOR3_STORE3(temp_v.simd, return_v.data_);
178 #endif // MATHFU_COMPILE_WITH_PADDING
182 inline Vector<float, 4>
operator*(
const Vector<float, 4>& v)
const {
183 Vector<float, 4> return_v;
184 simd4x4f_matrix_vector_mul(&data_.simd_matrix, &v.
data_.simd,
185 &return_v.data_.simd);
189 inline Vector<float, 4> VecMatTimes(
const Vector<float, 4>& v)
const {
190 return Vector<float, 4>(
191 simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.x),
192 simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.y),
193 simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.z),
194 simd4f_dot3_scalar(v.data_.simd, data_.simd_matrix.w));
197 inline Matrix<float, 4>
operator*(
const Matrix<float, 4>& m)
const {
198 Matrix<float, 4> return_m;
199 simd4x4f_matrix_mul(&data_.simd_matrix, &m.data_.simd_matrix,
200 &return_m.data_.simd_matrix);
204 inline Matrix<float, 4>
Inverse()
const {
205 Matrix<float, 4> return_m;
206 simd4x4f_inverse(&data_.simd_matrix, &return_m.data_.simd_matrix);
211 Matrix<float, 4, 4>*
const inverse)
const {
212 return fabs(simd4f_get_x(simd4x4f_inverse(&data_.simd_matrix,
213 &inverse->data_.simd_matrix))) >=
219 inline Matrix<float, 4, 4>
Transpose()
const {
220 Matrix<float, 4, 4> transpose;
221 simd4x4f_transpose(&data_.simd_matrix, &transpose.data_.simd_matrix);
226 Vector<float, 3> return_v;
227 MATHFU_VECTOR3_STORE3(FindColumn(3).simd, return_v.data_);
231 inline Matrix<float, 4>&
operator+=(
const Matrix<float, 4>& m) {
232 simd4x4f_add(&data_.simd_matrix, &m.data_.simd_matrix, &data_.simd_matrix);
236 inline Matrix<float, 4>&
operator-=(
const Matrix<float, 4>& m) {
237 simd4x4f_sub(&data_.simd_matrix, &m.data_.simd_matrix, &data_.simd_matrix);
241 inline Matrix<float, 4>&
operator*=(
const float& s) {
242 Matrix<float, 4> m(s);
243 simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix, &data_.simd_matrix);
247 inline Matrix<float, 4>&
operator/=(
const float& s) {
248 Matrix<float, 4> m(1 / s);
249 simd4x4f_mul(&m.data_.simd_matrix, &data_.simd_matrix, &data_.simd_matrix);
253 inline Matrix<float, 4>
operator*=(
const Matrix<float, 4>& m) {
254 Matrix<float, 4> copy_of_this(*
this);
255 simd4x4f_matrix_mul(©_of_this.data_.simd_matrix, &m.data_.simd_matrix,
260 template <
typename CompatibleT>
261 static inline Matrix<float, 4>
FromType(
const CompatibleT& compatible) {
262 return FromTypeHelper<float, 4, 4, CompatibleT>(compatible);
265 template <
typename CompatibleT>
266 static inline CompatibleT
ToType(
const Matrix<float, 4>& m) {
267 return ToTypeHelper<float, 4, 4, CompatibleT>(m);
270 static inline Matrix<float, 4>
OuterProduct(
const Vector<float, 4>& v1,
271 const Vector<float, 4>& v2) {
273 m.data_.simd_matrix =
274 simd4x4f_create(simd4f_mul(v1.data_.simd, simd4f_splat(v2[0])),
275 simd4f_mul(v1.data_.simd, simd4f_splat(v2[1])),
276 simd4f_mul(v1.data_.simd, simd4f_splat(v2[2])),
277 simd4f_mul(v1.data_.simd, simd4f_splat(v2[3])));
281 static inline Matrix<float, 4>
HadamardProduct(
const Matrix<float, 4>& m1,
282 const Matrix<float, 4>& m2) {
283 Matrix<float, 4> return_m;
284 simd4x4f_mul(&m1.data_.simd_matrix, &m2.data_.simd_matrix,
285 &return_m.data_.simd_matrix);
289 static inline Matrix<float, 4>
Identity() {
290 Matrix<float, 4> return_m;
291 simd4x4f_identity(&return_m.data_.simd_matrix);
296 const Vector<float, 3>& v) {
297 return Matrix<float, 4>(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, v[0], v[1],
301 static inline Matrix<float, 4>
FromScaleVector(
const Vector<float, 3>& v) {
302 return Matrix<float, 4>(v[0], 0, 0, 0, 0, v[1], 0, 0, 0, 0, v[2], 0, 0, 0,
307 return Matrix<float, 4>(m[0], m[1], m[2], 0, m[3], m[4], m[5], 0, m[6],
308 m[7], m[8], 0, 0, 0, 0, 1);
318 m.data_.simd_matrix.x = simd4f_uload4(&affine[0]);
319 m.data_.simd_matrix.y = simd4f_uload4(&affine[4]);
320 m.data_.simd_matrix.z = simd4f_uload4(&affine[8]);
321 m.data_.simd_matrix.w = simd4f_uload4(&kAffineWColumn[0]);
322 return m.Transpose();
334 const Matrix<float, 4> mt = m.Transpose();
335 simd4f_ustore4(mt.data_.simd_matrix.x, &affine[0]);
336 simd4f_ustore4(mt.data_.simd_matrix.y, &affine[4]);
337 simd4f_ustore4(mt.data_.simd_matrix.z, &affine[8]);
343 static inline Matrix<float, 4, 4>
Perspective(
float fovy,
float aspect,
344 float znear,
float zfar,
345 float handedness = 1.0f) {
346 return PerspectiveHelper(fovy, aspect, znear, zfar, handedness);
351 static inline Matrix<float, 4, 4>
Ortho(
float left,
float right,
float bottom,
352 float top,
float znear,
float zfar,
353 float handedness = 1.0f) {
354 return OrthoHelper(left, right, bottom, top, znear, zfar, handedness);
364 static inline Matrix<float, 4, 4>
LookAt(
const Vector<float, 3>& at,
365 const Vector<float, 3>& eye,
366 const Vector<float, 3>& up,
367 float handedness = -1.0f) {
368 return LookAtHelper(at, eye, up, handedness);
382 static inline Vector<float, 3>
UnProject(
383 const Vector<float, 3>& window_coord,
384 const Matrix<float, 4, 4>& model_view,
385 const Matrix<float, 4, 4>& projection,
const float window_width,
386 const float window_height) {
387 Vector<float, 3> result;
388 UnProjectHelper(window_coord, model_view, projection, window_width,
389 window_height, result);
395 static const int kRows = 4;
404 inline const Simd4fUnion& FindColumn(
const int i)
const {
405 return data_.simd4f_union_array[i];
408 inline Simd4fUnion& FindColumn(
const int i) {
409 return data_.simd4f_union_array[i];
412 static inline const float& FindElem(
const int i,
const Simd4fUnion& column) {
413 return column.float_array[i];
416 static inline float& FindElem(
const int i, Simd4fUnion& column) {
417 return column.float_array[i];
423 simd4x4f simd_matrix;
424 Simd4fUnion simd4f_union_array[4];
425 float float_array[16];
429 inline Matrix<float, 4>
operator*(
const float& s,
const Matrix<float, 4>& m) {
433 inline Vector<float, 4>
operator*(
const Vector<float, 4>& v,
434 const Matrix<float, 4>& m) {
435 return m.VecMatTimes(v);
438 #endif // MATHFU_COMPILE_WITH_SIMD
441 #endif // MATHFU_MATRIX_4X4_SIMD_H_
Matrix< T, rows, columns > Inverse() const
Calculate the inverse of this Matrix.
Definition: matrix.h:511
Vector< T, 3 > TranslationVector3D() const
Get the 3-dimensional translation of a 3-dimensional affine transform.
Definition: matrix.h:563
static Matrix< T, 4, 4 > LookAt(const Vector< T, 3 > &at, const Vector< T, 3 > &eye, const Vector< T, 3 > &up, T handedness=-1)
Create a 3-dimensional camera Matrix.
Definition: matrix.h:807
Matrix()
Construct a Matrix of uninitialized values.
Definition: matrix.h:150
static Matrix< T, 4 > FromAffineTransform(const Matrix< T, 4, 3 > &affine)
Constructs a Matrix<float, 4> from an AffineTransform.
Definition: matrix.h:696
static const int kElements
Total number of elements in the matrix.
Definition: matrix.h:853
Matrix< T, rows, columns > & operator*=(const T &s)
Multiply each element of this Matrix with a scalar (in-place).
Definition: matrix.h:483
static Matrix< T, 4, 4 > Ortho(T left, T right, T bottom, T top, T znear, T zfar, T handedness=1)
Create a 4x4 orthographic Matrix.
Definition: matrix.h:793
static float GetDeterminantThreshold()
Minimum absolute value of the determinant of an invertible float Matrix.
Definition: matrix.h:1186
bool InverseWithDeterminantCheck(Matrix< T, rows, columns > *const inverse) const
Calculate the inverse of this Matrix.
Definition: matrix.h:532
#define MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
Macro which defines the new and delete for MathFu classes.
Definition: utilities.h:600
static Matrix< T, 4 > FromRotationMatrix(const Matrix< T, 3 > &m)
Create a 4x4 Matrix from a 3x3 rotation Matrix.
Definition: matrix.h:675
static Matrix< T, rows > FromScaleVector(const Vector< T, rows-1 > &v)
Create a square Matrix with the diagonal component set to v.
Definition: matrix.h:659
MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE T data_[d]
Elements of the vector.
Definition: vector.h:495
static Vector< T, 3 > UnProject(const Vector< T, 3 > &window_coord, const Matrix< T, 4, 4 > &model_view, const Matrix< T, 4, 4 > &projection, const float window_width, const float window_height)
Get the 3D position in object space from a window coordinate.
Definition: matrix.h:825
Matrix< T, rows, columns > operator+(const Matrix< T, rows, columns > &m) const
Add a Matrix to this Matrix.
Definition: matrix.h:388
Matrix< T, rows, columns > & operator+=(const Matrix< T, rows, columns > &m)
Add a Matrix to this Matrix (in-place).
Definition: matrix.h:449
static Matrix< T, rows, columns > HadamardProduct(const Matrix< T, rows, columns > &m1, const Matrix< T, rows, columns > &m2)
Calculate the hadamard / component-wise product of two matrices.
Definition: matrix.h:619
static Matrix< T, rows, columns > OuterProduct(const Vector< T, rows > &v1, const Vector< T, columns > &v2)
Calculate the outer product of two Vectors.
Definition: matrix.h:609
Matrix< T, rows, columns > operator*(const T &s) const
Multiply each element of this Matrix with a scalar.
Definition: matrix.h:422
const T & operator()(const int row, const int column) const
Access an element of the matrix.
Definition: matrix.h:296
Vector< T, d > operator*(const Vector< T, d > &lhs, const Vector< T, d > &rhs)
Multiply a vector by another Vector.
Definition: vector.h:589
static Matrix< T, rows, columns > FromType(const CompatibleT &compatible)
Load from any byte-wise compatible external matrix.
Definition: matrix.h:585
Matrix< float, 4, 3 > AffineTransform
A typedef representing a 4x3 float affine transformation. Since the last row ('w' row) of an affine t...
Definition: matrix.h:1541
Matrix class and functions.
static const int kColumns
Number of columns in the matrix.
Definition: matrix.h:851
static Matrix< T, 4, 4 > Perspective(T fovy, T aspect, T znear, T zfar, T handedness=1)
Create a 4x4 perspective Matrix.
Definition: matrix.h:778
static CompatibleT ToType(const Matrix< T, rows, columns > &m)
Load into any byte-wise compatible external matrix.
Definition: matrix.h:602
const T & operator[](const int i) const
Access an element of the Matrix.
Definition: matrix.h:328
Matrix< T, rows, columns > & operator-=(const Matrix< T, rows, columns > &m)
Subtract a Matrix from this Matrix (in-place).
Definition: matrix.h:458
static Matrix< T, rows, columns > Identity()
Calculate the identity Matrix.
Definition: matrix.h:627
void Pack(VectorPacked< T, rows > *const vector) const
Pack the matrix to an array of "rows" element vectors, one vector per matrix column.
Definition: matrix.h:357
Matrix< T, rows, columns > & operator/=(const T &s)
Divide each element of this Matrix by a scalar (in-place).
Definition: matrix.h:491
Matrix< T, rows, columns > operator-() const
Negate this Matrix.
Definition: matrix.h:380
Matrix< T, rows, columns > operator/(const T &s) const
Divide each element of this Matrix with a scalar.
Definition: matrix.h:430
static Matrix< T, 3 > FromTranslationVector(const Vector< T, 2 > &v)
Create a 3x3 translation Matrix from a 2-dimensional Vector.
Definition: matrix.h:637
static Matrix< T, 4, 3 > ToAffineTransform(const Matrix< T, 4 > &m)
Converts a Matrix<float, 4> into an AffineTransform.
Definition: matrix.h:711
Matrix< T, columns, rows > Transpose() const
Calculate the transpose of this Matrix.
Definition: matrix.h:540
static const int kRows
Number of rows in the matrix.
Definition: matrix.h:849