diff --git a/ApplicationCode/UserInterface/RiuCadNavigation.cpp b/ApplicationCode/UserInterface/RiuCadNavigation.cpp index 3a2b3fba7f..d86f641970 100644 --- a/ApplicationCode/UserInterface/RiuCadNavigation.cpp +++ b/ApplicationCode/UserInterface/RiuCadNavigation.cpp @@ -81,8 +81,7 @@ bool RiuCadNavigation::handleInputEvent(QInputEvent* inputEvent) if (hitSomething) { cvf::Vec3d pointOfInterest = hic.firstItem()->intersectionPoint(); - m_trackball->setRotationPoint(pointOfInterest); - m_pointOfInterest = pointOfInterest; + this->setPointOfInterest(pointOfInterest); } else { @@ -170,7 +169,7 @@ bool RiuCadNavigation::handleInputEvent(QInputEvent* inputEvent) m_viewer->mainCamera()->setFromLookAt(newPos,newVrp, up ); - m_viewer->updateParallelProjectionHeight(m_pointOfInterest); + m_viewer->updateParallelProjectionHeightFromMoveZoom(m_pointOfInterest); m_viewer->navigationPolicyUpdate(); } } @@ -188,11 +187,16 @@ bool RiuCadNavigation::handleInputEvent(QInputEvent* inputEvent) //-------------------------------------------------------------------------------------------------- void RiuCadNavigation::initializeRotationCenter() { - if(m_isRotCenterInitialized || m_trackball.isNull() || !m_viewer->mainScene() || !m_viewer->currentScene()->boundingBox().isValid()) return; - m_pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + if (m_isRotCenterInitialized + || m_trackball.isNull() + || !m_viewer->currentScene()->boundingBox().isValid()) + { + return; + } - m_trackball->setRotationPoint(m_pointOfInterest); - m_isRotCenterInitialized = true; + cvf::Vec3d pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + + this->setPointOfInterest(pointOfInterest); } //-------------------------------------------------------------------------------------------------- @@ -237,4 +241,6 @@ void RiuCadNavigation::setPointOfInterest(cvf::Vec3d poi) m_pointOfInterest = poi; m_trackball->setRotationPoint(poi); m_isRotCenterInitialized = true; + m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest); + } diff --git a/ApplicationCode/UserInterface/RiuGeoQuestNavigation.cpp b/ApplicationCode/UserInterface/RiuGeoQuestNavigation.cpp index 0f4020bda0..3d5977a987 100644 --- a/ApplicationCode/UserInterface/RiuGeoQuestNavigation.cpp +++ b/ApplicationCode/UserInterface/RiuGeoQuestNavigation.cpp @@ -69,8 +69,7 @@ bool RiuGeoQuestNavigation::handleInputEvent(QInputEvent* inputEvent) if (hitSomething) { cvf::Vec3d pointOfInterest = hic.firstItem()->intersectionPoint(); - m_trackball->setRotationPoint(pointOfInterest); - m_pointOfInterest = pointOfInterest; + this->setPointOfInterest(pointOfInterest); } else { @@ -178,11 +177,16 @@ bool RiuGeoQuestNavigation::handleInputEvent(QInputEvent* inputEvent) //-------------------------------------------------------------------------------------------------- void RiuGeoQuestNavigation::initializeRotationCenter() { - if(m_isRotCenterInitialized || m_trackball.isNull() || !m_viewer->mainScene() || !m_viewer->currentScene()->boundingBox().isValid()) return; - m_pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + if (m_isRotCenterInitialized + || m_trackball.isNull() + || !m_viewer->currentScene()->boundingBox().isValid()) + { + return; + } - m_trackball->setRotationPoint(m_pointOfInterest); - m_isRotCenterInitialized = true; + cvf::Vec3d pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + + this->setPointOfInterest(pointOfInterest); } //-------------------------------------------------------------------------------------------------- @@ -227,6 +231,8 @@ void RiuGeoQuestNavigation::setPointOfInterest(cvf::Vec3d poi) m_pointOfInterest = poi; m_trackball->setRotationPoint(poi); m_isRotCenterInitialized = true; + m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest); + } //-------------------------------------------------------------------------------------------------- @@ -245,7 +251,7 @@ void RiuGeoQuestNavigation::zoomAlongRay(cvf::Ray* ray, int delta) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos, newVrp, up ); - m_viewer->updateParallelProjectionHeight(m_pointOfInterest); + m_viewer->updateParallelProjectionHeightFromMoveZoom(m_pointOfInterest); m_viewer->navigationPolicyUpdate(); } diff --git a/ApplicationCode/UserInterface/RiuRmsNavigation.cpp b/ApplicationCode/UserInterface/RiuRmsNavigation.cpp index 07f57f91bf..e8b5be8694 100644 --- a/ApplicationCode/UserInterface/RiuRmsNavigation.cpp +++ b/ApplicationCode/UserInterface/RiuRmsNavigation.cpp @@ -69,8 +69,7 @@ bool RiuRmsNavigation::handleInputEvent(QInputEvent* inputEvent) if (hitSomething) { cvf::Vec3d pointOfInterest = hic.firstItem()->intersectionPoint(); - m_trackball->setRotationPoint(pointOfInterest); - m_pointOfInterest = pointOfInterest; + this->setPointOfInterest(pointOfInterest); } else { @@ -202,11 +201,16 @@ bool RiuRmsNavigation::handleInputEvent(QInputEvent* inputEvent) //-------------------------------------------------------------------------------------------------- void RiuRmsNavigation::initializeRotationCenter() { - if(m_isRotCenterInitialized || m_trackball.isNull() || !m_viewer->mainScene() || !m_viewer->currentScene()->boundingBox().isValid()) return; - m_pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + if (m_isRotCenterInitialized + || m_trackball.isNull() + || !m_viewer->currentScene()->boundingBox().isValid()) + { + return; + } - m_trackball->setRotationPoint(m_pointOfInterest); - m_isRotCenterInitialized = true; + cvf::Vec3d pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + + this->setPointOfInterest(pointOfInterest); } //-------------------------------------------------------------------------------------------------- @@ -251,6 +255,8 @@ void RiuRmsNavigation::setPointOfInterest(cvf::Vec3d poi) m_pointOfInterest = poi; m_trackball->setRotationPoint(poi); m_isRotCenterInitialized = true; + m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest); + } //-------------------------------------------------------------------------------------------------- @@ -269,7 +275,7 @@ void RiuRmsNavigation::zoomAlongRay(cvf::Ray* ray, int delta) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos, newVrp, up ); - m_viewer->updateParallelProjectionHeight(m_pointOfInterest); + m_viewer->updateParallelProjectionHeightFromMoveZoom(m_pointOfInterest); m_viewer->navigationPolicyUpdate(); } diff --git a/Fwk/AppFwk/cafViewer/cafCadNavigation.cpp b/Fwk/AppFwk/cafViewer/cafCadNavigation.cpp index 7dcb1b477e..d9ad91dee4 100644 --- a/Fwk/AppFwk/cafViewer/cafCadNavigation.cpp +++ b/Fwk/AppFwk/cafViewer/cafCadNavigation.cpp @@ -92,8 +92,7 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) if (hitSomething) { cvf::Vec3d pointOfInterest = hic.firstItem()->intersectionPoint(); - m_trackball->setRotationPoint(pointOfInterest); - m_pointOfInterest = pointOfInterest; + this->setPointOfInterest(pointOfInterest); } else { @@ -172,7 +171,7 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos,newVrp, up ); - m_viewer->updateParallelProjectionHeight(m_pointOfInterest); + m_viewer->updateParallelProjectionHeightFromMoveZoom(m_pointOfInterest); m_viewer->navigationPolicyUpdate(); } } @@ -190,11 +189,16 @@ bool caf::CadNavigation::handleInputEvent(QInputEvent* inputEvent) //-------------------------------------------------------------------------------------------------- void caf::CadNavigation::initializeRotationCenter() { - if(m_isRotCenterInitialized || m_trackball.isNull() || !m_viewer->mainScene() || !m_viewer->currentScene()->boundingBox().isValid()) return; - m_pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + if (m_isRotCenterInitialized + || m_trackball.isNull() + || !m_viewer->currentScene()->boundingBox().isValid()) + { + return; + } - m_trackball->setRotationPoint(m_pointOfInterest); - m_isRotCenterInitialized = true; + cvf::Vec3d pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + + this->setPointOfInterest(pointOfInterest); } //-------------------------------------------------------------------------------------------------- @@ -239,4 +243,5 @@ void caf::CadNavigation::setPointOfInterest(cvf::Vec3d poi) m_pointOfInterest = poi; m_trackball->setRotationPoint(poi); m_isRotCenterInitialized = true; + m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest); } diff --git a/Fwk/AppFwk/cafViewer/cafCeetronNavigation.cpp b/Fwk/AppFwk/cafViewer/cafCeetronNavigation.cpp index 23c856a26f..6796cdd391 100644 --- a/Fwk/AppFwk/cafViewer/cafCeetronNavigation.cpp +++ b/Fwk/AppFwk/cafViewer/cafCeetronNavigation.cpp @@ -201,7 +201,7 @@ void caf::CeetronNavigation::wheelEvent(QWheelEvent* event) m_trackball->updateNavigation(event->x(), posY + navDelta); m_trackball->endNavigation(); - m_viewer->updateParallelProjectionHeight( m_pointOfInterest); + m_viewer->updateParallelProjectionHeightFromMoveZoom( m_pointOfInterest); m_viewer->navigationPolicyUpdate(); @@ -263,15 +263,16 @@ void caf::CeetronNavigation::setCursorFromCurrentState() //-------------------------------------------------------------------------------------------------- void caf::CeetronNavigation::initializeRotationCenter() { - if(m_isRotCenterInitialized || m_trackball.isNull() || !m_viewer->mainScene()) return; - - cvf::BoundingBox bb = m_viewer->mainScene()->boundingBox(); - if(bb.isValid()) + if (m_isRotCenterInitialized + || m_trackball.isNull() + || !m_viewer->currentScene()->boundingBox().isValid()) { - m_pointOfInterest = bb.center(); - m_trackball->setRotationPoint(m_pointOfInterest); - m_isRotCenterInitialized = true; + return; } + + cvf::Vec3d pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + + this->setPointOfInterest(pointOfInterest); } //-------------------------------------------------------------------------------------------------- @@ -291,6 +292,8 @@ void caf::CeetronNavigation::setPointOfInterest(cvf::Vec3d poi) m_pointOfInterest = poi; m_trackball->setRotationPoint(poi); m_isRotCenterInitialized = true; + m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest); + } diff --git a/Fwk/AppFwk/cafViewer/cafCeetronPlusNavigation.cpp b/Fwk/AppFwk/cafViewer/cafCeetronPlusNavigation.cpp index c51d45a73a..24f978050c 100644 --- a/Fwk/AppFwk/cafViewer/cafCeetronPlusNavigation.cpp +++ b/Fwk/AppFwk/cafViewer/cafCeetronPlusNavigation.cpp @@ -57,8 +57,7 @@ bool caf::CeetronPlusNavigation::handleInputEvent(QInputEvent* inputEvent) if (hitSomething) { cvf::Vec3d pointOfInterest = hic.firstItem()->intersectionPoint(); - m_trackball->setRotationPoint(pointOfInterest); - m_pointOfInterest = pointOfInterest; + this->setPointOfInterest(pointOfInterest); } else { @@ -190,11 +189,16 @@ bool caf::CeetronPlusNavigation::handleInputEvent(QInputEvent* inputEvent) //-------------------------------------------------------------------------------------------------- void caf::CeetronPlusNavigation::initializeRotationCenter() { - if(m_isRotCenterInitialized || m_trackball.isNull() || !m_viewer->mainScene() || !m_viewer->currentScene()->boundingBox().isValid()) return; - m_pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + if (m_isRotCenterInitialized + || m_trackball.isNull() + || !m_viewer->currentScene()->boundingBox().isValid()) + { + return; + } - m_trackball->setRotationPoint(m_pointOfInterest); - m_isRotCenterInitialized = true; + cvf::Vec3d pointOfInterest = m_viewer->currentScene()->boundingBox().center(); + + this->setPointOfInterest(pointOfInterest); } //-------------------------------------------------------------------------------------------------- @@ -239,6 +243,8 @@ void caf::CeetronPlusNavigation::setPointOfInterest(cvf::Vec3d poi) m_pointOfInterest = poi; m_trackball->setRotationPoint(poi); m_isRotCenterInitialized = true; + m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest); + } //-------------------------------------------------------------------------------------------------- @@ -257,7 +263,7 @@ void caf::CeetronPlusNavigation::zoomAlongRay(cvf::Ray* ray, int delta) cvf::Vec3d newVrp = vrp + trans; m_viewer->mainCamera()->setFromLookAt(newPos, newVrp, up ); - m_viewer->updateParallelProjectionHeight(m_pointOfInterest); + m_viewer->updateParallelProjectionHeightFromMoveZoom(m_pointOfInterest); m_viewer->navigationPolicyUpdate(); } } diff --git a/Fwk/AppFwk/cafViewer/cafViewer.cpp b/Fwk/AppFwk/cafViewer/cafViewer.cpp index 978ac7d6fb..788fac3e38 100644 --- a/Fwk/AppFwk/cafViewer/cafViewer.cpp +++ b/Fwk/AppFwk/cafViewer/cafViewer.cpp @@ -68,6 +68,7 @@ #include #include #include +#include "cvfTrace.h" std::list caf::Viewer::sm_viewers; cvf::ref caf::Viewer::sm_openGLContextGroup; @@ -951,7 +952,7 @@ void caf::Viewer::enableParallelProjection(bool enableOrtho) pointOfInterest = m_navigationPolicy->pointOfInterest(); } m_mainCamera->setProjectionAsOrtho(1.0, m_mainCamera->nearPlane(), m_mainCamera->farPlane()); - this->updateParallelProjectionHeight(pointOfInterest); + this->updateParallelProjectionHeightFromMoveZoom(pointOfInterest); this->update(); } @@ -974,28 +975,84 @@ double calculateOrthoHeight(double perspectiveViewAngleYDeg, double focusPlaneDi { return 2 * (cvf::Math::tan( cvf::Math::toRadians(0.5 * perspectiveViewAngleYDeg) ) * focusPlaneDist); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + +double calculateDistToPlaneOfInterest(double perspectiveViewAngleYDeg, double orthoHeight) +{ + return orthoHeight / (2 * (cvf::Math::tan( cvf::Math::toRadians(0.5 * perspectiveViewAngleYDeg) ))); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + +double distToPlaneOfInterest(const cvf::Camera* camera, const cvf::Vec3d& pointOfInterest) +{ + using namespace cvf; + CVF_ASSERT(camera); + + Vec3d eye, vrp, up; + camera->toLookAt(&eye, &vrp, &up); + + Vec3d camDir = vrp - eye; + camDir.normalize(); + + Vec3d eyeToFocus = pointOfInterest - eye; + double distToFocusPlane = eyeToFocus*camDir; + + return distToFocusPlane; +} //-------------------------------------------------------------------------------------------------- /// Update the ortho projection view height from a walk based camera manipulation. /// Using pointOfInterest, the perspective Y-field Of View along with the camera position //-------------------------------------------------------------------------------------------------- -void caf::Viewer::updateParallelProjectionHeight(const cvf::Vec3d& pointOfInterest) +void caf::Viewer::updateParallelProjectionHeightFromMoveZoom(const cvf::Vec3d& pointOfInterest) { using namespace cvf; cvf::Camera* camera = m_mainCamera.p(); if (!camera || camera->projection() != Camera::ORTHO) return; - Vec3d eye, vrp, up; - camera->toLookAt(&eye, &vrp, &up); - Vec3d eyeToFocus = pointOfInterest - eye; - Vec3d camDir = vrp - eye; - camDir.normalize(); - - double distToFocusPlane = eyeToFocus*camDir; + double distToFocusPlane = distToPlaneOfInterest(camera, pointOfInterest); double orthoHeight = calculateOrthoHeight(m_cameraFieldOfViewYDeg, distToFocusPlane); camera->setProjectionAsOrtho(orthoHeight, camera->nearPlane(), camera->farPlane()); } + +//-------------------------------------------------------------------------------------------------- +/// Update the camera eye position from point of interest, keeping the ortho height fixed and in sync +/// with distToPlaneOfInterest from a walk based camera manipulation in ortho projection. +//-------------------------------------------------------------------------------------------------- +void caf::Viewer::updateParallelProjectionCameraPosFromPointOfInterestMove(const cvf::Vec3d& pointOfInterest) +{ + using namespace cvf; + cvf::Camera* camera = m_mainCamera.p(); + + if (!camera || camera->projection() != Camera::ORTHO) return; + + + double orthoHeight = camera->frontPlaneFrustumHeight(); + Trace::show(String::number(orthoHeight)); + + double neededDistToFocusPlane = calculateDistToPlaneOfInterest(m_cameraFieldOfViewYDeg, orthoHeight); + + Vec3d eye, vrp, up; + camera->toLookAt(&eye, &vrp, &up); + Vec3d camDir = vrp - eye; + camDir.normalize(); + + double existingDistToFocusPlane = distToPlaneOfInterest(camera, pointOfInterest); + + Vec3d newEye = eye + (existingDistToFocusPlane - neededDistToFocusPlane) * camDir; + + Trace::show(String::number(newEye.x()) + ", " + String::number(newEye.y()) + ", " +String::number(newEye.z())); + camera->setFromLookAt(newEye, newEye + 10.0*camDir, up); + +} + diff --git a/Fwk/AppFwk/cafViewer/cafViewer.h b/Fwk/AppFwk/cafViewer/cafViewer.h index ad53143a53..8681294b52 100644 --- a/Fwk/AppFwk/cafViewer/cafViewer.h +++ b/Fwk/AppFwk/cafViewer/cafViewer.h @@ -117,9 +117,14 @@ public: void setView( const cvf::Vec3d& alongDirection, const cvf::Vec3d& upDirection ); void zoomAll(); void enableParallelProjection(bool enable); - void updateParallelProjectionHeight(const cvf::Vec3d& pointOfInterest); + + // Interface for navigation policies + void updateParallelProjectionHeightFromMoveZoom(const cvf::Vec3d& pointOfInterest); + void updateParallelProjectionCameraPosFromPointOfInterestMove(const cvf::Vec3d& pointOfInterest); + virtual void navigationPolicyUpdate(); + // Min max near far plane. void setMinNearPlaneDistance(double dist); void setMaxFarPlaneDistance(double dist);