Gui: Improve lookAtPoint (#13556)
* Gui: Rename NavigationStyle::pan to setupPanningPlane * Gui: Replace duplicate code with NavigationStyle::setupPanningPlane * Gui: Use panning plane when hit point not found in lookAtPoint Also enables navigation animations when pressing MMB while the mouse is not over an object * Gui: Remove unused methods
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<NS::AwaitingReleaseState>();
|
||||
}
|
||||
|
||||
@@ -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<const NS::Event*>(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<const NS::Event*>(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;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user