Move Vectormath main
C++20 game and graphics mathematics
Loading...
Searching...
No Matches
TransformConversions.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <optional>
4#include <type_traits>
5
6#include <mv/math/Mat4.hpp>
10
11namespace mv::math
12{
13 template <typename T>
15 const AffineTransform3<T>& transform) noexcept
16 {
17 const Vec3<T>& x = transform.AxisX();
18 const Vec3<T>& y = transform.AxisY();
19 const Vec3<T>& z = transform.AxisZ();
20 const Vec3<T>& translation = transform.Translation();
21 return Mat4<T>(x.X(), x.Y(), x.Z(), T(0), y.X(), y.Y(), y.Z(), T(0),
22 z.X(), z.Y(), z.Z(), T(0), translation.X(),
23 translation.Y(), translation.Z(), T(1));
24 }
25
26 template <typename T>
28 const RigidTransform3<T>& transform) noexcept
29 {
30 return ToMat4(ToAffine(transform));
31 }
32
33 template <typename T>
35 const TrsTransform3<T>& transform) noexcept
36 {
37 return ToMat4(transform.ToAffine());
38 }
39
40 template <typename T>
41 [[nodiscard]] inline std::optional<AffineTransform3<T>> TryToAffine(
42 const Mat4<T>& matrix,
44 {
45 if (!matrix.IsFinite() ||
46 !IsNearlyZero(matrix.Element(0U, 3U), tolerance.Absolute) ||
47 !IsNearlyZero(matrix.Element(1U, 3U), tolerance.Absolute) ||
48 !IsNearlyZero(matrix.Element(2U, 3U), tolerance.Absolute) ||
49 !IsNearlyEqual(matrix.Element(3U, 3U), T(1), tolerance))
50 {
51 return std::nullopt;
52 }
54 Vec3<T>(matrix.Element(0U, 0U), matrix.Element(0U, 1U),
55 matrix.Element(0U, 2U)),
56 Vec3<T>(matrix.Element(1U, 0U), matrix.Element(1U, 1U),
57 matrix.Element(1U, 2U)),
58 Vec3<T>(matrix.Element(2U, 0U), matrix.Element(2U, 1U),
59 matrix.Element(2U, 2U)),
60 Vec3<T>(matrix.Element(3U, 0U), matrix.Element(3U, 1U),
61 matrix.Element(3U, 2U)));
62 }
63
64 template <typename T>
65 [[nodiscard]] inline std::optional<RigidTransform3<T>> TryToRigid(
68 {
69 const auto decomposition =
70 DecomposeTrs(transform, tolerance.Absolute * T(8));
71 if (!decomposition.Transform)
72 {
73 return std::nullopt;
74 }
75 const Vec3<T>& scale = decomposition.Transform->Scale();
76 if (!IsNearlyEqual(scale.X(), T(1), tolerance) ||
77 !IsNearlyEqual(scale.Y(), T(1), tolerance) ||
78 !IsNearlyEqual(scale.Z(), T(1), tolerance))
79 {
80 return std::nullopt;
81 }
82 return RigidTransform3<T>(decomposition.Transform->Rotation(),
83 transform.Translation());
84 }
85
86 template <typename T>
87 [[nodiscard]] inline std::optional<RigidTransform3<T>> TryToRigid(
88 const Mat4<T>& matrix,
90 {
91 const auto affine = TryToAffine(matrix, tolerance);
92 return affine ? TryToRigid(*affine, tolerance) : std::nullopt;
93 }
94} // namespace mv::math
std::optional< RigidTransform3< T > > TryToRigid(const AffineTransform3< T > &transform, Tolerance< T > tolerance=Tolerance< T >::Default()) noexcept
TrsDecomposition3< T > DecomposeTrs(const AffineTransform3< T > &transform, T orthogonalityTolerance=static_cast< T >(1.0e-5)) noexcept
Mat4< T > ToMat4(const AffineTransform3< T > &transform) noexcept
AffineTransform3< T > ToAffine(const RigidTransform3< T > &transform) noexcept
bool IsNearlyEqual(const Quat< T > &left, const Quat< T > &right, Tolerance< T > tolerance=Tolerance< T >::Default()) noexcept
Definition Quat.hpp:176
std::optional< AffineTransform3< T > > TryToAffine(const Mat4< T > &matrix, Tolerance< T > tolerance=Tolerance< T >::Default()) noexcept
constexpr bool IsNearlyZero(T value, T absoluteTolerance=Tolerance< T >::Default().Absolute) noexcept
Definition Tolerance.hpp:54