add option to drag at cursor instead of view center

This commit is contained in:
wmayer
2018-07-25 22:36:35 +02:00
parent 6e8b60589f
commit d4987d088f
5 changed files with 131 additions and 16 deletions

View File

@@ -323,6 +323,22 @@
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkBoxDragAtCursor">
<property name="text">
<string>Drag at cursor</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>DragAtCursor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<property name="spacing">
@@ -624,6 +640,7 @@
<tabstop>checkBoxZoomAtCursor</tabstop>
<tabstop>spinBoxZoomStep</tabstop>
<tabstop>checkBoxInvertZoom</tabstop>
<tabstop>checkBoxDragAtCursor</tabstop>
<tabstop>FloatSpinBox_EyeDistance</tabstop>
<tabstop>checkBoxBacklight</tabstop>
<tabstop>backlightColor</tabstop>

View File

@@ -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();

View File

@@ -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)

View File

@@ -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,

View File

@@ -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));
}