Skip to content

Commit

Permalink
Gui: Avoid possible jumps when rotating at mouse cursor
Browse files Browse the repository at this point in the history
For a perspective camera it makes a difference if the distance of its position to the focal plane changes. If it's increased then the 3d model appears smaller
and bigger otherwise. In contrast, for an orthographic camera changing its distance to the focal plane doesn't show this effect.

Now, when a perspective camera is set and the user starts to rotate around the mouse cursor position then zoom jumps can be observed.
But it only happens when the user has clicked a point on the model while it doesn't happen when he has clicked on an empty area (i.e. on the focal plane).

The reason is that the distance of the camera to the rotation center is not kept constant.

So, the fix is to save the distance of the rotation center to the camera position and adjust it after every spin step so that the distance
to the rotation center is kept constant.
  • Loading branch information
wwmayer committed Jan 8, 2025
1 parent 6deb424 commit 37d3a61
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/Gui/NavigationStyle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ void NavigationStyle::initialize()
this->spinningAnimationEnabled = false;
this->spinsamplecounter = 0;
this->spinincrement = SbRotation::identity();
this->distanceRotationCenterCamera = 0.0F;
this->rotationCenterFound = false;
this->rotationCenterIsScenePointAtCursor = false;

Expand Down Expand Up @@ -838,6 +839,29 @@ void NavigationStyle::setRotationCenter(const SbVec3f& cnt)
this->rotationCenterFound = true;
}

void NavigationStyle::saveDistanceCameraToRotationCenter(const SbVec3f& cnt)
{
rotationCenterIsScenePointAtCursor = true;
if (auto cam = viewer->getSoRenderManager()->getCamera()) {
SbVec3f pnt = cam->position.getValue();
distanceRotationCenterCamera = (pnt - cnt).length();
}
}

void NavigationStyle::adjustPerspectiveCameraPosition()
{
// when rotating around cursor make sure that the distance between
// rotation center and camera position is kept constant
// Note: This only works for perspective camera but not orthographic camera
if (auto cam = dynamic_cast<SoPerspectiveCamera*>(viewer->getSoRenderManager()->getCamera())) {
if (rotationCenterIsScenePointAtCursor) {
SbVec3f diff = cam->position.getValue() - rotationCenter;
diff.normalize();
cam->position = rotationCenter + diff * distanceRotationCenterCamera;
}
}
}

SbVec3f NavigationStyle::getFocalPoint() const
{
SoCamera* cam = viewer->getSoRenderManager()->getCamera();
Expand Down Expand Up @@ -922,6 +946,8 @@ void NavigationStyle::spin(const SbVec2f & pointerpos)
posn[0] = float(this->localPos[0]) / float(std::max((int)(glsize[0]-1), 1));
posn[1] = float(this->localPos[1]) / float(std::max((int)(glsize[1]-1), 1));
panCamera(viewer->getSoRenderManager()->getCamera(), ratio, panplane, posn, SbVec2f(0.5,0.5));

adjustPerspectiveCameraPosition();
}

// Calculate an average angle magnitude value to make the transition
Expand Down Expand Up @@ -1060,7 +1086,7 @@ void NavigationStyle::saveCursorPosition(const SoEvent * const ev)
SoPickedPoint * picked = rpaction.getPickedPoint();
if (picked) {
setRotationCenter(picked->getPoint());
rotationCenterIsScenePointAtCursor = true;
saveDistanceCameraToRotationCenter(picked->getPoint());
return;
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/Gui/NavigationStyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ class GuiExport NavigationStyle : public Base::BaseClass
void addToLog(const SbVec2s pos, const SbTime time);

void syncModifierKeys(const SoEvent * const ev);
void saveDistanceCameraToRotationCenter(const SbVec3f& cnt);
void adjustPerspectiveCameraPosition();

protected:
struct { // tracking mouse movement in a log
Expand Down Expand Up @@ -282,6 +284,7 @@ class GuiExport NavigationStyle : public Base::BaseClass
private:
friend class NavigationAnimator;

float distanceRotationCenterCamera;
SbVec3f rotationCenter;
SbBool rotationCenterFound;
SbBool rotationCenterIsScenePointAtCursor;
Expand Down

0 comments on commit 37d3a61

Please sign in to comment.