diff --git a/src/Gui/BlenderNavigationStyle.cpp b/src/Gui/BlenderNavigationStyle.cpp index cb6775ccf8..28a6954dd6 100644 --- a/src/Gui/BlenderNavigationStyle.cpp +++ b/src/Gui/BlenderNavigationStyle.cpp @@ -172,9 +172,7 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev) case SoMouseButtonEvent::BUTTON3: if (press) { this->centerTime = ev->getTime(); - float ratio = vp.getViewportAspectRatio(); - SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio); - this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); + setupPanningPlane(getCamera()); this->lockrecenter = false; } else { @@ -182,10 +180,7 @@ SbBool BlenderNavigationStyle::processSoEvent(const SoEvent * const ev) float dci = (float)QApplication::doubleClickInterval()/1000.0f; // is it just a middle click? if (tmp.getValue() < dci && !this->lockrecenter) { - if (!this->lookAtPoint(pos)) { - panToCenter(panningplane, posn); - this->interactiveCountDec(); - } + lookAtPoint(pos); processed = true; } } diff --git a/src/Gui/CADNavigationStyle.cpp b/src/Gui/CADNavigationStyle.cpp index 931eafaf5a..b5d9dbb632 100644 --- a/src/Gui/CADNavigationStyle.cpp +++ b/src/Gui/CADNavigationStyle.cpp @@ -179,9 +179,7 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev) case SoMouseButtonEvent::BUTTON3: if (press) { this->centerTime = ev->getTime(); - float ratio = vp.getViewportAspectRatio(); - SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio); - this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); + setupPanningPlane(getCamera()); this->lockrecenter = false; } else { @@ -189,10 +187,7 @@ SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev) float dci = (float)QApplication::doubleClickInterval()/1000.0f; // is it just a middle click? if (tmp.getValue() < dci && !this->lockrecenter) { - if (!this->lookAtPoint(pos)) { - panToCenter(panningplane, posn); - this->interactiveCountDec(); - } + lookAtPoint(pos); processed = true; } } diff --git a/src/Gui/GestureNavigationStyle.cpp b/src/Gui/GestureNavigationStyle.cpp index cedae26205..01ef0aec9e 100644 --- a/src/Gui/GestureNavigationStyle.cpp +++ b/src/Gui/GestureNavigationStyle.cpp @@ -297,7 +297,8 @@ public: //MMB click if(ev.isPress(3) && ev.mbstate() == 0x010){ ev.flags->processed = true; - ns.onSetRotationCenter(ev.inventor_event->getPosition()); + ns.setupPanningPlane(ns.viewer->getCamera()); + ns.lookAtPoint(ev.inventor_event->getPosition()); return transit(); } @@ -314,8 +315,10 @@ public: bool press = (kbev->getState() == SoKeyboardEvent::DOWN); switch (kbev->getKey()) { case SoKeyboardEvent::H: - if (!press) - ns.onSetRotationCenter(kbev->getPosition()); + if (!press) { + ns.setupPanningPlane(ns.viewer->getCamera()); + ns.lookAtPoint(kbev->getPosition()); + } break; case SoKeyboardEvent::PAGE_UP: if(!press){ @@ -538,7 +541,7 @@ public: if (ns.logging) Base::Console().Log(" -> PanState\n"); this->ratio = ns.viewer->getSoRenderManager()->getViewportRegion().getViewportAspectRatio(); - ns.pan(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane + ns.setupPanningPlane(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane } virtual ~PanState() = default; @@ -585,7 +588,7 @@ public: if (ns.logging) Base::Console().Log(" -> StickyPanState\n"); this->ratio = ns.viewer->getSoRenderManager()->getViewportRegion().getViewportAspectRatio(); - ns.pan(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane + ns.setupPanningPlane(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane } virtual ~StickyPanState(){ auto &ns = this->outermost_context().ns; @@ -631,7 +634,7 @@ public: this->base_pos = static_cast(this->triggering_event())->inventor_event->getPosition(); if (ns.logging) Base::Console().Log(" -> TiltState\n"); - ns.pan(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane + ns.setupPanningPlane(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane } virtual ~TiltState() = default; @@ -681,7 +684,7 @@ public: this->base_pos = static_cast(this->triggering_event())->inventor_event->getPosition(); if (ns.logging) Base::Console().Log(" -> GestureState\n"); - ns.pan(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane + ns.setupPanningPlane(ns.viewer->getSoRenderManager()->getCamera());//set up panningplane this->ratio = ns.viewer->getSoRenderManager()->getViewportRegion().getViewportAspectRatio(); enableTilt = !(App::GetApplication().GetParameterGroupByPath ("User parameter:BaseApp/Preferences/View")->GetBool("DisableTouchTilt",true)); @@ -1007,16 +1010,6 @@ void GestureNavigationStyle::onRollGesture(int direction) } -void GestureNavigationStyle::onSetRotationCenter(SbVec2s cursor){ - SbBool ret = NavigationStyle::lookAtPoint(cursor); - if(!ret){ - this->interactiveCountDec(); //this was in original gesture nav. Not sure what is it needed for --DeepSOIC - Base::Console().Log( - "No object under cursor! Can't set new center of rotation.\n"); - } - -} - void GestureNavigationStyle::EventQueue::post(const NS::Event& ev) { ev.flags->processed = true; diff --git a/src/Gui/GestureNavigationStyle.h b/src/Gui/GestureNavigationStyle.h index 4ced3048ad..3b8886799b 100644 --- a/src/Gui/GestureNavigationStyle.h +++ b/src/Gui/GestureNavigationStyle.h @@ -107,8 +107,6 @@ public: //gesture reactions ///Roll gesture is like: press LMB, press RMB, release LMB, release RMB. /// This function is called by state machine whenever it picks up roll gesture. void onRollGesture(int direction); - ///Called by state machine, when set-rotation-center gesture is detected (MMB click, or H key) - void onSetRotationCenter(SbVec2s cursor); }; } diff --git a/src/Gui/InventorNavigationStyle.cpp b/src/Gui/InventorNavigationStyle.cpp index 3d553f78ff..6eae6323fc 100644 --- a/src/Gui/InventorNavigationStyle.cpp +++ b/src/Gui/InventorNavigationStyle.cpp @@ -126,9 +126,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev) if (press && ev->wasShiftDown() && (this->currentmode != NavigationStyle::SELECTION)) { this->centerTime = ev->getTime(); - float ratio = vp.getViewportAspectRatio(); - SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio); - this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); + setupPanningPlane(getCamera()); this->lockrecenter = false; } else if (!press && ev->wasShiftDown() && @@ -137,10 +135,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev) float dci = (float)QApplication::doubleClickInterval()/1000.0f; // is it just a left click? if (tmp.getValue() < dci && !this->lockrecenter) { - if (!this->lookAtPoint(pos)) { - panToCenter(panningplane, posn); - this->interactiveCountDec(); - } + lookAtPoint(pos); processed = true; } } @@ -191,9 +186,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev) case SoMouseButtonEvent::BUTTON3: if (press) { this->centerTime = ev->getTime(); - float ratio = vp.getViewportAspectRatio(); - SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio); - this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); + setupPanningPlane(getCamera()); this->lockrecenter = false; } else { @@ -201,10 +194,7 @@ SbBool InventorNavigationStyle::processSoEvent(const SoEvent * const ev) float dci = (float)QApplication::doubleClickInterval()/1000.0f; // is it just a middle click? if (tmp.getValue() < dci && !this->lockrecenter) { - if (!this->lookAtPoint(pos)) { - panToCenter(panningplane, posn); - this->interactiveCountDec(); - } + lookAtPoint(pos); processed = true; } } diff --git a/src/Gui/MayaGestureNavigationStyle.cpp b/src/Gui/MayaGestureNavigationStyle.cpp index 1f58d2972d..fc9353016d 100644 --- a/src/Gui/MayaGestureNavigationStyle.cpp +++ b/src/Gui/MayaGestureNavigationStyle.cpp @@ -280,13 +280,9 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev) switch (event->getKey()) { case SoKeyboardEvent::H: processed = true; - if(!press){ - SbBool ret = NavigationStyle::lookAtPoint(event->getPosition()); - if(!ret){ - this->interactiveCountDec(); - Base::Console().Log( - "No object under cursor! Can't set new center of rotation.\n"); - } + if (!press) { + setupPanningPlane(viewer->getCamera()); + lookAtPoint(event->getPosition()); } break; default: @@ -397,7 +393,7 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev) //reset/start move detection machine this->mousedownPos = pos; this->mouseMoveThresholdBroken = false; - pan(viewer->getSoRenderManager()->getCamera());//set up panningplane + setupPanningPlane(viewer->getSoRenderManager()->getCamera());//set up panningplane int &cnt = this->mousedownConsumedCount; this->mousedownConsumedEvents[cnt] = *event;//hopefully, a shallow copy is enough. There are no pointers stored in events, apparently. Will lose a subclass, though. cnt++; @@ -431,12 +427,8 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev) setViewingMode(NavigationStyle::PANNING); } else if(press){ // if not PANNING then look at point - SbBool ret = NavigationStyle::lookAtPoint(event->getPosition()); - if(!ret){ - this->interactiveCountDec(); - Base::Console().Log( - "No object under cursor! Can't set new center of rotation.\n"); - } + setupPanningPlane(viewer->getCamera()); + lookAtPoint(event->getPosition()); } processed = true; break; @@ -480,11 +472,11 @@ SbBool MayaGestureNavigationStyle::processSoEvent(const SoEvent * const ev) if (gesture->state == SoGestureEvent::SbGSStart || gesture->state == SoGestureEvent::SbGSUpdate) {//even if we didn't get a start, assume the first update is a start (sort-of fail-safe). if (type.isDerivedFrom(SoGesturePanEvent::getClassTypeId())) { - pan(viewer->getSoRenderManager()->getCamera());//set up panning plane + setupPanningPlane(viewer->getSoRenderManager()->getCamera());//set up panning plane setViewingMode(NavigationStyle::PANNING); processed = true; } else if (type.isDerivedFrom(SoGesturePinchEvent::getClassTypeId())) { - pan(viewer->getSoRenderManager()->getCamera());//set up panning plane + setupPanningPlane(viewer->getSoRenderManager()->getCamera());//set up panning plane setRotationCenter(getFocalPoint()); setViewingMode(NavigationStyle::DRAGGING); processed = true; diff --git a/src/Gui/NavigationStyle.cpp b/src/Gui/NavigationStyle.cpp index f657f1a8b1..99595fd71d 100644 --- a/src/Gui/NavigationStyle.cpp +++ b/src/Gui/NavigationStyle.cpp @@ -327,27 +327,41 @@ void NavigationStyle::seekToPoint(const SbVec3f& scenepos) viewer->seekToPoint(scenepos); } -SbBool NavigationStyle::lookAtPoint(const SbVec2s screenpos) +void NavigationStyle::lookAtPoint(const SbVec2s screenpos) { - SoCamera* cam = viewer->getSoRenderManager()->getCamera(); - if (!cam) - return false; + const SoCamera* camera = viewer->getCamera(); + if (!camera) { + return; + } - SoRayPickAction rpaction(viewer->getSoRenderManager()->getViewportRegion()); + SoRayPickAction rpaction(viewer->getViewportRegion()); rpaction.setPoint(screenpos); rpaction.setRadius(viewer->getPickRadius()); rpaction.apply(viewer->getSoRenderManager()->getSceneGraph()); - SoPickedPoint * picked = rpaction.getPickedPoint(); - if (!picked) { - this->interactiveCountInc(); - return false; + const SoPickedPoint* picked = rpaction.getPickedPoint(); + + // Point is either the hitpoint or the projected point on the panning plane + SbVec3f point; + if (picked) { + point = picked->getPoint(); + } + else { + const SbViewportRegion& vp = viewer->getViewportRegion(); + const float aspectratio = vp.getViewportAspectRatio(); + SbViewVolume vv = camera->getViewVolume(aspectratio); + + // See note in Coin docs for SoCamera::getViewVolume re:viewport mapping + if (aspectratio < 1.0) { + vv.scale(1.0 / aspectratio); + } + + SbLine line; + vv.projectPointToLine(normalizePixelPos(screenpos), line); + panningplane.intersect(line, point); } - SbVec3f hitpoint; - hitpoint = picked->getPoint(); - lookAtPoint(hitpoint); - return true; + lookAtPoint(point); } void NavigationStyle::lookAtPoint(const SbVec3f& position) @@ -593,35 +607,28 @@ void NavigationStyle::panCamera(SoCamera * cam, float aspectratio, const SbPlane } } -void NavigationStyle::pan(SoCamera* camera) +void NavigationStyle::setupPanningPlane(const SoCamera* camera) { // The plane we're projecting the mouse coordinates to get 3D // coordinates should stay the same during the whole pan // operation, so we should calculate this value here. - if (!camera) { // can happen for empty scenegraph + if (!camera) { // can happen for empty scenegraph this->panningplane = SbPlane(SbVec3f(0, 0, 1), 0); } else { - const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion(); - float aspectratio = vp.getViewportAspectRatio(); + const SbViewportRegion& vp = viewer->getViewportRegion(); + const float aspectratio = vp.getViewportAspectRatio(); SbViewVolume vv = camera->getViewVolume(aspectratio); // See note in Coin docs for SoCamera::getViewVolume re:viewport mapping - if(aspectratio < 1.0) + if (aspectratio < 1.0) { vv.scale(1.0 / aspectratio); + } this->panningplane = vv.getPlane(camera->focalDistance.getValue()); } } -void NavigationStyle::panToCenter(const SbPlane & pplane, const SbVec2f & currpos) -{ - const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion(); - float ratio = vp.getViewportAspectRatio(); - panCamera(viewer->getSoRenderManager()->getCamera(), ratio, pplane, SbVec2f(0.5,0.5), currpos); - this->rotationCenterFound = false; -} - /** Dependent on the camera type this will either shrink or expand the * height of the viewport (orthogonal camera) or move the camera * closer or further away from the focal point in the scene. @@ -1382,7 +1389,7 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode) case PANNING: animator->stop(); - pan(viewer->getSoRenderManager()->getCamera()); + setupPanningPlane(viewer->getSoRenderManager()->getCamera()); this->interactiveCountInc(); break; diff --git a/src/Gui/NavigationStyle.h b/src/Gui/NavigationStyle.h index ccaf598ff3..854ed41b3b 100644 --- a/src/Gui/NavigationStyle.h +++ b/src/Gui/NavigationStyle.h @@ -197,7 +197,7 @@ protected: void setSeekMode(SbBool enable); SbBool seekToPoint(const SbVec2s screenpos); void seekToPoint(const SbVec3f& scenepos); - SbBool lookAtPoint(const SbVec2s screenpos); + void lookAtPoint(const SbVec2s screenpos); void lookAtPoint(const SbVec3f& position); void panCamera(SoCamera * camera, @@ -205,8 +205,7 @@ protected: const SbPlane & panplane, const SbVec2f & previous, const SbVec2f & current); - void pan(SoCamera* camera); - void panToCenter(const SbPlane & pplane, const SbVec2f & currpos); + void setupPanningPlane(const SoCamera* camera); int getDelta() const; void zoom(SoCamera * camera, float diffvalue); void zoomByCursor(const SbVec2f & thispos, const SbVec2f & prevpos); diff --git a/src/Gui/OpenCascadeNavigationStyle.cpp b/src/Gui/OpenCascadeNavigationStyle.cpp index fe14812048..ddb6613069 100644 --- a/src/Gui/OpenCascadeNavigationStyle.cpp +++ b/src/Gui/OpenCascadeNavigationStyle.cpp @@ -170,9 +170,7 @@ SbBool OpenCascadeNavigationStyle::processSoEvent(const SoEvent * const ev) case SoMouseButtonEvent::BUTTON3: if (press) { this->centerTime = ev->getTime(); - float ratio = vp.getViewportAspectRatio(); - SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio); - this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); + setupPanningPlane(getCamera()); this->lockrecenter = false; } else if (this->currentmode == NavigationStyle::PANNING) { diff --git a/src/Gui/OpenSCADNavigationStyle.cpp b/src/Gui/OpenSCADNavigationStyle.cpp index a37b6ef21f..263e8f0f85 100644 --- a/src/Gui/OpenSCADNavigationStyle.cpp +++ b/src/Gui/OpenSCADNavigationStyle.cpp @@ -170,9 +170,7 @@ SbBool OpenSCADNavigationStyle::processSoEvent(const SoEvent * const ev) this->button3down = press; if (press) { this->centerTime = ev->getTime(); - float ratio = vp.getViewportAspectRatio(); - SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio); - this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); + setupPanningPlane(getCamera()); this->lockrecenter = false; } else if (curmode == NavigationStyle::PANNING) { diff --git a/src/Gui/RevitNavigationStyle.cpp b/src/Gui/RevitNavigationStyle.cpp index be45712689..3bbea4d7a7 100644 --- a/src/Gui/RevitNavigationStyle.cpp +++ b/src/Gui/RevitNavigationStyle.cpp @@ -171,9 +171,7 @@ SbBool RevitNavigationStyle::processSoEvent(const SoEvent * const ev) case SoMouseButtonEvent::BUTTON3: if (press) { this->centerTime = ev->getTime(); - float ratio = vp.getViewportAspectRatio(); - SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio); - this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); + setupPanningPlane(getCamera()); this->lockrecenter = false; } else { @@ -181,10 +179,7 @@ SbBool RevitNavigationStyle::processSoEvent(const SoEvent * const ev) float dci = (float)QApplication::doubleClickInterval()/1000.0f; // is it just a middle click? if (tmp.getValue() < dci && !this->lockrecenter) { - if (!this->lookAtPoint(pos)) { - panToCenter(panningplane, posn); - this->interactiveCountDec(); - } + lookAtPoint(pos); processed = true; } } diff --git a/src/Gui/TinkerCADNavigationStyle.cpp b/src/Gui/TinkerCADNavigationStyle.cpp index ff8e8ee85d..e7ca54f6c0 100644 --- a/src/Gui/TinkerCADNavigationStyle.cpp +++ b/src/Gui/TinkerCADNavigationStyle.cpp @@ -163,9 +163,7 @@ SbBool TinkerCADNavigationStyle::processSoEvent(const SoEvent * const ev) this->button3down = press; if (press) { this->centerTime = ev->getTime(); - float ratio = vp.getViewportAspectRatio(); - SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(ratio); - this->panningplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); + setupPanningPlane(getCamera()); } else if (curmode == NavigationStyle::PANNING) { newmode = NavigationStyle::IDLE;