30 #include <Qt3DCore/QTransform> 31 #include <Qt3DRender/QGeometryRenderer> 32 #include <Qt3DRender/QObjectPicker> 38 class TerrainMapUpdateJobFactory :
public QgsChunkQueueJobFactory
41 TerrainMapUpdateJobFactory( QgsTerrainTextureGenerator *textureGenerator )
42 : mTextureGenerator( textureGenerator )
46 QgsChunkQueueJob *createJob( QgsChunkNode *chunk )
override 48 return new TerrainMapUpdateJob( mTextureGenerator, chunk );
52 QgsTerrainTextureGenerator *mTextureGenerator =
nullptr;
59 QgsTerrainEntity::QgsTerrainEntity(
int maxLevel,
const Qgs3DMapSettings &map, Qt3DCore::QNode *parent )
60 : QgsChunkedEntity( map.terrainGenerator()->rootChunkBbox( map ),
61 map.terrainGenerator()->rootChunkError( map ),
62 map.maxTerrainScreenError(), maxLevel, map.terrainGenerator(), parent )
73 connectToLayersRepaintRequest();
77 mTextureGenerator =
new QgsTerrainTextureGenerator( map );
79 mUpdateJobFactory.reset(
new TerrainMapUpdateJobFactory( mTextureGenerator ) );
81 mTerrainPicker =
new Qt3DRender::QObjectPicker;
84 addComponent( mTerrainPicker );
87 QgsTerrainEntity::~QgsTerrainEntity()
93 delete mTextureGenerator;
94 delete mTerrainToMapTransform;
97 bool QgsTerrainEntity::rayIntersection(
const QgsRayCastingUtils::Ray3D &ray, QVector3D &intersectionPoint )
107 QList<QgsChunkNode *> lst = activeNodes();
108 for ( QgsChunkNode *n : lst )
110 if ( n->entity() && ( minDist < 0 || n->bbox().distanceFromPoint( ray.origin() ) < minDist ) && QgsRayCastingUtils::rayBoxIntersection( ray, n->bbox() ) )
112 Qt3DRender::QGeometryRenderer *rend = n->entity()->findChild<Qt3DRender::QGeometryRenderer *>();
113 Qt3DRender::QGeometry *geom = rend->geometry();
114 DemTerrainTileGeometry *demGeom =
static_cast<DemTerrainTileGeometry *
>( geom );
115 Qt3DCore::QTransform *tr = n->entity()->findChild<Qt3DCore::QTransform *>();
116 QVector3D nodeIntPoint;
117 if ( demGeom->rayIntersection( ray, tr->matrix(), nodeIntPoint ) )
119 float dist = ( ray.origin() - intersectionPoint ).length();
120 if ( minDist < 0 || dist < minDist )
123 intersectionPoint = nodeIntPoint;
132 void QgsTerrainEntity::onShowBoundingBoxesChanged()
134 setShowBoundingBoxes( mMap.showTerrainBoundingBoxes() );
138 void QgsTerrainEntity::invalidateMapImages()
142 updateNodes( mActiveNodes, mUpdateJobFactory.get() );
146 QList<QgsChunkNode *> inactiveNodes;
147 Q_FOREACH ( QgsChunkNode *node, mRootNode->descendants() )
149 if ( !node->entity() )
151 if ( mActiveNodes.contains( node ) )
153 inactiveNodes << node;
156 updateNodes( inactiveNodes, mUpdateJobFactory.get() );
158 setNeedsUpdate(
true );
161 void QgsTerrainEntity::onLayersChanged()
163 connectToLayersRepaintRequest();
164 invalidateMapImages();
167 void QgsTerrainEntity::connectToLayersRepaintRequest()
174 mLayers = mMap.layers();
186 TerrainMapUpdateJob::TerrainMapUpdateJob( QgsTerrainTextureGenerator *textureGenerator, QgsChunkNode *node )
187 : QgsChunkQueueJob( node )
188 , mTextureGenerator( textureGenerator )
190 QgsTerrainTileEntity *entity = qobject_cast<QgsTerrainTileEntity *>( node->entity() );
191 connect( textureGenerator, &QgsTerrainTextureGenerator::tileReady,
this, &TerrainMapUpdateJob::onTileReady );
192 mJobId = textureGenerator->render( entity->textureImage()->imageExtent(), entity->textureImage()->imageDebugText() );
195 void TerrainMapUpdateJob::cancel()
198 mTextureGenerator->cancelJob( mJobId );
202 void TerrainMapUpdateJob::onTileReady(
int jobId,
const QImage &image )
204 if ( mJobId == jobId )
206 QgsTerrainTileEntity *entity = qobject_cast<QgsTerrainTileEntity *>( mNode->entity() );
207 entity->textureImage()->setImage( image );
Base class for all map layer types.
void layersChanged()
Emitted when the list of map layers for terrain texture has changed.
3 Definition of the world
Terrain is built from raster layer with digital elevation model.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
QgsCoordinateReferenceSystem crs() const
Returns CRS of the terrain.
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.
QgsCoordinateReferenceSystem crs() const
Returns coordinate reference system used in the 3D scene.
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...