main sync #3

Merged
Patrick Busch merged 318 commits from blender/blender:main into main 2023-03-17 15:52:21 +01:00
5 changed files with 47 additions and 74 deletions
Showing only changes of commit 219be2e755 - Show all commits

View File

@ -256,13 +256,13 @@ template<typename MatT, typename VectorT>
* Extract euler rotation from transform matrix. * Extract euler rotation from transform matrix.
* \return the rotation with the smallest values from the potential candidates. * \return the rotation with the smallest values from the potential candidates.
*/ */
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::EulerXYZ<T> to_euler(const MatBase<T, 3, 3> &mat); [[nodiscard]] inline detail::EulerXYZ<T> to_euler(const MatBase<T, 3, 3> &mat);
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::EulerXYZ<T> to_euler(const MatBase<T, 4, 4> &mat); [[nodiscard]] inline detail::EulerXYZ<T> to_euler(const MatBase<T, 4, 4> &mat);
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::Euler3<T> to_euler(const MatBase<T, 3, 3> &mat, EulerOrder order); [[nodiscard]] inline detail::Euler3<T> to_euler(const MatBase<T, 3, 3> &mat, EulerOrder order);
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::Euler3<T> to_euler(const MatBase<T, 4, 4> &mat, EulerOrder order); [[nodiscard]] inline detail::Euler3<T> to_euler(const MatBase<T, 4, 4> &mat, EulerOrder order);
/** /**
@ -272,25 +272,25 @@ template<typename T, bool Normalized = false>
* \return the rotation with the smallest values from the potential candidates. * \return the rotation with the smallest values from the potential candidates.
* \note this correspond to the C API "to_compatible" functions. * \note this correspond to the C API "to_compatible" functions.
*/ */
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::EulerXYZ<T> to_nearest_euler(const MatBase<T, 3, 3> &mat, [[nodiscard]] inline detail::EulerXYZ<T> to_nearest_euler(const MatBase<T, 3, 3> &mat,
const detail::EulerXYZ<T> &reference); const detail::EulerXYZ<T> &reference);
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::EulerXYZ<T> to_nearest_euler(const MatBase<T, 4, 4> &mat, [[nodiscard]] inline detail::EulerXYZ<T> to_nearest_euler(const MatBase<T, 4, 4> &mat,
const detail::EulerXYZ<T> &reference); const detail::EulerXYZ<T> &reference);
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::Euler3<T> to_nearest_euler(const MatBase<T, 3, 3> &mat, [[nodiscard]] inline detail::Euler3<T> to_nearest_euler(const MatBase<T, 3, 3> &mat,
const detail::Euler3<T> &reference); const detail::Euler3<T> &reference);
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::Euler3<T> to_nearest_euler(const MatBase<T, 4, 4> &mat, [[nodiscard]] inline detail::Euler3<T> to_nearest_euler(const MatBase<T, 4, 4> &mat,
const detail::Euler3<T> &reference); const detail::Euler3<T> &reference);
/** /**
* Extract quaternion rotation from transform matrix. * Extract quaternion rotation from transform matrix.
*/ */
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::Quaternion<T> to_quaternion(const MatBase<T, 3, 3> &mat); [[nodiscard]] inline detail::Quaternion<T> to_quaternion(const MatBase<T, 3, 3> &mat);
template<typename T, bool Normalized = false> template<typename T>
[[nodiscard]] inline detail::Quaternion<T> to_quaternion(const MatBase<T, 4, 4> &mat); [[nodiscard]] inline detail::Quaternion<T> to_quaternion(const MatBase<T, 4, 4> &mat);
/** /**
@ -1076,61 +1076,44 @@ extern template MatBase<float, 4, 4> from_rotation(const math::AxisAngleCartesia
} // namespace detail } // namespace detail
template<typename T, bool Normalized> template<typename T>
[[nodiscard]] inline detail::Euler3<T> to_euler(const MatBase<T, 3, 3> &mat, EulerOrder order) [[nodiscard]] inline detail::Euler3<T> to_euler(const MatBase<T, 3, 3> &mat, EulerOrder order)
{ {
detail::Euler3<T> eul1(order), eul2(order); detail::Euler3<T> eul1(order), eul2(order);
if constexpr (Normalized) {
detail::normalized_to_eul2(mat, eul1, eul2); detail::normalized_to_eul2(mat, eul1, eul2);
}
else {
detail::normalized_to_eul2(normalize(mat), eul1, eul2);
}
/* Return best, which is just the one with lowest values in it. */ /* Return best, which is just the one with lowest values in it. */
return (length_manhattan(VecBase<T, 3>(eul1)) > length_manhattan(VecBase<T, 3>(eul2))) ? eul2 : return (length_manhattan(VecBase<T, 3>(eul1)) > length_manhattan(VecBase<T, 3>(eul2))) ? eul2 :
eul1; eul1;
} }
template<typename T, bool Normalized> template<typename T> [[nodiscard]] inline detail::EulerXYZ<T> to_euler(const MatBase<T, 3, 3> &mat)
[[nodiscard]] inline detail::EulerXYZ<T> to_euler(const MatBase<T, 3, 3> &mat)
{ {
detail::EulerXYZ<T> eul1, eul2; detail::EulerXYZ<T> eul1, eul2;
if constexpr (Normalized) {
detail::normalized_to_eul2(mat, eul1, eul2); detail::normalized_to_eul2(mat, eul1, eul2);
}
else {
detail::normalized_to_eul2(normalize(mat), eul1, eul2);
}
/* Return best, which is just the one with lowest values in it. */ /* Return best, which is just the one with lowest values in it. */
return (length_manhattan(VecBase<T, 3>(eul1)) > length_manhattan(VecBase<T, 3>(eul2))) ? eul2 : return (length_manhattan(VecBase<T, 3>(eul1)) > length_manhattan(VecBase<T, 3>(eul2))) ? eul2 :
eul1; eul1;
} }
template<typename T, bool Normalized> template<typename T>
[[nodiscard]] inline detail::Euler3<T> to_euler(const MatBase<T, 4, 4> &mat, EulerOrder order) [[nodiscard]] inline detail::Euler3<T> to_euler(const MatBase<T, 4, 4> &mat, EulerOrder order)
{ {
/* TODO(fclem): Avoid the copy with 3x3 ref. */ /* TODO(fclem): Avoid the copy with 3x3 ref. */
return to_euler<T, Normalized>(MatBase<T, 3, 3>(mat), order); return to_euler<T>(MatBase<T, 3, 3>(mat), order);
} }
template<typename T, bool Normalized> template<typename T> [[nodiscard]] inline detail::EulerXYZ<T> to_euler(const MatBase<T, 4, 4> &mat)
[[nodiscard]] inline detail::EulerXYZ<T> to_euler(const MatBase<T, 4, 4> &mat)
{ {
/* TODO(fclem): Avoid the copy with 3x3 ref. */ /* TODO(fclem): Avoid the copy with 3x3 ref. */
return to_euler<T, Normalized>(MatBase<T, 3, 3>(mat)); return to_euler<T>(MatBase<T, 3, 3>(mat));
} }
template<typename T, bool Normalized> template<typename T>
[[nodiscard]] inline detail::Euler3<T> to_nearest_euler(const MatBase<T, 3, 3> &mat, [[nodiscard]] inline detail::Euler3<T> to_nearest_euler(const MatBase<T, 3, 3> &mat,
const detail::Euler3<T> &reference) const detail::Euler3<T> &reference)
{ {
detail::Euler3<T> eul1(reference.order()), eul2(reference.order()); detail::Euler3<T> eul1(reference.order()), eul2(reference.order());
if constexpr (Normalized) {
detail::normalized_to_eul2(mat, eul1, eul2); detail::normalized_to_eul2(mat, eul1, eul2);
}
else {
detail::normalized_to_eul2(normalize(mat), eul1, eul2);
}
eul1 = eul1.wrapped_around(reference); eul1 = eul1.wrapped_around(reference);
eul2 = eul2.wrapped_around(reference); eul2 = eul2.wrapped_around(reference);
/* Return best, which is just the one with lowest values it in. */ /* Return best, which is just the one with lowest values it in. */
@ -1140,17 +1123,12 @@ template<typename T, bool Normalized>
eul1; eul1;
} }
template<typename T, bool Normalized> template<typename T>
[[nodiscard]] inline detail::EulerXYZ<T> to_nearest_euler(const MatBase<T, 3, 3> &mat, [[nodiscard]] inline detail::EulerXYZ<T> to_nearest_euler(const MatBase<T, 3, 3> &mat,
const detail::EulerXYZ<T> &reference) const detail::EulerXYZ<T> &reference)
{ {
detail::EulerXYZ<T> eul1, eul2; detail::EulerXYZ<T> eul1, eul2;
if constexpr (Normalized) {
detail::normalized_to_eul2(mat, eul1, eul2); detail::normalized_to_eul2(mat, eul1, eul2);
}
else {
detail::normalized_to_eul2(normalize(mat), eul1, eul2);
}
eul1 = eul1.wrapped_around(reference); eul1 = eul1.wrapped_around(reference);
eul2 = eul2.wrapped_around(reference); eul2 = eul2.wrapped_around(reference);
/* Return best, which is just the one with lowest values it in. */ /* Return best, which is just the one with lowest values it in. */
@ -1160,39 +1138,33 @@ template<typename T, bool Normalized>
eul1; eul1;
} }
template<typename T, bool Normalized> template<typename T>
[[nodiscard]] inline detail::Euler3<T> to_nearest_euler(const MatBase<T, 4, 4> &mat, [[nodiscard]] inline detail::Euler3<T> to_nearest_euler(const MatBase<T, 4, 4> &mat,
const detail::Euler3<T> &reference) const detail::Euler3<T> &reference)
{ {
/* TODO(fclem): Avoid the copy with 3x3 ref. */ /* TODO(fclem): Avoid the copy with 3x3 ref. */
return to_euler<T, Normalized>(MatBase<T, 3, 3>(mat), reference); return to_euler<T>(MatBase<T, 3, 3>(mat), reference);
} }
template<typename T, bool Normalized> template<typename T>
[[nodiscard]] inline detail::EulerXYZ<T> to_nearest_euler(const MatBase<T, 4, 4> &mat, [[nodiscard]] inline detail::EulerXYZ<T> to_nearest_euler(const MatBase<T, 4, 4> &mat,
const detail::EulerXYZ<T> &reference) const detail::EulerXYZ<T> &reference)
{ {
/* TODO(fclem): Avoid the copy with 3x3 ref. */ /* TODO(fclem): Avoid the copy with 3x3 ref. */
return to_euler<T, Normalized>(MatBase<T, 3, 3>(mat), reference); return to_euler<T>(MatBase<T, 3, 3>(mat), reference);
} }
template<typename T, bool Normalized> template<typename T>
[[nodiscard]] inline detail::Quaternion<T> to_quaternion(const MatBase<T, 3, 3> &mat) [[nodiscard]] inline detail::Quaternion<T> to_quaternion(const MatBase<T, 3, 3> &mat)
{ {
using namespace math;
if constexpr (Normalized) {
return detail::normalized_to_quat_with_checks(mat); return detail::normalized_to_quat_with_checks(mat);
}
else {
return detail::normalized_to_quat_with_checks(normalize(mat));
}
} }
template<typename T, bool Normalized> template<typename T>
[[nodiscard]] inline detail::Quaternion<T> to_quaternion(const MatBase<T, 4, 4> &mat) [[nodiscard]] inline detail::Quaternion<T> to_quaternion(const MatBase<T, 4, 4> &mat)
{ {
/* TODO(fclem): Avoid the copy with 3x3 ref. */ /* TODO(fclem): Avoid the copy with 3x3 ref. */
return to_quaternion<T, Normalized>(MatBase<T, 3, 3>(mat)); return to_quaternion<T>(MatBase<T, 3, 3>(mat));
} }
template<bool AllowNegativeScale, typename T, int NumCol, int NumRow> template<bool AllowNegativeScale, typename T, int NumCol, int NumRow>
@ -1222,22 +1194,22 @@ template<bool AllowNegativeScale, typename T>
/* Implementation details. Use `to_euler` and `to_quaternion` instead. */ /* Implementation details. Use `to_euler` and `to_quaternion` instead. */
namespace detail { namespace detail {
template<typename T, bool Normalized> template<typename T>
inline void to_rotation(const MatBase<T, 3, 3> &mat, detail::Quaternion<T> &r_rotation) inline void to_rotation(const MatBase<T, 3, 3> &mat, detail::Quaternion<T> &r_rotation)
{ {
r_rotation = to_quaternion<T, Normalized>(mat); r_rotation = to_quaternion<T>(mat);
} }
template<typename T, bool Normalized> template<typename T>
inline void to_rotation(const MatBase<T, 3, 3> &mat, detail::EulerXYZ<T> &r_rotation) inline void to_rotation(const MatBase<T, 3, 3> &mat, detail::EulerXYZ<T> &r_rotation)
{ {
r_rotation = to_euler<T, Normalized>(mat); r_rotation = to_euler<T>(mat);
} }
template<typename T, bool Normalized> template<typename T>
inline void to_rotation(const MatBase<T, 3, 3> &mat, detail::Euler3<T> &r_rotation) inline void to_rotation(const MatBase<T, 3, 3> &mat, detail::Euler3<T> &r_rotation)
{ {
r_rotation = to_euler<T, Normalized>(mat, r_rotation.order()); r_rotation = to_euler<T>(mat, r_rotation.order());
} }
} // namespace detail } // namespace detail
@ -1254,7 +1226,7 @@ inline void to_rot_scale(const MatBase<T, 3, 3> &mat,
r_scale = -r_scale; r_scale = -r_scale;
} }
} }
detail::to_rotation<T, true>(normalized_mat, r_rotation); detail::to_rotation<T>(normalized_mat, r_rotation);
} }
template<bool AllowNegativeScale, typename T, typename RotationT> template<bool AllowNegativeScale, typename T, typename RotationT>

