QGIS API Documentation  3.23.0-Master (eb871beae0)
quantizedmeshterraingenerator.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  quantizedmeshterraingenerator.cpp
3  ---------------------
4  begin : July 2017
5  copyright : (C) 2017 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
16 
17 #include "map3d.h"
18 #include "quantizedmeshgeometry.h"
19 #include "terrain.h"
20 
21 #include "qgsmapsettings.h"
22 
23 #include <Qt3DRender/QGeometryRenderer>
24 
25 #include "chunknode.h"
26 #include "terrainchunkloader.h"
27 
29 
31 class QuantizedMeshTerrainChunkLoader : public TerrainChunkLoader
32 {
33  public:
34  QuantizedMeshTerrainChunkLoader( Terrain *terrain, ChunkNode *node )
35  : TerrainChunkLoader( terrain, node )
36  , qmt( nullptr )
37  {
38  const Map3D &map = mTerrain->map3D();
39  QuantizedMeshTerrainGenerator *generator = static_cast<QuantizedMeshTerrainGenerator *>( map.terrainGenerator.get() );
40 
41  generator->quadTreeTileToBaseTile( node->x, node->y, node->z, tx, ty, tz );
42  tileRect = map.terrainGenerator->terrainTilingScheme.tileToExtent( tx, ty, tz );
43 
44  // we need map settings here for access to mapToPixel
45  mapSettings.setLayers( map.layers() );
46  mapSettings.setOutputSize( QSize( map.tileTextureSize, map.tileTextureSize ) );
47  mapSettings.setDestinationCrs( map.crs );
48  mapSettings.setExtent( mTerrain->terrainToMapTransform().transformBoundingBox( tileRect ) );
49  }
50 
51  void load() override
52  {
54  qmt = QuantizedMeshGeometry::readTile( tx, ty, tz, tileRect );
55  Q_ASSERT( qmt );
56 
57  loadTexture();
58  }
59 
60  virtual Qt3DCore::QEntity *createEntity( Qt3DCore::QEntity *parent )
61  {
62  Qt3DCore::QEntity *entity = new Qt3DCore::QEntity;
63 
64  // create geometry renderer
65 
66  Qt3DRender::QGeometryRenderer *mesh = new Qt3DRender::QGeometryRenderer;
67  mesh->setGeometry( new QuantizedMeshGeometry( qmt, mTerrain->map3D(), mapSettings.mapToPixel(), mTerrain->terrainToMapTransform(), mesh ) );
68  entity->addComponent( mesh );
69 
70  // create material
71 
72  createTextureComponent( entity );
73 
74  // create transform
75 
76  Qt3DCore::QTransform *transform = nullptr;
77  transform = new Qt3DCore::QTransform();
78  entity->addComponent( transform );
79 
80  const Map3D &map = mTerrain->map3D();
81 
82  transform->setScale3D( QVector3D( 1.f, map.zExaggeration, 1.f ) );
83 
84  QgsRectangle mapExtent = mapSettings.extent();
85  float x0 = mapExtent.xMinimum() - map.originX;
86  float y0 = mapExtent.yMinimum() - map.originY;
87  float x1 = mapExtent.xMaximum() - map.originX;
88  float y1 = mapExtent.yMaximum() - map.originY;
89  float z0 = qmt->header.MinimumHeight, z1 = qmt->header.MaximumHeight;
90 
91  node->setExactBbox( AABB( x0, z0 * map.zExaggeration, -y0, x1, z1 * map.zExaggeration, -y1 ) );
92  //epsilon = mapExtent.width() / map.tileTextureSize;
93 
94  entity->setEnabled( false );
95  entity->setParent( parent );
96  return entity;
97  }
98 
99  protected:
100  QuantizedMeshTile *qmt = nullptr;
101  QgsMapSettings mapSettings;
102  int tx, ty, tz;
103  QgsRectangle tileRect;
104 };
105 
107 
108 
109 // ---------------
110 
111 
112 
114 {
116  terrainTilingScheme = TilingScheme( QgsRectangle( -180, -90, 0, 90 ), QgsCoordinateReferenceSystem( "EPSG:4326" ) );
117 }
118 
120 {
121  terrainTilingScheme.extentToTile( extentInTerrainCrs, terrainBaseX, terrainBaseY, terrainBaseZ );
122 }
123 
124 void QuantizedMeshTerrainGenerator::quadTreeTileToBaseTile( int x, int y, int z, int &tx, int &ty, int &tz ) const
125 {
126  // true tile coords (using the base tile pos)
127  int multiplier = pow( 2, z );
128  tx = terrainBaseX * multiplier + x;
129  ty = terrainBaseY * multiplier + y;
130  tz = terrainBaseZ + z;
131 }
132 
133 TerrainGenerator::Type QuantizedMeshTerrainGenerator::type() const
134 {
135  return TerrainGenerator::QuantizedMesh;
136 }
137 
139 {
140  return terrainTilingScheme.tileToExtent( terrainBaseX, terrainBaseY, terrainBaseZ );
141 }
142 
143 void QuantizedMeshTerrainGenerator::writeXml( QDomElement &elem ) const
144 {
145  elem.setAttribute( "base-x", terrainBaseX );
146  elem.setAttribute( "base-y", terrainBaseY );
147  elem.setAttribute( "base-z", terrainBaseZ );
148 }
149 
150 void QuantizedMeshTerrainGenerator::readXml( const QDomElement &elem )
151 {
152  terrainBaseX = elem.attribute( "base-x" ).toInt();
153  terrainBaseY = elem.attribute( "base-y" ).toInt();
154  terrainBaseZ = elem.attribute( "base-z" ).toInt();
155  // TODO: update tiling scheme
156 }
157 
158 ChunkLoader *QuantizedMeshTerrainGenerator::createChunkLoader( ChunkNode *node ) const
159 {
160  return new QuantizedMeshTerrainChunkLoader( mTerrain, node );
161 }
This class represents a coordinate reference system (CRS).
The QgsMapSettings class contains configuration for rendering of the map.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
QgsTerrainEntity * mTerrain
static void downloadTileIfMissing(int tx, int ty, int tz)
Downloads a tile to to a file in the local disk cache.
static QuantizedMeshTile * readTile(int tx, int ty, int tz, const QgsRectangle &extent)
Reads a tile from a file in the local disk cache.
QgsTerrainGenerator::Type type() const override
What texture generator implementation is this.
void quadTreeTileToBaseTile(int x, int y, int z, int &tx, int &ty, int &tz) const
Converts tile coordinates (x,y,z) in our quadtree to tile coordinates of quantized mesh tree.
int terrainBaseZ
Coordinates of the base tile.
QgsChunkLoader * createChunkLoader(QgsChunkNode *node) const override SIP_FACTORY
void readXml(const QDomElement &elem) override
Read terrain generator's configuration from XML.
void setBaseTileFromExtent(const QgsRectangle &extentInTerrainCrs)
Determines base tile from map extent.
void writeXml(QDomElement &elem) const override
Write terrain generator's configuration to XML.
QgsRectangle extent() const override
extent of the terrain in terrain's CRS