Skip to content
Permalink
Browse files

[3d] fix crash when switching terrain generator (fixes #21538)

The problem was introduced in PR #8828 when fixing issue #20963

This fix immediately deletes terrain entity on generator change
and informs other code about that + identify map tool is now aware
of the fact that terrain entity may be temporarily null.
  • Loading branch information
wonder-sk committed Mar 10, 2019
1 parent 8305c0e commit 56e98f2b0b39a824f37159f026bc1df29801178e
Showing with 23 additions and 15 deletions.
  1. +10 −8 src/3d/qgs3dmapscene.cpp
  2. +1 −1 src/3d/qgs3dmapscene.h
  3. +12 −6 src/app/3d/qgs3dmaptoolidentify.cpp
@@ -351,6 +351,16 @@ void Qgs3DMapScene::onFrameTriggered( float dt )

void Qgs3DMapScene::createTerrain()
{
if ( mTerrain )
{
mChunkEntities.removeOne( mTerrain );

mTerrain->deleteLater();
mTerrain = nullptr;

emit terrainEntityChanged();
}

if ( !mTerrainUpdateScheduled )
{
// defer re-creation of terrain: there may be multiple invocations of this slot, so create the new entity just once
@@ -362,14 +372,6 @@ void Qgs3DMapScene::createTerrain()

void Qgs3DMapScene::createTerrainDeferred()
{
if ( mTerrain )
{
mChunkEntities.removeOne( mTerrain );

mTerrain->deleteLater();
mTerrain = nullptr;
}

double tile0width = mMap.terrainGenerator()->extent().width();
int maxZoomLevel = Qgs3DUtils::maxZoomLevel( tile0width, mMap.mapTileResolution(), mMap.maxTerrainGroundError() );

@@ -59,7 +59,7 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity

//! Returns camera controller
QgsCameraController *cameraController() { return mCameraController; }
//! Returns terrain entity
//! Returns terrain entity (may be temporarily null)
QgsTerrainEntity *terrainEntity() { return mTerrain; }

//! Resets camera view to show the whole scene (top view)
@@ -77,16 +77,20 @@ void Qgs3DMapToolIdentify::mousePressEvent( QMouseEvent *event )

void Qgs3DMapToolIdentify::activate()
{
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
connect( picker, &Qt3DRender::QObjectPicker::clicked, this, &Qgs3DMapToolIdentify::onTerrainPicked );
if ( QgsTerrainEntity *terrainEntity = mCanvas->scene()->terrainEntity() )
{
connect( terrainEntity->terrainPicker(), &Qt3DRender::QObjectPicker::clicked, this, &Qgs3DMapToolIdentify::onTerrainPicked );
}

mCanvas->scene()->registerPickHandler( mPickHandler.get() );
}

void Qgs3DMapToolIdentify::deactivate()
{
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
disconnect( picker, &Qt3DRender::QObjectPicker::clicked, this, &Qgs3DMapToolIdentify::onTerrainPicked );
if ( QgsTerrainEntity *terrainEntity = mCanvas->scene()->terrainEntity() )
{
disconnect( terrainEntity->terrainPicker(), &Qt3DRender::QObjectPicker::clicked, this, &Qgs3DMapToolIdentify::onTerrainPicked );
}

mCanvas->scene()->unregisterPickHandler( mPickHandler.get() );
}
@@ -137,6 +141,8 @@ void Qgs3DMapToolIdentify::onTerrainEntityChanged()
{
// no need to disconnect from the previous entity: it has been destroyed
// start listening to the new terrain entity
Qt3DRender::QObjectPicker *picker = mCanvas->scene()->terrainEntity()->terrainPicker();
connect( picker, &Qt3DRender::QObjectPicker::clicked, this, &Qgs3DMapToolIdentify::onTerrainPicked );
if ( QgsTerrainEntity *terrainEntity = mCanvas->scene()->terrainEntity() )
{
connect( terrainEntity->terrainPicker(), &Qt3DRender::QObjectPicker::clicked, this, &Qgs3DMapToolIdentify::onTerrainPicked );
}
}

0 comments on commit 56e98f2

Please sign in to comment.
You can’t perform that action at this time.