Fix Quaternion arc constructor to check dot & Add test for same vec3s

This commit is contained in:
Silc Lizard (Tokage) Renew 2025-01-19 20:44:59 +09:00
parent 7b1ed520bd
commit 27e23280c5
2 changed files with 16 additions and 5 deletions

View file

@ -141,16 +141,24 @@ struct [[nodiscard]] Quaternion {
} }
Quaternion(const Vector3 &p_v0, const Vector3 &p_v1) { // Shortest arc. Quaternion(const Vector3 &p_v0, const Vector3 &p_v1) { // Shortest arc.
Vector3 c = p_v0.cross(p_v1); #ifdef MATH_CHECKS
ERR_FAIL_COND_MSG(p_v0.is_zero_approx() || p_v1.is_zero_approx(), "The vectors must not be zero.");
if (c.is_zero_approx()) { #endif
Vector3 axis = p_v0.get_any_perpendicular(); constexpr real_t ALMOST_ONE = 1.0f - (real_t)CMP_EPSILON;
Vector3 n0 = p_v0.normalized();
Vector3 n1 = p_v1.normalized();
real_t d = n0.dot(n1);
if (abs(d) > ALMOST_ONE) {
if (d >= 0) {
return; // Vectors are same.
}
Vector3 axis = n0.get_any_perpendicular();
x = axis.x; x = axis.x;
y = axis.y; y = axis.y;
z = axis.z; z = axis.z;
w = 0; w = 0;
} else { } else {
real_t d = p_v0.dot(p_v1); Vector3 c = n0.cross(n1);
real_t s = Math::sqrt((1.0f + d) * 2.0f); real_t s = Math::sqrt((1.0f + d) * 2.0f);
real_t rs = 1.0f / s; real_t rs = 1.0f / s;

View file

@ -263,6 +263,9 @@ TEST_CASE("[Quaternion] Construct Shortest Arc For 180 Degree Arc") {
// For the consistency of the rotation direction, they should be symmetrical to the plane. // For the consistency of the rotation direction, they should be symmetrical to the plane.
CHECK(left_to_right.is_equal_approx(right_to_left.inverse())); CHECK(left_to_right.is_equal_approx(right_to_left.inverse()));
// If vectors are same, no rotation.
CHECK(Quaternion(diagonal_up, diagonal_up).is_equal_approx(Quaternion()));
} }
TEST_CASE("[Quaternion] Get Euler Orders") { TEST_CASE("[Quaternion] Get Euler Orders") {