From d66f7aaf5646887d0a3e54de59364a74ccd3533f Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Tue, 17 Feb 2026 14:47:56 -0700 Subject: [PATCH] fix: Calculate shortest path for camera rotations Co-authored-by: aider (gemini/gemini-2.5-pro) --- src/Camera.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/Camera.cpp b/src/Camera.cpp index 301a8d8..d5422ee 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -211,17 +211,37 @@ void Camera::animateToPlaneView(int plane) auto* animGroup = new QParallelAnimationGroup(this); + const float full_circle = 360.0f * 16.0f; + + float currentXRot = xRotation(); + float diffX = targetXRot - currentXRot; + diffX = fmod(diffX, full_circle); + if (diffX > full_circle / 2.0f) { + diffX -= full_circle; + } else if (diffX < -full_circle / 2.0f) { + diffX += full_circle; + } + auto* xRotAnim = new QPropertyAnimation(this, "xRotation"); xRotAnim->setDuration(300); - xRotAnim->setStartValue(xRotation()); - xRotAnim->setEndValue(targetXRot); + xRotAnim->setStartValue(currentXRot); + xRotAnim->setEndValue(currentXRot + diffX); xRotAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(xRotAnim); + float currentYRot = yRotation(); + float diffY = targetYRot - currentYRot; + diffY = fmod(diffY, full_circle); + if (diffY > full_circle / 2.0f) { + diffY -= full_circle; + } else if (diffY < -full_circle / 2.0f) { + diffY += full_circle; + } + auto* yRotAnim = new QPropertyAnimation(this, "yRotation"); yRotAnim->setDuration(300); - yRotAnim->setStartValue(yRotation()); - yRotAnim->setEndValue(targetYRot); + yRotAnim->setStartValue(currentYRot); + yRotAnim->setEndValue(currentYRot + diffY); yRotAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(yRotAnim); @@ -295,17 +315,39 @@ void Camera::animateRestoreState() { auto* animGroup = new QParallelAnimationGroup(this); + const float full_circle = 360.0f * 16.0f; + + float currentXRot = xRotation(); + float targetXRot = savedXRot(); + float diffX = targetXRot - currentXRot; + diffX = fmod(diffX, full_circle); + if (diffX > full_circle / 2.0f) { + diffX -= full_circle; + } else if (diffX < -full_circle / 2.0f) { + diffX += full_circle; + } + auto* xRotAnim = new QPropertyAnimation(this, "xRotation"); xRotAnim->setDuration(300); - xRotAnim->setStartValue(xRotation()); - xRotAnim->setEndValue(savedXRot()); + xRotAnim->setStartValue(currentXRot); + xRotAnim->setEndValue(currentXRot + diffX); xRotAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(xRotAnim); + float currentYRot = yRotation(); + float targetYRot = savedYRot(); + float diffY = targetYRot - currentYRot; + diffY = fmod(diffY, full_circle); + if (diffY > full_circle / 2.0f) { + diffY -= full_circle; + } else if (diffY < -full_circle / 2.0f) { + diffY += full_circle; + } + auto* yRotAnim = new QPropertyAnimation(this, "yRotation"); yRotAnim->setDuration(300); - yRotAnim->setStartValue(yRotation()); - yRotAnim->setEndValue(savedYRot()); + yRotAnim->setStartValue(currentYRot); + yRotAnim->setEndValue(currentYRot + diffY); yRotAnim->setEasingCurve(QEasingCurve::InOutQuad); animGroup->addAnimation(yRotAnim);