32#ifndef DVD_MATH_MATRICES_INL_
33#define DVD_MATH_MATRICES_INL_
37# define MakeShuffleMask(x,y,z,w) (x | y << 2 | z << 4 | w << 6)
40# define VecSwizzle(vec, x,y,z,w) _mm_shuffle_ps(vec, vec, MakeShuffleMask(x,y,z,w))
41# define VecSwizzle1(vec, x) _mm_shuffle_ps(vec, vec, MakeShuffleMask(x,x,x,x))
43# define VecSwizzle_0101(vec) _mm_movelh_ps(vec, vec)
44# define VecSwizzle_2323(vec) _mm_movehl_ps(vec, vec)
45# define VecSwizzle_0022(vec) _mm_moveldup_ps(vec)
46# define VecSwizzle_1133(vec) _mm_movehdup_ps(vec)
49# define VecShuffle(vec1, vec2, x,y,z,w) _mm_shuffle_ps(vec1, vec2, MakeShuffleMask(x,y,z,w))
51# define VecShuffle_0101(vec1, vec2) _mm_movelh_ps(vec1, vec2)
52# define VecShuffle_2323(vec1, vec2) _mm_movehl_ps(vec2, vec1)
59 const __m128 row1 = _mm_load_ps( &B[0] );
60 const __m128 row2 = _mm_load_ps( &B[4] );
61 const __m128 row3 = _mm_load_ps( &B[8] );
62 const __m128 row4 = _mm_load_ps( &B[12] );
63 for (
U8 i = 0u; i < 4u; ++i )
65 const __m128 brod1 = _mm_set1_ps( A[4 * i + 0] );
66 const __m128 brod2 = _mm_set1_ps( A[4 * i + 1] );
67 const __m128 brod3 = _mm_set1_ps( A[4 * i + 2] );
68 const __m128 brod4 = _mm_set1_ps( A[4 * i + 3] );
69 const __m128 row = _mm_add_ps( _mm_add_ps( _mm_mul_ps( brod1, row1 ),
70 _mm_mul_ps( brod2, row2 ) ),
71 _mm_add_ps( _mm_mul_ps( brod3, row3 ),
72 _mm_mul_ps( brod4, row4 ) ) );
73 _mm_store_ps( &C[4 * i], row );
81 const auto& bReg = B._reg;
82 __m128 result = _mm_mul_ps( _mm_broadcast_ss( &a[0] ), bReg[0]._reg );
83 result = _mm_add_ps( result, _mm_mul_ps( _mm_broadcast_ss( &a[1] ), bReg[1]._reg ) );
84 result = _mm_add_ps( result, _mm_mul_ps( _mm_broadcast_ss( &a[2] ), bReg[2]._reg ) );
85 result = _mm_add_ps( result, _mm_mul_ps( _mm_broadcast_ss( &a[3] ), bReg[3]._reg ) );
94 const auto& bReg = B.
_reg;
95 __m128 result = _mm_mul_ps( _mm_shuffle_ps( a, a, 0x00 ), bReg[0]._reg );
96 result = _mm_add_ps( result, _mm_mul_ps( _mm_shuffle_ps( a, a, 0x55 ), bReg[1]._reg ) );
97 result = _mm_add_ps( result, _mm_mul_ps( _mm_shuffle_ps( a, a, 0xaa ), bReg[2]._reg ) );
98 result = _mm_add_ps( result, _mm_mul_ps( _mm_shuffle_ps( a, a, 0xff ), bReg[3]._reg ) );
108 const __m128 t0 =
VecShuffle_0101( inM._reg[0]._reg, inM._reg[1]._reg );
109 const __m128 t1 =
VecShuffle_2323( inM._reg[0]._reg, inM._reg[1]._reg );
116 r._reg[3] =
SimdVector<F32>( _mm_add_ps( r._reg[3]._reg, _mm_mul_ps( r._reg[1]._reg,
VecSwizzle1( inM._reg[3]._reg, 1 ) ) ) );
117 r._reg[3] =
SimdVector<F32>( _mm_add_ps( r._reg[3]._reg, _mm_mul_ps( r._reg[2]._reg,
VecSwizzle1( inM._reg[3]._reg, 2 ) ) ) );
118 r._reg[3] =
SimdVector<F32>( _mm_sub_ps( _mm_setr_ps( 0.f, 0.f, 0.f, 1.f ), r._reg[3]._reg ) );
127 return _mm_add_ps( _mm_mul_ps( vec1,
VecSwizzle(
vec2, 0, 0, 3, 3 ) ),
133 return _mm_sub_ps( _mm_mul_ps(
VecSwizzle( vec1, 3, 0, 3, 0 ),
vec2 ),
140 return _mm_sub_ps( _mm_mul_ps( vec1,
VecSwizzle(
vec2, 3, 3, 0, 0 ) ),
148 const __m128 t0 =
VecShuffle_0101( inM._reg[0]._reg, inM._reg[1]._reg );
149 const __m128 t1 =
VecShuffle_2323( inM._reg[0]._reg, inM._reg[1]._reg );
150 r._reg[0]._reg =
VecShuffle( t0, inM._reg[2]._reg, 0, 2, 0, 3 );
151 r._reg[1]._reg =
VecShuffle( t0, inM._reg[2]._reg, 1, 3, 1, 3 );
152 r._reg[2]._reg =
VecShuffle( t1, inM._reg[2]._reg, 0, 2, 2, 3 );
154 __m128 sizeSqr = _mm_mul_ps( r._reg[0]._reg, r._reg[0]._reg );
155 sizeSqr = _mm_add_ps( sizeSqr, _mm_mul_ps( r._reg[1]._reg, r._reg[1]._reg ) );
156 sizeSqr = _mm_add_ps( sizeSqr, _mm_mul_ps( r._reg[2]._reg, r._reg[2]._reg ) );
159 const __m128 one = _mm_set1_ps( 1.f );
161 const __m128 rSizeSqr = _mm_blendv_ps(
162 _mm_div_ps( one, sizeSqr ),
164 _mm_cmplt_ps( sizeSqr, _mm_set1_ps( std::numeric_limits<F32>::epsilon() ) )
173 r._reg[3] =
SimdVector<F32>( _mm_add_ps( r._reg[3]._reg, _mm_mul_ps( r._reg[1]._reg,
VecSwizzle1( inM._reg[3]._reg, 1 ) ) ) );
174 r._reg[3] =
SimdVector<F32>( _mm_add_ps( r._reg[3]._reg, _mm_mul_ps( r._reg[2]._reg,
VecSwizzle1( inM._reg[3]._reg, 2 ) ) ) );
175 r._reg[3] =
SimdVector<F32>( _mm_sub_ps( _mm_setr_ps( 0.f, 0.f, 0.f, 1.f ), r._reg[3]._reg ) );
185 const __m128 A =
VecShuffle_0101( inM._reg[0]._reg, inM._reg[1]._reg );
186 const __m128 C =
VecShuffle_2323( inM._reg[0]._reg, inM._reg[1]._reg );
187 const __m128 B =
VecShuffle_0101( inM._reg[2]._reg, inM._reg[3]._reg );
188 const __m128 D =
VecShuffle_2323( inM._reg[2]._reg, inM._reg[3]._reg );
190 const __m128 detA = _mm_set1_ps( inM.m[0][0] * inM.m[1][1] - inM.m[0][1] * inM.m[1][0] );
191 const __m128 detC = _mm_set1_ps( inM.m[0][2] * inM.m[1][3] - inM.m[0][3] * inM.m[1][2] );
192 const __m128 detB = _mm_set1_ps( inM.m[2][0] * inM.m[3][1] - inM.m[2][1] * inM.m[3][0] );
193 const __m128 detD = _mm_set1_ps( inM.m[2][2] * inM.m[3][3] - inM.m[2][3] * inM.m[3][2] );
197 __m128 detSub = _mm_sub_ps(
198 _mm_mul_ps(
VecShuffle( inM._reg[0]._reg, inM._reg[2]._reg, 0, 2, 0, 2 ),
VecShuffle( inM._reg[1]._reg, inM._reg[3]._reg, 1, 3, 1, 3 ) ),
199 _mm_mul_ps(
VecShuffle( inM._reg[0]._reg, inM._reg[2]._reg, 1, 3, 1, 3 ),
VecShuffle( inM._reg[1]._reg, inM._reg[3]._reg, 0, 2, 0, 2 ) )
215 __m128 X_ = _mm_sub_ps( _mm_mul_ps( detD, A ),
Mat2Mul( B, D_C ) );
217 __m128 W_ = _mm_sub_ps( _mm_mul_ps( detA, D ),
Mat2Mul( C, A_B ) );
220 __m128 detM = _mm_mul_ps( detA, detD );
223 __m128 Y_ = _mm_sub_ps( _mm_mul_ps( detB, C ),
Mat2MulAdj( D, A_B ) );
225 __m128 Z_ = _mm_sub_ps( _mm_mul_ps( detC, B ),
Mat2MulAdj( A, D_C ) );
228 detM = _mm_add_ps( detM, _mm_mul_ps( detB, detC ) );
231 __m128 tr = _mm_mul_ps( A_B,
VecSwizzle( D_C, 0, 2, 1, 3 ) );
232 tr = _mm_hadd_ps( tr, tr );
233 tr = _mm_hadd_ps( tr, tr );
235 detM = _mm_sub_ps( detM, tr );
237 const __m128 adjSignMask = _mm_setr_ps( 1.f, -1.f, -1.f, 1.f );
239 const __m128 rDetM = _mm_div_ps( adjSignMask, detM );
241 X_ = _mm_mul_ps( X_, rDetM );
242 Y_ = _mm_mul_ps( Y_, rDetM );
243 Z_ = _mm_mul_ps( Z_, rDetM );
244 W_ = _mm_mul_ps( W_, rDetM );
247 r._reg[0]._reg =
VecShuffle( X_, Z_, 3, 1, 3, 1 );
248 r._reg[1]._reg =
VecShuffle( X_, Z_, 2, 0, 2, 0 );
249 r._reg[2]._reg =
VecShuffle( Y_, W_, 3, 1, 3, 1 );
250 r._reg[3]._reg =
VecShuffle( Y_, W_, 2, 0, 2, 0 );
269 return inM.getInverse();
293 : mat{
static_cast<T
>(m),
static_cast<T
>(m),
294 static_cast<T
>(m),
static_cast<T
>(m) }
301 U m2, U m3 ) noexcept
302 : mat{
static_cast<T
>(m0),
static_cast<T
>(m1),
303 static_cast<T
>(m2),
static_cast<T
>(m3) }
310 :
mat2( values[0], values[1],
311 values[2], values[3] )
348 return { mat[0] * v[0] + mat[1] * v[1],
349 mat[2] * v[0] + mat[3] * v[1] };
356 return { mat[0] * v[0] + mat[1] * v[1],
357 mat[2] * v[0] + mat[3] * v[1],
365 return { mat[0] * v[0] + mat[1] * v[1],
366 mat[2] * v[0] + mat[3] * v[1],
375 return mat2( mat[0] * B.mat[0] + mat[1] * B.mat[2], mat[0] * B.mat[1] + mat[1] * B.mat[3],
376 mat[2] * B.mat[0] + mat[3] * B.mat[2], mat[2] * B.mat[1] + mat[3] * B.mat[3] );
390 return mat2( mat[0] + B[0], mat[1] + B[1],
391 mat[2] + B[2], mat[3] + B[3] );
398 return mat2( mat[0] - B[0], mat[1] - B[1],
399 mat[2] - B[2], mat[3] - B[3] );
406 return *
this = *
this * B;
413 return *
this = *
this * B;
420 return *
this = *
this + B;
427 return *
this = *
this - B;
434 return mat2( *
this ) *= f;
441 return mat2( *
this ) /= f;
448 return mat2( *
this ) += f;
455 return mat2( *
this ) -= f;
462 for (
auto& val : _vec )
473 for (
auto& val : _vec )
484 for (
auto& val : _vec )
495 for (
auto& val : _vec )
505 for (
U8 i = 0; i < 4; ++i )
507 if ( !
COMPARE( mat[i], B.mat[i] ) )
518 for (
U8 i = 0; i < 4; ++i )
520 if ( !
COMPARE( mat[i], B.mat[i] ) )
532 for (
U8 i = 0; i < 4; ++i )
534 if ( !
COMPARE( mat[i], B.mat[i] ) )
546 for (
U8 i = 0; i < 4; ++i )
548 if ( !
COMPARE( mat[i], B.mat[i] ) )
559 for (
U8 i = 0; i < 4; ++i )
573 for (
U8 i = 0; i < 4; ++i )
610 return m[row][column];
616 return m[row][column];
623 mat[0] =
static_cast<T
>(m0);
624 mat[3] =
static_cast<T
>(m3);
625 mat[1] =
static_cast<T
>(m1);
626 mat[2] =
static_cast<T
>(m2);
633 if constexpr (
sizeof( T ) ==
sizeof( U ) )
635 std::memcpy( mat, matrix,
sizeof( U ) * 4 );
639 set( matrix[0], matrix[1],
640 matrix[2], matrix[3] );
655 set( matrix[0], matrix[1], matrix[3], matrix[4] );
662 set( matrix[0], matrix[1], matrix[4], matrix[5] );
669 _vec[index].set( value );
676 _vec[index].set( value );
683 _vec[index].set( x, y );
696 m[0][index] =
static_cast<T
>(value.x);
697 m[1][index] =
static_cast<T
>(value.y);
704 m[0][index] =
static_cast<T
>(value);
705 m[1][index] =
static_cast<T
>(value);
712 m[0][index] =
static_cast<T
>(x);
713 m[1][index] =
static_cast<T
>(y);
728 memset( mat, 0, 4 *
sizeof( T ) );
734 mat[0] =
static_cast<T
>(1);
735 mat[1] =
static_cast<T
>(0);
736 mat[2] =
static_cast<T
>(0);
737 mat[3] =
static_cast<T
>(1);
750 std::swap( m[0][0], B.m[0][0] );
751 std::swap( m[0][1], B.m[0][1] );
753 std::swap( m[1][0], B.m[1][0] );
754 std::swap( m[1][1], B.m[1][1] );
760 return mat[0] * mat[3] - mat[1] * mat[2];
766 return mat[0] + mat[1] + mat[2] + mat[3];
772 F32 idet =
static_cast<F32>(det());
776 set( mat[3] * idet, -mat[1] * idet,
777 -mat[2] * idet, mat[0] * idet );
856 : mat{
static_cast<T
>(m),
static_cast<T
>(m),
static_cast<T
>(m),
857 static_cast<T
>(m),
static_cast<T
>(m),
static_cast<T
>(m),
858 static_cast<T
>(m),
static_cast<T
>(m),
static_cast<T
>(m) }
866 U m6, U m7, U m8 ) noexcept
867 : mat{
static_cast<T
>(m0),
static_cast<T
>(m1),
static_cast<T
>(m2),
868 static_cast<T
>(m3),
static_cast<T
>(m4),
static_cast<T
>(m5),
869 static_cast<T
>(m6),
static_cast<T
>(m7),
static_cast<T
>(m8) }
876 :
mat3( values[0], values[1], values[2],
877 values[3], values[4], values[5],
878 values[6], values[7], values[8] )
885 :
mat3( B[0], B[1], 0,
887 0, 0, zeroFill ? 0 : 1 )
907 :
mat3( B[0], B[1], B[2],
921 const vec3<U> v = cross( z, d );
922 const F32 c = dot( z, d );
923 const F32 k = 1.0f / (1.0f + c);
925 set( v.
x * v.
x * k + c, v.
y * v.
x * k - v.
z, v.
z * v.
x * k + v.
y,
926 v.
x * v.
y * k + v.
z, v.
y * v.
y * k + c, v.
z * v.
y * k - v.
x,
927 v.
x * v.
z * k - v.
y, v.
y * v.
z * k + v.
x, v.
z * v.
z * k + c );
948 return vec3<U>( mat[0] * v[0] + mat[3] * v[1] + mat[6] * v[2],
949 mat[1] * v[0] + mat[4] * v[1] + mat[7] * v[2],
950 mat[2] * v[0] + mat[5] * v[1] + mat[8] * v[2] );
957 return vec4<U>( mat[0] * v[0] + mat[3] * v[1] + mat[6] * v[2],
958 mat[1] * v[0] + mat[4] * v[1] + mat[7] * v[2],
959 mat[2] * v[0] + mat[5] * v[1] + mat[8] * v[2],
967 return mat3( B.m[0][0] * m[0][0] + B.m[1][0] * m[0][1] + B.m[2][0] * m[0][2], B.m[0][1] * m[0][0] + B.m[1][1] * m[0][1] + B.m[2][1] * m[0][2], B.m[0][2] * m[0][0] + B.m[1][2] * m[0][1] + B.m[2][2] * m[0][2],
968 B.m[0][0] * m[1][0] + B.m[1][0] * m[1][1] + B.m[2][0] * m[1][2], B.m[0][1] * m[1][0] + B.m[1][1] * m[1][1] + B.m[2][1] * m[1][2], B.m[0][2] * m[1][0] + B.m[1][2] * m[1][1] + B.m[2][2] * m[1][2],
969 B.m[0][0] * m[2][0] + B.m[1][0] * m[2][1] + B.m[2][0] * m[2][2], B.m[0][1] * m[2][0] + B.m[1][1] * m[2][1] + B.m[2][1] * m[2][2], B.m[0][2] * m[2][0] + B.m[1][2] * m[2][1] + B.m[2][2] * m[2][2] );
983 return mat3( mat[0] + B[0], mat[1] + B[1], mat[2] + B[2],
984 mat[3] + B[3], mat[4] + B[4], mat[5] + B[5],
985 mat[6] + B[6], mat[7] + B[7], mat[8] + B[8] );
992 return mat3( mat[0] - B[0], mat[1] - B[1], mat[2] - B[2],
993 mat[3] - B[3], mat[4] - B[4], mat[5] - B[5],
994 mat[6] - B[6], mat[7] - B[7], mat[8] - B[8] );
1001 return *
this = *
this * B;
1004 template<
typename T>
1005 template<
typename U>
1008 return *
this = *
this / B;
1011 template<
typename T>
1012 template<
typename U>
1015 return *
this = *
this + B;
1018 template<
typename T>
1019 template<
typename U>
1022 return *
this = *
this - B;
1025 template<
typename T>
1026 template<
typename U>
1029 return mat3( *
this ) *= f;
1032 template<
typename T>
1033 template<
typename U>
1036 return mat3( *
this ) /= f;
1039 template<
typename T>
1040 template<
typename U>
1043 return mat3( *
this ) += f;
1046 template<
typename T>
1047 template<
typename U>
1050 return mat3( *
this ) -= f;
1053 template<
typename T>
1054 template<
typename U>
1057 for (
auto& val : _vec )
1064 template<
typename T>
1065 template<
typename U>
1068 for (
auto& val : _vec )
1075 template<
typename T>
1076 template<
typename U>
1079 for (
auto& val : _vec )
1086 template<
typename T>
1087 template<
typename U>
1090 for (
auto& val : _vec )
1097 template<
typename T>
1100 for (
U8 i = 0; i < 9; ++i )
1102 if ( !
COMPARE( mat[i], B.mat[i] ) )
1111 template<
typename T>
1112 template<
typename U>
1115 for (
U8 i = 0; i < 9; ++i )
1117 if ( !
COMPARE( mat[i], B.mat[i] ) )
1126 template<
typename T>
1127 template<
typename U>
1130 for (
U8 i = 0; i < 9; ++i )
1132 if ( !
COMPARE( mat[i], B.mat[i] ) )
1141 template<
typename T>
1144 for (
U8 i = 0; i < 9; ++i )
1146 if ( !
COMPARE( mat[i], B.mat[i] ) )
1155 template<
typename T>
1158 for (
U8 i = 0; i < 9; ++i )
1169 template<
typename T>
1170 template<
typename U>
1173 for (
U8 i = 0; i < 9; ++i )
1184 template<
typename T>
1190 template<
typename T>
1196 template<
typename T>
1202 template<
typename T>
1208 template<
typename T>
1211 return m[row][column];
1214 template<
typename T>
1217 return m[row][column];
1220 template<
typename T>
1221 template<
typename U>
1222 void mat3<T>::set( U m0, U m1, U m2, U m3, U m4, U m5, U m6, U m7, U m8 )
noexcept
1224 mat[0] =
static_cast<T
>(m0); mat[1] =
static_cast<T
>(m1); mat[3] =
static_cast<T
>(m3);
1225 mat[2] =
static_cast<T
>(m2); mat[4] =
static_cast<T
>(m4); mat[5] =
static_cast<T
>(m5);
1226 mat[6] =
static_cast<T
>(m6); mat[7] =
static_cast<T
>(m7); mat[8] =
static_cast<T
>(m8);
1229 template<
typename T>
1230 template<
typename U>
1233 if (
sizeof( T ) ==
sizeof( U ) )
1235 memcpy( mat, matrix,
sizeof( U ) * 9 );
1239 set( matrix[0], matrix[1], matrix[2],
1240 matrix[3], matrix[4], matrix[5],
1241 matrix[6], matrix[7], matrix[8] );
1245 template<
typename T>
1246 template<
typename U>
1249 const U zero =
static_cast<U
>(0);
1250 set( matrix[0], matrix[1], zero,
1251 matrix[2], matrix[3], zero,
1255 template<
typename T>
1256 template<
typename U>
1262 template<
typename T>
1263 template<
typename U>
1266 set( matrix[0], matrix[1], matrix[2],
1267 matrix[4], matrix[5], matrix[6],
1268 matrix[8], matrix[9], matrix[10] );
1271 template<
typename T>
1272 template<
typename U>
1275 _vec[index].set( value );
1278 template<
typename T>
1279 template<
typename U>
1282 _vec[index].set( value );
1285 template<
typename T>
1286 template<
typename U>
1289 _vec[index].set( x, y, z );
1292 template<
typename T>
1298 template<
typename T>
1299 template<
typename U>
1302 m[0][index] =
static_cast<T
>(value.x);
1303 m[1][index] =
static_cast<T
>(value.y);
1304 m[2][index] =
static_cast<T
>(value.z);
1307 template<
typename T>
1308 template<
typename U>
1311 m[0][index] =
static_cast<T
>(value);
1312 m[1][index] =
static_cast<T
>(value);
1313 m[2][index] =
static_cast<T
>(value);
1316 template<
typename T>
1317 template<
typename U>
1320 m[0][index] =
static_cast<T
>(x);
1321 m[1][index] =
static_cast<T
>(y);
1322 m[2][index] =
static_cast<T
>(z);
1325 template<
typename T>
1335 template<
typename T>
1338 memset( mat, 0, 9 *
sizeof( T ) );
1341 template<
typename T>
1344 constexpr T zero =
static_cast<T
>(0);
1345 constexpr T one =
static_cast<T
>(1);
1346 mat[0] = one; mat[1] = zero; mat[2] = zero;
1347 mat[3] = zero; mat[4] = one; mat[5] = zero;
1348 mat[6] = zero; mat[7] = zero; mat[8] = one;
1351 template<
typename T>
1359 template<
typename T>
1362 return isColOrthogonal() && getScaleSq().isUniform( tolerance );
1365 template<
typename T>
1377 template<
typename T>
1380 std::swap( m[0][0], B.m[0][0] );
1381 std::swap( m[0][1], B.m[0][1] );
1382 std::swap( m[0][2], B.m[0][2] );
1384 std::swap( m[1][0], B.m[1][0] );
1385 std::swap( m[1][1], B.m[1][1] );
1386 std::swap( m[1][2], B.m[1][2] );
1388 std::swap( m[2][0], B.m[2][0] );
1389 std::swap( m[2][1], B.m[2][1] );
1390 std::swap( m[2][2], B.m[2][2] );
1393 template<
typename T>
1396 return mat[0] * mat[4] * mat[8] +
1397 mat[3] * mat[7] * mat[2] +
1398 mat[6] * mat[1] * mat[5] -
1399 mat[6] * mat[4] * mat[2] -
1400 mat[3] * mat[1] * mat[8] -
1401 mat[0] * mat[7] * mat[5];
1404 template<
typename T>
1407 return mat[0] + mat[1] + mat[2] +
1408 mat[3] + mat[4] + mat[5] +
1409 mat[6] + mat[7] + mat[8];
1412 template<
typename T>
1416 if (
IS_ZERO( idet ) ) [[unlikely]]
1423 set( (mat[4] * mat[8] - mat[7] * mat[5]) * idet,
1424 -(mat[1] * mat[8] - mat[7] * mat[2]) * idet,
1425 (mat[1] * mat[5] - mat[4] * mat[2]) * idet,
1426 -(mat[3] * mat[8] - mat[6] * mat[5]) * idet,
1427 (mat[0] * mat[8] - mat[6] * mat[2]) * idet,
1428 -(mat[0] * mat[5] - mat[3] * mat[2]) * idet,
1429 (mat[3] * mat[7] - mat[6] * mat[4]) * idet,
1430 -(mat[0] * mat[7] - mat[6] * mat[1]) * idet,
1431 (mat[0] * mat[4] - mat[3] * mat[1]) * idet );
1434 template<
typename T>
1437 set( mat[0], mat[3], mat[6],
1438 mat[1], mat[4], mat[7],
1439 mat[2], mat[5], mat[8] );
1442 template<
typename T>
1449 template<
typename T>
1457 template<
typename T>
1464 template<
typename T>
1472 template<
typename T>
1479 template<
typename T>
1487 template<
typename T>
1491 ret.inverseTranspose();
1494 template<
typename T>
1495 template<
typename U>
1498 fromRotation( v.
x, v.
y, v.
z, angle );
1501 template<
typename T>
1502 template<
typename U>
1505 const U c = std::cos( angle );
1506 const U s = std::sin( angle );
1507 U l =
static_cast<U
>(
Sqrt(
static_cast<D64>(x * x + y * y + z * z) ));
1522 set( c1 * x * x + c, c1 * xy + zs, c1 * zx - ys,
1523 c1 * xy - zs, c1 * y * y + c, c1 * yz + xs,
1524 c1 * zx + ys, c1 * yz - xs, c1 * z * z + c );
1527 template<
typename T>
1528 template<
typename U>
1531 constexpr U zero =
static_cast<U
>(0);
1532 constexpr U one =
static_cast<U
>(1);
1533 const U c = std::cos( angle );
1534 const U s = std::sin( angle );
1536 set( one, zero, zero,
1541 template<
typename T>
1542 template<
typename U>
1545 constexpr U zero =
static_cast<U
>(0);
1546 constexpr U one =
static_cast<U
>(1);
1548 const U c = std::cos( angle );
1549 const U s = std::sin( angle );
1556 template<
typename T>
1557 template<
typename U>
1560 constexpr U zero =
static_cast<U
>(0);
1561 constexpr U one =
static_cast<U
>(1);
1563 const U c = std::cos( angle );
1564 const U s = std::sin( angle );
1572 template<
typename T>
1573 template<
typename U>
1576 mat[0] =
static_cast<T
>(x);
1577 mat[4] =
static_cast<T
>(y);
1578 mat[8] =
static_cast<T
>(z);
1581 template<
typename T>
1582 template<
typename U>
1585 setScale( v.x, v.y, v.z );
1588 template<
typename T>
1592 getRow( 0 ).length(),
1593 getRow( 1 ).length(),
1594 getRow( 2 ).length()
1598 template<
typename T>
1602 getRow( 0 ).lengthSquared(),
1603 getRow( 1 ).lengthSquared(),
1604 getRow( 2 ).lengthSquared()
1608 template<
typename T>
1614 template<
typename T>
1620 template<
typename T>
1624 return -getCol( 2 );
1627 template<
typename T>
1633 template<
typename T>
1639 template<
typename T>
1646 template<
typename T>
1649 vec3<T> x( mat[0], mat[1], mat[2] );
1651 vec3<T> y( mat[3], mat[4], mat[5] );
1666 template<
typename T>
1675 template<
typename T>
1676 template<
typename U>
1678 : mat{
static_cast<T
>(value),
static_cast<T
>(value),
static_cast<T
>(value),
static_cast<T
>(value),
1679 static_cast<T
>(value),
static_cast<T
>(value),
static_cast<T
>(value),
static_cast<T
>(value),
1680 static_cast<T
>(value),
static_cast<T
>(value),
static_cast<T
>(value),
static_cast<T
>(value),
1681 static_cast<T
>(value),
static_cast<T
>(value),
static_cast<T
>(value),
static_cast<T
>(value) }
1685 template<
typename T>
1686 template<
typename U>
1688 U m4, U m5, U m6, U m7,
1689 U m8, U m9, U m10, U m11,
1690 U m12, U m13, U m14, U m15 ) noexcept
1691 : mat{
static_cast<T
>(m0),
static_cast<T
>(m1),
static_cast<T
>(m2),
static_cast<T
>(m3),
1692 static_cast<T
>(m4),
static_cast<T
>(m5),
static_cast<T
>(m6),
static_cast<T
>(m7),
1693 static_cast<T
>(m8),
static_cast<T
>(m9),
static_cast<T
>(m10),
static_cast<T
>(m11),
1694 static_cast<T
>(m12),
static_cast<T
>(m13),
static_cast<T
>(m14),
static_cast<T
>(m15) }
1698 template<
typename T>
1699 template<
typename U>
1701 : mat{
static_cast<T
>(values[0]),
static_cast<T
>(values[1]),
static_cast<T
>(values[2]),
static_cast<T
>(values[3]),
1702 static_cast<T
>(values[4]),
static_cast<T
>(values[5]),
static_cast<T
>(values[6]),
static_cast<T
>(values[7]),
1703 static_cast<T
>(values[8]),
static_cast<T
>(values[9]),
static_cast<T
>(values[10]),
static_cast<T
>(values[11]),
1704 static_cast<T
>(values[12]),
static_cast<T
>(values[13]),
static_cast<T
>(values[14]),
static_cast<T
>(values[15]) }
1708 template<
typename T>
1709 template<
typename U>
1711 :
mat4( { B[0], B[1],
static_cast<U
>(0),
static_cast<U
>(0),
1712 B[2], B[3],
static_cast<U
>(0),
static_cast<U
>(0),
1713 static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(zeroFill ? 0 : 1),
static_cast<U
>(0),
1714 static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(zeroFill ? 0 : 1) } )
1718 template<
typename T>
1719 template<
typename U>
1721 :
mat4( { B[0], B[1], B[2],
static_cast<U
>(0),
1722 B[3], B[4], B[5],
static_cast<U
>(0),
1723 B[6], B[7], B[8],
static_cast<U
>(0),
1724 static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(zeroFill ? 0 : 1) } )
1728 template<
typename T>
1734 template<
typename T>
1735 template<
typename U>
1741 template<
typename T>
1742 template<
typename U>
1744 :
mat4( { scale.x,
static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(0),
1745 static_cast<U
>(0), scale.y,
static_cast<U
>(0),
static_cast<U
>(0),
1746 static_cast<U
>(0),
static_cast<U
>(0), scale.z,
static_cast<U
>(0),
1747 translation.x, translation.y, translation.z,
static_cast<U
>(1) } )
1751 template<
typename T>
1752 template<
typename U>
1754 :
mat4( { scale.x,
static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(0),
1755 static_cast<U
>(0), scale.y,
static_cast<U
>(0),
static_cast<U
>(0),
1756 static_cast<U
>(0),
static_cast<U
>(0), scale.z,
static_cast<U
>(0),
1757 static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(1) } )
1760 set( *
this *
mat4<U>( rotation,
false ) );
1761 setTranslation( translation );
1764 template<
typename T>
1765 template<
typename U>
1767 :
mat4( translation.x, translation.y, translation.z )
1771 template<
typename T>
1772 template<
typename U>
1774 :
mat4( {
static_cast<U
>(1),
static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(0),
1775 static_cast<U
>(0),
static_cast<U
>(1),
static_cast<U
>(0),
static_cast<U
>(0),
1776 static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(1),
static_cast<U
>(0),
1777 translationX, translationY, translationZ,
static_cast<U
>(1) } )
1781 template<
typename T>
1782 template<
typename U>
1784 :
mat4( axis.x, axis.y, axis.z, angle )
1788 template<
typename T>
1789 template<
typename U>
1793 fromRotation( x, y, z, angle );
1796 template<
typename T>
1797 template<
typename U>
1801 reflect( reflectionPlane );
1804 template<
typename T>
1805 template<
typename U>
1811 template<
typename T>
1812 template<
typename U>
1818 template<
typename T>
1819 template<
typename U>
1822 return { mat[0] * v.x + mat[4] * v.y + mat[8] * v.z + mat[12] * v.w,
1823 mat[1] * v.x + mat[5] * v.y + mat[9] * v.z + mat[13] * v.w,
1824 mat[2] * v.x + mat[6] * v.y + mat[10] * v.z + mat[14] * v.w,
1825 mat[3] * v.x + mat[7] * v.y + mat[11] * v.z + mat[15] * v.w };
1828 template<
typename T>
1829 template<
typename U>
1833 Multiply( matrix, *
this, retValue );
1837 template<
typename T>
1838 template<
typename U>
1842 Multiply( matrix.getInverse(), *
this, retValue );
1846 template<
typename T>
1847 template<
typename U>
1850 return mat4( *
this ) += matrix;
1853 template<
typename T>
1854 template<
typename U>
1857 return mat4( *
this ) -= matrix;
1860 template<
typename T>
1861 template<
typename U>
1864 Multiply( matrix, *
this, *
this );
1868 template<
typename T>
1869 template<
typename U>
1872 Multiply( matrix.getInverse(), *
this, *
this );
1876 template<
typename T>
1877 template<
typename U>
1880 for (
U8 i = 0u; i < 4u; ++i )
1882 _vec[i] += matrix.
_vec[i];
1887 template<
typename T>
1888 template<
typename U>
1891 for (
U8 i = 0u; i < 4u; ++i )
1893 _vec[i] -= matrix.
_vec[i];
1899 template<
typename T>
1900 template<
typename U>
1903 return mat4( *
this ) *= f;
1906 template<
typename T>
1907 template<
typename U>
1910 return mat4( *
this ) /= f;
1913 template<
typename T>
1914 template<
typename U>
1917 return mat4( *
this ) += f;
1920 template<
typename T>
1921 template<
typename U>
1924 return mat4( *
this ) -= f;
1927 template<
typename T>
1928 template<
typename U>
1931 for (
U8 i = 0u; i < 4u; ++i )
1939 template<
typename T>
1940 template<
typename U>
1943 for (
U8 i = 0u; i < 4u; ++i )
1951 template<
typename T>
1952 template<
typename U>
1955 for (
U8 i = 0u; i < 4u; ++i )
1963 template<
typename T>
1964 template<
typename U>
1967 for (
U8 i = 0u; i < 4u; ++i )
1975 template<
typename T>
1978 for (
U8 i = 0u; i < 4u; ++i )
1980 if ( _reg[i] != B._reg[i] )
1989 template<
typename T>
1992 for (
U8 i = 0u; i < 4u; ++i )
1994 if ( _reg[i] != B._reg[i] )
2003 template<
typename T>
2004 template<
typename U>
2014 for (
U8 i = 0u; i < 16u; ++i )
2016 if ( !
COMPARE( mat[i], B.mat[i] ) )
2025 template<
typename T>
2026 template<
typename U>
2036 for (
U8 i = 0u; i < 16u; ++i )
2038 if ( !
COMPARE( mat[i], B.mat[i] ) )
2047 template<
typename T>
2050 for (
U8 i = 0u; i < 16u; ++i )
2061 template<
typename T>
2062 template<
typename U>
2065 for (
U8 i = 0u; i < 16u; ++i )
2076 template<
typename T>
2082 template<
typename T>
2088 template<
typename T>
2094 template<
typename T>
2100 template<
typename T>
2103 return m[row][column];
2106 template<
typename T>
2109 return m[row][column];
2112 template<
typename T>
2115 set( matrix.begin() );
2118 template<
typename T>
2119 template<
typename U>
2122 if constexpr ( std::is_same<T, U>::value )
2124 std::memcpy( mat, matrix,
sizeof( T ) * 16 );
2128 for (
U8 i = 0u; i < 16u; ++i )
2130 mat[i] =
static_cast<T
>(matrix[i]);
2135 template<
typename T>
2136 template<
typename U>
2141 mat[0] = matrix[0]; mat[1] = matrix[1];
2142 mat[4] = matrix[2]; mat[5] = matrix[3];
2145 template<
typename T>
2146 template<
typename U>
2151 mat[0] = matrix[0]; mat[1] = matrix[1]; mat[2] = matrix[2];
2152 mat[4] = matrix[3]; mat[5] = matrix[4]; mat[6] = matrix[5];
2153 mat[8] = matrix[6]; mat[9] = matrix[7]; mat[10] = matrix[8];
2157 template<
typename T>
2158 template<
typename U>
2164 template<
typename T>
2165 template<
typename U>
2168 set( scale.x,
static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(0),
2169 static_cast<U
>(0), scale.y,
static_cast<U
>(0),
static_cast<U
>(0),
2170 static_cast<U
>(0),
static_cast<U
>(0), scale.z,
static_cast<U
>(0),
2171 static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(0),
static_cast<U
>(1) );
2173 set( *
this * rotation );
2175 setTranslation( translation );
2178 template<
typename T>
2179 template<
typename U>
2182 _vec[index].set( value );
2185 template<
typename T>
2186 template<
typename U>
2189 _vec[index].set( value );
2192 template<
typename T>
2193 template<
typename U>
2196 _vec[index].set( x, y, z, w );
2199 template<
typename T>
2205 template<
typename T>
2206 template<
typename U>
2209 setCol( index, value.x, value.y, value.z, value.w );
2212 template<
typename T>
2213 template<
typename U>
2216 m[0][index] =
static_cast<T
>(value);
2217 m[1][index] =
static_cast<T
>(value);
2218 m[2][index] =
static_cast<T
>(value);
2219 m[3][index] =
static_cast<T
>(value);
2222 template<
typename T>
2223 template<
typename U>
2226 m[0][index] =
static_cast<T
>(x);
2227 m[1][index] =
static_cast<T
>(y);
2228 m[2][index] =
static_cast<T
>(z);
2229 m[3][index] =
static_cast<T
>(w);
2232 template<
typename T>
2243 template<
typename T>
2246 memset( mat, 0,
sizeof( T ) * 16 );
2249 template<
typename T>
2254 m[0][0] = m[1][1] = m[2][2] = m[3][3] =
static_cast<T
>(1);
2257 template<
typename T>
2263 template<
typename T>
2266 return isColOrthogonal() && getScaleSq().isUniform( tolerance );
2269 template<
typename T>
2281 template<
typename T>
2284 for (
U8 i = 0u; i < 16u; ++i )
2286 std::swap( mat[i], B.mat[i] );
2290 template<
typename T>
2293 return mat[0] * mat[5] * mat[10] + mat[4] * mat[9] * mat[2] +
2294 mat[8] * mat[1] * mat[6] - mat[8] * mat[5] * mat[2] -
2295 mat[4] * mat[1] * mat[10] - mat[0] * mat[9] * mat[6];
2298 template<
typename T>
2301 return mat[0] + mat[1] + mat[2] + mat[3] +
2302 mat[4] + mat[5] + mat[6] + mat[7] +
2303 mat[8] + mat[9] + mat[10] + mat[11] +
2304 mat[12] + mat[13] + mat[14] + mat[15];
2307 template<
typename T>
2310 _vec[0].normalize();
2311 _vec[1].normalize();
2312 _vec[2].normalize();
2315 template<
typename T>
2329 template<
typename T>
2333 mat[0], mat[4], mat[8], mat[12],
2334 mat[1], mat[5], mat[9], mat[13],
2335 mat[2], mat[6], mat[10], mat[14],
2336 mat[3], mat[7], mat[11], mat[15]
2340 template<
typename T>
2348 template<
typename T>
2351 set( { mat[0], mat[4], mat[8], mat[3],
2352 mat[1], mat[5], mat[9], mat[7],
2353 mat[2], mat[6], mat[10], mat[11],
2354 mat[12], mat[13], mat[14], mat[15]
2360 template<
typename T>
2376 template<
typename T>
2388 template<
typename T>
2391 return mat4( { mat[0], mat[4], mat[8], mat[12],
2392 mat[1], mat[5], mat[9], mat[13],
2393 mat[2], mat[6], mat[10], mat[14],
2394 mat[3], mat[7], mat[11], mat[15] } );
2397 template<
typename T>
2400 out.
set( { mat[0], mat[4], mat[8], mat[12],
2401 mat[1], mat[5], mat[9], mat[13],
2402 mat[2], mat[6], mat[10], mat[14],
2403 mat[3], mat[7], mat[11], mat[15] } );
2406 template<
typename T>
2424 template<
typename T>
2438 template<
typename T>
2441 return mat4( mat[0], mat[4], mat[8], mat[3],
2442 mat[1], mat[5], mat[9], mat[7],
2443 mat[2], mat[6], mat[10], mat[11],
2444 mat[12], mat[13], mat[14], mat[15] );
2447 template<
typename T>
2450 ret.
set( mat[0], mat[4], mat[8], mat[3],
2451 mat[1], mat[5], mat[9], mat[7],
2452 mat[2], mat[6], mat[10], mat[11],
2453 mat[12], mat[13], mat[14], mat[15] );
2456 template<
typename T>
2457 template<
typename U>
2463 const U c = std::cos( angle );
2464 const U s = std::sin( angle );
2466 const U xx = v.
x * v.
x;
2467 const U yy = v.
y * v.
y;
2468 const U zz = v.
z * v.
z;
2469 const U xy = v.
x * v.
y;
2470 const U yz = v.
y * v.
z;
2471 const U zx = v.
z * v.
x;
2472 const U xs = v.
x * s;
2473 const U ys = v.
y * s;
2474 const U zs = v.
z * s;
2476 set( (1 - c) * xx + c, (1 - c) * xy + zs, (1 - c) * zx - ys,
static_cast<U
>(mat[3]),
2477 (1 - c) * xy - zs, (1 - c) * yy + c, (1 - c) * yz + xs,
static_cast<U
>(mat[7]),
2478 (1 - c) * zx + ys, (1 - c) * yz - xs, (1 - c) * zz + c,
static_cast<U
>(mat[11]),
2479 static_cast<U
>(mat[12]),
static_cast<U
>(mat[13]),
static_cast<U
>(mat[14]),
static_cast<U
>(mat[15]) );
2482 template<
typename T>
2483 template<
typename U>
2486 const U c = std::cos( angle );
2487 const U s = std::sin( angle );
2489 mat[5] =
static_cast<T
>(c);
2490 mat[9] =
static_cast<T
>(-s);
2491 mat[6] =
static_cast<T
>(s);
2492 mat[10] =
static_cast<T
>(c);
2495 template<
typename T>
2496 template<
typename U>
2499 const U c = std::cos( angle );
2500 const U s = std::sin( angle );
2502 mat[0] =
static_cast<T
>(c);
2503 mat[8] =
static_cast<T
>(s);
2504 mat[2] =
static_cast<T
>(-s);
2505 mat[10] =
static_cast<T
>(c);
2508 template<
typename T>
2509 template<
typename U>
2512 const U c = std::cos( angle );
2513 const U s = std::sin( angle );
2515 mat[0] =
static_cast<T
>(c);
2516 mat[4] =
static_cast<T
>(-s);
2517 mat[1] =
static_cast<T
>(s);
2518 mat[5] =
static_cast<T
>(c);
2521 template<
typename T>
2522 template<
typename U>
2525 setTranslation( v.x, v.y, v.z );
2528 template<
typename T>
2529 template<
typename U>
2532 mat[12] =
static_cast<T
>(x);
2533 mat[13] =
static_cast<T
>(y);
2534 mat[14] =
static_cast<T
>(z);
2537 template<
typename T>
2538 template<
typename U>
2541 mat[0] =
static_cast<T
>(x);
2542 mat[5] =
static_cast<T
>(y);
2543 mat[10] =
static_cast<T
>(z);
2546 template<
typename T>
2547 template<
typename U>
2550 setScale( v.x, v.y, v.z );
2553 template<
typename T>
2557 getRow( 0 ).length(),
2558 getRow( 1 ).length(),
2559 getRow( 2 ).length()
2563 template<
typename T>
2567 getRow( 0 ).lengthSquared(),
2568 getRow( 1 ).lengthSquared(),
2569 getRow( 2 ).lengthSquared()
2573 template<
typename T>
2576 return getCol( 0 ).xyz;
2579 template<
typename T>
2582 return getCol( 1 ).xyz;
2585 template<
typename T>
2589 return -getCol( 2 ).xyz;
2592 template<
typename T>
2598 template<
typename T>
2604 template<
typename T>
2611 template<
typename T>
2612 template<
typename U>
2615 return homogeneous ? transformHomogeneous( v )
2616 : transformNonHomogeneous( v );
2619 template<
typename T>
2620 template<
typename U>
2624 const F32 fInvW = 1.f / (m[0][3] * v.
x + m[1][3] * v.
y +
2625 m[2][3] * v.
z + m[3][3] * 1.f);
2627 return { (m[0][0] * v.
x + m[1][1] * v.
y + m[2][0] * v.
z + m[3][0]) * fInvW,
2628 (m[0][1] * v.
x + m[1][1] * v.
y + m[2][1] * v.
z + m[3][1]) * fInvW,
2629 (m[0][2] * v.
x + m[1][2] * v.
y + m[2][2] * v.
z + m[3][2]) * fInvW };
2632 template<
typename T>
2633 template<
typename U>
2636 return *
this *
vec4<U>( v,
static_cast<U
>(0) );
2639 template<
typename T>
2640 template<
typename U>
2643 translate( v.x, v.y, v.z );
2646 template<
typename T>
2647 template<
typename U>
2650 mat[12] +=
static_cast<T
>(x);
2651 mat[13] +=
static_cast<T
>(y);
2652 mat[14] +=
static_cast<T
>(z);
2655 template<
typename T>
2656 template<
typename U>
2659 scale( v.x, v.y, v.z );
2662 template<
typename T>
2663 template<
typename U>
2666 mat[0] *=
static_cast<T
>(x);
2667 mat[1] *=
static_cast<T
>(x);
2668 mat[2] *=
static_cast<T
>(x);
2669 mat[3] *=
static_cast<T
>(x);
2670 mat[4] *=
static_cast<T
>(y);
2671 mat[5] *=
static_cast<T
>(y);
2672 mat[6] *=
static_cast<T
>(y);
2673 mat[7] *=
static_cast<T
>(y);
2674 mat[8] *=
static_cast<T
>(z);
2675 mat[9] *=
static_cast<T
>(z);
2676 mat[10] *=
static_cast<T
>(z);
2677 mat[11] *=
static_cast<T
>(z);
2680 template<
typename T>
2690 template<
typename T>
2693 const T zero =
static_cast<T
>(0);
2694 const T one =
static_cast<T
>(1);
2695 mat4 ret( { mat[0], mat[1], mat[2], zero,
2696 mat[4], mat[5], mat[6], zero,
2697 mat[8], mat[9], mat[10], zero,
2698 zero, zero, zero, one } );
2704 template<
typename T>
2705 template<
typename U>
2708 return reflect(
Plane<U>( x, y, z, w ) );
2711 template<
typename T>
2712 template<
typename U>
2715 constexpr U zero =
static_cast<U
>(0);
2716 constexpr U one =
static_cast<U
>(1);
2718 const vec4<U>& eq = plane._equation;
2725 *
this =
mat4( { -2 * x * x + 1, -2 * y * x, -2 * z * x, zero,
2726 -2 * x * y, -2 * y * y + 1, -2 * z * y, zero,
2727 -2 * x * z, -2 * y * z, -2 * z * z + 1, zero,
2728 -2 * x * d, -2 * y * d, -2 * z * d, one } ) * *
this;
2733 template<
typename T>
2734 template<
typename U>
2737 matrix3.m[0][0] =
static_cast<U
>(m[0][0]);
2738 matrix3.m[0][1] =
static_cast<U
>(m[0][1]);
2739 matrix3.m[0][2] =
static_cast<U
>(m[0][2]);
2740 matrix3.m[1][0] =
static_cast<U
>(m[1][0]);
2741 matrix3.m[1][1] =
static_cast<U
>(m[1][1]);
2742 matrix3.m[1][2] =
static_cast<U
>(m[1][2]);
2743 matrix3.m[2][0] =
static_cast<U
>(m[2][0]);
2744 matrix3.m[2][1] =
static_cast<U
>(m[2][1]);
2745 matrix3.m[2][2] =
static_cast<U
>(m[2][2]);
2748 template<
typename T>
2751 for (
U8 i = 0u; i < 4u; ++i )
2753 const vec4<T>& rowA = matrixB.getRow( i );
2754 ret.setRow( i, matrixA.getRow( 0 ) * rowA[0] +
2755 matrixA.getRow( 1 ) * rowA[1] +
2756 matrixA.getRow( 2 ) * rowA[2] +
2757 matrixA.getRow( 3 ) * rowA[3] );
2761 template<
typename T>
2765 Multiply( matrixA, matrixB, ret );
2772#if defined(HAS_AVX2)
2776 ret._reg[0]._reg = AVX::lincomb_AVX_4mem( matrixB.m[0], matrixA );
2777 ret._reg[1]._reg = AVX::lincomb_AVX_4mem( matrixB.m[1], matrixA );
2778 ret._reg[2]._reg = AVX::lincomb_AVX_4mem( matrixB.m[2], matrixA );
2779 ret._reg[3]._reg = AVX::lincomb_AVX_4mem( matrixB.m[3], matrixA );
2789 template<
typename T>
2792 const T m00 = in[0], m10 = in[1], m20 = in[2], m30 = in[3];
2793 const T m01 = in[4], m11 = in[5], m21 = in[6], m31 = in[7];
2794 const T m02 = in[8], m12 = in[9], m22 = in[10], m32 = in[11];
2795 const T m03 = in[12], m13 = in[13], m23 = in[14], m33 = in[15];
2797 const T a0 = m00 * m11 - m10 * m01;
2798 const T a1 = m00 * m21 - m20 * m01;
2799 const T a2 = m00 * m31 - m30 * m01;
2800 const T a3 = m10 * m21 - m20 * m11;
2801 const T a4 = m10 * m31 - m30 * m11;
2802 const T a5 = m20 * m31 - m30 * m21;
2803 const T b0 = m02 * m13 - m12 * m03;
2804 const T b1 = m02 * m23 - m22 * m03;
2805 const T b2 = m02 * m33 - m32 * m03;
2806 const T b3 = m12 * m23 - m22 * m13;
2807 const T b4 = m12 * m33 - m32 * m13;
2808 const T b5 = m22 * m33 - m32 * m23;
2811 F32 idet =
to_F32( a0 ) * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
2813 if ( !
IS_ZERO( idet ) ) [[likely]]
2817 out[0] =
static_cast<T
>(( m11 * b5 - m21 * b4 + m31 * b3) * idet);
2818 out[1] =
static_cast<T
>((-m10 * b5 + m20 * b4 - m30 * b3) * idet);
2819 out[2] =
static_cast<T
>(( m13 * a5 - m23 * a4 + m33 * a3) * idet);
2820 out[3] =
static_cast<T
>((-m12 * a5 + m22 * a4 - m32 * a3) * idet);
2821 out[4] =
static_cast<T
>((-m01 * b5 + m21 * b2 - m31 * b1) * idet);
2822 out[5] =
static_cast<T
>(( m00 * b5 - m20 * b2 + m30 * b1) * idet);
2823 out[6] =
static_cast<T
>((-m03 * a5 + m23 * a2 - m33 * a1) * idet);
2824 out[7] =
static_cast<T
>(( m02 * a5 - m22 * a2 + m32 * a1) * idet);
2825 out[8] =
static_cast<T
>(( m01 * b4 - m11 * b2 + m31 * b0) * idet);
2826 out[9] =
static_cast<T
>((-m00 * b4 + m10 * b2 - m30 * b0) * idet);
2827 out[10] =
static_cast<T
>(( m03 * a4 - m13 * a2 + m33 * a0) * idet);
2828 out[11] =
static_cast<T
>((-m02 * a4 + m12 * a2 - m32 * a0) * idet);
2829 out[12] =
static_cast<T
>((-m01 * b3 + m11 * b1 - m21 * b0) * idet);
2830 out[13] =
static_cast<T
>(( m00 * b3 - m10 * b1 + m20 * b0) * idet);
2831 out[14] =
static_cast<T
>((-m03 * a3 + m13 * a1 - m23 * a0) * idet);
2832 out[15] =
static_cast<T
>(( m02 * a3 - m12 * a1 + m22 * a0) * idet);
2836 memcpy( out, in,
sizeof( T ) * 16 );
#define VecShuffle_0101(vec1, vec2)
#define VecSwizzle1(vec, x)
#define VecSwizzle(vec, x, y, z, w)
#define VecShuffle_2323(vec1, vec2)
#define VecShuffle(vec1, vec2, x, y, z, w)
void set(U m0, U m1, U m2, U m3) noexcept
void setCol(I32 index, vec2< U > value) noexcept
bool isIdentity() const noexcept
vec2< T > getRow(I32 index) const noexcept
bool operator!=(const mat2 &B) const noexcept
vec2< T > getCol(I32 index) const noexcept
mat2 & operator+=(const mat2< U > &B) noexcept
mat2 operator+(const mat2< U > &B) const noexcept
mat2 & operator/=(const mat2< U > &B) noexcept
mat2 getTranspose() const noexcept
void swap(mat2 &B) noexcept
mat2 getInverseTranspose() const noexcept
void transpose() noexcept
mat2 getInverse() const noexcept
mat2 & operator-=(const mat2< U > &B) noexcept
void inverseTranspose() noexcept
T elementSum() const noexcept
bool compare(const mat2 &B, F32 epsilon) const noexcept
bool operator==(const mat2 &B) const noexcept
T & element(U8 row, U8 column) noexcept
void setRow(I32 index, U value) noexcept
vec2< T > operator*(const vec2< U > v) const noexcept
mat2 & operator*=(const mat2< U > &B) noexcept
mat2 operator/(const mat2< U > &B) const noexcept
mat2 operator-(const mat2< U > &B) const noexcept
void fromZRotation(Angle::RADIANS< U > angle)
mat3 & operator*=(const mat3< U > &B) noexcept
T elementSum() const noexcept
vec3< T > getForwardDirection() const noexcept
Returns normalized(getForwardVec())
bool operator==(const mat3 &B) const noexcept
mat3 getTranspose() const noexcept
const vec3< T > & getRow(I32 index) const noexcept
void setCol(I32 index, const vec3< U > &value) noexcept
mat3 & operator/=(const mat3< U > &B) noexcept
T & operator[](I32 i) noexcept
vec3< T > getScaleSq() const noexcept
vec3< T > getScale() const noexcept
mat3 operator/(const mat3< U > &B) const noexcept
void setRow(I32 index, U value) noexcept
vec3< T > getRightVec() const noexcept
Alias for getCol(0)
mat3 getInverseTranspose() const noexcept
mat3 & operator-=(const mat3< U > &B) noexcept
bool isColOrthogonal() const noexcept
vec3< T > getCol(I32 index) const noexcept
void fromXRotation(Angle::RADIANS< U > angle)
T & element(U8 row, U8 column) noexcept
bool operator!=(const mat3 &B) const noexcept
bool isUniformScale(F32 tolerance=0.0001f) const noexcept
void setScale(U x, U y, U z) noexcept
void set(U m0, U m1, U m2, U m3, U m4, U m5, U m6, U m7, U m8) noexcept
bool compare(const mat3 &B, F32 epsilon) const noexcept
vec2< U > operator*(const vec2< U > v) const noexcept
void inverseTranspose() noexcept
mat3 operator+(const mat3< U > &B) const noexcept
mat3 & operator+=(const mat3< U > &B) noexcept
vec3< T > getRightDirection() const noexcept
Returns normalized(getRightVec())
bool isIdentity() const noexcept
void transpose() noexcept
mat3 getInverse() const noexcept
vec3< T > getForwardVec() const noexcept
Alias for -getCol(2). Assumes -Z fwd.
mat3 operator-(const mat3< U > &B) const noexcept
vec3< T > getUpDirection() const noexcept
Returns normalized(getUpVec())
void fromRotation(const vec3< U > &v, Angle::RADIANS< U > angle)
vec3< T > getUpVec() const noexcept
Alias for getCol(1)
void swap(mat3 &B) noexcept
void fromYRotation(Angle::RADIANS< U > angle)
vec3< T > getForwardDirection() const noexcept
Returns normalized(getForwardVec())
vec3< T > getScaleSq() const noexcept
vec3< T > getForwardVec() const noexcept
Alias for -getCol(2). Assumes -Z fwd.
T & element(U8 row, U8 column) noexcept
void swap(mat4 &B) noexcept
void setCol(I32 index, const vec4< U > &value) noexcept
mat4 getTransposeRotation() const noexcept
void inverseTranspose() noexcept
bool isUniformScale(F32 tolerance=0.0001f) const noexcept
vec3< T > getTranslation() const noexcept
const mat4 & reflect(U x, U y, U z, U w) noexcept
vec3< T > getUpDirection() const noexcept
Returns normalized(getUpVec())
mat4 transposeRotation() const noexcept
void setRow(I32 index, U value) noexcept
T elementSum() const noexcept
vec2< U > operator*(const vec2< U > v) const noexcept
mat4 & operator*=(const mat4< U > &matrix) noexcept
mat4 getInverse() const noexcept
void fromXRotation(Angle::RADIANS< U > angle) noexcept
T & operator[](I32 i) noexcept
void transpose() noexcept
bool isIdentity() const noexcept
vec3< T > getRightVec() const noexcept
Alias for getCol(0)
static mat4< T > Multiply(const mat4< T > &matrixA, const mat4< T > &matrixB) noexcept
ret = A * B
void extractMat3(mat3< U > &matrix3) const noexcept
bool operator==(const mat4 &B) const noexcept
void fromZRotation(Angle::RADIANS< U > angle) noexcept
vec3< U > transformHomogeneous(const vec3< U > &v) const
vec3< T > getRightDirection() const noexcept
Returns normalized(getRightVec())
void setScale(U x, U y, U z) noexcept
void fromRotation(U x, U y, U z, Angle::RADIANS< U > angle) noexcept
void fromYRotation(Angle::RADIANS< U > angle) noexcept
static void Inverse(const T *in, T *out) noexcept
const vec4< T > & getRow(I32 index) const noexcept
void setTranslation(const vec3< U > &v) noexcept
vec3< T > getUpVec() const noexcept
Alias for getCol(1)
vec3< U > transformNonHomogeneous(const vec3< U > &v) const noexcept
mat4 & operator/=(const mat4< U > &matrix) noexcept
mat4 operator/(const mat4< U > &matrix) const noexcept
void orthoNormalize() noexcept
void set(std::initializer_list< T > matrix) noexcept
mat4 operator-(const mat4< U > &matrix) const noexcept
mat4 & operator+=(const mat4< U > &matrix) noexcept
mat4 & operator-=(const mat4< U > &matrix) noexcept
void translate(const vec3< U > &v) noexcept
mat4 getInverseTranspose() const noexcept
vec3< T > getScale() const noexcept
vec3< U > transform(const vec3< U > &v, bool homogeneous) const
vec4< T > getCol(I32 index) const noexcept
bool compare(const mat4 &B, F32 epsilon) const noexcept
mat4 getTranspose() const noexcept
mat4 operator+(const mat4< U > &matrix) const noexcept
void scale(const vec3< U > &v) noexcept
bool operator!=(const mat4 &B) const noexcept
bool isColOrthogonal() const noexcept
vec3 & normalize() noexcept
transform the vector to unit length
void cross(const vec3 &v1, const vec3 &v2) noexcept
set this vector to be equal to the cross of the 2 specified vectors
static FORCE_INLINE __m128 lincomb_SSE(const __m128 &a, const mat4< F32 > &B)
FORCE_INLINE void GetTransformInverseNoScale(const mat4< F32 > &inM, mat4< F32 > &r) noexcept
FORCE_INLINE void GetTransformInverse(const mat4< F32 > &inM, mat4< F32 > &r) noexcept
FORCE_INLINE __m128 Mat2Mul(const __m128 vec1, const __m128 vec2) noexcept
FORCE_INLINE __m128 Mat2MulAdj(const __m128 vec1, const __m128 vec2) noexcept
FORCE_INLINE __m128 Mat2AdjMul(const __m128 vec1, const __m128 vec2) noexcept
FORCE_INLINE void M4x4_SSE(const F32 *A, const F32 *B, F32 *C) noexcept
FORCE_INLINE void GetInverse(const mat4< F32 > &inM, mat4< F32 > &r) noexcept
Handle console commands that start with a forward slash.
vec2< T > Normalized(vec2< T > vector) noexcept
bool IS_ZERO(const T X) noexcept
vec2< T > Inverse(vec2< T > v) noexcept
constexpr F32 to_F32(const T value)
void GetInverse(const mat4< T > &inM, mat4< T > &r) noexcept
constexpr F32 EPSILON_F32
vec3< T > AreOrthogonal(const vec3< T > &v1, const vec3< T > &v2) noexcept
bool COMPARE_TOLERANCE(const T X, const U Y, const T TOLERANCE) noexcept
bool COMPARE(T X, U Y) noexcept
static const mat4< F32 > MAT4_IDENTITY