Skip to content

Commit 3d9d455

Browse files
committed
Signals/slots in Map3D + partial scene udates from Map3D signals
1 parent 9e0bf1d commit 3d9d455

26 files changed

+271
-99
lines changed

src/3d/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ SET(QGIS_3D_SRCS
3939

4040
SET(QGIS_3D_MOC_HDRS
4141
cameracontroller.h
42+
map3d.h
4243
scene.h
4344

4445
chunks/chunkedentity.h
@@ -48,6 +49,7 @@ SET(QGIS_3D_MOC_HDRS
4849
terrain/maptexturegenerator.h
4950
terrain/maptextureimage.h
5051
terrain/terrain.h
52+
terrain/terraingenerator.h
5153
)
5254

5355
QT5_WRAP_CPP(QGIS_3D_MOC_SRCS ${QGIS_3D_MOC_HDRS})

src/3d/cameracontroller.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
CameraController::CameraController( Qt3DCore::QNode *parent )
88
: Qt3DCore::QEntity( parent )
9-
, mTerrainPicker( nullptr )
109
, mLastPressedHeight( 0 )
1110
, mMouseDevice( new Qt3DInput::QMouseDevice() )
1211
, mKeyboardDevice( new Qt3DInput::QKeyboardDevice() )
@@ -26,10 +25,6 @@ CameraController::CameraController( Qt3DCore::QNode *parent )
2625
, mKeyboardTyNegInput( new Qt3DInput::QButtonAxisInput() )
2726
{
2827

29-
// object picker for terrain for correct map panning. it will be associated as a component of terrain entity
30-
mTerrainPicker = new Qt3DRender::QObjectPicker;
31-
connect( mTerrainPicker, &Qt3DRender::QObjectPicker::pressed, this, &CameraController::onPickerMousePressed );
32-
3328
// not using QAxis + QAnalogAxisInput for mouse X,Y because
3429
// it is only in action when a mouse button is pressed.
3530
mMouseHandler->setSourceDevice( mMouseDevice );
@@ -95,6 +90,12 @@ CameraController::CameraController( Qt3DCore::QNode *parent )
9590
addComponent( mLogicalDevice );
9691
}
9792

93+
void CameraController::addTerrainPicker( Qt3DRender::QObjectPicker *picker )
94+
{
95+
// object picker for terrain for correct map panning
96+
connect( picker, &Qt3DRender::QObjectPicker::pressed, this, &CameraController::onPickerMousePressed );
97+
}
98+
9899
void CameraController::setCamera( Qt3DRender::QCamera *camera )
99100
{
100101
if ( mCamera == camera )

src/3d/cameracontroller.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class _3D_EXPORT CameraController : public Qt3DCore::QEntity
1818

1919
Qt3DRender::QCamera *camera() const { return mCamera; }
2020
QRect viewport() const { return mViewport; }
21-
Qt3DRender::QObjectPicker *terrainPicker() const { return mTerrainPicker; }
21+
22+
void addTerrainPicker( Qt3DRender::QObjectPicker *picker );
2223

2324
void setCamera( Qt3DRender::QCamera *camera );
2425
void setViewport( const QRect &viewport );
@@ -43,8 +44,6 @@ class _3D_EXPORT CameraController : public Qt3DCore::QEntity
4344
Qt3DRender::QCamera *mCamera;
4445
//! used for computation of translation when dragging mouse
4546
QRect mViewport;
46-
//! picker of terrain to know height of terrain when dragging
47-
Qt3DRender::QObjectPicker *mTerrainPicker;
4847
//! height of terrain when mouse button was last pressed - for camera control
4948
float mLastPressedHeight;
5049

src/3d/map3d.cpp

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,29 +81,30 @@ Map3D::Map3D()
8181
, tileTextureSize( 512 )
8282
, maxTerrainError( 3.f )
8383
, skybox( false )
84-
, showBoundingBoxes( false )
85-
, drawTerrainTileInfo( false )
84+
, mShowTerrainBoundingBoxes( false )
85+
, mShowTerrainTileInfo( false )
8686
{
8787
}
8888

8989
Map3D::Map3D( const Map3D &other )
90-
: originX( other.originX )
90+
: QObject()
91+
, originX( other.originX )
9192
, originY( other.originY )
9293
, originZ( other.originZ )
9394
, crs( other.crs )
9495
, backgroundColor( other.backgroundColor )
9596
, zExaggeration( other.zExaggeration )
9697
, tileTextureSize( other.tileTextureSize )
9798
, maxTerrainError( other.maxTerrainError )
98-
, terrainGenerator( other.terrainGenerator ? other.terrainGenerator->clone() : nullptr )
99+
, mTerrainGenerator( other.mTerrainGenerator ? other.mTerrainGenerator->clone() : nullptr )
99100
, polygonRenderers( other.polygonRenderers )
100101
, pointRenderers( other.pointRenderers )
101102
, lineRenderers( other.lineRenderers )
102103
, skybox( other.skybox )
103104
, skyboxFileBase( other.skyboxFileBase )
104105
, skyboxFileExtension( other.skyboxFileExtension )
105-
, showBoundingBoxes( other.showBoundingBoxes )
106-
, drawTerrainTileInfo( other.drawTerrainTileInfo )
106+
, mShowTerrainBoundingBoxes( other.mShowTerrainBoundingBoxes )
107+
, mShowTerrainTileInfo( other.mShowTerrainTileInfo )
107108
, mLayers( other.mLayers )
108109
{
109110
}
@@ -141,7 +142,7 @@ void Map3D::readXml( const QDomElement &elem, const QgsReadWriteContext &context
141142
QString terrainGenType = elemTerrainGenerator.attribute( "type" );
142143
if ( terrainGenType == "dem" )
143144
{
144-
terrainGenerator.reset( new DemTerrainGenerator );
145+
mTerrainGenerator.reset( new DemTerrainGenerator );
145146
}
146147
else if ( terrainGenType == "quantized-mesh" )
147148
{
@@ -154,9 +155,9 @@ void Map3D::readXml( const QDomElement &elem, const QgsReadWriteContext &context
154155
{
155156
FlatTerrainGenerator *flatGen = new FlatTerrainGenerator;
156157
flatGen->setCrs( crs );
157-
terrainGenerator.reset( flatGen );
158+
mTerrainGenerator.reset( flatGen );
158159
}
159-
terrainGenerator->readXml( elemTerrainGenerator );
160+
mTerrainGenerator->readXml( elemTerrainGenerator );
160161

161162
polygonRenderers.clear();
162163
pointRenderers.clear();
@@ -193,8 +194,8 @@ void Map3D::readXml( const QDomElement &elem, const QgsReadWriteContext &context
193194
skyboxFileExtension = elemSkybox.attribute( "file-ext" );
194195

195196
QDomElement elemDebug = elem.firstChildElement( "debug" );
196-
showBoundingBoxes = elemDebug.attribute( "bounding-boxes", "0" ).toInt();
197-
drawTerrainTileInfo = elemDebug.attribute( "terrain-tile-info", "0" ).toInt();
197+
mShowTerrainBoundingBoxes = elemDebug.attribute( "bounding-boxes", "0" ).toInt();
198+
mShowTerrainTileInfo = elemDebug.attribute( "terrain-tile-info", "0" ).toInt();
198199
}
199200

200201
QDomElement Map3D::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
@@ -225,8 +226,8 @@ QDomElement Map3D::writeXml( QDomDocument &doc, const QgsReadWriteContext &conte
225226
}
226227
elemTerrain.appendChild( elemMapLayers );
227228
QDomElement elemTerrainGenerator = doc.createElement( "generator" );
228-
elemTerrainGenerator.setAttribute( "type", TerrainGenerator::typeToString( terrainGenerator->type() ) );
229-
terrainGenerator->writeXml( elemTerrainGenerator );
229+
elemTerrainGenerator.setAttribute( "type", TerrainGenerator::typeToString( mTerrainGenerator->type() ) );
230+
mTerrainGenerator->writeXml( elemTerrainGenerator );
230231
elemTerrain.appendChild( elemTerrainGenerator );
231232
elem.appendChild( elemTerrain );
232233

@@ -262,8 +263,8 @@ QDomElement Map3D::writeXml( QDomDocument &doc, const QgsReadWriteContext &conte
262263
elem.appendChild( elemSkybox );
263264

264265
QDomElement elemDebug = doc.createElement( "debug" );
265-
elemDebug.setAttribute( "bounding-boxes", showBoundingBoxes ? 1 : 0 );
266-
elemDebug.setAttribute( "terrain-tile-info", drawTerrainTileInfo ? 1 : 0 );
266+
elemDebug.setAttribute( "bounding-boxes", mShowTerrainBoundingBoxes ? 1 : 0 );
267+
elemDebug.setAttribute( "terrain-tile-info", mShowTerrainTileInfo ? 1 : 0 );
267268
elem.appendChild( elemDebug );
268269

269270
return elem;
@@ -277,7 +278,7 @@ void Map3D::resolveReferences( const QgsProject &project )
277278
layerRef.setLayer( project.mapLayer( layerRef.layerId ) );
278279
}
279280

280-
terrainGenerator->resolveReferences( project );
281+
mTerrainGenerator->resolveReferences( project );
281282

282283
for ( int i = 0; i < polygonRenderers.count(); ++i )
283284
{
@@ -306,7 +307,12 @@ void Map3D::setLayers( const QList<QgsMapLayer *> &layers )
306307
{
307308
lst.append( layer );
308309
}
310+
311+
if ( mLayers == lst )
312+
return;
313+
309314
mLayers = lst;
315+
emit layersChanged();
310316
}
311317

312318
QList<QgsMapLayer *> Map3D::layers() const
@@ -321,6 +327,30 @@ QList<QgsMapLayer *> Map3D::layers() const
321327
return lst;
322328
}
323329

330+
void Map3D::setTerrainGenerator( TerrainGenerator *gen )
331+
{
332+
mTerrainGenerator.reset( gen );
333+
emit terrainGeneratorChanged();
334+
}
335+
336+
void Map3D::setShowTerrainBoundingBoxes( bool enabled )
337+
{
338+
if ( mShowTerrainBoundingBoxes == enabled )
339+
return;
340+
341+
mShowTerrainBoundingBoxes = enabled;
342+
emit showTerrainBoundingBoxesChanged();
343+
}
344+
345+
void Map3D::setShowTerrainTilesInfo( bool enabled )
346+
{
347+
if ( mShowTerrainTileInfo == enabled )
348+
return;
349+
350+
mShowTerrainTileInfo = enabled;
351+
emit showTerrainTilesInfoChanged();
352+
}
353+
324354
// ---------------
325355

326356
PolygonRenderer::PolygonRenderer()

src/3d/map3d.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,9 @@ class QgsProject;
147147
class QDomElement;
148148

149149
//! Definition of the world
150-
class _3D_EXPORT Map3D
150+
class _3D_EXPORT Map3D : public QObject
151151
{
152+
Q_OBJECT
152153
public:
153154
Map3D();
154155
Map3D( const Map3D &other );
@@ -175,7 +176,10 @@ class _3D_EXPORT Map3D
175176

176177
int tileTextureSize; //!< Size of map textures of tiles in pixels (width/height)
177178
int maxTerrainError; //!< Maximum allowed terrain error in pixels
178-
std::unique_ptr<TerrainGenerator> terrainGenerator; //!< Implementation of the terrain generation
179+
180+
//! Takes ownership of the generator
181+
void setTerrainGenerator( TerrainGenerator *gen );
182+
TerrainGenerator *terrainGenerator() const { return mTerrainGenerator.get(); }
179183

180184
//
181185
// 3D renderers
@@ -189,10 +193,21 @@ class _3D_EXPORT Map3D
189193
QString skyboxFileBase;
190194
QString skyboxFileExtension;
191195

192-
bool showBoundingBoxes; //!< Whether to show bounding boxes of entities - useful for debugging
193-
bool drawTerrainTileInfo; //!< Whether to draw extra information about terrain tiles to the textures - useful for debugging
196+
void setShowTerrainBoundingBoxes( bool enabled );
197+
bool showTerrainBoundingBoxes() const { return mShowTerrainBoundingBoxes; }
198+
void setShowTerrainTilesInfo( bool enabled );
199+
bool showTerrainTilesInfo() const { return mShowTerrainTileInfo; }
200+
201+
signals:
202+
void layersChanged();
203+
void terrainGeneratorChanged();
204+
void showTerrainBoundingBoxesChanged();
205+
void showTerrainTilesInfoChanged();
194206

195207
private:
208+
std::unique_ptr<TerrainGenerator> mTerrainGenerator; //!< Implementation of the terrain generation
209+
bool mShowTerrainBoundingBoxes; //!< Whether to show bounding boxes of entities - useful for debugging
210+
bool mShowTerrainTileInfo; //!< Whether to draw extra information about terrain tiles to the textures - useful for debugging
196211
QList<QgsMapLayerRef> mLayers; //!< Layers to be rendered
197212
};
198213

src/3d/pointentity.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ PointEntity::PointEntity( const Map3D &map, const PointRenderer &settings, Qt3DC
5252
{
5353
QgsPoint *pt = static_cast<QgsPoint *>( g );
5454
// TODO: use Z coordinates if the point is 3D
55-
float h = map.terrainGenerator->heightAt( pt->x(), pt->y(), map ) * map.zExaggeration;
55+
float h = map.terrainGenerator()->heightAt( pt->x(), pt->y(), map ) * map.zExaggeration;
5656
positions.append( QVector3D( pt->x() - map.originX, h + settings.height, -( pt->y() - map.originY ) ) );
5757
//qDebug() << positions.last();
5858
}

src/3d/scene.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph, Qt3DRender::QRenderSettings *renderSettings, Qt3DRender::QCamera *camera, const QRect &viewportRect, Qt3DCore::QNode *parent )
2727
: Qt3DCore::QEntity( parent )
28+
, mMap( map )
29+
, mTerrain( nullptr )
2830
{
2931
defaultFrameGraph->setClearColor( map.backgroundColor );
3032

@@ -53,14 +55,9 @@ Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph,
5355
mCameraController->resetView();
5456

5557
// create terrain entity
56-
mTerrain = new Terrain( 3, map );
57-
//mTerrain->setEnabled(false);
58-
mTerrain->setParent( this );
59-
// add camera control's terrain picker as a component to be able to capture height where mouse was
60-
// pressed in order to correcly pan camera when draggin mouse
61-
mTerrain->addComponent( mCameraController->terrainPicker() );
62-
if ( map.showBoundingBoxes )
63-
mTerrain->setShowBoundingBoxes( true );
58+
59+
createTerrain();
60+
connect( &map, &Map3D::terrainGeneratorChanged, this, &Scene::createTerrain );
6461

6562
Q_FOREACH ( const PolygonRenderer &pr, map.polygonRenderers )
6663
{
@@ -103,8 +100,6 @@ Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph,
103100
connect( mCameraController, &CameraController::cameraChanged, this, &Scene::onCameraChanged );
104101
connect( mCameraController, &CameraController::viewportChanged, this, &Scene::onCameraChanged );
105102

106-
chunkEntities << mTerrain;
107-
108103
#if 0
109104
// experiments with loading of existing 3D models.
110105

@@ -182,3 +177,27 @@ void Scene::onFrameTriggered( float dt )
182177
}
183178
}
184179
}
180+
181+
void Scene::createTerrain()
182+
{
183+
if ( mTerrain )
184+
{
185+
chunkEntities.removeOne( mTerrain );
186+
187+
mTerrain->deleteLater();
188+
mTerrain = nullptr;
189+
}
190+
191+
mTerrain = new Terrain( 3, mMap );
192+
//mTerrain->setEnabled(false);
193+
mTerrain->setParent( this );
194+
195+
if ( mMap.showTerrainBoundingBoxes() )
196+
mTerrain->setShowBoundingBoxes( true );
197+
198+
mCameraController->addTerrainPicker( mTerrain->terrainPicker() );
199+
200+
chunkEntities << mTerrain;
201+
202+
onCameraChanged(); // force update of the new terrain
203+
}

src/3d/scene.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ class _3D_EXPORT Scene : public Qt3DCore::QEntity
4141
private slots:
4242
void onCameraChanged();
4343
void onFrameTriggered( float dt );
44+
void createTerrain();
4445

4546
private:
47+
const Map3D &mMap;
4648
//! Provides a way to have a synchronous function executed each frame
4749
Qt3DLogic::QFrameAction *mFrameAction;
4850
CameraController *mCameraController;

src/3d/terrain/demterraingenerator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class DemTerrainChunkLoader : public TerrainChunkLoader
5555
virtual void load() override
5656
{
5757
const Map3D &map = mTerrain->map3D();
58-
DemTerrainGenerator *generator = static_cast<DemTerrainGenerator *>( map.terrainGenerator.get() );
58+
DemTerrainGenerator *generator = static_cast<DemTerrainGenerator *>( map.terrainGenerator() );
5959

6060
heightMap = generator->heightMapGenerator()->renderSynchronously( node->x, node->y, node->z );
6161
resolution = generator->heightMapGenerator()->resolution();
@@ -65,7 +65,7 @@ class DemTerrainChunkLoader : public TerrainChunkLoader
6565

6666
virtual Qt3DCore::QEntity *createEntity( Qt3DCore::QEntity *parent )
6767
{
68-
Qt3DCore::QEntity *entity = new Qt3DCore::QEntity;
68+
TerrainChunkEntity *entity = new TerrainChunkEntity;
6969

7070
// create geometry renderer
7171

@@ -87,7 +87,7 @@ class DemTerrainChunkLoader : public TerrainChunkLoader
8787
_heightMapMinMax( heightMap, zMin, zMax );
8888

8989
const Map3D &map = mTerrain->map3D();
90-
QgsRectangle extent = map.terrainGenerator->terrainTilingScheme.tileToExtent( node->x, node->y, node->z ); //node->extent;
90+
QgsRectangle extent = map.terrainGenerator()->terrainTilingScheme.tileToExtent( node->x, node->y, node->z ); //node->extent;
9191
double x0 = extent.xMinimum() - map.originX;
9292
double y0 = extent.yMinimum() - map.originY;
9393
double side = extent.width();

src/3d/terrain/flatterraingenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void FlatTerrainChunkLoader::load()
3939

4040
Qt3DCore::QEntity *FlatTerrainChunkLoader::createEntity( Qt3DCore::QEntity *parent )
4141
{
42-
Qt3DCore::QEntity *entity = new Qt3DCore::QEntity;
42+
TerrainChunkEntity *entity = new TerrainChunkEntity;
4343

4444
// make geometry renderer
4545

src/3d/terrain/maptexturegenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ QImage MapTextureGenerator::renderSynchronously( const QgsRectangle &extent, con
6565
QgsMapRendererCustomPainterJob job( mapSettings, &p );
6666
job.renderSynchronously();
6767

68-
if ( !debugText.isEmpty() )
68+
if ( map.showTerrainTilesInfo() )
6969
{
7070
// extra tile information for debugging
7171
p.setPen( Qt::white );

0 commit comments

Comments
 (0)