(#168) Wip: Parallel projection. Basics in place

This commit is contained in:
Jacob Støren 2015-12-05 00:56:14 +01:00
parent 64b3281382
commit bbb0a5e993
10 changed files with 132 additions and 48 deletions

View File

@ -77,6 +77,8 @@ RimView::RimView(void)
showWindow.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&cameraPosition, "CameraPosition", cvf::Mat4d::IDENTITY, "", "", "", "");
cameraPosition.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&isPerspectiveView, "PerspectiveProjection", true, "Perspective Projection", "", "", "");
double defaultScaleFactor = preferences->defaultScaleFactorZ;
CAF_PDM_InitField(&scaleZ, "GridZScale", defaultScaleFactor, "Z Scale", "", "Scales the scene in the Z direction", "");
@ -491,6 +493,10 @@ void RimView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QV
RiuMainWindow::instance()->refreshDrawStyleActions();
RiuMainWindow::instance()->refreshAnimationActions();
}
else if (changedField == &isPerspectiveView)
{
if (m_viewer) m_viewer->enableParallelProjection(!isPerspectiveView());
}
else if (changedField == &scaleZ)
{
if (scaleZ < 1) scaleZ = 1;

View File

@ -76,6 +76,7 @@ public:
caf::PdmField<bool> showWindow;
caf::PdmField<cvf::Mat4d> cameraPosition;
caf::PdmField<bool> isPerspectiveView;
caf::PdmField< cvf::Color3f > backgroundColor;
caf::PdmField<int> maximumFrameRate;

View File

@ -169,6 +169,8 @@ bool RiuCadNavigation::handleInputEvent(QInputEvent* inputEvent)
cvf::Vec3d newVrp = vrp + trans;
m_viewer->mainCamera()->setFromLookAt(newPos,newVrp, up );
m_viewer->updateParallelProjectionHeight(m_pointOfInterest);
m_viewer->navigationPolicyUpdate();
}
}

View File

@ -245,6 +245,8 @@ 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->navigationPolicyUpdate();
}
}

View File

@ -269,6 +269,8 @@ 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->navigationPolicyUpdate();
}
}

View File

@ -172,6 +172,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->navigationPolicyUpdate();
}
}

View File

@ -196,18 +196,13 @@ void caf::CeetronNavigation::wheelEvent(QWheelEvent* event)
int posY = m_viewer->height() - event->y();
if (m_viewer->mainCamera()->projection() == cvf::Camera::PERSPECTIVE)
{
m_trackball->startNavigation(ManipulatorTrackball::WALK, event->x(), posY);
}
else
{
m_trackball->startNavigation(ManipulatorTrackball::ZOOM, event->x(), posY);
}
m_trackball->startNavigation(ManipulatorTrackball::WALK, event->x(), posY);
m_trackball->updateNavigation(event->x(), posY + navDelta);
m_trackball->endNavigation();
m_viewer->updateParallelProjectionHeight( m_pointOfInterest);
m_viewer->navigationPolicyUpdate();
event->accept();
@ -229,14 +224,7 @@ ManipulatorTrackball::NavigationType caf::CeetronNavigation::getNavigationTypeFr
}
else if (mouseButtons == Qt::MidButton || mouseButtons == (Qt::LeftButton | Qt::RightButton))
{
if (m_viewer->mainCamera()->projection() == cvf::Camera::PERSPECTIVE)
{
return ManipulatorTrackball::WALK;
}
else
{
return ManipulatorTrackball::ZOOM;
}
return ManipulatorTrackball::WALK;
}
else
{

View File

@ -257,6 +257,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->navigationPolicyUpdate();
}
}

View File