View File

@ -586,7 +586,7 @@ template<typename T>
const Mat4T baseinv = invert(basemat); const Mat4T baseinv = invert(basemat);
/* Extra orthogonalize, to avoid flipping with stretched bones. */ /* Extra orthogonalize, to avoid flipping with stretched bones. */
detail::Quaternion<T> basequat = to_quaternion(orthogonalize(baseRS, Axis::Y)); detail::Quaternion<T> basequat = to_quaternion(normalize(orthogonalize(baseRS, Axis::Y)));
Mat4T baseR = from_rotation<Mat4T>(basequat); Mat4T baseR = from_rotation<Mat4T>(basequat);
baseR.location() = baseRS.location(); baseR.location() = baseRS.location();
@ -603,7 +603,7 @@ template<typename T>
} }
/* Non-dual part. */ /* Non-dual part. */
const detail::Quaternion<T> q = to_quaternion(R); const detail::Quaternion<T> q = to_quaternion(normalize(R));
/* Dual part. */ /* Dual part. */
const Vec3T &t = R.location().xyz(); const Vec3T &t = R.location().xyz();
@ -663,7 +663,7 @@ template<typename T> detail::EulerXYZ<T> to_euler(const detail::Quaternion<T> &q
using Mat3T = MatBase<T, 3, 3>; using Mat3T = MatBase<T, 3, 3>;
BLI_assert(is_unit_scale(quat)); BLI_assert(is_unit_scale(quat));
Mat3T unit_mat = from_rotation<Mat3T>(quat); Mat3T unit_mat = from_rotation<Mat3T>(quat);
return to_euler<T, true>(unit_mat); return to_euler<T>(unit_mat);
} }
template<typename T> template<typename T>
@ -672,7 +672,7 @@ detail::Euler3<T> to_euler(const detail::Quaternion<T> &quat, EulerOrder order)
using Mat3T = MatBase<T, 3, 3>; using Mat3T = MatBase<T, 3, 3>;
BLI_assert(is_unit_scale(quat)); BLI_assert(is_unit_scale(quat));
Mat3T unit_mat = from_rotation<Mat3T>(quat); Mat3T unit_mat = from_rotation<Mat3T>(quat);
return to_euler<T, true>(unit_mat, order); return to_euler<T>(unit_mat, order);
} }
/** \} */ /** \} */

