Fix #119703: Incorrect conversion of identity quaternion to axis angle #119762
|
@ -630,8 +630,11 @@ AxisAngleBase<T, AngleT> to_axis_angle(const QuaternionBase<T> &quat)
|
||||||
T sin_half_angle = math::length(axis);
|
T sin_half_angle = math::length(axis);
|
||||||
/* Prevent division by zero for axis conversion. */
|
/* Prevent division by zero for axis conversion. */
|
||||||
if (sin_half_angle < T(0.0005)) {
|
if (sin_half_angle < T(0.0005)) {
|
||||||
sin_half_angle = T(1);
|
const AxisAngleBase<T, AngleT>::vec3_type identity_axis =
|
||||||
axis[1] = T(1);
|
AxisAngleBase<T, AngleT>::identity().axis();
|
||||||
|
BLI_assert(abs(cos_half_angle) > 0.0005);
|
||||||
mod_moder marked this conversation as resolved
Outdated
|
|||||||
|
AxisAngleBase<T, AngleT> identity(identity_axis * sign(cos_half_angle), AngleT(0));
|
||||||
|
return identity;
|
||||||
}
|
}
|
||||||
/* Normalize the axis. */
|
/* Normalize the axis. */
|
||||||
axis /= sin_half_angle;
|
axis /= sin_half_angle;
|
||||||
|
|
|
@ -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
|
} // namespace blender::math::tests
|
||||||
|
|
Loading…
Reference in New Issue
Use
AngleT(0)
.sign
will return0
ifcos_half_angle
is 0. Is that what you want?No, i expect that
sign
will always be non zero... But here this looks like its will be enough to just add assertion. This is safe for normalized quaternion.