Skip to content

Commit

Permalink
[3d] fix crash when switching terrain generator (fixes #21538)
Browse files Browse the repository at this point in the history
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 56ec3cf commit 8e9250a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 15 deletions.
18 changes: 10 additions & 8 deletions src/3d/qgs3dmapscene.cpp
Expand Up @@ -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
Expand All @@ -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() );

Expand Down
2 changes: 1 addition & 1 deletion src/3d/qgs3dmapscene.h
Expand Up @@ -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)
Expand Down
18 changes: 12 additions & 6 deletions src/app/3d/qgs3dmaptoolidentify.cpp
Expand Up @@ -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() );
}
Expand Down Expand Up @@ -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 8e9250a

Please sign in to comment.