@ -80,6 +80,7 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent)
m_navigationPolicy(NULL),
m_minNearPlaneDistance(0.05),
m_maxFarPlaneDistance(cvf::UNDEFINED_DOUBLE),
m_cameraFieldOfViewYDeg(40.0),
m_releaseOGLResourcesEachFrame(false),
m_paintCounter(0),
m_navigationPolicyEnabled(true),
@ -233,15 +234,11 @@ void caf::Viewer::updateCamera(int width, int height)
if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE)
{
m_mainCamera->setProjectionAsPerspective(40, m_mainCamera->nearPlane(), m_mainCamera->farPlane());
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, m_mainCamera->nearPlane(), m_mainCamera->farPlane());
}
else
{
cvf::BoundingBox bb = m_renderingSequence->boundingBox();
if (bb.isValid())
{
m_mainCamera->setProjectionAsOrtho(bb.extent().length(), m_mainCamera->nearPlane(), m_mainCamera->farPlane());
}
m_mainCamera->setProjectionAsOrtho(m_mainCamera->frontPlaneFrustumHeight(), m_mainCamera->nearPlane(), m_mainCamera->farPlane());
}
}
@ -266,32 +263,36 @@ bool caf::Viewer::canRender() const
//--------------------------------------------------------------------------------------------------
void caf::Viewer::optimizeClippingPlanes()
{
cvf::BoundingBox bb = m_renderingSequence->boundingBox();
if (!bb.isValid()) return;
cvf::Vec3d eye, vrp, up;
m_mainCamera->toLookAt(&eye, &vrp, &up);
cvf::Vec3d viewdir = (vrp - eye).getNormalized();
double distEyeBoxCenterAlongViewDir = (bb.center() - eye)*viewdir;
double farPlaneDist = distEyeBoxCenterAlongViewDir + bb.radius() * 1.2;
farPlaneDist = CVF_MIN(farPlaneDist, m_maxFarPlaneDistance);
double nearPlaneDist = distEyeBoxCenterAlongViewDir - bb.radius();
if (nearPlaneDist < m_minNearPlaneDistance) nearPlaneDist = m_minNearPlaneDistance;
if (m_navigationPolicy.notNull() && m_navigationPolicyEnabled)
{
double pointOfInterestDist = (eye - m_navigationPolicy->pointOfInterest()).length();
nearPlaneDist = CVF_MIN(nearPlaneDist, pointOfInterestDist*0.2);
}
if (farPlaneDist <= nearPlaneDist) farPlaneDist = nearPlaneDist + 1.0;
if (m_mainCamera->projection() == cvf::Camera::PERSPECTIVE)
{
cvf::BoundingBox bb = m_renderingSequence->boundingBox();
if (!bb.isValid()) return;
cvf::Vec3d eye, vrp, up;
m_mainCamera->toLookAt(&eye, &vrp, &up);
cvf::Vec3d viewdir = (vrp - eye).getNormalized();
double distEyeBoxCenterAlongViewDir = (bb.center() - eye)*viewdir;
double farPlaneDist = distEyeBoxCenterAlongViewDir + bb.radius() * 1.2;
farPlaneDist = CVF_MIN(farPlaneDist, m_maxFarPlaneDistance);
double nearPlaneDist = distEyeBoxCenterAlongViewDir - bb.radius();
if (nearPlaneDist < m_minNearPlaneDistance) nearPlaneDist = m_minNearPlaneDistance;
if ( m_navigationPolicy.notNull())
{
double pointOfInterestDist = (eye - m_navigationPolicy->pointOfInterest()).length();
nearPlaneDist = CVF_MIN( nearPlaneDist, pointOfInterestDist*0.2);
}
if (farPlaneDist <= nearPlaneDist) farPlaneDist = nearPlaneDist + 1.0;
m_mainCamera->setProjectionAsPerspective(m_mainCamera->fieldOfViewYDeg(), nearPlaneDist, farPlaneDist);
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, nearPlaneDist, farPlaneDist);
}
else
{
m_mainCamera->setProjectionAsOrtho(m_mainCamera->frontPlaneFrustumHeight(), nearPlaneDist, farPlaneDist);
}
}
@ -514,7 +515,7 @@ void caf::Viewer::setMaxFarPlaneDistance(double dist)
//--------------------------------------------------------------------------------------------------
void caf::Viewer::setView(const cvf::Vec3d& alongDirection, const cvf::Vec3d& upDirection)
{
if (m_navigationPolicy.notNull())
if (m_navigationPolicy.notNull() && m_navigationPolicyEnabled)
{
m_navigationPolicy->setView(alongDirection, upDirection);
@ -921,3 +922,80 @@ cvf::OverlayItem* caf::Viewer::overlayItem(int winPosX, int winPosY)
return m_mainRendering->overlayItemFromWindowCoordinates(translatedMousePosX, translatedMousePosY);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::enableParallelProjection(bool enableOrtho)
{
if (enableOrtho && m_mainCamera->projection() == cvf::Camera::PERSPECTIVE)
{
cvf::Vec3d pointOfInterest;
if (m_navigationPolicy.isNull() || !m_navigationPolicyEnabled)
{
using namespace cvf;
Vec3d eye, vrp, up;
m_mainCamera->toLookAt(&eye, &vrp, &up);
Vec3d eyeToFocus = pointOfInterest - eye;
Vec3d camDir = vrp - eye;
camDir.normalize();
double distToFocusPlane = 0.5*(m_mainCamera->farPlane() - m_mainCamera->nearPlane());
pointOfInterest = camDir *distToFocusPlane;
}
else
{
pointOfInterest = m_navigationPolicy->pointOfInterest();
}
m_mainCamera->setProjectionAsOrtho(1.0, m_mainCamera->nearPlane(), m_mainCamera->farPlane());
this->updateParallelProjectionHeight(pointOfInterest);
this->update();
}
else if (!enableOrtho && m_mainCamera->projection() == cvf::Camera::ORTHO)
{
// We currently expect all the navigation policies to do walk-based navigation and not fiddle with the field of view
// so we do not need to update the camera position based on orthoHeight and fieldOfView.
// We assume the camera is in a sensible position.
m_mainCamera->setProjectionAsPerspective(m_cameraFieldOfViewYDeg, m_mainCamera->nearPlane(), m_mainCamera->farPlane());
this->update();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double calculateOrthoHeight(double perspectiveViewAngleYDeg, double focusPlaneDist)
{
return 2 * (cvf::Math::tan( cvf::Math::toRadians(0.5 * perspectiveViewAngleYDeg) ) * focusPlaneDist);
}
//--------------------------------------------------------------------------------------------------
/// 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)
{
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 orthoHeight = calculateOrthoHeight(m_cameraFieldOfViewYDeg, distToFocusPlane);
camera->setProjectionAsOrtho(orthoHeight, camera->nearPlane(), camera->farPlane());
}

View File

@ -116,6 +116,9 @@ public:
void enableNavigationPolicy(bool enable);
void setView( const cvf::Vec3d& alongDirection, const cvf::Vec3d& upDirection );
void zoomAll();
void enableParallelProjection(bool enable);
void updateParallelProjectionHeight(const cvf::Vec3d& pointOfInterest);
virtual void navigationPolicyUpdate();
void setMinNearPlaneDistance(double dist);
void setMaxFarPlaneDistance(double dist);
@ -140,7 +143,6 @@ public:
// Find out whether the system supports shaders
static bool isShadersSupported();
virtual void navigationPolicyUpdate();
public slots:
virtual void slotSetCurrentFrame(int frameIndex);
@ -174,6 +176,7 @@ protected:
double m_minNearPlaneDistance;
double m_maxFarPlaneDistance;
double m_cameraFieldOfViewYDeg;
private:
void setupMainRendering();