add option to drag at cursor instead of view center
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user