diff --git a/src/OgreWidget.cpp b/src/OgreWidget.cpp index 885b72f..bf1b35a 100755 --- a/src/OgreWidget.cpp +++ b/src/OgreWidget.cpp @@ -268,7 +268,8 @@ bool OgreWidget::event(QEvent *e) if (e->type() == QEvent::NativeGesture) { auto *gestureEvent = static_cast(e); if (gestureEvent->gestureType() == Qt::ZoomNativeGesture) { - int delta = static_cast(gestureEvent->value() * 200 * mCamera->getCameraSpeed()); + // value() is typically ±0.01..0.1 per gesture event; scale to usable range + Ogre::Real delta = static_cast(gestureEvent->value() * 5.0); mCamera->zoomByDelta(delta); e->accept(); return true; diff --git a/src/SpaceCamera.cpp b/src/SpaceCamera.cpp index af82e85..b40eee2 100755 --- a/src/SpaceCamera.cpp +++ b/src/SpaceCamera.cpp @@ -218,10 +218,27 @@ void SpaceCamera::mouseMoveEvent(QMouseEvent *event) void SpaceCamera::wheelEvent(QWheelEvent *event) { - int delta = event->angleDelta().y() * 10 / 60 * getCameraSpeed(); - zoom(delta); + Ogre::Real xDelta = event->angleDelta().x() / 120.0f; + Ogre::Real yDelta = event->angleDelta().y() / 120.0f; - pan(Ogre::Vector2 ( event->angleDelta().x() * 10 / 60 * getCameraSpeed() , 0.0 )); + if (event->modifiers().testFlag(Qt::ControlModifier)) + { + // Ctrl + scroll = zoom (for mouse wheel users) + zoom(yDelta); + } + else if (event->source() == Qt::MouseEventSynthesizedBySystem) + { + // Trackpad two-finger swipe = pan in both axes + Ogre::Real panScale = 3.0f; + pan(Ogre::Vector2(xDelta * panScale, yDelta * panScale)); + } + else + { + // Mouse scroll wheel = zoom + zoom(yDelta); + if (std::abs(xDelta) > 0.01f) + pan(Ogre::Vector2(xDelta * 3.0f, 0.0f)); + } event->accept(); } @@ -331,20 +348,37 @@ void SpaceCamera::keyReleaseEvent(QKeyEvent *event) ////////////////////////////////////////////////////////////////////////////////// //Private Methods -void SpaceCamera::zoomByDelta(int delta) +void SpaceCamera::zoomByDelta(Ogre::Real delta) { zoom(delta); } -void SpaceCamera::zoom(const int delta) +void SpaceCamera::zoom(Ogre::Real delta) { - Ogre::Vector3 zTranslation(0, 0, delta); - mCameraNode->translate(zTranslation,Ogre::Node::TS_PARENT); + // Proportional zoom: step size scales with distance to target, + // so zooming feels consistent regardless of model size. + Ogre::Real distance = std::abs(mCameraNode->getPosition().z); + Ogre::Real minDistance = 0.01f; + Ogre::Real zoomFactor = 0.15f; // 15% of distance per scroll tick + + Ogre::Real step = delta * std::max(distance, minDistance) * zoomFactor; + + Ogre::Vector3 newPos = mCameraNode->getPosition(); + newPos.z += step; + + // Don't pass through the target + if (newPos.z > -minDistance) + newPos.z = -minDistance; + + mCameraNode->setPosition(newPos); } void SpaceCamera::pan(const Ogre::Real& deltaX, const Ogre::Real& deltaY) { - mTarget->translate(deltaX,deltaY,0,Ogre::Node::TS_LOCAL ); + // Proportional pan: step scales with distance to target + Ogre::Real distance = std::abs(mCameraNode->getPosition().z); + Ogre::Real scale = std::max(distance, 0.01f) * 0.01f; + mTarget->translate(deltaX * scale, deltaY * scale, 0, Ogre::Node::TS_LOCAL); } void SpaceCamera::pan(const Ogre::Vector2& translation) diff --git a/src/SpaceCamera.h b/src/SpaceCamera.h index e657e3a..e5c53dd 100755 --- a/src/SpaceCamera.h +++ b/src/SpaceCamera.h @@ -74,7 +74,7 @@ class SpaceCamera : Ogre::FrameListener virtual void mouseMoveEvent(QMouseEvent *event); virtual void wheelEvent(QWheelEvent *event); - void zoomByDelta(int delta); + void zoomByDelta(Ogre::Real delta); protected: SpaceCamera(){} // for testing purposes @@ -104,7 +104,7 @@ class SpaceCamera : Ogre::FrameListener float mAnimDuration = 0.5f; void setKeyMapping(); - void zoom(const int delta); + void zoom(Ogre::Real delta); void pan(const Ogre::Real& deltaX, const Ogre::Real& deltaY); void pan(const Ogre::Vector2& translation); void arcBall(const Ogre::Vector2& rotation);