From d4987d088f8897c62307feb549536486e4dbbb9c Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 25 Jul 2018 22:36:35 +0200 Subject: [PATCH] add option to drag at cursor instead of view center --- src/Gui/DlgSettings3DView.ui | 17 +++++ src/Gui/DlgSettings3DViewImp.cpp | 2 + src/Gui/NavigationStyle.cpp | 112 ++++++++++++++++++++++++++----- src/Gui/NavigationStyle.h | 12 ++++ src/Gui/View3DInventor.cpp | 4 ++ 5 files changed, 131 insertions(+), 16 deletions(-) diff --git a/src/Gui/DlgSettings3DView.ui b/src/Gui/DlgSettings3DView.ui index 11fbe268f9..4e48fa2966 100644 --- a/src/Gui/DlgSettings3DView.ui +++ b/src/Gui/DlgSettings3DView.ui @@ -323,6 +323,22 @@ + + + + Drag at cursor + + + false + + + DragAtCursor + + + View + + + @@ -624,6 +640,7 @@ checkBoxZoomAtCursor spinBoxZoomStep checkBoxInvertZoom + checkBoxDragAtCursor FloatSpinBox_EyeDistance checkBoxBacklight backlightColor diff --git a/src/Gui/DlgSettings3DViewImp.cpp b/src/Gui/DlgSettings3DViewImp.cpp index f6811e4ddb..888b8e57fa 100644 --- a/src/Gui/DlgSettings3DViewImp.cpp +++ b/src/Gui/DlgSettings3DViewImp.cpp @@ -89,6 +89,7 @@ void DlgSettings3DViewImp::saveSettings() checkBoxZoomAtCursor->onSave(); checkBoxInvertZoom->onSave(); spinBoxZoomStep->onSave(); + checkBoxDragAtCursor->onSave(); CheckBox_CornerCoordSystem->onSave(); CheckBox_ShowFPS->onSave(); CheckBox_useVBO->onSave(); @@ -107,6 +108,7 @@ void DlgSettings3DViewImp::loadSettings() checkBoxZoomAtCursor->onRestore(); checkBoxInvertZoom->onRestore(); spinBoxZoomStep->onRestore(); + checkBoxDragAtCursor->onRestore(); CheckBox_CornerCoordSystem->onRestore(); CheckBox_ShowFPS->onRestore(); CheckBox_useVBO->onRestore(); diff --git a/src/Gui/NavigationStyle.cpp b/src/Gui/NavigationStyle.cpp index d239035a27..3f22ed20d1 100644 --- a/src/Gui/NavigationStyle.cpp +++ b/src/Gui/NavigationStyle.cpp @@ -53,8 +53,9 @@ struct NavigationStyleP { int animationsteps; int animationdelta; SbVec3f focal1, focal2; - SbVec3f startDragPoint; - SbBool dragPointFound; + SbVec3f rotationCenter; + SbBool rotationCenterFound; + NavigationStyle::RotationCenterMode rotationCenterMode; SbBool dragAtCursor; SbRotation endRotation; SoTimerSensor * animsensor; @@ -68,7 +69,8 @@ struct NavigationStyleP { this->animsensor = 0; this->sensitivity = 2.0f; this->resetcursorpos = false; - this->dragPointFound = false; + this->rotationCenterFound = false; + this->rotationCenterMode = NavigationStyle::ScenePointAtCursor; this->dragAtCursor = false; } static void viewAnimationCB(void * data, SoSensor * sensor); @@ -239,6 +241,8 @@ void NavigationStyle::initialize() ("User parameter:BaseApp/Preferences/View")->GetBool("ZoomAtCursor",true); this->zoomStep = App::GetApplication().GetParameterGroupByPath ("User parameter:BaseApp/Preferences/View")->GetFloat("ZoomStep",0.2f); + PRIVATE(this)->dragAtCursor = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/View")->GetBool("DragAtCursor",false); } void NavigationStyle::finalize() @@ -331,7 +335,7 @@ void NavigationStyle::lookAtPoint(const SbVec3f& pos) { SoCamera* cam = viewer->getSoRenderManager()->getCamera(); if (cam == 0) return; - PRIVATE(this)->dragPointFound = false; + PRIVATE(this)->rotationCenterFound = false; // Find global coordinates of focal point. SbVec3f direction; @@ -667,7 +671,7 @@ void NavigationStyle::panToCenter(const SbPlane & pplane, const SbVec2f & currpo const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion(); float ratio = vp.getViewportAspectRatio(); panCamera(viewer->getSoRenderManager()->getCamera(), ratio, pplane, SbVec2f(0.5,0.5), currpos); - PRIVATE(this)->dragPointFound = false; + PRIVATE(this)->rotationCenterFound = false; } /** Dependent on the camera type this will either shrink or expand the @@ -852,6 +856,33 @@ void NavigationStyle::doRotate(SoCamera * camera, float angle, const SbVec2f& po } +SbVec3f NavigationStyle::getRotationCenter(SbBool* ok) const +{ + if (ok) + *ok = PRIVATE(this)->rotationCenterFound; + return PRIVATE(this)->rotationCenter; +} + +void NavigationStyle::setRotationCenter(const SbVec3f& cnt) +{ + PRIVATE(this)->rotationCenter = cnt; + PRIVATE(this)->rotationCenterFound = true; +} + +SbVec3f NavigationStyle::getFocalPoint() const +{ + SoCamera* cam = viewer->getSoRenderManager()->getCamera(); + if (cam == 0) + return SbVec3f(0,0,0); + + // Find global coordinates of focal point. + SbVec3f direction; + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + SbVec3f focal = cam->position.getValue() + + cam->focalDistance.getValue() * direction; + return focal; +} + /** Uses the sphere sheet projector to map the mouseposition onto * a 3D point and find a rotation from this and the last calculated point. */ @@ -866,8 +897,8 @@ void NavigationStyle::spin(const SbVec2f & pointerpos) lastpos[0] = float(this->log.position[1][0]) / float(std::max((int)(glsize[0]-1), 1)); lastpos[1] = float(this->log.position[1][1]) / float(std::max((int)(glsize[1]-1), 1)); - if (PRIVATE(this)->dragAtCursor && PRIVATE(this)->dragPointFound) { - SbVec3f hitpoint = PRIVATE(this)->startDragPoint; + if (PRIVATE(this)->dragAtCursor && PRIVATE(this)->rotationCenterFound) { + SbVec3f hitpoint = PRIVATE(this)->rotationCenter; // set to the given position SbVec3f direction; @@ -894,7 +925,7 @@ void NavigationStyle::spin(const SbVec2f & pointerpos) r.invert(); this->reorientCamera(viewer->getSoRenderManager()->getCamera(), r); - if (PRIVATE(this)->dragAtCursor && PRIVATE(this)->dragPointFound) { + if (PRIVATE(this)->dragAtCursor && PRIVATE(this)->rotationCenterFound) { float ratio = vp.getViewportAspectRatio(); SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(vp.getViewportAspectRatio()); SbPlane panplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); @@ -996,15 +1027,44 @@ void NavigationStyle::saveCursorPosition(const SoEvent * const ev) // get the 3d point to the screen position, if possible if (PRIVATE(this)->dragAtCursor) { - SoRayPickAction rpaction(viewer->getSoRenderManager()->getViewportRegion()); - rpaction.setPoint(this->localPos); - rpaction.setRadius(viewer->getPickRadius()); - rpaction.apply(viewer->getSoRenderManager()->getSceneGraph()); + //Option to get point on model (slow) or always on focal plane (fast) + switch (PRIVATE(this)->rotationCenterMode) { + case ScenePointAtCursor: + { + SoRayPickAction rpaction(viewer->getSoRenderManager()->getViewportRegion()); + rpaction.setPoint(this->localPos); + rpaction.setRadius(viewer->getPickRadius()); + rpaction.apply(viewer->getSoRenderManager()->getSceneGraph()); - SoPickedPoint * picked = rpaction.getPickedPoint(); - if (picked) { - PRIVATE(this)->dragPointFound = true; - PRIVATE(this)->startDragPoint = picked->getPoint(); + SoPickedPoint * picked = rpaction.getPickedPoint(); + if (picked) { + setRotationCenter(picked->getPoint()); + break; + } + } + // mode is FocalPointAtCursor or a ScenePointAtCursor failed + case FocalPointAtCursor: + { + // get the intersection point of the ray and the focal plane + const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion(); + float ratio = vp.getViewportAspectRatio(); + + SoCamera* cam = viewer->getSoRenderManager()->getCamera(); + if (!cam) return; // no camera + SbViewVolume vv = cam->getViewVolume(ratio); + + SbLine line; + SbVec2f currpos = ev->getNormalizedPosition(vp); + vv.projectPointToLine(currpos, line); + SbVec3f current_planept; + SbPlane panplane = vv.getPlane(cam->focalDistance.getValue()); + panplane.intersect(line, current_planept); + + setRotationCenter(current_planept); + break; + } + default: + break; } } } @@ -1173,6 +1233,26 @@ SbBool NavigationStyle::isZoomAtCursor() const return this->zoomAtCursor; } +void NavigationStyle::setRotationCenterMode(NavigationStyle::RotationCenterMode mode) +{ + PRIVATE(this)->rotationCenterMode = mode; +} + +NavigationStyle::RotationCenterMode NavigationStyle::getRotationCenterMode() const +{ + return PRIVATE(this)->rotationCenterMode; +} + +void NavigationStyle::setDragAtCursor(SbBool on) +{ + PRIVATE(this)->dragAtCursor = on; +} + +SbBool NavigationStyle::isDragAtCursor() const +{ + return PRIVATE(this)->dragAtCursor; +} + void NavigationStyle::startSelection(AbstractMouseSelection* mouse) { if (!mouse) diff --git a/src/Gui/NavigationStyle.h b/src/Gui/NavigationStyle.h index 8e73988cdc..7f29a6acbe 100644 --- a/src/Gui/NavigationStyle.h +++ b/src/Gui/NavigationStyle.h @@ -98,6 +98,11 @@ public: Trackball }; + enum RotationCenterMode { + ScenePointAtCursor, /**< Find the point in the scene at the cursor position. If there is no point then the focal plane is used */ + FocalPointAtCursor /**< Find the point on the focal plane at the cursor postion. */ + }; + public: NavigationStyle(); virtual ~NavigationStyle(); @@ -125,6 +130,12 @@ public: SbBool isZoomAtCursor() const; void zoomIn(); void zoomOut(); + void setDragAtCursor(SbBool); + SbBool isDragAtCursor() const; + void setRotationCenterMode(RotationCenterMode); + RotationCenterMode getRotationCenterMode() const; + void setRotationCenter(const SbVec3f& cnt); + SbVec3f getFocalPoint() const; void updateAnimation(); void redraw(); @@ -166,6 +177,7 @@ protected: SbBool seekToPoint(const SbVec2s screenpos); void seekToPoint(const SbVec3f& scenepos); SbBool lookAtPoint(const SbVec2s screenpos); + SbVec3f getRotationCenter(SbBool*) const; void reorientCamera(SoCamera * camera, const SbRotation & rot); void panCamera(SoCamera * camera, diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index 730246de1a..4113b97741 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -348,6 +348,10 @@ void View3DInventor::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M float val = rGrp.GetFloat("ZoomStep", 0.0f); _viewer->navigationStyle()->setZoomStep(val); } + else if (strcmp(Reason,"DragAtCursor") == 0) { + bool on = rGrp.GetBool("DragAtCursor", false); + _viewer->navigationStyle()->setDragAtCursor(on); + } else if (strcmp(Reason,"EyeDistance") == 0) { _viewer->getSoRenderManager()->setStereoOffset(rGrp.GetFloat("EyeDistance",5.0)); }