diff --git a/source/blender/blenlib/BLI_math_quaternion.hh b/source/blender/blenlib/BLI_math_quaternion.hh index 4c0be97f225..9f18022bc9b 100644 --- a/source/blender/blenlib/BLI_math_quaternion.hh +++ b/source/blender/blenlib/BLI_math_quaternion.hh @@ -630,8 +630,11 @@ AxisAngleBase to_axis_angle(const QuaternionBase &quat) T sin_half_angle = math::length(axis); /* Prevent division by zero for axis conversion. */ if (sin_half_angle < T(0.0005)) { - sin_half_angle = T(1); - axis[1] = T(1); + using AngleAxisT = typename AxisAngleBase::vec3_type; + const AngleAxisT identity_axis = AxisAngleBase::identity().axis(); + BLI_assert(abs(cos_half_angle) > 0.0005); + AxisAngleBase identity(identity_axis * sign(cos_half_angle), AngleT(0)); + return identity; } /* Normalize the axis. */ axis /= sin_half_angle; diff --git a/source/blender/blenlib/tests/BLI_math_rotation_test.cc b/source/blender/blenlib/tests/BLI_math_rotation_test.cc index 8a04184532f..f5d0ed7cfb8 100644 --- a/source/blender/blenlib/tests/BLI_math_rotation_test.cc +++ b/source/blender/blenlib/tests/BLI_math_rotation_test.cc @@ -879,4 +879,22 @@ TEST(math_rotation, DualQuaternionTransform) } } +TEST(math_axis_angle, AxisAngleFromQuaternion) +{ + { + const math::AxisAngle axis_angle({0.0f, 1.0f, 0.0f}, math::AngleRadian(0)); + const math::Quaternion quaternion(1.0f, {0.0f, 0.0f, 0.0f}); + const math::AxisAngle from_quaternion = math::to_axis_angle(quaternion); + EXPECT_V3_NEAR(axis_angle.axis(), from_quaternion.axis(), 1e-6); + EXPECT_NEAR(axis_angle.angle().radian(), from_quaternion.angle().radian(), 1e-6); + } + { + const math::AxisAngle axis_angle({0.0f, -1.0f, 0.0f}, math::AngleRadian(0)); + const math::Quaternion quaternion(-1.0f, {0.0f, 0.0f, 0.0f}); + const math::AxisAngle from_quaternion = math::to_axis_angle(quaternion); + EXPECT_V3_NEAR(axis_angle.axis(), from_quaternion.axis(), 1e-6); + EXPECT_NEAR(axis_angle.angle().radian(), from_quaternion.angle().radian(), 1e-6); + } +} + } // namespace blender::math::tests