Skip to content

Commit

Permalink
Fix more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdkon committed Feb 8, 2025
1 parent 25685b6 commit bd66507
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 13 deletions.
13 changes: 9 additions & 4 deletions src/3d/qgs3dutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,21 @@ typedef Qt3DCore::QBuffer Qt3DQBuffer;
// declared here as Qgs3DTypes has no cpp file
const char *Qgs3DTypes::PROP_NAME_3D_RENDERER_FLAG = "PROP_NAME_3D_RENDERER_FLAG";

static void waitForFrame( Qgs3DMapScene *scene )
void Qgs3DUtils::waitForFrame( QgsAbstract3DEngine &engine, Qgs3DMapScene *scene )
{
// Set policy to always render frame, so we don't wait forever.
Qt3DRender::QRenderSettings::RenderPolicy oldPolicy = engine.renderSettings()->renderPolicy();
engine.renderSettings()->setRenderPolicy( Qt3DRender::QRenderSettings::RenderPolicy::Always );

// Wait for at least one frame to render
Qt3DLogic::QFrameAction *frameAction = new Qt3DLogic::QFrameAction();
scene->addComponent( frameAction );
QEventLoop evLoop;
QObject::connect( frameAction, &Qt3DLogic::QFrameAction::triggered, &evLoop, &QEventLoop::quit );
evLoop.exec();
scene->removeComponent( frameAction );

engine.renderSettings()->setRenderPolicy( oldPolicy );
}

