Skip to content

Commit

Permalink
qgs3dmapscene: Fix near/far planes computation once the scene is ready
Browse files Browse the repository at this point in the history
The near/far planes are computed in `Qgs3DMapScene` when the camera
parameters have changed. However, the near and far planes are not
computed once the scene is ready.
This works well when a new 3d scene is displayed because the camera is
far from the entities and this does affect the near/far planes
computation.
However, when a 3d scene is restored, this does not work if the
entities are close to the camera.

This issue is fixed by using a new logic:
The near and far planes are computed before the scene update to get a
first approximation needed by `updateScene`. Then, `updateScene` is
called. The active nodes may have changed. This can affect the scene
depth. Therefore, once the scene is ready, `updateCameraNearFarPlanes`
is called one more time by `setSceneState` to get an accurate result.
  • Loading branch information
ptitjano committed Dec 15, 2023
1 parent 684a6b9 commit 4d3f699
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 16 deletions.
23 changes: 14 additions & 9 deletions src/3d/qgs3dmapscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,16 +314,14 @@ void Qgs3DMapScene::onCameraChanged()
mEngine->camera()->lens()->setOrthographicProjection( -viewWidthFromCenter, viewWidthFromCenter, -viewHeightFromCenter, viewHeightFromCenter, mEngine->camera()->nearPlane(), mEngine->camera()->farPlane() );
}

// The near and far planes are computed before the scene update
// to get a first approximation needed by `updateScene`.
// Then, `updateScene` is called. The active nodes may have changed.
// This can affect the scene depth.
// Therefore, once the scene is ready, `updateCameraNearFarPlanes`
// is called one more time by `setSceneState` to get an accurate result.
updateCameraNearFarPlanes();
updateScene();
bool changedCameraPlanes = updateCameraNearFarPlanes();

if ( changedCameraPlanes )
{
// repeat update of entities - because we have updated camera's near/far planes,
// the active nodes may have changed as well
updateScene();
updateCameraNearFarPlanes();
}

onShadowSettingsChanged();

Expand Down Expand Up @@ -894,7 +892,14 @@ void Qgs3DMapScene::setSceneState( Qgs3DMapScene::SceneState state )
{
if ( mSceneState == state )
return;

mSceneState = state;
if ( mSceneState == SceneState::Ready )
{
// compute the correct near/far planes once all the entities are loaded
updateCameraNearFarPlanes();
}

emit sceneStateChanged();
}

Expand Down
14 changes: 7 additions & 7 deletions tests/src/3d/testqgs3drendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1403,9 +1403,9 @@ void TestQgs3DRendering::testDepthBuffer()

scene->cameraController()->depthBufferCaptured( depthImage );

QGSCOMPARENEARVECTOR3D( testCam->zoomPoint(), QVector3D( -32.4, 222.8, 184.1 ), 1.0 );
QGSCOMPARENEARVECTOR3D( testCam->cameraPose()->centerPoint(), QVector3D( -32.4, 222.8, 184.1 ), 1.0 );
QGSCOMPARENEAR( testCam->cameraPose()->distanceFromCenterPoint(), 126.4, 0.1 );
QGSCOMPARENEARVECTOR3D( testCam->zoomPoint(), QVector3D( -40.3, 276.8, 228.8 ), 1.0 );
QGSCOMPARENEARVECTOR3D( testCam->cameraPose()->centerPoint(), QVector3D( -40.3, 276.8, 228.8 ), 1.0 );
QGSCOMPARENEAR( testCam->cameraPose()->distanceFromCenterPoint(), 114.6, 0.1 );
QCOMPARE( testCam->cumulatedWheelY(), 0 );

// Checking fourth wheel action
Expand All @@ -1422,14 +1422,14 @@ void TestQgs3DRendering::testDepthBuffer()

scene->cameraController()->depthBufferCaptured( depthImage );

QGSCOMPARENEARVECTOR3D( testCam->zoomPoint(), QVector3D( -32.3, 221.7, 183.2 ), 1.0 );
QGSCOMPARENEARVECTOR3D( testCam->cameraPose()->centerPoint(), QVector3D( -32.3, 221.7, 183.2 ), 1.0 );
QGSCOMPARENEAR( testCam->cameraPose()->distanceFromCenterPoint(), 101.1, 0.1 );
QGSCOMPARENEARVECTOR3D( testCam->zoomPoint(), QVector3D( -31.2, 214.4, 177.1 ), 1.0 );
QGSCOMPARENEARVECTOR3D( testCam->cameraPose()->centerPoint(), QVector3D( -31.2, 214.4, 177.1 ), 1.0 );
QGSCOMPARENEAR( testCam->cameraPose()->distanceFromCenterPoint(), 155.3, 0.1 );
QCOMPARE( testCam->cumulatedWheelY(), 0 );

// Checking camera position
QVector3D diff = scene->cameraController()->camera()->position() - startPos;
QGSCOMPARENEARVECTOR3D( diff, QVector3D( 125, -850, -700 ), 3.0 );
QGSCOMPARENEARVECTOR3D( diff, QVector3D( 119, -816, -674 ), 3.0 );

delete scene;
mapSettings.setLayers( {} );
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4d3f699

Please sign in to comment.