30inline void TransformRT::WarnIfRotationNotNormalized()
const {
33#if MOCHI_ASSERT_VERBOSE_ENABLED && MOCHI_LOG_ENABLED
34 auto norm =
Norm(_rotation);
35 if (!
NearEqual(norm, 1_r, kQuaternionTol))
38 "TransformRT expects a unit length quaternion, but got [%g, %g, %g, %g] (magnitude %g).",
49 : _rotation(rotation), _translation(
ToReal3(translation)) {
50 WarnIfRotationNotNormalized();
54 : _rotation(rotation), _translation(translation) {
55 WarnIfRotationNotNormalized();
59 WarnIfRotationNotNormalized();
63 : _translation(
ToReal3(translation)) {}
80 Store(x, matColumns[0]);
81 Store(y, matColumns[1]);
82 Store(z, matColumns[2]);
85 int k0 = 0, k1 = 0, k2 = 0, k3 = 0;
86 real s0 = 0_r, s1 = 0_r, s2 = 0_r;
87 if (x[0] + y[1] + z[2] > 0_r) {
95 }
else if (x[0] > y[1] && x[0] > z[2]) {
103 }
else if (y[1] > z[2]) {
120 real t = (s0 * x[0]) + (s1 * y[1]) + (s2 * z[2]) + 1.0_r;
121 real s = (1.0_r / std::sqrt(t)) * 0.5_r;
123 q[k1] = (x[1] - s2 * y[0]) * s;
124 q[k2] = (z[0] - s1 * x[2]) * s;
125 q[k3] = (y[2] - s0 * z[1]) * s;
139 _rotation = rotation;
140 WarnIfRotationNotNormalized();
144 return ToSimd(_translation, 1_r);
152 _translation =
ToReal3(translation);
156 _translation = translation;
160 return _rotation == rhs._rotation && _translation == rhs._translation;
164 return !(*
this == rhs);
174 *
this = (*this) * rhs;
217 q *
Vec4r(1.0_r, 0.0_r, 0.0_r),
218 q *
Vec4r(0.0_r, 1.0_r, 0.0_r),
219 q *
Vec4r(0.0_r, 0.0_r, 1.0_r),
269 auto translation =
ToReal3(matrixT[3]);
277 auto determinant =
Det3x3(matrixT);
278 if (determinant < 0_r) {
279 scale[0] = -scale[0];
283 matrixT[0] /= scale[0] + std::numeric_limits<real>::min();
284 matrixT[1] /= scale[1] + std::numeric_limits<real>::min();
285 matrixT[2] /= scale[2] + std::numeric_limits<real>::min();
288 return std::make_pair(scale,
TransformRT{rotation, translation});
#define MOCHI_LOG_WARNING(...)
Quaternion Slerp(Quaternion a, Quaternion b, real t)
Simd< T, N > VIsFinite(Simd< T, N > a)
Simd< T, 4 > ToSimd(NdArray< T, 2 > const &v, T z=T(0), T w=T(0))
Real3 ToReal3(Simd< T, 4 > v)
NdArray< Simd< T, 4 >, 3 > Transpose3x3(NdArray< Simd< T, 4 >, D0 > const &m)
std::pair< Real3, TransformRT > DecomposeMatrixTransform(VMatrix4x4r const &matrixTransform)
NdArray< Simd< real, 4 >, 4 > VMatrix4x4r
Simd< T, N > Normalize(Simd< T, N > a)
TransformRT Invert(TransformRT const &a)
VMatrix4x4r ToVMatrix4x4(TransformRT const &a)
NdArray< Simd< T, 4 >, 4 > Transpose4x4(NdArray< Simd< T, 4 >, 4 > const &m)
Quaternion Conjugate(Quaternion const &a)
TransformRT Repivot(TransformRT const &transform, Real3 const &pivot)
VMatrix4x4r ToVMatrix4x4Transpose(TransformRT const &a)
void Store(T *ptr, Simd< T, N > a)
TransformRT NormalizeRotation(TransformRT const &a)
TransformRT Interpolate(TransformRT const &a, TransformRT const &b, real t)
bool NearEqual(TransformRT const &a, TransformRT const &b, real epsilon=kDefaultNearEqualEpsilon< real >)
T Det3x3(NdArray< Simd< T, 4 >, N > const &A)
Quaternion QuaternionFromMatrix(VMatrix3x3r const &matrix, real eps=1e-3_r)
bool IsFinite(TransformRT const &a)