8 #ifndef META_OCEAN_MATH_SQUARE_MATRIX_4_H
9 #define META_OCEAN_MATH_SQUARE_MATRIX_4_H
23 template <
typename T>
class AnyCameraT;
26 template <
typename T>
class HomogenousMatrixT4;
29 template <
typename T>
class SquareMatrixT3;
32 template <
typename T>
class SquareMatrixT4;
114 template <
typename U>
128 template <
typename U>
143 template <
typename U>
292 template <
typename U>
437 inline T
operator()(
const unsigned int row,
const unsigned int column)
const;
446 inline T&
operator()(
const unsigned int row,
const unsigned int column);
551 template <
typename U>
561 template <
typename U>
571 void swapRows(
const unsigned int row0,
const unsigned int row1);
586 void addRows(
const unsigned int targetRow,
const unsigned int sourceRow,
const T scalar);
594 template <
typename T>
600 template <
typename T>
601 template <
typename U>
604 values[ 0] = T(matrix.
values[ 0]);
605 values[ 1] = T(matrix.
values[ 1]);
606 values[ 2] = T(matrix.
values[ 2]);
607 values[ 3] = T(matrix.
values[ 3]);
608 values[ 4] = T(matrix.
values[ 4]);
609 values[ 5] = T(matrix.
values[ 5]);
610 values[ 6] = T(matrix.
values[ 6]);
611 values[ 7] = T(matrix.
values[ 7]);
612 values[ 8] = T(matrix.
values[ 8]);
613 values[ 9] = T(matrix.
values[ 9]);
614 values[10] = T(matrix.
values[10]);
615 values[11] = T(matrix.
values[11]);
616 values[12] = T(matrix.
values[12]);
617 values[13] = T(matrix.
values[13]);
618 values[14] = T(matrix.
values[14]);
619 values[15] = T(matrix.
values[15]);
622 template <
typename T>
665 template <
typename T>
666 template <
typename U>
669 ocean_assert(arrayValues);
671 for (
unsigned int n = 0u; n < 16u; ++n)
673 values[n] = T(arrayValues[n]);
677 template <
typename T>
680 ocean_assert(arrayValues);
681 memcpy(values, arrayValues,
sizeof(T) * 16);
684 template <
typename T>
685 template <
typename U>
688 ocean_assert(arrayValues);
690 if (valuesRowAligned)
692 values[ 0] = T(arrayValues[ 0]);
693 values[ 1] = T(arrayValues[ 4]);
694 values[ 2] = T(arrayValues[ 8]);
695 values[ 3] = T(arrayValues[12]);
696 values[ 4] = T(arrayValues[ 1]);
697 values[ 5] = T(arrayValues[ 5]);
698 values[ 6] = T(arrayValues[ 9]);
699 values[ 7] = T(arrayValues[13]);
700 values[ 8] = T(arrayValues[ 2]);
701 values[ 9] = T(arrayValues[ 6]);
702 values[10] = T(arrayValues[10]);
703 values[11] = T(arrayValues[14]);
704 values[12] = T(arrayValues[ 3]);
705 values[13] = T(arrayValues[ 7]);
706 values[14] = T(arrayValues[11]);
707 values[15] = T(arrayValues[15]);
711 for (
unsigned int n = 0u; n < 16u; ++n)
712 values[n] = T(arrayValues[n]);
716 template <
typename T>
719 ocean_assert(arrayValues);
721 if (valuesRowAligned)
723 values[ 0] = arrayValues[ 0];
724 values[ 1] = arrayValues[ 4];
725 values[ 2] = arrayValues[ 8];
726 values[ 3] = arrayValues[12];
727 values[ 4] = arrayValues[ 1];
728 values[ 5] = arrayValues[ 5];
729 values[ 6] = arrayValues[ 9];
730 values[ 7] = arrayValues[13];
731 values[ 8] = arrayValues[ 2];
732 values[ 9] = arrayValues[ 6];
733 values[10] = arrayValues[10];
734 values[11] = arrayValues[14];
735 values[12] = arrayValues[ 3];
736 values[13] = arrayValues[ 7];
737 values[14] = arrayValues[11];
738 values[15] = arrayValues[15];
742 memcpy(values, arrayValues,
sizeof(T) * 16);
746 template <
typename T>
749 memcpy(values, transformation(),
sizeof(T) * 16);
752 template <
typename T>
763 memcpy(values, subMatrix(),
sizeof(T) * 3);
764 memcpy(values + 4, subMatrix() + 3,
sizeof(T) * 3);
765 memcpy(values + 8, subMatrix() + 6,
sizeof(T) * 3);
768 template <
typename T>
771 values[ 0] = diagonal[0];
776 values[ 5] = diagonal[1];
781 values[10] = diagonal[2];
786 values[15] = diagonal[3];
789 template <
typename T>
795 template <
typename T>
801 template <
typename T>
806 result.
values[1] = values[4];
807 result.
values[4] = values[1];
809 result.
values[2] = values[8];
810 result.
values[8] = values[2];
812 result.
values[3] = values[12];
813 result.
values[12] = values[3];
815 result.
values[6] = values[9];
816 result.
values[9] = values[6];
818 result.
values[7] = values[13];
819 result.
values[13] = values[7];
821 result.
values[11] = values[14];
822 result.
values[14] = values[11];
827 template <
typename T>
832 values[4] = tmp.
values[1];
833 values[1] = tmp.
values[4];
835 values[8] = tmp.
values[2];
836 values[2] = tmp.
values[8];
838 values[12] = tmp.
values[3];
839 values[3] = tmp.
values[12];
841 values[9] = tmp.
values[6];
842 values[6] = tmp.
values[9];
844 values[13] = tmp.
values[7];
845 values[7] = tmp.
values[13];
847 values[14] = tmp.
values[11];
848 values[11] = tmp.
values[14];
851 template <
typename T>
856 if (!invert(invertedMatrix))
858 ocean_assert(
false &&
"Could not invert matrix.");
862 return invertedMatrix;
865 template <
typename T>
870 if (!invert(invertedMatrix))
875 *
this = invertedMatrix;
880 template <
typename T>
888 for (
unsigned int col = 0; col < 4u; ++col)
893 unsigned int selectedRow = 0u;
895 for (
unsigned int row = col; row < 4u; ++row)
898 if (absolute < value)
913 if (selectedRow != col)
916 invertedMatrix.
swapRows(col, selectedRow);
922 const T divisor = T(1.0) / source(col, col);
923 ocean_assert(divisor != T(0.0));
930 for (
unsigned int row = 0; row < 4u; ++row)
934 const T value = -source(row, col);
936 source.
addRows(row, col, value);
937 invertedMatrix.
addRows(row, col, value);
945 template <
typename T>
948 const T v6_15 = values[6] * values[15];
949 const T v10_15 = values[10] * values[15];
950 const T v11_14 = values[11] * values[14];
951 const T v7_10 = values[7] * values[10];
952 const T v9_14 = values[9] * values[14];
953 const T v6_13 = values[6] * values[13];
954 const T v2_13 = values[2] * values[13];
955 const T v2_9 = values[2] * values[9];
956 const T v3_10 = values[3] * values[10];
957 const T v2_5 = values[2] * values[5];
959 return values[0] * (values[5] * v10_15 - values[13] * v7_10
960 + v9_14 * values[7] - values[5] * v11_14
961 + v6_13 * values[11] - values[9] * v6_15)
962 - values[4] * (v9_14 * values[3] - values[1] * v11_14
963 + v2_13 * values[11] - v2_9 * values[15]
964 + values[1] * v10_15 - values[13] * v3_10)
965 + values[8] * (values[1] * v6_15 - v6_13 * values[3]
966 + values[5] * values[14] * values[3] - values[1] * values[14] * values[7]
967 + v2_13 * values[7] - v2_5 * values[15])
968 - values[12] * (values[1] * values[6] * values[11] - values[9] * values[6] * values[3]
969 + values[5] * v3_10 - values[1] * v7_10
970 + v2_9 * values[7] - v2_5 * values[11]);
973 template <
typename T>
976 return values[0] + values[5] + values[10] + values[15];
979 template <
typename T>
1000 template <
typename T>
1003 values[ 0] = T(0.0);
1004 values[ 1] = T(0.0);
1005 values[ 2] = T(0.0);
1006 values[ 3] = T(0.0);
1007 values[ 4] = T(0.0);
1008 values[ 5] = T(0.0);
1009 values[ 6] = T(0.0);
1010 values[ 7] = T(0.0);
1011 values[ 8] = T(0.0);
1012 values[ 9] = T(0.0);
1013 values[10] = T(0.0);
1014 values[11] = T(0.0);
1015 values[12] = T(0.0);
1016 values[13] = T(0.0);
1017 values[14] = T(0.0);
1018 values[15] = T(0.0);
1021 template <
typename T>
1030 template <
typename T>
1039 template <
typename T>
1045 template <
typename T>
1048 ocean_assert(epsilon >= T(0));
1054 template <
typename T>
1067 template <
typename T>
1095 const T a = values[0];
1096 const T b = values[1];
1097 const T c = values[2];
1098 const T d = values[3];
1099 const T e = values[4];
1100 const T f = values[5];
1101 const T g = values[6];
1102 const T h = values[7];
1103 const T i = values[8];
1104 const T j = values[9];
1105 const T k = values[10];
1106 const T l = values[11];
1107 const T m = values[12];
1108 const T n = values[13];
1109 const T o = values[14];
1110 const T p = values[15];
1113 const T a2 = -a - f - k - p;
1114 const T a3 = -b * e + a * f - c * i - g * j + a * k + f * k - d * m - h * n - l * o + a * p + f * p + k * p;
1115 const T a4 = c * f * i - b * g * i - c * e * j + a * g * j + b * e * k - a * f * k + d * f * m - b * h * m
1116 + d * k * m - c * l * m - d * e * n + a * h * n + h * k * n - g * l * n - d * i * o - h * j * o
1117 + a * l * o + f * l * o + b * e * p - a * f * p + c * i * p + g * j * p - a * k * p - f * k * p;
1118 const T a5 = d * g * j * m - c * h * j * m - d * f * k * m + b * h * k * m + c * f * l * m - b * g * l * m
1119 - d * g * i * n + c * h * i * n + d * e * k * n - a * h * k * n - c * e * l * n + a * g * l * n
1120 + d * f * i * o - b * h * i * o - d * e * j * o + a * h * j * o + b * e * l * o - a * f * l * o
1121 - c * f * i * p + b * g * i * p + c * e * j * p - a * g * j * p - b * e * k * p + a * f * k * p;
1123 #if defined(SQUARE_MATRIX_DISABLED_MISSING_IMPLEMENTATION)
1128 ocean_assert(
false &&
"Missing implementation, calculate eigen vectors");
1129 OCEAN_SUPPRESS_UNUSED_WARNING(eigenValues);
1130 OCEAN_SUPPRESS_UNUSED_WARNING(eigenVectors);
1135 template <
typename T>
1136 template <
typename U>
1139 ocean_assert(arrayValues);
1141 arrayValues[ 0] = U(values[ 0]);
1142 arrayValues[ 1] = U(values[ 1]);
1143 arrayValues[ 2] = U(values[ 2]);
1144 arrayValues[ 3] = U(values[ 3]);
1145 arrayValues[ 4] = U(values[ 4]);
1146 arrayValues[ 5] = U(values[ 5]);
1147 arrayValues[ 6] = U(values[ 6]);
1148 arrayValues[ 7] = U(values[ 7]);
1149 arrayValues[ 8] = U(values[ 8]);
1150 arrayValues[ 9] = U(values[ 9]);
1151 arrayValues[10] = U(values[10]);
1152 arrayValues[11] = U(values[11]);
1153 arrayValues[12] = U(values[12]);
1154 arrayValues[13] = U(values[13]);
1155 arrayValues[14] = U(values[14]);
1156 arrayValues[15] = U(values[15]);
1159 template <
typename T>
1162 ocean_assert(arrayValues);
1164 memcpy(arrayValues, values,
sizeof(T) * 16);
1167 template <
typename T>
1170 return !(*
this == matrix);
1173 template <
typename T>
1176 *
this = *
this * matrix;
1180 template <
typename T>
1183 *
this = *
this * matrix;
1187 template <
typename T>
1190 ocean_assert(index < 16u);
1191 return values[index];
1194 template <
typename T>
1197 ocean_assert(index < 16u);
1198 return values[index];
1201 template <
typename T>
1204 ocean_assert(row < 4u && column < 4u);
1205 return values[(column << 2) + row];
1208 template <
typename T>
1211 ocean_assert(row < 4u && column < 4u);
1212 return values[(column << 2) + row];
1215 template <
typename T>
1218 ocean_assert(index < 16u);
1219 return values[index];
1222 template <
typename T>
1225 ocean_assert(index < 16u);
1226 return values[index];
1229 template <
typename T>
1235 template <
typename T>
1241 template <
typename T>
1244 size_t seed = std::hash<T>{}(matrix.
values[0]);
1246 for (
unsigned int n = 1u; n < 16u; ++n)
1248 seed ^= std::hash<T>{}(matrix.
values[n]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
1254 template <
typename T>
1260 template <
typename T>
1263 return isEqual(matrix);
1266 template <
typename T>
1291 template <
typename T>
1294 values[0] += matrix.
values[0];
1295 values[1] += matrix.
values[1];
1296 values[2] += matrix.
values[2];
1297 values[3] += matrix.
values[3];
1298 values[4] += matrix.
values[4];
1299 values[5] += matrix.
values[5];
1300 values[6] += matrix.
values[6];
1301 values[7] += matrix.
values[7];
1302 values[8] += matrix.
values[8];
1303 values[9] += matrix.
values[9];
1304 values[10] += matrix.
values[10];
1305 values[11] += matrix.
values[11];
1306 values[12] += matrix.
values[12];
1307 values[13] += matrix.
values[13];
1308 values[14] += matrix.
values[14];
1309 values[15] += matrix.
values[15];
1314 template <
typename T>
1339 template <
typename T>
1342 values[0] -= matrix.
values[0];
1343 values[1] -= matrix.
values[1];
1344 values[2] -= matrix.
values[2];
1345 values[3] -= matrix.
values[3];
1346 values[4] -= matrix.
values[4];
1347 values[5] -= matrix.
values[5];
1348 values[6] -= matrix.
values[6];
1349 values[7] -= matrix.
values[7];
1350 values[8] -= matrix.
values[8];
1351 values[9] -= matrix.
values[9];
1352 values[10] -= matrix.
values[10];
1353 values[11] -= matrix.
values[11];
1354 values[12] -= matrix.
values[12];
1355 values[13] -= matrix.
values[13];
1356 values[14] -= matrix.
values[14];
1357 values[15] -= matrix.
values[15];
1362 template <
typename T>
1367 result.
values[ 0] = -values[ 0];
1368 result.
values[ 1] = -values[ 1];
1369 result.
values[ 2] = -values[ 2];
1370 result.
values[ 3] = -values[ 3];
1371 result.
values[ 4] = -values[ 4];
1372 result.
values[ 5] = -values[ 5];
1373 result.
values[ 6] = -values[ 6];
1374 result.
values[ 7] = -values[ 7];
1375 result.
values[ 8] = -values[ 8];
1376 result.
values[ 9] = -values[ 9];
1377 result.
values[10] = -values[10];
1378 result.
values[11] = -values[11];
1379 result.
values[12] = -values[12];
1380 result.
values[13] = -values[13];
1381 result.
values[14] = -values[14];
1386 template <
typename T>
1403 result.
values[10] = values[2] * matrix.
values[8] + values[6] * matrix.
values[9] + values[10] * matrix.
values[10] + values[14] * matrix.
values[11];
1404 result.
values[11] = values[3] * matrix.
values[8] + values[7] * matrix.
values[9] + values[11] * matrix.
values[10] + values[15] * matrix.
values[11];
1406 result.
values[12] = values[0] * matrix.
values[12] + values[4] * matrix.
values[13] + values[8] * matrix.
values[14] + values[12] * matrix.
values[15];
1407 result.
values[13] = values[1] * matrix.
values[12] + values[5] * matrix.
values[13] + values[9] * matrix.
values[14] + values[13] * matrix.
values[15];
1408 result.
values[14] = values[2] * matrix.
values[12] + values[6] * matrix.
values[13] + values[10] * matrix.
values[14] + values[14] * matrix.
values[15];
1409 result.
values[15] = values[3] * matrix.
values[12] + values[7] * matrix.
values[13] + values[11] * matrix.
values[14] + values[15] * matrix.
values[15];
1414 #if defined(OCEAN_HARDWARE_AVX_VERSION) && OCEAN_HARDWARE_AVX_VERSION >= 10
1432 __m256d c0 = _mm256_loadu_pd(values + 0);
1433 __m256d c1 = _mm256_loadu_pd(values + 4);
1434 __m256d c2 = _mm256_loadu_pd(values + 8);
1435 __m256d c3 = _mm256_loadu_pd(values + 12);
1439 __m256d v0 = _mm256_broadcast_sd(matrix.
data() + 0);
1440 __m256d r0 = _mm256_mul_pd(c0, v0);
1442 __m256d v1 = _mm256_broadcast_sd(matrix.
data() + 1);
1443 __m256d r1 = _mm256_mul_pd(c1, v1);
1445 r0 = _mm256_add_pd(r0, r1);
1447 __m256d v2 = _mm256_broadcast_sd(matrix.
data() + 2);
1448 __m256d r2 = _mm256_mul_pd(c2, v2);
1450 r0 = _mm256_add_pd(r0, r2);
1452 __m256d v3 = _mm256_broadcast_sd(matrix.
data() + 3);
1453 __m256d r3 = _mm256_mul_pd(c3, v3);
1455 r0 = _mm256_add_pd(r0, r3);
1459 _mm256_storeu_pd(result.
data(), r0);
1463 __m256d v4 = _mm256_broadcast_sd(matrix.
data() + 4);
1464 __m256d r4 = _mm256_mul_pd(c0, v4);
1466 __m256d v5 = _mm256_broadcast_sd(matrix.
data() + 5);
1467 __m256d r5 = _mm256_mul_pd(c1, v5);
1469 r4 = _mm256_add_pd(r4, r5);
1471 __m256d v6 = _mm256_broadcast_sd(matrix.
data() + 6);
1472 __m256d r6 = _mm256_mul_pd(c2, v6);
1474 r4 = _mm256_add_pd(r4, r6);
1476 __m256d v7 = _mm256_broadcast_sd(matrix.
data() + 7);
1477 __m256d r7 = _mm256_mul_pd(c3, v7);
1479 r4 = _mm256_add_pd(r4, r7);
1481 _mm256_storeu_pd(result.
data() + 4, r4);
1485 __m256d v8 = _mm256_broadcast_sd(matrix.
data() + 8);
1486 __m256d r8 = _mm256_mul_pd(c0, v8);
1488 __m256d v9 = _mm256_broadcast_sd(matrix.
data() + 9);
1489 __m256d r9 = _mm256_mul_pd(c1, v9);
1491 r8 = _mm256_add_pd(r8, r9);
1493 __m256d v10 = _mm256_broadcast_sd(matrix.
data() + 10);
1494 __m256d r10 = _mm256_mul_pd(c2, v10);
1496 r8 = _mm256_add_pd(r8, r10);
1498 __m256d v11 = _mm256_broadcast_sd(matrix.
data() + 11);
1499 __m256d r11 = _mm256_mul_pd(c3, v11);
1501 r8 = _mm256_add_pd(r8, r11);
1503 _mm256_storeu_pd(result.
data() + 8, r8);
1507 __m256d v12 = _mm256_broadcast_sd(matrix.
data() + 12);
1508 __m256d r12 = _mm256_mul_pd(c0, v12);
1510 __m256d v13 = _mm256_broadcast_sd(matrix.
data() + 13);
1511 __m256d r13 = _mm256_mul_pd(c1, v13);
1513 r12 = _mm256_add_pd(r12, r13);
1515 __m256d v14 = _mm256_broadcast_sd(matrix.
data() + 14);
1516 __m256d r14 = _mm256_mul_pd(c2, v14);
1518 r12 = _mm256_add_pd(r12, r14);
1520 __m256d v15 = _mm256_broadcast_sd(matrix.
data() + 15);
1521 __m256d r15 = _mm256_mul_pd(c3, v15);
1523 r12 = _mm256_add_pd(r12, r15);
1525 _mm256_storeu_pd(result.
data() + 12, r12);
1539 __m256 c0 = _mm256_broadcast_ps((
const __m128*)values + 0);
1540 __m256 c1 = _mm256_broadcast_ps((
const __m128*)values + 1);
1541 __m256 c2 = _mm256_broadcast_ps((
const __m128*)values + 2);
1542 __m256 c3 = _mm256_broadcast_ps((
const __m128*)values + 3);
1544 __m256 m01 = _mm256_loadu_ps(matrix.
data() + 0);
1545 __m256 m23 = _mm256_loadu_ps(matrix.
data() + 8);
1549 __m256 v0_4 = _mm256_permute_ps(m01, 0x00);
1550 __m256 r0 = _mm256_mul_ps(c0, v0_4);
1552 #ifdef OCEAN_COMPILER_MSC
1564 __m256 v1_5 = _mm256_permute_ps(m01, 0x55);
1565 __m256 r1 = _mm256_mul_ps(c1, v1_5);
1567 #ifdef OCEAN_COMPILER_MSC
1579 r0 = _mm256_add_ps(r0, r1);
1582 __m256 v2_6 = _mm256_permute_ps(m01, 0xAA);
1583 __m256 r2 = _mm256_mul_ps(c2, v2_6);
1585 r0 = _mm256_add_ps(r0, r2);
1588 __m256 v3_7 = _mm256_permute_ps(m01, 0xFF);
1589 __m256 r3 = _mm256_mul_ps(c3, v3_7);
1591 r0 = _mm256_add_ps(r0, r3);
1595 _mm256_storeu_ps(result.
data(), r0);
1600 __m256 v8_12 = _mm256_permute_ps(m23, 0x00);
1601 __m256 r8 = _mm256_mul_ps(c0, v8_12);
1604 __m256 v9_13 = _mm256_permute_ps(m23, 0x55);
1605 __m256 r9 = _mm256_mul_ps(c1, v9_13);
1607 r8 = _mm256_add_ps(r8, r9);
1610 __m256 v10_14 = _mm256_permute_ps(m23, 0xAA);
1611 __m256 r10 = _mm256_mul_ps(c2, v10_14);
1613 r8 = _mm256_add_ps(r8, r10);
1616 __m256 v11_15 = _mm256_permute_ps(m23, 0xFF);
1617 __m256 r11 = _mm256_mul_ps(c3, v11_15);
1619 r8 = _mm256_add_ps(r8, r11);
1621 _mm256_storeu_ps(result.
data() + 8, r8);
1628 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 10
1646 __m128 c0 = _mm_loadu_ps(values + 0);
1647 __m128 c1 = _mm_loadu_ps(values + 4);
1648 __m128 c2 = _mm_loadu_ps(values + 8);
1649 __m128 c3 = _mm_loadu_ps(values + 12);
1653 __m128 v0 = _mm_load1_ps(matrix.
data() + 0);
1654 __m128 r0 = _mm_mul_ps(c0, v0);
1656 __m128 v1 = _mm_load1_ps(matrix.
data() + 1);
1657 __m128 r1 = _mm_mul_ps(c1, v1);
1659 r0 = _mm_add_ps(r0, r1);
1661 __m128 v2 = _mm_load1_ps(matrix.
data() + 2);
1662 __m128 r2 = _mm_mul_ps(c2, v2);
1664 r0 = _mm_add_ps(r0, r2);
1666 __m128 v3 = _mm_load1_ps(matrix.
data() + 3);
1667 __m128 r3 = _mm_mul_ps(c3, v3);
1669 r0 = _mm_add_ps(r0, r3);
1673 _mm_storeu_ps(result.
data(), r0);
1677 __m128 v4 = _mm_load1_ps(matrix.
data() + 4);
1678 __m128 r4 = _mm_mul_ps(c0, v4);
1680 __m128 v5 = _mm_load1_ps(matrix.
data() + 5);
1681 __m128 r5 = _mm_mul_ps(c1, v5);
1683 r4 = _mm_add_ps(r4, r5);
1685 __m128 v6 = _mm_load1_ps(matrix.
data() + 6);
1686 __m128 r6 = _mm_mul_ps(c2, v6);
1688 r4 = _mm_add_ps(r4, r6);
1690 __m128 v7 = _mm_load1_ps(matrix.
data() + 7);
1691 __m128 r7 = _mm_mul_ps(c3, v7);
1693 r4 = _mm_add_ps(r4, r7);
1695 _mm_storeu_ps(result.
data() + 4, r4);
1699 __m128 v8 = _mm_load1_ps(matrix.
data() + 8);
1700 __m128 r8 = _mm_mul_ps(c0, v8);
1702 __m128 v9 = _mm_load1_ps(matrix.
data() + 9);
1703 __m128 r9 = _mm_mul_ps(c1, v9);
1705 r8 = _mm_add_ps(r8, r9);
1707 __m128 v10 = _mm_load1_ps(matrix.
data() + 10);
1708 __m128 r10 = _mm_mul_ps(c2, v10);
1710 r8 = _mm_add_ps(r8, r10);
1712 __m128 v11 = _mm_load1_ps(matrix.
data() + 11);
1713 __m128 r11 = _mm_mul_ps(c3, v11);
1715 r8 = _mm_add_ps(r8, r11);
1717 _mm_storeu_ps(result.
data() + 8, r8);
1721 __m128 v12 = _mm_load1_ps(matrix.
data() + 12);
1722 __m128 r12 = _mm_mul_ps(c0, v12);
1724 __m128 v13 = _mm_load1_ps(matrix.
data() + 13);
1725 __m128 r13 = _mm_mul_ps(c1, v13);
1727 r12 = _mm_add_ps(r12, r13);
1729 __m128 v14 = _mm_load1_ps(matrix.
data() + 14);
1730 __m128 r14 = _mm_mul_ps(c2, v14);
1732 r12 = _mm_add_ps(r12, r14);
1734 __m128 v15 = _mm_load1_ps(matrix.
data() + 15);
1735 __m128 r15 = _mm_mul_ps(c3, v15);
1737 r12 = _mm_add_ps(r12, r15);
1739 _mm_storeu_ps(result.
data() + 12, r12);
1748 template <
typename T>
1753 result.
values[0] = values[0] * matrix[0] + values[4] * matrix[1] + values[8] * matrix[2];
1754 result.
values[1] = values[1] * matrix[0] + values[5] * matrix[1] + values[9] * matrix[2];
1755 result.
values[2] = values[2] * matrix[0] + values[6] * matrix[1] + values[10] * matrix[2];
1756 result.
values[3] = values[3] * matrix[0] + values[7] * matrix[1] + values[11] * matrix[2];
1758 result.
values[4] = values[0] * matrix[4] + values[4] * matrix[5] + values[8] * matrix[6];
1759 result.
values[5] = values[1] * matrix[4] + values[5] * matrix[5] + values[9] * matrix[6];
1760 result.
values[6] = values[2] * matrix[4] + values[6] * matrix[5] + values[10] * matrix[6];
1761 result.
values[7] = values[3] * matrix[4] + values[7] * matrix[5] + values[11] * matrix[6];
1763 result.
values[8] = values[0] * matrix[8] + values[4] * matrix[9] + values[8] * matrix[10];
1764 result.
values[9] = values[1] * matrix[8] + values[5] * matrix[9] + values[9] * matrix[10];
1765 result.
values[10] = values[2] * matrix[8] + values[6] * matrix[9] + values[10] * matrix[10];
1766 result.
values[11] = values[3] * matrix[8] + values[7] * matrix[9] + values[11] * matrix[10];
1768 result.
values[12] = values[0] * matrix[12] + values[4] * matrix[13] + values[8] * matrix[14] + values[12];
1769 result.
values[13] = values[1] * matrix[12] + values[5] * matrix[13] + values[9] * matrix[14] + values[13];
1770 result.
values[14] = values[2] * matrix[12] + values[6] * matrix[13] + values[10] * matrix[14] + values[14];
1771 result.
values[15] = values[3] * matrix[12] + values[7] * matrix[13] + values[11] * matrix[14] + values[15];
1776 template <
typename T>
1779 const T w = values[3] * vector[0] + values[7] * vector[1] + values[11] * vector[2] + values[15];
1782 const T factor = 1 / w;
1784 return VectorT3<T>((values[0] * vector[0] + values[4] * vector[1] + values[8] * vector[2] + values[12]) * factor,
1785 (values[1] * vector[0] + values[5] * vector[1] + values[9] * vector[2] + values[13]) * factor,
1786 (values[2] * vector[0] + values[6] * vector[1] + values[10] * vector[2] + values[14]) * factor);
1789 template <
typename T>
1792 return VectorT4<T>(values[0] * vector[0] + values[4] * vector[1] + values[8] * vector[2] + values[12] * vector[3],
1793 values[1] * vector[0] + values[5] * vector[1] + values[9] * vector[2] + values[13] * vector[3],
1794 values[2] * vector[0] + values[6] * vector[1] + values[10] * vector[2] + values[14] * vector[3],
1795 values[3] * vector[0] + values[7] * vector[1] + values[11] * vector[2] + values[15] * vector[3]);
1798 #if defined(OCEAN_HARDWARE_AVX_VERSION) && OCEAN_HARDWARE_AVX_VERSION >= 10
1800 #ifdef OCEAN_USE_SLOWER_IMPLEMENTATION
1818 __m256d row0 = _mm256_loadu_pd(values + 0);
1819 __m256d row1 = _mm256_loadu_pd(values + 4);
1820 __m256d row2 = _mm256_loadu_pd(values + 8);
1821 __m256d row3 = _mm256_loadu_pd(values + 12);
1824 __m256d v = _mm256_loadu_pd(vector.
data());
1834 __m256d temp0 = _mm256_shuffle_pd(row0, row1, 0x00);
1836 __m256d temp2 = _mm256_shuffle_pd(row0, row1, 0x0F);
1838 __m256d temp1 = _mm256_shuffle_pd(row2, row3, 0x00);
1840 __m256d temp3 = _mm256_shuffle_pd(row2, row3, 0x0F);
1843 row0 = _mm256_permute2f128_pd(temp0, temp1, 0x20);
1845 row1 = _mm256_permute2f128_pd(temp2, temp3, 0x20);
1847 row2 = _mm256_permute2f128_pd(temp0, temp1, 0x31);
1849 row3 = _mm256_permute2f128_pd(temp2, temp3, 0x31);
1851 #ifdef OCEAN_COMPILER_MSC
1852 ocean_assert(row0.m256d_f64[0] == values[0] && row0.m256d_f64[1] == values[4] && row0.m256d_f64[2] == values[ 8] && row0.m256d_f64[3] == values[12]);
1853 ocean_assert(row1.m256d_f64[0] == values[1] && row1.m256d_f64[1] == values[5] && row1.m256d_f64[2] == values[ 9] && row1.m256d_f64[3] == values[13]);
1854 ocean_assert(row2.m256d_f64[0] == values[2] && row2.m256d_f64[1] == values[6] && row2.m256d_f64[2] == values[10] && row2.m256d_f64[3] == values[14]);
1855 ocean_assert(row3.m256d_f64[0] == values[3] && row3.m256d_f64[1] == values[7] && row3.m256d_f64[2] == values[11] && row3.m256d_f64[3] == values[15]);
1860 __m256d r0v = _mm256_mul_pd(row0, v);
1861 __m256d r1v = _mm256_mul_pd(row1, v);
1862 __m256d r2v = _mm256_mul_pd(row2, v);
1863 __m256d r3v = _mm256_mul_pd(row3, v);
1866 __m256d sum_interleaved_r0_r1 = _mm256_hadd_pd(r0v, r1v);
1867 __m256d sum_interleaved_r2_r3 = _mm256_hadd_pd(r2v, r3v);
1870 __m256d sum_first = _mm256_permute2f128_pd(sum_interleaved_r0_r1, sum_interleaved_r2_r3, 0x20);
1871 __m256d sum_second = _mm256_permute2f128_pd(sum_interleaved_r0_r1, sum_interleaved_r2_r3, 0x31);
1874 __m256d sum = _mm256_add_pd(sum_first, sum_second);
1877 _mm256_storeu_pd(result.
data(), sum);
1879 ocean_assert(
NumericD::isEqual(result[0], values[0] * vector[0] + values[4] * vector[1] + values[ 8] * vector[2] + values[12] * vector[3],
NumericD::eps() * 100));
1880 ocean_assert(
NumericD::isEqual(result[1], values[1] * vector[0] + values[5] * vector[1] + values[ 9] * vector[2] + values[13] * vector[3],
NumericD::eps() * 100));
1881 ocean_assert(
NumericD::isEqual(result[2], values[2] * vector[0] + values[6] * vector[1] + values[10] * vector[2] + values[14] * vector[3],
NumericD::eps() * 100));
1882 ocean_assert(
NumericD::isEqual(result[3], values[3] * vector[0] + values[7] * vector[1] + values[11] * vector[2] + values[15] * vector[3],
NumericD::eps() * 100));
1904 __m256d v0 = _mm256_broadcast_sd(vector.
data() + 0);
1907 __m256d c0 = _mm256_loadu_pd(values + 0);
1910 __m256d r0 = _mm256_mul_pd(c0, v0);
1914 __m256d v1 = _mm256_broadcast_sd(vector.
data() + 1);
1915 __m256d c1 = _mm256_loadu_pd(values + 4);
1916 __m256d r1 = _mm256_mul_pd(c1, v1);
1919 r0 = _mm256_add_pd(r0, r1);
1923 __m256d v2 = _mm256_broadcast_sd(vector.
data() + 2);
1924 __m256d c2 = _mm256_loadu_pd(values + 8);
1925 __m256d r2 = _mm256_mul_pd(c2, v2);
1928 r0 = _mm256_add_pd(r0, r2);
1932 __m256d v3 = _mm256_broadcast_sd(vector.
data() + 3);
1933 __m256d c3 = _mm256_loadu_pd(values + 12);
1934 __m256d r3 = _mm256_mul_pd(c3, v3);
1937 r0 = _mm256_add_pd(r0, r3);
1942 _mm256_storeu_pd(result.
data(), r0);
1951 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 20
1976 __m128d v0 = _mm_load1_pd(vector.
data() + 0);
1979 __m128d c0a = _mm_loadu_pd(values + 0);
1980 __m128d c0b = _mm_loadu_pd(values + 2);
1983 __m128d r0a = _mm_mul_pd(c0a, v0);
1984 __m128d r0b = _mm_mul_pd(c0b, v0);
1988 __m128d v1 = _mm_load1_pd(vector.
data() + 1);
1990 __m128d c1a = _mm_loadu_pd(values + 4);
1991 __m128d c1b = _mm_loadu_pd(values + 6);
1993 __m128d r1a = _mm_mul_pd(c1a, v1);
1994 __m128d r1b = _mm_mul_pd(c1b, v1);
1997 r0a = _mm_add_pd(r0a, r1a);
1998 r0b = _mm_add_pd(r0b, r1b);
2002 __m128d v2 = _mm_load1_pd(vector.
data() + 2);
2004 __m128d c2a = _mm_loadu_pd(values + 8);
2005 __m128d c2b = _mm_loadu_pd(values + 10);
2007 __m128d r2a = _mm_mul_pd(c2a, v2);
2008 __m128d r2b = _mm_mul_pd(c2b, v2);
2011 r0a = _mm_add_pd(r0a, r2a);
2012 r0b = _mm_add_pd(r0b, r2b);
2016 __m128d v3 = _mm_load1_pd(vector.
data() + 3);
2018 __m128d c3a = _mm_loadu_pd(values + 12);
2019 __m128d c3b = _mm_loadu_pd(values + 14);
2021 __m128d r3a = _mm_mul_pd(c3a, v3);
2022 __m128d r3b = _mm_mul_pd(c3b, v3);
2025 r0a = _mm_add_pd(r0a, r3a);
2026 r0b = _mm_add_pd(r0b, r3b);
2031 _mm_storeu_pd(result.
data() + 0, r0a);
2032 _mm_storeu_pd(result.
data() + 2, r0b);
2041 #ifdef OCEAN_USE_SLOWER_IMPLEMENTATION
2045 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
2062 __m128 row0 = _mm_loadu_ps(values + 0);
2063 __m128 row1 = _mm_loadu_ps(values + 4);
2064 __m128 row2 = _mm_loadu_ps(values + 8);
2065 __m128 row3 = _mm_loadu_ps(values + 12);
2068 __m128 v = _mm_loadu_ps(vector.
data());
2078 __m128 temp0 = _mm_shuffle_ps(row0, row1, 0x44);
2080 __m128 temp2 = _mm_shuffle_ps(row0, row1, 0xEE);
2082 __m128 temp1 = _mm_shuffle_ps(row2, row3, 0x44);
2084 __m128 temp3 = _mm_shuffle_ps(row2, row3, 0xEE);
2087 row0 = _mm_shuffle_ps(temp0, temp1, 0x88);
2089 row1 = _mm_shuffle_ps(temp0, temp1, 0xDD);
2091 row2 = _mm_shuffle_ps(temp2, temp3, 0x88);
2093 row3 = _mm_shuffle_ps(temp2, temp3, 0xDD);
2095 #ifdef OCEAN_COMPILER_MSC
2096 ocean_assert(row0.m128_f32[0] == values[0] && row0.m128_f32[1] == values[4] && row0.m128_f32[2] == values[ 8] && row0.m128_f32[3] == values[12]);
2097 ocean_assert(row1.m128_f32[0] == values[1] && row1.m128_f32[1] == values[5] && row1.m128_f32[2] == values[ 9] && row1.m128_f32[3] == values[13]);
2098 ocean_assert(row2.m128_f32[0] == values[2] && row2.m128_f32[1] == values[6] && row2.m128_f32[2] == values[10] && row2.m128_f32[3] == values[14]);
2099 ocean_assert(row3.m128_f32[0] == values[3] && row3.m128_f32[1] == values[7] && row3.m128_f32[2] == values[11] && row3.m128_f32[3] == values[15]);
2103 row0 = _mm_dp_ps(row0, v, 0xF1);
2106 row1 = _mm_dp_ps(row1, v, 0xF2);
2107 row2 = _mm_dp_ps(row2, v, 0xF4);
2108 row3 = _mm_dp_ps(row3, v, 0xF8);
2111 __m128 result01 = _mm_or_ps(row0, row1);
2112 __m128 result23 = _mm_or_ps(row2, row3);
2113 __m128 result03 = _mm_or_ps(result01, result23);
2116 _mm_storeu_ps(result.
data(), result03);
2125 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 10
2151 __m128 v0 = _mm_load1_ps(vector.
data() + 0);
2154 __m128 c0 = _mm_loadu_ps(values + 0);
2157 __m128 r0 = _mm_mul_ps(c0, v0);
2161 __m128 v1 = _mm_load1_ps(vector.
data() + 1);
2162 __m128 c1 = _mm_loadu_ps(values + 4);
2163 __m128 r1 = _mm_mul_ps(c1, v1);
2166 r0 = _mm_add_ps(r0, r1);
2170 __m128 v2 = _mm_load1_ps(vector.
data() + 2);
2171 __m128 c2 = _mm_loadu_ps(values + 8);
2172 __m128 r2 = _mm_mul_ps(c2, v2);
2175 r0 = _mm_add_ps(r0, r2);
2179 __m128 v3 = _mm_load1_ps(vector.
data() + 3);
2180 __m128 c3 = _mm_loadu_ps(values + 12);
2181 __m128 r3 = _mm_mul_ps(c3, v3);
2184 r0 = _mm_add_ps(r0, r3);
2189 _mm_storeu_ps(result.
data(), r0);
2198 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
2218 float64x2_t v0 = vld1q_dup_f64(vector.
data() + 0);
2221 float64x2_t c0a = vld1q_f64(values + 0);
2222 float64x2_t c0b = vld1q_f64(values + 2);
2225 float64x2_t r0a = vmulq_f64(c0a, v0);
2226 float64x2_t r0b = vmulq_f64(c0b, v0);
2230 float64x2_t v1 = vld1q_dup_f64(vector.
data() + 1);
2232 float64x2_t c1a = vld1q_f64(values + 4);
2233 float64x2_t c1b = vld1q_f64(values + 6);
2235 float64x2_t r1a = vmulq_f64(c1a, v1);
2236 float64x2_t r1b = vmulq_f64(c1b, v1);
2239 r0a = vaddq_f64(r0a, r1a);
2240 r0b = vaddq_f64(r0b, r1b);
2244 float64x2_t v2 = vld1q_dup_f64(vector.
data() + 2);
2246 float64x2_t c2a = vld1q_f64(values + 8);
2247 float64x2_t c2b = vld1q_f64(values + 10);
2249 float64x2_t r2a = vmulq_f64(c2a, v2);
2250 float64x2_t r2b = vmulq_f64(c2b, v2);
2253 r0a = vaddq_f64(r0a, r2a);
2254 r0b = vaddq_f64(r0b, r2b);
2258 float64x2_t v3 = vld1q_dup_f64(vector.
data() + 3);
2260 float64x2_t c3a = vld1q_f64(values + 12);
2261 float64x2_t c3b = vld1q_f64(values + 14);
2263 float64x2_t r3a = vmulq_f64(c3a, v3);
2264 float64x2_t r3b = vmulq_f64(c3b, v3);
2267 r0a = vaddq_f64(r0a, r3a);
2268 r0b = vaddq_f64(r0b, r3b);
2273 vst1q_f64(result.
data() + 0, r0a);
2274 vst1q_f64(result.
data() + 2, r0b);
2297 float32x4_t v0 = vld1q_dup_f32(vector.
data() + 0);
2300 float32x4_t c0 = vld1q_f32(values + 0);
2303 float32x4_t r0 = vmulq_f32(c0, v0);
2307 float32x4_t v1 = vld1q_dup_f32(vector.
data() + 1);
2308 float32x4_t c1 = vld1q_f32(values + 4);
2309 float32x4_t r1 = vmulq_f32(c1, v1);
2312 r0 = vaddq_f32(r0, r1);
2316 float32x4_t v2 = vld1q_dup_f32(vector.
data() + 2);
2317 float32x4_t c2 = vld1q_f32(values + 8);
2318 float32x4_t r2 = vmulq_f32(c2, v2);
2321 r0 = vaddq_f32(r0, r2);
2325 float32x4_t v3 = vld1q_dup_f32(vector.
data() + 3);
2326 float32x4_t c3 = vld1q_f32(values + 12);
2327 float32x4_t r3 = vmulq_f32(c3, v3);
2330 r0 = vaddq_f32(r0, r3);
2335 vst1q_f32(result.
data(), r0);
2342 template <
typename T>
2347 result.
values[0] *= value;
2348 result.
values[1] *= value;
2349 result.
values[2] *= value;
2350 result.
values[3] *= value;
2351 result.
values[4] *= value;
2352 result.
values[5] *= value;
2353 result.
values[6] *= value;
2354 result.
values[7] *= value;
2355 result.
values[8] *= value;
2356 result.
values[9] *= value;
2357 result.
values[10] *= value;
2358 result.
values[11] *= value;
2359 result.
values[12] *= value;
2360 result.
values[13] *= value;
2361 result.
values[14] *= value;
2362 result.
values[15] *= value;
2367 template <
typename T>
2380 values[10] *= value;
2381 values[11] *= value;
2382 values[12] *= value;
2383 values[13] *= value;
2384 values[14] *= value;
2385 values[15] *= value;
2390 template <
typename T>
2409 ocean_assert(aspectRatio > 0);
2410 ocean_assert(nearDistance > 0);
2411 ocean_assert(nearDistance < farDistance);
2416 ocean_assert(matrix(1, 0) == 0 && matrix(2, 0) == 0 && matrix(3, 0) == 0);
2417 ocean_assert(matrix(0, 1) == 0 && matrix(2, 1) == 0 && matrix(3, 1) == 0);
2418 ocean_assert(matrix(0, 2) == 0 && matrix(1, 2) == 0);
2419 ocean_assert(matrix(0, 3) == 0 && matrix(1, 3) == 0 && matrix(3, 3) == 0);
2424 const T factor = T(1.0) / (nearDistance - farDistance);
2426 matrix(0, 0) = f / aspectRatio;
2428 matrix(2, 2) = (farDistance + nearDistance) * factor;
2429 matrix(3, 2) = -T(1.0);
2430 matrix(2, 3) = (T(2.0) * farDistance * nearDistance) * factor;
2435 template <
typename T>
2453 ocean_assert(anyCamera.
isValid());
2455 ocean_assert(nearDistance > 0);
2456 ocean_assert(nearDistance < farDistance);
2460 ocean_assert(fxPixel > T(1) && fyPixel > T(1));
2465 const T width_2 = T(anyCamera.
width()) / T(2);
2466 const T height_2 = T(anyCamera.
height()) / T(2);
2471 const T fx = fxPixel / width_2;
2472 const T fy = fyPixel / height_2;
2474 const T mx = (mxPixel - width_2) / width_2;
2475 const T my = (myPixel - height_2) / height_2;
2477 const T factor = T(1.0) / (nearDistance - farDistance);
2485 matrix(2, 2) = (farDistance + nearDistance) * factor;
2486 matrix(3, 2) = -T(1);
2487 matrix(2, 3) = (T(2) * farDistance * nearDistance) * factor;
2492 template <
typename T>
2513 ocean_assert(matrix(1, 0) == 0 && matrix(2, 0) == 0 && matrix(3, 0) == 0);
2514 ocean_assert(matrix(0, 1) == 0 && matrix(2, 1) == 0 && matrix(3, 1) == 0);
2515 ocean_assert(matrix(0, 3) == 0 && matrix(1, 3) == 0 && matrix(3, 3) == 0);
2517 const T rightLeft = T(1.0) / (right - left);
2518 const T near2 = nearDistance * T(2.0);
2520 matrix(0, 0) = near2 * rightLeft;
2521 matrix(0, 2) = (right + left) * rightLeft;
2523 const T topBottom = T(1.0) / (top - bottom);
2525 matrix(1, 1) = near2 * topBottom;
2526 matrix(1, 2) = (top + bottom) * topBottom;
2528 const T farNear = T(1.0) / (farDistance - nearDistance);
2530 matrix(2, 2) = -(farDistance + nearDistance) * farNear;
2531 matrix(2, 3) = -T(2.0) * farDistance * nearDistance * farNear;
2533 matrix(3, 2) = -T(1.0);
2538 template <
typename T>
2542 ocean_assert(nearDistance >=
NumericT<T>::eps() && farDistance > nearDistance);
2549 const VectorT3<T> leftTop(width * -T(0.5), height * T(0.5), 0);
2550 const VectorT3<T> rightBottom(width * T(0.5), height * -T(0.5), 0);
2552 const VectorT3<T> leftTopInCamera(inversedViewingMatrix * leftTop);
2553 const VectorT3<T> rightBottomInCamera(inversedViewingMatrix * rightBottom);
2555 const T factor = nearDistance / planeDistance;
2557 return frustumMatrix(factor * leftTopInCamera.
x(), factor * rightBottomInCamera.
x(), factor * leftTopInCamera.
y(), factor * rightBottomInCamera.
y(), nearDistance, farDistance);
2560 template <
typename T>
2563 ocean_assert((vectors && results) || number == 0);
2565 for (
size_t n = 0; n < number; ++n)
2567 results[n] = matrix * vectors[n];
2571 #if defined(OCEAN_HARDWARE_AVX_VERSION) && OCEAN_HARDWARE_AVX_VERSION >= 10
2587 __m256d c0 = _mm256_loadu_pd(matrix.
values + 0);
2588 __m256d c1 = _mm256_loadu_pd(matrix.
values + 4);
2589 __m256d c2 = _mm256_loadu_pd(matrix.
values + 8);
2590 __m256d c3 = _mm256_loadu_pd(matrix.
values + 12);
2592 for (
size_t n = 0; n < number; ++n)
2594 __m256d v0 = _mm256_broadcast_sd(vectors[n].data() + 0);
2595 __m256d r0 = _mm256_mul_pd(c0, v0);
2597 __m256d v1 = _mm256_broadcast_sd(vectors[n].data() + 1);
2598 __m256d r1 = _mm256_mul_pd(c1, v1);
2600 r0 = _mm256_add_pd(r0, r1);
2602 __m256d v2 = _mm256_broadcast_sd(vectors[n].data() + 2);
2603 __m256d r2 = _mm256_mul_pd(c2, v2);
2605 r0 = _mm256_add_pd(r0, r2);
2607 __m256d v3 = _mm256_broadcast_sd(vectors[n].data() + 3);
2608 __m256d r3 = _mm256_mul_pd(c3, v3);
2610 r0 = _mm256_add_pd(r0, r3);
2612 _mm256_storeu_pd(results[n].data(), r0);
2618 #ifdef OCEAN_USE_SLOWER_IMPLEMENTATION
2622 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
2639 __m128 row0 = _mm_loadu_ps(matrix.
values + 0);
2640 __m128 row1 = _mm_loadu_ps(matrix.
values + 4);
2641 __m128 row2 = _mm_loadu_ps(matrix.
values + 8);
2642 __m128 row3 = _mm_loadu_ps(matrix.
values + 12);
2652 __m128 temp0 = _mm_shuffle_ps(row0, row1, 0x44);
2654 __m128 temp2 = _mm_shuffle_ps(row0, row1, 0xEE);
2656 __m128 temp1 = _mm_shuffle_ps(row2, row3, 0x44);
2658 __m128 temp3 = _mm_shuffle_ps(row2, row3, 0xEE);
2661 row0 = _mm_shuffle_ps(temp0, temp1, 0x88);
2663 row1 = _mm_shuffle_ps(temp0, temp1, 0xDD);
2665 row2 = _mm_shuffle_ps(temp2, temp3, 0x88);
2667 row3 = _mm_shuffle_ps(temp2, temp3, 0xDD);
2669 #ifdef OCEAN_COMPILER_MSC
2670 ocean_assert(row0.m128_f32[0] == matrix.
values[0] && row0.m128_f32[1] == matrix.
values[4] && row0.m128_f32[2] == matrix.
values[ 8] && row0.m128_f32[3] == matrix.
values[12]);
2671 ocean_assert(row1.m128_f32[0] == matrix.
values[1] && row1.m128_f32[1] == matrix.
values[5] && row1.m128_f32[2] == matrix.
values[ 9] && row1.m128_f32[3] == matrix.
values[13]);
2672 ocean_assert(row2.m128_f32[0] == matrix.
values[2] && row2.m128_f32[1] == matrix.
values[6] && row2.m128_f32[2] == matrix.
values[10] && row2.m128_f32[3] == matrix.
values[14]);
2673 ocean_assert(row3.m128_f32[0] == matrix.
values[3] && row3.m128_f32[1] == matrix.
values[7] && row3.m128_f32[2] == matrix.
values[11] && row3.m128_f32[3] == matrix.
values[15]);
2676 for (
size_t n = 0u; n < number; ++n)
2679 __m128 v = _mm_loadu_ps(vectors[n].data());
2682 __m128 dot0 = _mm_dp_ps(row0, v, 0xF1);
2685 __m128 dot1 = _mm_dp_ps(row1, v, 0xF2);
2686 __m128 dot2 = _mm_dp_ps(row2, v, 0xF4);
2687 __m128 dot3 = _mm_dp_ps(row3, v, 0xF8);
2690 __m128 result01 = _mm_or_ps(dot0, dot1);
2691 __m128 result23 = _mm_or_ps(dot2, dot3);
2692 __m128 result03 = _mm_or_ps(result01, result23);
2694 _mm_storeu_ps(results[n].data(), result03);
2702 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 20
2717 __m128d c0a = _mm_loadu_pd(matrix.
values + 0);
2718 __m128d c0b = _mm_loadu_pd(matrix.
values + 2);
2719 __m128d c1a = _mm_loadu_pd(matrix.
values + 4);
2720 __m128d c1b = _mm_loadu_pd(matrix.
values + 6);
2721 __m128d c2a = _mm_loadu_pd(matrix.
values + 8);
2722 __m128d c2b = _mm_loadu_pd(matrix.
values + 10);
2723 __m128d c3a = _mm_loadu_pd(matrix.
values + 12);
2724 __m128d c3b = _mm_loadu_pd(matrix.
values + 14);
2726 for (
size_t n = 0u; n < number; ++n)
2728 __m128d v0 = _mm_load1_pd(vectors[n].data() + 0);
2729 __m128d v1 = _mm_load1_pd(vectors[n].data() + 1);
2730 __m128d v2 = _mm_load1_pd(vectors[n].data() + 2);
2731 __m128d v3 = _mm_load1_pd(vectors[n].data() + 3);
2734 __m128d r0a = _mm_mul_pd(c0a, v0);
2735 __m128d r0b = _mm_mul_pd(c0b, v0);
2738 __m128d r1a = _mm_mul_pd(c1a, v1);
2739 __m128d r1b = _mm_mul_pd(c1b, v1);
2741 r0a = _mm_add_pd(r0a, r1a);
2742 r0b = _mm_add_pd(r0b, r1b);
2745 __m128d r2a = _mm_mul_pd(c2a, v2);
2746 __m128d r2b = _mm_mul_pd(c2b, v2);
2747 r0a = _mm_add_pd(r0a, r2a);
2748 r0b = _mm_add_pd(r0b, r2b);
2751 __m128d r3a = _mm_mul_pd(c3a, v3);
2752 __m128d r3b = _mm_mul_pd(c3b, v3);
2753 r0a = _mm_add_pd(r0a, r3a);
2754 r0b = _mm_add_pd(r0b, r3b);
2756 _mm_storeu_pd(results[n].data() + 0, r0a);
2757 _mm_storeu_pd(results[n].data() + 2, r0b);
2763 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 10
2778 __m128 c0 = _mm_loadu_ps(matrix.
values + 0);
2779 __m128 c1 = _mm_loadu_ps(matrix.
values + 4);
2780 __m128 c2 = _mm_loadu_ps(matrix.
values + 8);
2781 __m128 c3 = _mm_loadu_ps(matrix.
values + 12);
2783 for (
size_t n = 0u; n < number; ++n)
2785 __m128 v0 = _mm_load1_ps(vectors[n].data() + 0);
2786 __m128 v1 = _mm_load1_ps(vectors[n].data() + 1);
2787 __m128 v2 = _mm_load1_ps(vectors[n].data() + 2);
2788 __m128 v3 = _mm_load1_ps(vectors[n].data() + 3);
2791 __m128 r0 = _mm_mul_ps(c0, v0);
2794 __m128 r1 = _mm_mul_ps(c1, v1);
2796 r0 = _mm_add_ps(r0, r1);
2799 __m128 r2 = _mm_mul_ps(c2, v2);
2800 r0 = _mm_add_ps(r0, r2);
2803 __m128 r3 = _mm_mul_ps(c3, v3);
2804 r0 = _mm_add_ps(r0, r3);
2806 _mm_storeu_ps(results[n].data(), r0);
2816 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
2826 float64x2_t c0a = vld1q_f64(matrix.
values + 0);
2827 float64x2_t c0b = vld1q_f64(matrix.
values + 2);
2828 float64x2_t c1a = vld1q_f64(matrix.
values + 4);
2829 float64x2_t c1b = vld1q_f64(matrix.
values + 6);
2830 float64x2_t c2a = vld1q_f64(matrix.
values + 8);
2831 float64x2_t c2b = vld1q_f64(matrix.
values + 10);
2832 float64x2_t c3a = vld1q_f64(matrix.
values + 12);
2833 float64x2_t c3b = vld1q_f64(matrix.
values + 14);
2835 for (
size_t n = 0u; n < number; ++n)
2837 float64x2_t v0 = vld1q_dup_f64(vectors[n].data() + 0);
2838 float64x2_t v1 = vld1q_dup_f64(vectors[n].data() + 1);
2839 float64x2_t v2 = vld1q_dup_f64(vectors[n].data() + 2);
2840 float64x2_t v3 = vld1q_dup_f64(vectors[n].data() + 3);
2842 float64x2_t r0a = vmulq_f64(c0a, v0);
2843 float64x2_t r0b = vmulq_f64(c0b, v0);
2845 float64x2_t r1a = vmulq_f64(c1a, v1);
2846 float64x2_t r1b = vmulq_f64(c1b, v1);
2848 r0a = vaddq_f64(r0a, r1a);
2849 r0b = vaddq_f64(r0b, r1b);
2851 float64x2_t r2a = vmulq_f64(c2a, v2);
2852 float64x2_t r2b = vmulq_f64(c2b, v2);
2854 r0a = vaddq_f64(r0a, r2a);
2855 r0b = vaddq_f64(r0b, r2b);
2857 float64x2_t r3a = vmulq_f64(c3a, v3);
2858 float64x2_t r3b = vmulq_f64(c3b, v3);
2860 r0a = vaddq_f64(r0a, r3a);
2861 r0b = vaddq_f64(r0b, r3b);
2863 vst1q_f64(results[n].data() + 0, r0a);
2864 vst1q_f64(results[n].data() + 2, r0b);
2876 float32x4_t c0 = vld1q_f32(matrix.
values + 0);
2877 float32x4_t c1 = vld1q_f32(matrix.
values + 4);
2878 float32x4_t c2 = vld1q_f32(matrix.
values + 8);
2879 float32x4_t c3 = vld1q_f32(matrix.
values + 12);
2881 for (
size_t n = 0u; n < number; ++n)
2883 float32x4_t v0 = vld1q_dup_f32(vectors[n].data() + 0);
2884 float32x4_t v1 = vld1q_dup_f32(vectors[n].data() + 1);
2885 float32x4_t v2 = vld1q_dup_f32(vectors[n].data() + 2);
2886 float32x4_t v3 = vld1q_dup_f32(vectors[n].data() + 3);
2889 float32x4_t r0 = vmulq_f32(c0, v0);
2892 float32x4_t r1 = vmulq_f32(c1, v1);
2894 r0 = vaddq_f32(r0, r1);
2897 float32x4_t r2 = vmulq_f32(c2, v2);
2899 r0 = vaddq_f32(r0, r2);
2902 float32x4_t r3 = vmulq_f32(c3, v3);
2904 r0 = vaddq_f32(r0, r3);
2906 vst1q_f32(results[n].data(), r0);
2912 template <
typename T>
2913 template <
typename U>
2916 std::vector< SquareMatrixT4<T> > result;
2917 result.reserve(matrices.size());
2919 for (
typename std::vector<
SquareMatrixT4<U> >::const_iterator i = matrices.begin(); i != matrices.end(); ++i)
2941 template <
typename T>
2942 template <
typename U>
2945 std::vector< SquareMatrixT4<T> > result;
2946 result.reserve(size);
2948 for (
size_t n = 0; n < size; ++n)
2956 template <
typename T>
2959 ocean_assert(row0 < 4u && row1 < 4u);
2966 T* first = values + row0;
2967 T* second = values + row1;
2992 template <
typename T>
2995 ocean_assert(row < 4u);
2997 T* element = values + row;
3008 template <
typename T>
3011 ocean_assert(targetRow < 4u && sourceRow < 4u);
3012 ocean_assert(targetRow != sourceRow);
3014 T* target = values + targetRow;
3015 T* source = values + sourceRow;
3017 *target += *source * scalar;
3021 *target += *source * scalar;
3025 *target += *source * scalar;
3029 *target += *source * scalar;
3032 template <
typename T>
3035 stream <<
"|" << matrix(0, 0) <<
", " << matrix(0, 1) <<
", " << matrix(0, 2) <<
", " << matrix(0, 3) <<
"|" << std::endl;
3036 stream <<
"|" << matrix(1, 0) <<
", " << matrix(1, 1) <<
", " << matrix(1, 2) <<
", " << matrix(1, 3) <<
"|" << std::endl;
3037 stream <<
"|" << matrix(2, 0) <<
", " << matrix(2, 1) <<
", " << matrix(2, 2) <<
", " << matrix(2, 3) <<
"|" << std::endl;
3038 stream <<
"|" << matrix(3, 0) <<
", " << matrix(3, 1) <<
", " << matrix(3, 2) <<
", " << matrix(3, 3) <<
"|";
3043 template <
bool tActive,
typename T>
3044 MessageObject<tActive>&
operator<<(MessageObject<tActive>& messageObject,
const SquareMatrixT4<T>& matrix)
3046 return messageObject <<
"|" << matrix(0, 0) <<
", " << matrix(0, 1) <<
", " << matrix(0, 2) <<
", " << matrix(0, 3) <<
"|\n|"
3047 << matrix(1, 0) <<
", " << matrix(1, 1) <<
", " << matrix(1, 2) <<
", " << matrix(1, 3) <<
"|\n|"
3048 << matrix(2, 0) <<
", " << matrix(2, 1) <<
", " << matrix(2, 2) <<
", " << matrix(2, 3) <<
"|\n|"
3049 << matrix(3, 0) <<
", " << matrix(3, 1) <<
", " << matrix(3, 2) <<
", " << matrix(3, 3) <<
"|";
3052 template <
bool tActive,
typename T>
3053 MessageObject<tActive>&
operator<<(MessageObject<tActive>&& messageObject,
const SquareMatrixT4<T>& matrix)
3055 return messageObject <<
"|" << matrix(0, 0) <<
", " << matrix(0, 1) <<
", " << matrix(0, 2) <<
", " << matrix(0, 3) <<
"|\n|"
3056 << matrix(1, 0) <<
", " << matrix(1, 1) <<
", " << matrix(1, 2) <<
", " << matrix(1, 3) <<
"|\n|"
3057 << matrix(2, 0) <<
", " << matrix(2, 1) <<
", " << matrix(2, 2) <<
", " << matrix(2, 3) <<
"|\n|"
3058 << matrix(3, 0) <<
", " << matrix(3, 1) <<
", " << matrix(3, 2) <<
", " << matrix(3, 3) <<
"|";
This class implements the abstract base class for all AnyCamera objects.
Definition: AnyCamera.h:130
virtual unsigned int width() const =0
Returns the width of the camera image.
virtual T focalLengthX() const =0
Returns the horizontal focal length parameter.
virtual T focalLengthY() const =0
Returns the vertical focal length parameter.
virtual unsigned int height() const =0
Returns the height of the camera image.
virtual T principalPointY() const =0
Returns the y-value of the principal point of the camera image in the pixel domain.
virtual bool isValid() const =0
Returns whether this camera is valid.
virtual T principalPointX() const =0
Returns the x-value of the principal point of the camera image in the pixel domain.
static unsigned int solveQuartic(const T a, const T b, const T c, const T d, const T e, T *x)
Solves a quartic equation with the form: ax^4 + bx^3 + cx^2 + dx + e = 0.
Definition: Equation.h:273
This class implements a 4x4 homogeneous transformation matrix using floating point values with the pr...
Definition: HomogenousMatrix4.h:110
HomogenousMatrixT4< T > inverted() const noexcept
Returns the inverted of this matrix.
Definition: HomogenousMatrix4.h:1575
VectorT3< T > translation() const
Returns the translation of the transformation.
Definition: HomogenousMatrix4.h:1381
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition: HomogenousMatrix4.h:1806
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static T atan(const T value)
Returns the arctangent of a given value.
Definition: Numeric.h:1616
static T abs(const T value)
Returns the absolute value of a given value.
Definition: Numeric.h:1220
static constexpr T eps()
Returns a small epsilon.
static bool isEqual(const T first, const T second)
Returns whether two values are equal up to a small epsilon.
Definition: Numeric.h:2386
static T tan(const T value)
Returns the tangent of a given value.
Definition: Numeric.h:1600
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition: Numeric.h:2087
This class implements a 3x3 square matrix.
Definition: SquareMatrix3.h:88
OCEAN_FORCE_INLINE SquareMatrixT4< T > & operator*=(const SquareMatrixT4< T > &matrix)
Multiplies and assigns two matrices.
Definition: SquareMatrix4.h:1174
void copyElements(U *arrayValues) const
Copies the elements of this matrix to an array with floating point values of type U.
Definition: SquareMatrix4.h:1137
SquareMatrixT4< T > & operator-=(const SquareMatrixT4< T > &matrix)
Subtracts and assigns two matrices.
Definition: SquareMatrix4.h:1340
const T * data() const
Returns a pointer to the internal values.
Definition: SquareMatrix4.h:790
T operator()(const unsigned int index) const
Element operator.
Definition: SquareMatrix4.h:1216
SquareMatrixT4(const U *arrayValues, const bool valuesRowAligned)
Creates a new SquareMatrixT4 object by an array of at least sixteen elements of float type U.
Definition: SquareMatrix4.h:686
static SquareMatrixT4< T > projectionMatrix(const T fovX, const T aspectRatio, const T nearDistance, const T farDistance)
Creates a projection matrix defined by the horizontal field of view, the aspect ratio and the near an...
Definition: SquareMatrix4.h:2391
OCEAN_FORCE_INLINE VectorT3< T > operator*(const VectorT3< T > &vector) const
Multiply operator for a 3D vector.
Definition: SquareMatrix4.h:1777
bool isIdentity() const
Returns whether this matrix is the identity matrix.
Definition: SquareMatrix4.h:1022
SquareMatrixT4(const U *arrayValues)
Creates a new SquareMatrixT4 object by an array of at least sixteen elements of float type U.
Definition: SquareMatrix4.h:667
SquareMatrixT4(const SquareMatrixT4< U > &matrix)
Copy constructor for a matrix with difference element data type than T.
Definition: SquareMatrix4.h:602
void transpose()
Transposes the matrix.
Definition: SquareMatrix4.h:828
static SquareMatrixT4< T > projectionMatrix(const AnyCameraT< T > &anyCamera, const T nearDistance, const T farDistance)
Creates a projection matrix defined by a camera profile of a pinhole camera and the near and far clip...
Definition: SquareMatrix4.h:2436
SquareMatrixT4< T > transposed() const
Returns the transposed of this matrix.
Definition: SquareMatrix4.h:802
void swapRows(const unsigned int row0, const unsigned int row1)
Swaps two rows of this matrix.
Definition: SquareMatrix4.h:2957
void copyElements(T *arrayValues) const
Copies the elements of this matrix to an array with floating point values.
Definition: SquareMatrix4.h:1160
SquareMatrixT4< T > inverted() const
Returns the inverted matrix of this matrix.
Definition: SquareMatrix4.h:852
bool invert(SquareMatrixT4< T > &invertedMatrix) const
Inverts the matrix and returns the result.
Definition: SquareMatrix4.h:881
SquareMatrixT4< T > operator+(const SquareMatrixT4< T > &matrix) const
Adds two matrices.
Definition: SquareMatrix4.h:1267
T operator[](const unsigned int index) const
Element operator.
Definition: SquareMatrix4.h:1188
bool isSingular() const
Returns whether this matrix is singular (and thus cannot be inverted).
Definition: SquareMatrix4.h:1040
SquareMatrixT4()
Creates a new SquareMatrixT4 object with undefined elements.
Definition: SquareMatrix4.h:595
SquareMatrixT4(const VectorT4< T > &diagonal)
Creates a new SquareMatrixT4 object by a given diagonal vector.
Definition: SquareMatrix4.h:769
OCEAN_FORCE_INLINE SquareMatrixT4< T > operator*(const HomogenousMatrixT4< T > &matrix) const
Multiplies two matrices.
Definition: SquareMatrix4.h:1749
friend class SquareMatrixT4
Definition: SquareMatrix4.h:86
bool isSymmetric(const T epsilon=NumericT< T >::eps()) const
Returns whether this matrix is symmetric.
Definition: SquareMatrix4.h:1046
T values[16]
The sixteen values of the matrix.
Definition: SquareMatrix4.h:591
T determinant() const
Returns the determinant of the matrix.
Definition: SquareMatrix4.h:946
T * data()
Returns a pointer to the internal values.
Definition: SquareMatrix4.h:796
T operator()(const unsigned int row, const unsigned int column) const
Element operator.
Definition: SquareMatrix4.h:1202
bool isEqual(const SquareMatrixT4< T > &matrix, const T eps=NumericT< T >::eps()) const
Returns whether two matrices are almost identical up to a specified epsilon.
Definition: SquareMatrix4.h:1055
void toNull()
Sets the matrix to a zero matrix.
Definition: SquareMatrix4.h:1001
bool eigenSystem(VectorT4< T > &eigenValues, SquareMatrixT4< T > &eigenVectors)
Performs an eigen value analysis.
Definition: SquareMatrix4.h:1068
bool operator==(const SquareMatrixT4< T > &matrix) const
Returns whether two matrices are identical up to a small epsilon.
Definition: SquareMatrix4.h:1261
static size_t elements()
Returns the number of elements this matrix has.
Definition: SquareMatrix4.h:1255
SquareMatrixT4< T > & operator+=(const SquareMatrixT4< T > &matrix)
Adds and assigns two matrices.
Definition: SquareMatrix4.h:1292
const T * operator()() const
Access operator.
Definition: SquareMatrix4.h:1230
SquareMatrixT4(const T *arrayValues, const bool valuesRowAligned)
Creates a new SquareMatrixT4 object by an array of at least sixteen elements.
Definition: SquareMatrix4.h:717
static void multiply(const SquareMatrixT4< T > &matrix, const VectorT4< T > *vectors, VectorT4< T > *results, const size_t number)
Multiplies several 4D vectors with a given matrix.
Definition: SquareMatrix4.h:2561
SquareMatrixT4< T > & operator=(const SquareMatrixT4< T > &)=default
Default assign operator.
SquareMatrixT4< T > operator-() const
Returns the negative matrix of this matrix (all matrix elements are multiplied by -1).
Definition: SquareMatrix4.h:1363
bool isNull() const
Returns whether this matrix is a null matrix.
Definition: SquareMatrix4.h:1031
OCEAN_FORCE_INLINE SquareMatrixT4< T > & operator*=(const HomogenousMatrixT4< T > &matrix)
Multiplies and assigns two matrices.
Definition: SquareMatrix4.h:1181
SquareMatrixT4(const SquareMatrixT3< T > &subMatrix)
Creates a new SquareMatrixT4 object by given 3x3 sub matrix.
Definition: SquareMatrix4.h:753
SquareMatrixT4< T > operator-(const SquareMatrixT4< T > &matrix) const
Subtracts two matrices.
Definition: SquareMatrix4.h:1315
void addRows(const unsigned int targetRow, const unsigned int sourceRow, const T scalar)
Multiplies elements from a specific row with a scalar and adds them to another row.
Definition: SquareMatrix4.h:3009
static std::vector< SquareMatrixT4< T > > matrices2matrices(const std::vector< SquareMatrixT4< U > > &matrices)
Converts matrices with specific data type to matrices with different data type.
Definition: SquareMatrix4.h:2914
static SquareMatrixT4< T > frustumMatrix(const T left, const T right, const T top, const T bottom, const T nearDistance, const T farDistance)
Creates a projection matrix defined by an asymmetric viewing frustum.
Definition: SquareMatrix4.h:2493
T & operator()(const unsigned int index)
Element operator.
Definition: SquareMatrix4.h:1223
SquareMatrixT4< T > operator*(const T value) const
Multiplies this matrix with a scalar value.
Definition: SquareMatrix4.h:2343
bool invert()
Inverts this matrix in place.
Definition: SquareMatrix4.h:866
bool operator!=(const SquareMatrixT4< T > &matrix) const
Returns whether two matrices are not identical up to a small epsilon.
Definition: SquareMatrix4.h:1168
size_t operator()(const SquareMatrixT4< T > &matrix) const
Hash function.
Definition: SquareMatrix4.h:1242
static std::vector< SquareMatrixT4< T > > matrices2matrices(const SquareMatrixT4< U > *matrices, const size_t size)
Converts matrices with specific data type to matrices with different data type.
Definition: SquareMatrix4.h:2943
OCEAN_FORCE_INLINE SquareMatrixT4< T > operator*(const SquareMatrixT4< T > &matrix) const
Multiplies two matrices.
Definition: SquareMatrix4.h:1387
T & operator()(const unsigned int row, const unsigned int column)
Element operator.
Definition: SquareMatrix4.h:1209
T & operator[](const unsigned int index)
Element operator.
Definition: SquareMatrix4.h:1195
void multiplyRow(const unsigned int row, const T scalar)
Multiplies a row with a scalar value.
Definition: SquareMatrix4.h:2993
T trace() const
Returns the trace of the matrix which is the sum of the diagonal elements.
Definition: SquareMatrix4.h:974
SquareMatrixT4(const bool setToIdentity)
Creates a new SquareMatrixT4 object.
Definition: SquareMatrix4.h:623
SquareMatrixT4(const HomogenousMatrixT4< T > &transformation)
Creates a new SquareMatrixT4 object by given transformation matrix.
Definition: SquareMatrix4.h:747
OCEAN_FORCE_INLINE VectorT4< T > operator*(const VectorT4< T > &vector) const
Multiply operator for a 4D vector.
Definition: SquareMatrix4.h:1790
T * operator()()
Access operator.
Definition: SquareMatrix4.h:1236
T Type
Definition of the used data type.
Definition: SquareMatrix4.h:93
static SquareMatrixT4< T > frustumMatrix(const T width, const T height, const HomogenousMatrixT4< T > &viewingMatrix, const T nearDistance, const T farDistance)
Creates a project matrix defined by an asymmetric viewing frustum.
Definition: SquareMatrix4.h:2539
SquareMatrixT4< T > & operator*=(const T value)
Multiplies and assigns this matrix with a scalar value.
Definition: SquareMatrix4.h:2368
void toIdentity()
Sets the matrix to the identity matrix.
Definition: SquareMatrix4.h:980
SquareMatrixT4(const SquareMatrixT4< T > &matrix)=default
Copy constructor.
SquareMatrixT4(const T *arrayValues)
Creates a new SquareMatrixT4 object by an array of at least sixteen elements.
Definition: SquareMatrix4.h:678
This class implements a vector with three elements.
Definition: Vector3.h:97
const T & y() const noexcept
Returns the y value.
Definition: Vector3.h:812
const T & x() const noexcept
Returns the x value.
Definition: Vector3.h:800
This class implements a vector with four elements.
Definition: Vector4.h:97
const T * data() const noexcept
Returns an pointer to the vector elements.
Definition: Vector4.h:720
std::vector< SquareMatrixT4< T > > SquareMatricesT4
Definition of a typename alias for vectors with SquareMatrixT4 objects.
Definition: SquareMatrix4.h:61
SquareMatrixT4< float > SquareMatrixF4
Instantiation of the SquareMatrixT4 template class using a double precision float data type.
Definition: SquareMatrix4.h:53
SquareMatrixT4< Scalar > SquareMatrix4
Definition of the SquareMatrix4 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with ...
Definition: SquareMatrix4.h:32
std::vector< SquareMatrix4 > SquareMatrices4
Definition of a vector holding SquareMatrix4 objects.
Definition: SquareMatrix4.h:68
SquareMatrixT4< double > SquareMatrixD4
Instantiation of the SquareMatrixT4 template class using a double precision float data type.
Definition: SquareMatrix4.h:46
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15
std::ostream & operator<<(std::ostream &stream, const HighPerformanceStatistic &highPerformanceStatistic)
Definition: HighPerformanceTimer.h:963