27template<
typename T,
int Size>
28[[nodiscard]] MatBase<T, Size, Size>
invert(
const MatBase<T, Size, Size> &mat,
bool &r_success);
33template<
typename T,
int NumCol,
int NumRow>
34[[nodiscard]] MatBase<T, NumCol, NumRow>
transpose(
const MatBase<T, NumRow, NumCol> &mat);
39template<
typename T,
int NumCol,
int NumRow>
40[[nodiscard]] MatBase<T, NumCol, NumRow>
normalize(
const MatBase<T, NumCol, NumRow> &a);
46template<
typename T,
int NumCol,
int NumRow,
typename VectorT>
48 const MatBase<T, NumCol, NumRow> &a, VectorT &r_size);
54template<
typename T,
int Size> [[nodiscard]]
T determinant(
const MatBase<T, Size, Size> &mat);
59template<
typename T,
int Size>
60[[nodiscard]] MatBase<T, Size, Size>
adjoint(
const MatBase<T, Size, Size> &mat);
65template<
typename T,
int NumCol,
int NumRow,
typename VectorT>
66[[nodiscard]] MatBase<T, NumCol, NumRow>
translate(
const MatBase<T, NumCol, NumRow> &mat,
67 const VectorT &translation);
73template<
typename T,
int NumCol,
int NumRow,
typename RotationT>
75 const RotationT &rotation);
80template<
typename T,
int NumCol,
int NumRow,
typename VectorT>
82 const VectorT &
scale);
87template<
typename T,
int NumCol,
int NumRow>
168template<
typename T,
int Size>
181template<
typename MatT> [[nodiscard]] MatT
from_location(
const typename MatT::loc_type &location);
187template<
typename MatT,
int ScaleDim>
193template<
typename MatT,
typename RotationT>
199template<
typename MatT,
typename RotationT,
typename VectorT>
205template<
typename MatT,
typename RotationT>
206[[nodiscard]] MatT
from_loc_rot(
const typename MatT::loc_type &location,
207 const RotationT &rotation);
212template<
typename MatT,
int ScaleDim>
213[[nodiscard]] MatT
from_loc_scale(
const typename MatT::loc_type &location,
219template<
typename MatT,
typename RotationT,
int ScaleDim>
221 const RotationT &rotation,
235template<
typename MatT,
typename VectorT>
242template<
typename MatT,
typename VectorT>
244 const VectorT forward,
255template<
typename MatT,
typename VectorT> [[nodiscard]] MatT
from_up_axis(
const VectorT up);
266template<
typename MatT> [[nodiscard]] MatT
orthogonalize(
const MatT &mat,
const Axis axis);
273template<
typename MatT,
typename VectorT>
335template<
bool AllowNegativeScale = false,
typename T,
int NumCol,
int NumRow>
337template<
bool AllowNegativeScale = false,
typename T>
346template<
bool AllowNegativeScale = false,
typename T>
350template<
bool AllowNegativeScale = false,
typename T>
355template<
bool AllowNegativeScale = false,
typename T,
typename RotationT>
357 RotationT &r_rotation,
359template<
bool AllowNegativeScale = false,
typename T,
typename RotationT>
362 RotationT &r_rotation,
416template<
typename MatT,
typename VectorT>
463 T angle_left,
T angle_right,
T angle_bottom,
T angle_top,
T near_clip,
T far_clip);
503template<
typename T,
int NumCol,
int NumRow>
506 const T epsilon =
T(0))
508 for (
int i = 0;
i < NumCol;
i++) {
509 for (
int j = 0; j < NumRow; j++) {
521template<
typename T,
int NumCol,
int NumRow>
524 for (
int i = 0;
i < NumCol;
i++) {
525 for (
int j = 0; j < NumRow; j++) {
526 if (mat[
i][j] != (
i != j ? 0.0f : 1.0f)) {
537template<
typename MatT> [[nodiscard]]
inline bool is_orthogonal(
const MatT &mat)
579 using T =
typename MatT::base_type;
587template<
typename T,
int NumCol,
int NumRow>
590 for (
int i = 0;
i < NumCol;
i++) {
607template<
typename T,
int NumCol,
int NumRow>
610template<
typename T,
int NumCol,
int NumRow>
613template<
typename T,
int NumCol,
int NumRow>
616template<
typename T,
int NumCol,
int NumRow>
619template<
typename T,
int NumCol,
int NumRow>
622template<
typename T,
int NumCol,
int NumRow>
625template<
typename T,
int NumCol,
int NumRow,
typename AngleT>
631template<
typename T,
int NumCol,
int NumRow>
634 for (
int i = 0;
i < NumCol;
i++) {
642template<
typename T,
int Size>
650template<
typename T,
int NumCol,
int NumRow>
658template<
typename T,
int NumCol,
int NumRow,
typename VectorT>
660 const VectorT &translation)
664 "Translation should be at least 1 column less than the matrix.");
665 constexpr int location_col = MatT::col_len - 1;
668 using IntermediateVecT =
669 VecBase<
typename MatT::base_type,
670 (MatT::row_len > MatT::col_len - 1) ? (MatT::col_len - 1) : MatT::row_len>;
674 *
reinterpret_cast<IntermediateVecT *
>(
675 &
result[location_col]) += translation[c] *
676 *
reinterpret_cast<const IntermediateVecT *
>(&mat[c]);
681template<
typename T,
int NumCol,
int NumRow,
typename AngleT>
686 using Vec3T =
typename MatT::vec3_type;
687 const T angle_sin =
sin(rotation.
angle());
688 const T angle_cos =
cos(rotation.
angle());
689 const Vec3T &axis_vec = rotation.
axis();
693 if (axis_vec.x ==
T(1)) {
695 result[2][c] = -angle_sin * mat[1][c] + angle_cos * mat[2][c];
696 result[1][c] = angle_cos * mat[1][c] + angle_sin * mat[2][c];
699 else if (axis_vec.y ==
T(1)) {
701 result[0][c] = angle_cos * mat[0][c] - angle_sin * mat[2][c];
702 result[2][c] = angle_sin * mat[0][c] + angle_cos * mat[2][c];
705 else if (axis_vec.z ==
T(1)) {
707 result[0][c] = angle_cos * mat[0][c] + angle_sin * mat[1][c];
708 result[1][c] = -angle_sin * mat[0][c] + angle_cos * mat[1][c];
718template<
typename T,
int NumCol,
int NumRow,
typename VectorT>
720 const VectorT &
scale)
723 "Scale should be less or equal to the matrix in column count.");
729template<
typename T,
int NumCol,
int NumRow>
771 "r_size dimension should be equal to matrix column count.");
777template<
typename T,
int NumCol,
int NumRow>
785template<
typename T,
int NumCol,
int NumRow,
typename VectorT>
790 "r_size dimension should be equal to matrix column count.");
810 if (cy >
T(16) * std::numeric_limits<T>::epsilon()) {
831 const int i_index = eul1.
i_index();
832 const int j_index = eul1.
j_index();
833 const int k_index = eul1.
k_index();
835 const T cy =
math::hypot(mat[i_index][i_index], mat[i_index][j_index]);
836 if (cy >
T(16) * std::numeric_limits<T>::epsilon()) {
837 eul1.
i() =
math::atan2(mat[j_index][k_index], mat[k_index][k_index]);
839 eul1.
k() =
math::atan2(mat[i_index][j_index], mat[i_index][i_index]);
841 eul2.
i() =
math::atan2(-mat[j_index][k_index], -mat[k_index][k_index]);
843 eul2.
k() =
math::atan2(-mat[i_index][j_index], -mat[i_index][i_index]);
846 eul1.
i() =
math::atan2(-mat[k_index][j_index], mat[j_index][j_index]);
882 if (mat[2][2] < 0.0f) {
883 if (mat[0][0] > mat[1][1]) {
884 const T trace = 1.0f + mat[0][0] - mat[1][1] - mat[2][2];
886 if (mat[1][2] < mat[2][1]) {
892 q.
w = (mat[1][2] - mat[2][1]) * s;
893 q.
y = (mat[0][1] + mat[1][0]) * s;
894 q.
z = (mat[2][0] + mat[0][2]) * s;
895 if (
UNLIKELY((trace == 1.0f) && (q.
w == 0.0f && q.
y == 0.0f && q.
z == 0.0f))) {
901 const T trace = 1.0f - mat[0][0] + mat[1][1] - mat[2][2];
903 if (mat[2][0] < mat[0][2]) {
909 q.
w = (mat[2][0] - mat[0][2]) * s;
910 q.
x = (mat[0][1] + mat[1][0]) * s;
911 q.
z = (mat[1][2] + mat[2][1]) * s;
912 if (
UNLIKELY((trace == 1.0f) && (q.
w == 0.0f && q.
x == 0.0f && q.
z == 0.0f))) {
919 if (mat[0][0] < -mat[1][1]) {
920 const T trace = 1.0f - mat[0][0] - mat[1][1] + mat[2][2];
922 if (mat[0][1] < mat[1][0]) {
928 q.
w = (mat[0][1] - mat[1][0]) * s;
929 q.
x = (mat[2][0] + mat[0][2]) * s;
930 q.
y = (mat[1][2] + mat[2][1]) * s;
931 if (
UNLIKELY((trace == 1.0f) && (q.
w == 0.0f && q.
x == 0.0f && q.
y == 0.0f))) {
940 const T trace = 1.0f + mat[0][0] + mat[1][1] + mat[2][2];
944 q.
x = (mat[1][2] - mat[2][1]) * s;
945 q.
y = (mat[2][0] - mat[0][2]) * s;
946 q.
z = (mat[0][1] - mat[1][0]) * s;
947 if (
UNLIKELY((trace == 1.0f) && (q.
x == 0.0f && q.
y == 0.0f && q.
z == 0.0f))) {
960 const T q_len_squared = q.
x * q.
x + q.
y * q.
y + q.
z * q.
z + q.
w * q.
w;
961 const T threshold = 0.0002f * 3;
962 if (
math::abs(q_len_squared - 1.0f) >= threshold) {
963 const T q_len_inv = 1.0 /
math::sqrt(q_len_squared);
977 if (
UNLIKELY(!std::isfinite(det))) {
990template<
typename T,
int NumCol,
int NumRow>
995 const DoublePrecision cos_i =
math::cos(DoublePrecision(rotation.
x().
radian()));
996 const DoublePrecision cos_j =
math::cos(DoublePrecision(rotation.
y().
radian()));
997 const DoublePrecision cos_k =
math::cos(DoublePrecision(rotation.
z().
radian()));
998 const DoublePrecision sin_i =
math::sin(DoublePrecision(rotation.
x().
radian()));
999 const DoublePrecision sin_j =
math::sin(DoublePrecision(rotation.
y().
radian()));
1000 const DoublePrecision sin_k =
math::sin(DoublePrecision(rotation.
z().
radian()));
1001 const DoublePrecision cos_i_cos_k = cos_i * cos_k;
1002 const DoublePrecision cos_i_sin_k = cos_i * sin_k;
1003 const DoublePrecision sin_i_cos_k = sin_i * cos_k;
1004 const DoublePrecision sin_i_sin_k = sin_i * sin_k;
1006 MatT mat = MatT::identity();
1007 mat[0][0] =
T(cos_j * cos_k);
1008 mat[1][0] =
T(sin_j * sin_i_cos_k - cos_i_sin_k);
1009 mat[2][0] =
T(sin_j * cos_i_cos_k + sin_i_sin_k);
1011 mat[0][1] =
T(cos_j * sin_k);
1012 mat[1][1] =
T(sin_j * sin_i_sin_k + cos_i_cos_k);
1013 mat[2][1] =
T(sin_j * cos_i_sin_k - sin_i_cos_k);
1015 mat[0][2] =
T(-sin_j);
1016 mat[1][2] =
T(cos_j * sin_i);
1017 mat[2][2] =
T(cos_j * cos_i);
1021template<
typename T,
int NumCol,
int NumRow>
1025 const int i_index = rotation.
i_index();
1026 const int j_index = rotation.
j_index();
1027 const int k_index = rotation.
k_index();
1031 MatT
result = MatT::identity();
1032 result[i_index][i_index] = mat[0][0];
1033 result[j_index][i_index] = mat[1][0];
1034 result[k_index][i_index] = mat[2][0];
1035 result[i_index][j_index] = mat[0][1];
1036 result[j_index][j_index] = mat[1][1];
1037 result[k_index][j_index] = mat[2][1];
1038 result[i_index][k_index] = mat[0][2];
1039 result[j_index][k_index] = mat[1][2];
1040 result[k_index][k_index] = mat[2][2];
1047template<
typename T,
int NumCol,
int NumRow>
1052 const DoublePrecision q0 =
numbers::sqrt2 * DoublePrecision(rotation.
w);
1053 const DoublePrecision q1 =
numbers::sqrt2 * DoublePrecision(rotation.
x);
1054 const DoublePrecision q2 =
numbers::sqrt2 * DoublePrecision(rotation.
y);
1055 const DoublePrecision q3 =
numbers::sqrt2 * DoublePrecision(rotation.
z);
1057 const DoublePrecision qda = q0 * q1;
1058 const DoublePrecision qdb = q0 * q2;
1059 const DoublePrecision qdc = q0 * q3;
1060 const DoublePrecision qaa = q1 * q1;
1061 const DoublePrecision qab = q1 * q2;
1062 const DoublePrecision qac = q1 * q3;
1063 const DoublePrecision qbb = q2 * q2;
1064 const DoublePrecision qbc = q2 * q3;
1065 const DoublePrecision qcc = q3 * q3;
1067 MatT mat = MatT::identity();
1068 mat[0][0] =
T(1.0 - qbb - qcc);
1069 mat[0][1] =
T(qdc + qab);
1070 mat[0][2] =
T(-qdb + qac);
1072 mat[1][0] =
T(-qdc + qab);
1073 mat[1][1] =
T(1.0 - qaa - qcc);
1074 mat[1][2] =
T(qda + qbc);
1076 mat[2][0] =
T(qdb + qac);
1077 mat[2][1] =
T(-qda + qbc);
1078 mat[2][2] =
T(1.0 - qaa - qbb);
1083template<
typename T,
int NumCol,
int NumRow>
1097 const T &w0 = c0.
w, &x0 = c0.
x, &y0 = c0.
y, &z0 = c0.
z;
1098 const T &we = ce.
w, &xe = ce.
x, &ye = ce.
y, &ze = ce.
z;
1102 mat[3][0] =
T(2) * (-we * x0 + xe * w0 - ye * z0 + ze * y0);
1103 mat[3][1] =
T(2) * (-we * y0 + xe * z0 + ye * w0 - ze * x0);
1104 mat[3][2] =
T(2) * (-we * z0 - xe * y0 + ye * x0 + ze * w0);
1112template<
typename T,
int NumCol,
int NumRow>
1116 MatT mat = MatT::identity();
1123template<
typename T,
int NumCol,
int NumRow,
typename AngleT>
1127 using Vec3T =
typename MatT::vec3_type;
1128 const T angle_sin =
sin(rotation.
angle());
1129 const T angle_cos =
cos(rotation.
angle());
1130 const Vec3T &axis = rotation.
axis();
1134 T ico = (
T(1) - angle_cos);
1135 Vec3T nsi = axis * angle_sin;
1137 Vec3T n012 = (axis * axis) * ico;
1138 T n_01 = (axis[0] * axis[1]) * ico;
1139 T n_02 = (axis[0] * axis[2]) * ico;
1140 T n_12 = (axis[1] * axis[2]) * ico;
1143 mat[0][1] = n_01 + nsi[2];
1144 mat[0][2] = n_02 - nsi[1];
1145 mat[1][0] = n_01 - nsi[2];
1146 mat[1][2] = n_12 + nsi[0];
1147 mat[2][0] = n_02 + nsi[1];
1148 mat[2][1] = n_12 - nsi[0];
1152template<
typename T,
int NumCol,
int NumRow>
1156 const T cos_i =
cos(rotation);
1157 const T sin_i =
sin(rotation);
1159 MatT mat = MatT::identity();
1227 eul1 = eul1.wrapped_around(reference);
1293template<
bool AllowNegativeScale,
typename T,
int NumCol,
int NumRow>
1297 if constexpr (AllowNegativeScale) {
1305template<
bool AllowNegativeScale,
typename T>
1309 if constexpr (AllowNegativeScale) {
1346template<
bool AllowNegativeScale,
typename T>
1352 if constexpr (AllowNegativeScale) {
1354 normalized_mat = -normalized_mat;
1361template<
bool AllowNegativeScale,
typename T>
1371template<
bool AllowNegativeScale,
typename T,
typename RotationT>
1373 RotationT &r_rotation,
1377 if constexpr (AllowNegativeScale) {
1379 normalized_mat = -normalized_mat;
1386template<
bool AllowNegativeScale,
typename T,
typename RotationT>
1389 RotationT &r_rotation,
1400template<
bool AllowNegativeScale,
typename T,
typename RotationT>
1403 RotationT &r_rotation,
1412 r_rotation = RotationT(euler_rotation);
1416template<
typename MatT> [[nodiscard]] MatT
from_location(
const typename MatT::loc_type &location)
1418 MatT mat = MatT::identity();
1419 mat.location() = location;
1423template<
typename MatT,
int ScaleDim>
1427 "Scale dimension should fit the matrix diagonal length.");
1430 [&](
auto i) {
result[
i][
i] = (
i < ScaleDim) ?
scale[
i] :
typename MatT::base_type(1); });
1434template<
typename MatT,
typename RotationT>
1440template<
typename MatT,
typename RotationT,
typename VectorT>
1446template<
typename MatT,
typename RotationT,
int ScaleDim>
1448 const RotationT &rotation,
1454 mat.location() = location;
1458template<
typename MatT,
typename RotationT>
1459[[nodiscard]] MatT
from_loc_rot(
const typename MatT::loc_type &location,
const RotationT &rotation)
1464 mat.location() = location;
1468template<
typename MatT,
int ScaleDim>
1473 mat.location() = location;
1484template<
typename MatT,
typename VectorT>
1492 matrix.x_axis() = forward;
1496 matrix.z_axis() = up;
1500template<
typename MatT,
typename VectorT>
1502 const VectorT forward,
1507 matrix.location() = location;
1511template<
typename MatT,
typename VectorT> [[nodiscard]] MatT
from_up_axis(
const VectorT up)
1514 using T =
typename MatT::base_type;
1517 T sign = up.z >=
T(0) ?
T(1) :
T(-1);
1518 T a =
T(-1) / (
sign + up.z);
1519 T b = up.x * up.y * a;
1530 using T =
typename MatT::base_type;
1566 if (
dot(
R.x,
R.y) <
T(1)) {
1570 else if (
dot(
R.x,
R.z) <
T(1)) {
1580 if (
dot(
R.y,
R.x) <
T(1)) {
1585 else if (
dot(
R.x,
R.z) <
T(1)) {
1595 if (
dot(
R.z,
R.x) <
T(1)) {
1599 else if (
dot(
R.z,
R.y) <
T(1)) {
1618 result.location() = mat.location();
1622template<
typename MatT,
typename VectorT>
1655 return mat * direction;
1661 return mat.template
view<3, 3>() * direction;
1664template<
typename T,
int N,
int NumRow>
1685 const T x_delta = right -
left;
1686 const T y_delta =
top - bottom;
1687 const T z_delta = far_clip - near_clip;
1690 if (x_delta != 0 && y_delta != 0 && z_delta != 0) {
1691 mat[0][0] =
T(2.0) / x_delta;
1692 mat[3][0] = -(right +
left) / x_delta;
1693 mat[1][1] =
T(2.0) / y_delta;
1694 mat[3][1] = -(
top + bottom) / y_delta;
1695 mat[2][2] = -
T(2.0) / z_delta;
1696 mat[3][2] = -(far_clip + near_clip) / z_delta;
1704 const T x_delta = right -
left;
1705 const T y_delta =
top - bottom;
1708 if (x_delta != 0 && y_delta != 0) {
1709 mat[0][0] =
T(2.0) / x_delta;
1710 mat[3][0] = -(right +
left) / x_delta;
1711 mat[1][1] =
T(2.0) / y_delta;
1712 mat[3][1] = -(
top + bottom) / y_delta;
1714 constexpr float eps = 2.4e-7f;
1719 mat[3][2] = -1.0f -
eps * near_clip;
1727 const T x_delta = right -
left;
1728 const T y_delta =
top - bottom;
1729 const T z_delta = far_clip - near_clip;
1732 if (x_delta != 0 && y_delta != 0 && z_delta != 0) {
1733 mat[0][0] = near_clip *
T(2.0) / x_delta;
1734 mat[1][1] = near_clip *
T(2.0) / y_delta;
1735 mat[2][0] = (right +
left) / x_delta;
1736 mat[2][1] = (
top + bottom) / y_delta;
1737 mat[2][2] = -(far_clip + near_clip) / z_delta;
1739 mat[3][2] = (-2.0f * near_clip * far_clip) / z_delta;
1748 const T x_delta = right -
left;
1749 const T y_delta =
top - bottom;
1753 if (x_delta != 0 && y_delta != 0) {
1754 mat[0][0] = near_clip *
T(2.0) / x_delta;
1755 mat[1][1] = near_clip *
T(2.0) / y_delta;
1756 mat[2][0] = (right +
left) / x_delta;
1757 mat[2][1] = (
top + bottom) / y_delta;
1759 constexpr float eps = 2.4e-7f;
1761 mat[2][3] = (
eps - 1.0f);
1762 mat[3][2] = (
eps - 2.0f) * near_clip;
1770 T angle_left,
T angle_right,
T angle_bottom,
T angle_top,
T near_clip,
T far_clip)
1778 mat[0][0] /= near_clip;
1779 mat[1][1] /= near_clip;
1787 const bool is_perspective = mat[2][3] == -1.0f;
1788 const bool is_perspective_infinite = mat[2][2] == -1.0f;
1789 if (is_perspective || is_perspective_infinite) {
1794 result[3][0] += offset.x;
1795 result[3][1] += offset.y;
1801 float left,
float right,
float bottom,
float top,
float near_clip,
float far_clip);
1803 float left,
float right,
float bottom,
float top,
float near_clip,
float far_clip);
1819 bool use_threading =
true);
1823 bool use_threading =
true);
#define BLI_assert_unreachable()
#define BLI_STATIC_ASSERT(a, msg)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
btMatrix3x3 adjoint() const
Return the adjoint of the matrix.
btScalar determinant() const
Return the determinant of the matrix.
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
static float normals[][3]
VecBase< float, D > normalize(VecOp< float, D >) RET
MatBase< R, C > transpose(MatBase< C, R >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
QuaternionBase< T > normalized_to_quat_with_checks(const MatBase< T, 3, 3 > &mat)
void normalized_to_eul2(const MatBase< T, 3, 3 > &mat, EulerXYZBase< T > &eul1, EulerXYZBase< T > &eul2)
void to_rotation(const MatBase< T, 2, 2 > &mat, AngleRadianBase< T > &r_rotation)
QuaternionBase< T > normalized_to_quat_fast(const MatBase< T, 3, 3 > &mat)
AngleRadianBase< T > normalized_to_angle(const MatBase< T, 2, 2 > &mat)
MatBase< T, NumCol, NumRow > from_rotation(const AngleRadianBase< T > &rotation)
MatBase< T, 4, 4 > orthographic(T left, T right, T bottom, T top, T near_clip, T far_clip)
Create an orthographic projection matrix using OpenGL coordinate convention: Maps each axis range to ...
MatBase< T, 4, 4 > orthographic_infinite(T left, T right, T bottom, T top)
Create an orthographic projection matrix using OpenGL coordinate convention: Maps each axis range to ...
MatBase< T, 4, 4 > perspective_fov(T angle_left, T angle_right, T angle_bottom, T angle_top, T near_clip, T far_clip)
Create a perspective projection matrix using OpenGL coordinate convention: Maps each axis range to [-...
MatBase< T, 4, 4 > translate(const MatBase< T, 4, 4 > &mat, const VecBase< T, 2 > &offset)
Translate a projection matrix after creation in the screen plane. Usually used for anti-aliasing jitt...
MatBase< T, 4, 4 > perspective_infinite(T left, T right, T bottom, T top, T near_clip)
Create a perspective projection matrix using OpenGL coordinate convention: Maps each axis range to [-...
MatBase< T, 4, 4 > perspective(T left, T right, T bottom, T top, T near_clip, T far_clip)
Create a perspective projection matrix using OpenGL coordinate convention: Maps each axis range to [-...
AngleRadianBase< float > AngleRadian
AngleRadianBase< T > to_angle(const MatBase< T, 2, 2 > &mat)
QuaternionBase< float > Quaternion
T length_squared(const VecBase< T, Size > &a)
T cos(const AngleRadianBase< T > &a)
bool is_normalized(const DualQuaternionBase< T > &dq)
QuaternionBase< T > to_quaternion(const AxisAngleBase< T, AngleT > &axis_angle)
bool is_negative(const MatBase< T, 3, 3 > &mat)
MatBase< T, NumCol, NumRow > scale(const MatBase< T, NumCol, NumRow > &mat, const VectorT &scale)
bool is_orthonormal(const MatT &mat)
Quaternion to_quaternion_legacy(const float3x3 &mat)
MatT from_up_axis(const VectorT up)
T to_vector(const Axis axis)
T length(const VecBase< T, Size > &a)
MatT from_loc_rot(const typename MatT::loc_type &location, const RotationT &rotation)
MatT from_loc_scale(const typename MatT::loc_type &location, const VecBase< typename MatT::base_type, ScaleDim > &scale)
AxisAngleBase< float, AngleRadianBase< float > > AxisAngle
bool is_uniformly_scaled(const MatT &mat)
QuaternionBase< T > normalize_and_get_length(const QuaternionBase< T > &q, T &out_length)
bool is_unit_scale(const MatBase< T, NumCol, NumRow > &m)
MatBase< T, Size, Size > pseudo_invert(const MatBase< T, Size, Size > &mat, T epsilon=1e-8)
T length_manhattan(const VecBase< T, Size > &a)
EulerXYZBase< float > EulerXYZ
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
CartesianBasis invert(const CartesianBasis &basis)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
VectorT project_point(const MatT &mat, const VectorT &point)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
T interpolate(const T &a, const T &b, const FactorT &t)
void transform_normals(const float3x3 &transform, MutableSpan< float3 > normals)
EulerXYZBase< T > to_nearest_euler(const MatBase< T, 3, 3 > &mat, const EulerXYZBase< T > &reference)
MatBase< T, 2, 2 > from_direction(const VecBase< T, 2 > &direction)
T atan2(const T &y, const T &x)
MatBase< T, 3, 3 > interpolate_fast(const MatBase< T, 3, 3 > &a, const MatBase< T, 3, 3 > &b, T t)
MatBase< T, NumCol, NumRow > translate(const MatBase< T, NumCol, NumRow > &mat, const VectorT &translation)
QuaternionBase< T > normalized_to_quaternion_safe(const MatBase< T, 3, 3 > &mat)
MatBase< T, NumCol, NumRow > normalize_and_get_size(const MatBase< T, NumCol, NumRow > &a, VectorT &r_size)
MatT from_origin_transform(const MatT &transform, const VectorT origin)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > to_scale(const MatBase< T, NumCol, NumRow > &mat)
AxisAngleBase< float, AngleCartesianBase< float > > AxisAngleCartesian
bool is_equal(const MatBase< T, NumCol, NumRow > &a, const MatBase< T, NumCol, NumRow > &b, const T epsilon=T(0))
T sin(const AngleRadianBase< T > &a)
void to_rot_scale(const MatBase< T, 2, 2 > &mat, AngleRadianBase< T > &r_rotation, VecBase< T, 2 > &r_scale)
MatT orthogonalize(const MatT &mat, const Axis axis)
Euler3Base< float > Euler3
bool is_identity(const MatBase< T, NumCol, NumRow > &mat)
MatBase< T, NumCol, NumRow > interpolate_linear(const MatBase< T, NumCol, NumRow > &a, const MatBase< T, NumCol, NumRow > &b, T t)
T tan(const AngleRadianBase< T > &a)
void to_loc_rot_scale_safe(const MatBase< T, 4, 4 > &mat, VecBase< T, 3 > &r_location, RotationT &r_rotation, VecBase< T, 3 > &r_scale)
MatT from_location(const typename MatT::loc_type &location)
void to_loc_rot_scale(const MatBase< T, 3, 3 > &mat, VecBase< T, 2 > &r_location, AngleRadianBase< T > &r_rotation, VecBase< T, 2 > &r_scale)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
MatT from_rot_scale(const RotationT &rotation, const VectorT &scale)
MatBase< T, NumCol, NumRow > rotate(const MatBase< T, NumCol, NumRow > &mat, const RotationT &rotation)
CartesianBasis from_orthonormal_axes(const AxisSigned forward, const AxisSigned up)
MatT from_rotation(const RotationT &rotation)
T hypot(const T &y, const T &x)
T determinant(const MatBase< T, Size, Size > &mat)
Euler3Base< T > to_euler(const AxisAngleBase< T, AngleT > &axis_angle, EulerOrder order)
void transform_points(const float4x4 &transform, MutableSpan< float3 > points, bool use_threading=true)
MatT from_loc_rot_scale(const typename MatT::loc_type &location, const RotationT &rotation, const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
bool is_orthogonal(const MatT &mat)
MatBase< float, 4, 4 > float4x4
MatBase< double, 3, 3 > double3x3
VecBase< float, 2 > float2
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
static MatBase identity()
const AngleT & angle() const
const vec3_type & axis() const
VecBase< AxisSigned, 3 > axes
QuaternionBase< T > trans
Euler3Base wrapped_around(const Euler3Base &reference) const
const EulerOrder & order() const
EulerXYZBase wrapped_around(const EulerXYZBase &reference) const
static QuaternionBase identity()