View File

@ -339,8 +339,8 @@ MatBase<T, 3, 3> interpolate(const MatBase<T, 3, 3> &A, const MatBase<T, 3, 3> &
P_B = -P_B; P_B = -P_B;
} }
detail::Quaternion<T> quat_A = math::to_quaternion(U_A); detail::Quaternion<T> quat_A = math::to_quaternion(normalize(U_A));
detail::Quaternion<T> quat_B = math::to_quaternion(U_B); detail::Quaternion<T> quat_B = math::to_quaternion(normalize(U_B));
detail::Quaternion<T> quat = math::interpolate(quat_A, quat_B, t); detail::Quaternion<T> quat = math::interpolate(quat_A, quat_B, t);
Mat3T U = from_rotation<Mat3T>(quat); Mat3T U = from_rotation<Mat3T>(quat);

View File

@ -347,8 +347,6 @@ TEST(math_matrix, MatrixMethods)
float3 expect_scale = float3(3, 2, 2); float3 expect_scale = float3(3, 2, 2);
float3 expect_location = float3(0, 1, 0); float3 expect_location = float3(0, 1, 0);
EXPECT_V3_NEAR(float3(to_euler(m)), float3(expect_eul), 0.0002f);
EXPECT_V4_NEAR(float4(to_quaternion(m)), float4(expect_qt), 0.0002f);
EXPECT_EQ(to_scale(m), expect_scale); EXPECT_EQ(to_scale(m), expect_scale);
float4 expect_sz = {3, 2, 2, M_SQRT2}; float4 expect_sz = {3, 2, 2, M_SQRT2};
@ -360,6 +358,9 @@ TEST(math_matrix, MatrixMethods)
float4x4 m2 = normalize(m); float4x4 m2 = normalize(m);
EXPECT_TRUE(is_unit_scale(m2)); EXPECT_TRUE(is_unit_scale(m2));
EXPECT_V3_NEAR(float3(to_euler(m1)), float3(expect_eul), 0.0002f);
EXPECT_V4_NEAR(float4(to_quaternion(m1)), float4(expect_qt), 0.0002f);
EulerXYZ eul; EulerXYZ eul;
Quaternion qt; Quaternion qt;
float3 scale; float3 scale;

View File

@ -268,7 +268,7 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
if (STREQ(column_id.name, "Rotation")) { if (STREQ(column_id.name, "Rotation")) {
return std::make_unique<ColumnValues>( return std::make_unique<ColumnValues>(
column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) { column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
return float3(math::to_euler(transforms[index])); return float3(math::to_euler(math::normalize(transforms[index])));
})); }));
} }
if (STREQ(column_id.name, "Scale")) { if (STREQ(column_id.name, "Scale")) {