QImage Qgs3DUtils::captureSceneImage( QgsAbstract3DEngine &engine, Qgs3DMapScene *scene )
Expand All @@ -78,7 +84,7 @@ QImage Qgs3DUtils::captureSceneImage( QgsAbstract3DEngine &engine, Qgs3DMapScene
// We need to change render policy to RenderPolicy::Always, since otherwise render capture node won't work
engine.renderSettings()->setRenderPolicy( Qt3DRender::QRenderSettings::RenderPolicy::Always );

waitForFrame( scene );
waitForFrame( engine, scene );

auto saveImageFcn = [&evLoop, &resImage]( const QImage &img ) {
resImage = img;
Expand Down Expand Up @@ -124,11 +130,10 @@ QImage Qgs3DUtils::captureSceneDepthBuffer( QgsAbstract3DEngine &engine, Qgs3DMa
// We need to change render policy to RenderPolicy::Always, since otherwise render capture node won't work
engine.renderSettings()->setRenderPolicy( Qt3DRender::QRenderSettings::RenderPolicy::Always );

waitForFrame( scene );

auto requestImageFcn = [&engine, scene] {
if ( scene->sceneState() == Qgs3DMapScene::Ready )
{
waitForFrame( engine, scene );
engine.renderSettings()->setRenderPolicy( Qt3DRender::QRenderSettings::RenderPolicy::OnDemand );
engine.requestDepthBufferCapture();
}
Expand Down
6 changes: 6 additions & 0 deletions src/3d/qgs3dutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ class _3D_EXPORT Qgs3DUtils
*/
static QImage captureSceneImage( QgsAbstract3DEngine &engine, Qgs3DMapScene *scene );

/**
* Waits for a frame to be rendered. Useful to trigger once-per-frame updates
* \since QGIS 3.42
*/
static void waitForFrame( QgsAbstract3DEngine &engine, Qgs3DMapScene *scene );

/**
* Captures the depth buffer of the current 3D scene of a 3D engine. The function waits
* until the scene is not fully loaded/updated before capturing the image.
Expand Down
1 change: 1 addition & 0 deletions src/3d/qgscameracontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ void QgsCameraController::onWheel( Qt3DInput::QWheelEvent *wheel )
if ( mCurrentOperation != MouseOperation::ZoomWheel )
{
setMouseParameters( MouseOperation::ZoomWheel );
// The actual zooming will happen after we get a new depth buffer
}
else
{
Expand Down
27 changes: 18 additions & 9 deletions tests/src/3d/testqgs3dcameracontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,14 +455,22 @@ void TestQgs3DCameraController::testRotationCenterZoomWheelRotationCenter()

// look from the top
scene->cameraController()->setLookingAtPoint( QgsVector3D( 0, 0, 0 ), 2500, 0, 0 );
// XXX: Sometimes the near/far planes aren't calculated correctly, so they're
// left at the too-deep default. This causes the rest of the test to fail in
// weird ways every once in a while, so loop until we get good values.
do {
// Force recalcualtion of near/far planes.
scene->cameraController()->mCameraChanged = true;

// this call is not used but ensures to synchronize the scene
Qgs3DUtils::captureSceneImage( engine, scene );
} while(scene->cameraController()->camera()->nearPlane() < 1000);

QVector3D initialCamViewCenter = scene->cameraController()->camera()->viewCenter();
QVector3D initialCamPosition = scene->cameraController()->camera()->position();
float initialPitch = scene->cameraController()->pitch();
float initialYaw = scene->cameraController()->yaw();

// this call is not used but ensures to synchronize the scene
Qgs3DUtils::captureSceneImage( engine, scene );

QMouseEvent mousePressEvent( QEvent::MouseButtonPress, midPos, Qt::LeftButton, Qt::LeftButton, Qt::ShiftModifier );
scene->cameraController()->onMousePressed( new Qt3DInput::QMouseEvent( mousePressEvent ) );

Expand Down Expand Up @@ -522,8 +530,8 @@ void TestQgs3DCameraController::testRotationCenterZoomWheelRotationCenter()
depthImage = Qgs3DUtils::captureSceneDepthBuffer( engine, scene );
scene->cameraController()->depthBufferCaptured( depthImage );

QGSCOMPARENEARVECTOR3D( scene->cameraController()->mZoomPoint, QVector3D( 283.2, -923.1, -27.0 ), 1.5 );
QGSCOMPARENEARVECTOR3D( scene->cameraController()->cameraPose().centerPoint(), QVector3D( 99.4, -319.9, -8.8 ), 2.0 );
QGSCOMPARENEARVECTOR3D( scene->cameraController()->mZoomPoint, QVector3D( 312.936, -950.772, -125.381 ), 1.5 );
QGSCOMPARENEARVECTOR3D( scene->cameraController()->cameraPose().centerPoint(), QVector3D( 109.8, -329.4, -43.3 ), 2.0 );
QGSCOMPARENEAR( scene->cameraController()->cameraPose().distanceFromCenterPoint(), 1631.9, 2.0 );
QCOMPARE( scene->cameraController()->pitch(), initialPitch );
QCOMPARE( scene->cameraController()->yaw(), initialYaw );
Expand All @@ -540,6 +548,7 @@ void TestQgs3DCameraController::testRotationCenterZoomWheelRotationCenter()
initialPitch = scene->cameraController()->pitch();
initialYaw = scene->cameraController()->yaw();

Qgs3DUtils::waitForFrame(engine, scene);
// the first mouse event only updates the mouse position
// the second one will update the camera
QMouseEvent mouseMoveEvent3( QEvent::MouseMove, midPos + movement1 + movement2, Qt::LeftButton, Qt::LeftButton, Qt::ShiftModifier );
Expand All @@ -558,9 +567,9 @@ void TestQgs3DCameraController::testRotationCenterZoomWheelRotationCenter()
QCOMPARE( scene->cameraController()->mCurrentOperation, QgsCameraController::MouseOperation::RotationCenter );

diffViewCenter = scene->cameraController()->camera()->viewCenter() - initialCamViewCenter;
QGSCOMPARENEARVECTOR3D( diffViewCenter, QVector3D( 25.9, 7.1, 5.2 ), 1.0 );
QGSCOMPARENEARVECTOR3D( diffViewCenter, QVector3D( 26.9, 7.3, 5.4 ), 2.0 );
diffPosition = scene->cameraController()->camera()->position() - initialCamPosition;
QGSCOMPARENEARVECTOR3D( diffPosition, QVector3D( -44.3, -9.1, -11.7 ), 1.0 );
QGSCOMPARENEARVECTOR3D( diffPosition, QVector3D( -43.2, -9.1, -11.1 ), 1.0 );
diffPitch = scene->cameraController()->pitch() - initialPitch;
diffYaw = scene->cameraController()->yaw() - initialYaw;
QGSCOMPARENEAR( diffPitch, 2.5, 0.1 );
Expand Down Expand Up @@ -857,9 +866,9 @@ void TestQgs3DCameraController::testTranslateZoomWheelTranslate()
QCOMPARE( scene->cameraController()->mCurrentOperation, QgsCameraController::MouseOperation::Translation );

diffViewCenter = scene->cameraController()->camera()->viewCenter() - initialCamViewCenter;
QGSCOMPARENEARVECTOR3D( diffViewCenter, QVector3D( -11.3, 11.3, 0.0 ), 1.0 );
QGSCOMPARENEARVECTOR3D( diffViewCenter, QVector3D( -17.2, 17.2, 0.0 ), 1.0 );
diffPosition = scene->cameraController()->camera()->position() - initialCamPosition;
QGSCOMPARENEARVECTOR3D( diffPosition, QVector3D( -11.3, 11.3, 0.0 ), 1.0 );
QGSCOMPARENEARVECTOR3D( diffPosition, QVector3D( -17.2, 17.2, 0.0 ), 1.0 );
QCOMPARE( scene->cameraController()->pitch(), initialPitch );
QCOMPARE( scene->cameraController()->yaw(), initialYaw );

Expand Down

0 comments on commit bd66507

Please sign in to comment.