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