@@ -407,6 +407,11 @@ void CelestiaCore::mouseButtonDown(float x, float y, int button)
407407{
408408 mouseMotion = 0 .0f ;
409409
410+ MouseLocation newLocation;
411+ newLocation.x = x;
412+ newLocation.y = y;
413+ dragLocation = newLocation;
414+
410415#ifdef CELX
411416 if (m_script != nullptr )
412417 {
@@ -429,6 +434,8 @@ void CelestiaCore::mouseButtonDown(float x, float y, int button)
429434
430435void CelestiaCore::mouseButtonUp (float x, float y, int button)
431436{
437+ dragLocation = std::nullopt ;
438+
432439 // Four pixel tolerance for picking
433440 float obsPickTolerance = sim->getActiveObserver ()->getFOV () / static_cast <float >(metrics.height ) * this ->pickTolerance ;
434441
@@ -454,17 +461,7 @@ void CelestiaCore::mouseButtonUp(float x, float y, int button)
454461 {
455462 viewManager->pickView (sim, metrics, x, y);
456463
457- float pickX;
458- float pickY;
459- float aspectRatio = static_cast <float >(metrics.width ) / static_cast <float >(metrics.height );
460- viewManager->activeView ()->mapWindowToView (x / static_cast <float >(metrics.width ),
461- y / static_cast <float >(metrics.height ),
462- pickX, pickY);
463- pickX *= aspectRatio;
464- if (isViewportEffectUsed)
465- viewportEffect->distortXY (pickX, pickY);
466-
467- Vector3f pickRay = renderer->getProjectionMode ()->getPickRay (pickX, pickY, viewManager->activeView ()->getObserver ()->getZoom ());
464+ Vector3f pickRay = getPickRay (x, y, viewManager->activeView ());
468465
469466 Selection oldSel = sim->getSelection ();
470467 Selection newSel = sim->pickObject (pickRay, renderer->getRenderFlags (), obsPickTolerance);
@@ -560,6 +557,13 @@ void CelestiaCore::mouseMove(float x, float y)
560557
561558void CelestiaCore::mouseMove (float dx, float dy, int modifiers)
562559{
560+ auto oldLocation = dragLocation;
561+ if (dragLocation.has_value ())
562+ {
563+ dragLocation.value ().x += dx;
564+ dragLocation.value ().y += dy;
565+ }
566+
563567 if (viewManager->resizeViews (metrics, dx, dy))
564568 {
565569 setFOVFromZoom ();
@@ -652,27 +656,21 @@ void CelestiaCore::mouseMove(float dx, float dy, int modifiers)
652656 flash (fmt::sprintf (_ (" Magnitude limit: %.2f" ), sim->getFaintestVisible ()));
653657 }
654658 }
655- else
659+ else if ((modifiers & RightButton) != 0 )
656660 {
657- // For a small field of view, rotate the camera more finely
658- float coarseness = 1 .5f ;
659- if ((modifiers & RightButton) == 0 )
660- {
661- coarseness = math::radToDeg (sim->getActiveObserver ()->getFOV ()) / 30 .0f ;
662- }
663- else
664- {
665- // If right dragging to rotate, adjust the rotation rate
666- // based on the distance from the reference object.
667- coarseness = ComputeRotationCoarseness (*sim);
668- }
661+ // Adjust the rotation rate based on the distance from the reference object.
662+ float coarseness = ComputeRotationCoarseness (*sim);
669663
670664 Quaternionf q = math::XRotation (dy / static_cast <float >(metrics.height ) * coarseness) *
671665 math::YRotation (dx / static_cast <float >(metrics.width ) * coarseness);
672- if ((modifiers & RightButton) != 0 )
673- sim->orbit (q);
674- else
675- sim->rotate (q.conjugate ());
666+ sim->orbit (q);
667+ }
668+ else if (oldLocation.has_value () && dragLocation.has_value ())
669+ {
670+ auto view = viewManager->activeView ();
671+ auto oldPickRay = getPickRay (oldLocation.value ().x , oldLocation.value ().y , view);
672+ auto newPickRay = getPickRay (dragLocation.value ().x , dragLocation.value ().y , view);
673+ sim->rotate (Eigen::Quaternionf::FromTwoVectors (oldPickRay, newPickRay));
676674 }
677675
678676 mouseMotion += abs (dy) + abs (dx);
@@ -2216,6 +2214,22 @@ void CelestiaCore::renderOverlay()
22162214}
22172215
22182216
2217+ Eigen::Vector3f CelestiaCore::getPickRay (float x, float y, const celestia::View *view)
2218+ {
2219+ float pickX;
2220+ float pickY;
2221+ float aspectRatio = static_cast <float >(metrics.width ) / static_cast <float >(metrics.height );
2222+ view->mapWindowToView (x / static_cast <float >(metrics.width ),
2223+ y / static_cast <float >(metrics.height ),
2224+ pickX, pickY);
2225+ pickX *= aspectRatio;
2226+ if (isViewportEffectUsed)
2227+ viewportEffect->distortXY (pickX, pickY);
2228+
2229+ return renderer->getProjectionMode ()->getPickRay (pickX, pickY, view->getObserver ()->getZoom ());
2230+ }
2231+
2232+
22192233class SolarSystemLoader
22202234{
22212235 Universe* universe;
0 commit comments