From b234fc525d070d85ccfc68c49dff3a4e3c32d965 Mon Sep 17 00:00:00 2001 From: Martin Dobias Date: Thu, 10 Aug 2017 22:35:10 +0200 Subject: [PATCH] Correctly working "zoom full" + more robust near/far plane config --- src/3d/cameracontroller.cpp | 8 ++++---- src/3d/cameracontroller.h | 2 +- src/3d/scene.cpp | 30 ++++++++++++++++++++++++++++-- src/3d/scene.h | 2 ++ src/app/3d/qgs3dmapcanvas.cpp | 4 +++- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/3d/cameracontroller.cpp b/src/3d/cameracontroller.cpp index a63edae11ab..7ac3ab3808d 100644 --- a/src/3d/cameracontroller.cpp +++ b/src/3d/cameracontroller.cpp @@ -240,12 +240,12 @@ void CameraController::frameTriggered( float dt ) } } -void CameraController::resetView() +void CameraController::resetView( float distance ) { - setCameraData( 0, 0, 1000 ); + setCameraData( 0, 0, distance ); // a basic setup to make frustum depth range long enough that it does not cull everything - mCamera->setNearPlane( 1 ); - mCamera->setFarPlane( 10000 ); + mCamera->setNearPlane( distance / 2 ); + mCamera->setFarPlane( distance * 2 ); emit cameraChanged(); } diff --git a/src/3d/cameracontroller.h b/src/3d/cameracontroller.h index 14d96b16385..ec4d4a9c026 100644 --- a/src/3d/cameracontroller.h +++ b/src/3d/cameracontroller.h @@ -29,7 +29,7 @@ class _3D_EXPORT CameraController : public Qt3DCore::QEntity void frameTriggered( float dt ); //! Move camera back to the initial position (looking down towards origin of world's coordinates) - void resetView(); + void resetView( float distance ); signals: void cameraChanged(); diff --git a/src/3d/scene.cpp b/src/3d/scene.cpp index 484e2d4fe48..0e32e06ec70 100644 --- a/src/3d/scene.cpp +++ b/src/3d/scene.cpp @@ -58,7 +58,7 @@ Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph, mCameraController = new CameraController( this ); // attaches to the scene mCameraController->setViewport( viewportRect ); mCameraController->setCamera( camera ); - mCameraController->resetView(); + mCameraController->resetView( 1000 ); // create terrain entity @@ -147,6 +147,13 @@ Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph, onCameraChanged(); } +void Scene::viewZoomFull() +{ + QgsRectangle extent = mMap.terrainGenerator()->extent(); + float side = qMax( extent.width(), extent.height() ); + mCameraController->resetView( side ); // assuming FOV being 45 degrees +} + SceneState _sceneState( CameraController *cameraController ) { Qt3DRender::QCamera *camera = cameraController->camera(); @@ -187,6 +194,13 @@ void Scene::onCameraChanged() float far = 0; QList activeNodes = mTerrain->getActiveNodes(); + + // it could be that there are no active nodes - they could be all culled or because root node + // is not yet loaded - we still need at least something to understand bounds of our scene + // so lets use the root node + if ( activeNodes.isEmpty() ) + activeNodes << mTerrain->getRootNode(); + Q_FOREACH ( ChunkNode *node, activeNodes ) { // project each corner of bbox to camera coordinates @@ -206,14 +220,26 @@ void Scene::onCameraChanged() far = dst; } } - //qDebug() << "near/far" << near << far; if ( near < 1 ) near = 1; // does not really make sense to use negative far plane (behind camera) + if ( near == 1e9 && far == 0 ) + { + // the update didn't work out... this should not happen + // well at least temprarily use some conservative starting values + qDebug() << "oops... this should not happen! couldn't determine near/far plane. defaulting to 1...1e9"; + near = 1; + far = 1e9; + } + // set near/far plane - with some tolerance in front/behind expected near/far planes camera->setFarPlane( far * 2 ); camera->setNearPlane( near / 2 ); } + else + qDebug() << "no terrain - not setting near/far plane"; + + //qDebug() << "camera near/far" << mCameraController->camera()->nearPlane() << mCameraController->camera()->farPlane(); } void Scene::onFrameTriggered( float dt ) diff --git a/src/3d/scene.h b/src/3d/scene.h index f19fdda0fcd..f6f404add10 100644 --- a/src/3d/scene.h +++ b/src/3d/scene.h @@ -39,6 +39,8 @@ class _3D_EXPORT Scene : public Qt3DCore::QEntity CameraController *cameraController() { return mCameraController; } Terrain *terrain() { return mTerrain; } + void viewZoomFull(); + private slots: void onCameraChanged(); void onFrameTriggered( float dt ); diff --git a/src/app/3d/qgs3dmapcanvas.cpp b/src/app/3d/qgs3dmapcanvas.cpp index 8e07c3d64dc..9c6ff826d96 100644 --- a/src/app/3d/qgs3dmapcanvas.cpp +++ b/src/app/3d/qgs3dmapcanvas.cpp @@ -55,9 +55,11 @@ void Qgs3DMapCanvas::setMap( Map3D *map ) delete mMap; mMap = map; + + resetView(); } void Qgs3DMapCanvas::resetView() { - mScene->cameraController()->resetView(); + mScene->viewZoomFull(); }