31 #include <Qt3DCore/QTransform> 32 #include <Qt3DRender/QGeometryRenderer> 33 #include <Qt3DRender/QObjectPicker> 39 class TerrainMapUpdateJobFactory :
public QgsChunkQueueJobFactory
42 TerrainMapUpdateJobFactory( QgsTerrainTextureGenerator *textureGenerator )
43 : mTextureGenerator( textureGenerator )
47 QgsChunkQueueJob *createJob( QgsChunkNode *chunk )
override 49 return new TerrainMapUpdateJob( mTextureGenerator, chunk );
53 QgsTerrainTextureGenerator *mTextureGenerator =
nullptr;
60 QgsTerrainEntity::QgsTerrainEntity(
int maxLevel,
const Qgs3DMapSettings &map, Qt3DCore::QNode *parent )
61 : QgsChunkedEntity( map.terrainGenerator()->rootChunkBbox( map ),
62 map.terrainGenerator()->rootChunkError( map ),
63 map.maxTerrainScreenError(), maxLevel, map.terrainGenerator(), parent )
75 connectToLayersRepaintRequest();
79 mTextureGenerator =
new QgsTerrainTextureGenerator( map );
81 mUpdateJobFactory.reset(
new TerrainMapUpdateJobFactory( mTextureGenerator ) );
83 mTerrainPicker =
new Qt3DRender::QObjectPicker;
86 addComponent( mTerrainPicker );
89 QgsTerrainEntity::~QgsTerrainEntity()
94 delete mTextureGenerator;
95 delete mTerrainToMapTransform;
98 bool QgsTerrainEntity::rayIntersection(
const QgsRayCastingUtils::Ray3D &ray, QVector3D &intersectionPoint )
108 QList<QgsChunkNode *> lst = activeNodes();
109 for ( QgsChunkNode *n : lst )
111 if ( n->entity() && ( minDist < 0 || n->bbox().distanceFromPoint( ray.origin() ) < minDist ) && QgsRayCastingUtils::rayBoxIntersection( ray, n->bbox() ) )
113 Qt3DRender::QGeometryRenderer *rend = n->entity()->findChild<Qt3DRender::QGeometryRenderer *>();
114 Qt3DRender::QGeometry *geom = rend->geometry();
115 DemTerrainTileGeometry *demGeom =
static_cast<DemTerrainTileGeometry *
>( geom );
116 Qt3DCore::QTransform *tr = n->entity()->findChild<Qt3DCore::QTransform *>();
117 QVector3D nodeIntPoint;
118 if ( demGeom->rayIntersection( ray, tr->matrix(), nodeIntPoint ) )
120 float dist = ( ray.origin() - intersectionPoint ).length();
121 if ( minDist < 0 || dist < minDist )
124 intersectionPoint = nodeIntPoint;
133 void QgsTerrainEntity::onShowBoundingBoxesChanged()
135 setShowBoundingBoxes( mMap.showTerrainBoundingBoxes() );
139 void QgsTerrainEntity::invalidateMapImages()
141 QgsEventTracing::addEvent( QgsEventTracing::Instant, QStringLiteral(
"3D" ), QStringLiteral(
"Invalidate textures" ) );
145 updateNodes( mActiveNodes, mUpdateJobFactory.get() );
149 QList<QgsChunkNode *> inactiveNodes;
150 Q_FOREACH ( QgsChunkNode *node, mRootNode->descendants() )
152 if ( !node->entity() )
154 if ( mActiveNodes.contains( node ) )
156 inactiveNodes << node;
159 updateNodes( inactiveNodes, mUpdateJobFactory.get() );
161 setNeedsUpdate(
true );
164 void QgsTerrainEntity::onLayersChanged()
166 connectToLayersRepaintRequest();
167 invalidateMapImages();
170 void QgsTerrainEntity::connectToLayersRepaintRequest()
177 mLayers = mMap.layers();
189 TerrainMapUpdateJob::TerrainMapUpdateJob( QgsTerrainTextureGenerator *textureGenerator, QgsChunkNode *node )
190 : QgsChunkQueueJob( node )
191 , mTextureGenerator( textureGenerator )
193 QgsTerrainTileEntity *entity = qobject_cast<QgsTerrainTileEntity *>( node->entity() );
194 connect( textureGenerator, &QgsTerrainTextureGenerator::tileReady,
this, &TerrainMapUpdateJob::onTileReady );
195 mJobId = textureGenerator->render( entity->textureImage()->imageExtent(), node->tileId(), entity->textureImage()->imageDebugText() );
198 void TerrainMapUpdateJob::cancel()
201 mTextureGenerator->cancelJob( mJobId );
205 void TerrainMapUpdateJob::onTileReady(
int jobId,
const QImage &image )
207 if ( mJobId == jobId )
209 QgsTerrainTileEntity *entity = qobject_cast<QgsTerrainTileEntity *>( mNode->entity() );
210 entity->textureImage()->setImage( image );
Base class for all map layer types.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used in the 3D scene.
void layersChanged()
Emitted when the list of map layers for terrain texture has changed.
QgsCoordinateReferenceSystem crs() const
Returns CRS of the terrain.
3 Definition of the world
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Terrain is built from raster layer with digital elevation model.
void terrainMapThemeChanged()
Emitted when terrain's map theme has changed.
void showTerrainBoundingBoxesChanged()
Emitted when the flag whether terrain's bounding boxes are shown has changed.
void repaintRequested(bool deferredUpdate=false)
By emitting this signal the layer tells that either appearance or content have been changed and any v...
void showTerrainTilesInfoChanged()
Emitted when the flag whether terrain's tile info is shown has changed.
void showLabelsChanged()
Emitted when the flag whether labels are displayed on terrain tiles has changed.
void setTerrain(QgsTerrainEntity *t)
Sets terrain entity for the generator (does not transfer ownership)
void backgroundColorChanged()
Emitted when the background color has changed.
QgsTerrainGenerator * terrainGenerator() const
Returns terrain generator. It takes care of producing terrain tiles from the input data...