diff --git a/src/Gui/NavigationAnimation.cpp b/src/Gui/NavigationAnimation.cpp index 4a086fc63f..8294c154f9 100644 --- a/src/Gui/NavigationAnimation.cpp +++ b/src/Gui/NavigationAnimation.cpp @@ -57,6 +57,7 @@ FixedTimeAnimation::FixedTimeAnimation(NavigationStyle* navigation, const SbRota void FixedTimeAnimation::initialize() { + navigation->findBoundingSphere(); prevAngle = 0; prevTranslation = SbVec3f(0, 0, 0); @@ -133,6 +134,7 @@ SpinningAnimation::SpinningAnimation(NavigationStyle* navigation, const SbVec3f& void SpinningAnimation::initialize() { + navigation->findBoundingSphere(); prevAngle = 0; navigation->setViewing(true); diff --git a/src/Gui/NavigationStyle.cpp b/src/Gui/NavigationStyle.cpp index b49e1ed45f..0d03e51d29 100644 --- a/src/Gui/NavigationStyle.cpp +++ b/src/Gui/NavigationStyle.cpp @@ -479,6 +479,13 @@ void NavigationStyle::viewAll() } } +void NavigationStyle::findBoundingSphere() { + // Find a bounding sphere for the scene + SoGetBoundingBoxAction action(viewer->getSoRenderManager()->getViewportRegion()); + action.apply(viewer->getSceneGraph()); + boundingSphere.circumscribe(action.getBoundingBox()); +} + /** Rotate the camera by the given amount, then reposition it so we're still pointing at the same * focal point */ @@ -503,17 +510,31 @@ void NavigationStyle::reorientCamera(SoCamera* camera, const SbRotation& rotatio // Set new orientation value by accumulating the new rotation camera->orientation = rotation * camera->orientation.getValue(); - // Fix issue with near clipping in orthogonal view - if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) { - camera->focalDistance = static_cast(camera)->height; - } - // Distance from rotation center to new camera position in global coordinate system SbVec3f newRotationCenterDistance; camera->orientation.getValue().multVec(rotationCenterDistanceCam, newRotationCenterDistance); // Reposition camera so the rotation center stays in the same place camera->position = rotationCenter + newRotationCenterDistance; + + // Fix issue with near clipping in orthogonal view + if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) { + + // The center of the bounding sphere in camera coordinate system + SbVec3f center; + camera->orientation.getValue().inverse().multVec(boundingSphere.getCenter() - camera->position.getValue(), center); + + SbVec3f dir; + camera->orientation.getValue().multVec(SbVec3f(0, 0, -1), dir); + + // Reposition the camera but keep the focal point the same + // nearDistance is 0 and farDistance is the diameter of the bounding sphere + float repositionDistance = -center.getValue()[2] - boundingSphere.getRadius(); + camera->position = camera->position.getValue() + repositionDistance * dir; + camera->nearDistance = 0; + camera->farDistance = 2 * boundingSphere.getRadius(); + camera->focalDistance = camera->focalDistance.getValue() - repositionDistance; + } } void NavigationStyle::panCamera(SoCamera * cam, float aspectratio, const SbPlane & panplane, @@ -1280,6 +1301,7 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode) // first starting a drag operation. animator->stop(); viewer->showRotationCenter(true); + findBoundingSphere(); this->spinprojector->project(this->lastmouseposition); this->interactiveCountInc(); this->clearLog(); diff --git a/src/Gui/NavigationStyle.h b/src/Gui/NavigationStyle.h index c499776456..12c5e4a00d 100644 --- a/src/Gui/NavigationStyle.h +++ b/src/Gui/NavigationStyle.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -151,6 +152,7 @@ public: SoCamera* getCamera() const; void setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter = false); void translateCamera(const SbVec3f& translation); + void findBoundingSphere(); void reorientCamera(SoCamera* camera, const SbRotation& rotation); void reorientCamera(SoCamera* camera, const SbRotation& rotation, const SbVec3f& rotationCenter); @@ -278,6 +280,8 @@ private: NavigationStyle::RotationCenterModes rotationCenterMode; float sensitivity; SbBool resetcursorpos; + + SbSphere boundingSphere; }; /** Sub-classes of this class appear in the preference dialog where users can diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index 2a50022f1e..fc4ff34ad1 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -1498,6 +1498,8 @@ void View3DInventorViewer::setSceneGraph(SoNode* root) static_cast(scene)->insertChild(this->backlight, 0); } } + + navigation->findBoundingSphere(); } void View3DInventorViewer::savePicture(int width, int height, int sample, const QColor& bg, QImage& img) const