QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsterraintileloader_p.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsterraintileloader_p.cpp
3  --------------------------------------
4  Date : 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  ***************************************************************************/
15 
16 #include "qgsterraintileloader_p.h"
17 
18 #include "qgs3dmapsettings.h"
19 #include "qgschunknode_p.h"
20 #include "qgsterrainentity_p.h"
21 #include "qgsterraingenerator.h"
24 #include "qgsterraintileentity_p.h"
25 #include "qgscoordinatetransform.h"
26 
27 #include <Qt3DRender/QTexture>
28 #include <Qt3DRender/QTechnique>
29 #include <Qt3DRender/QCullFace>
30 
31 #include <Qt3DExtras/QTextureMaterial>
32 #include <Qt3DExtras/QDiffuseSpecularMaterial>
33 #include <Qt3DExtras/QPhongMaterial>
34 
36 
38 
39 QgsTerrainTileLoader::QgsTerrainTileLoader( QgsTerrainEntity *terrain, QgsChunkNode *node )
40  : QgsChunkLoader( node )
41  , mTerrain( terrain )
42 {
43  const Qgs3DMapSettings &map = mTerrain->map3D();
44 #if 0
45  int tx, ty, tz;
46  if ( map.terrainGenerator->type() == TerrainGenerator::QuantizedMesh )
47  {
48  // TODO: sort out - should not be here
49  QuantizedMeshTerrainGenerator *generator = static_cast<QuantizedMeshTerrainGenerator *>( map.terrainGenerator.get() );
50  generator->quadTreeTileToBaseTile( node->x, node->y, node->z, tx, ty, tz );
51  }
52 #endif
53 
54  const QgsChunkNodeId nodeId = node->tileId();
55  const QgsRectangle extentTerrainCrs = map.terrainGenerator()->tilingScheme().tileToExtent( nodeId );
56  QgsCoordinateTransform transform = terrain->terrainToMapTransform();
57  transform.setBallparkTransformsAreAppropriate( true );
58  mExtentMapCrs = transform.transformBoundingBox( extentTerrainCrs );
59  mTileDebugText = nodeId.text();
60 }
61 
62 void QgsTerrainTileLoader::loadTexture()
63 {
64  connect( mTerrain->textureGenerator(), &QgsTerrainTextureGenerator::tileReady, this, &QgsTerrainTileLoader::onImageReady );
65  mTextureJobId = mTerrain->textureGenerator()->render( mExtentMapCrs, mNode->tileId(), mTileDebugText );
66 }
67 
68 void QgsTerrainTileLoader::createTextureComponent( QgsTerrainTileEntity *entity, bool isShadingEnabled, const QgsPhongMaterialSettings &shadingMaterial, bool useTexture )
69 {
70  Qt3DRender::QTexture2D *texture = useTexture || !isShadingEnabled ? createTexture( entity ) : nullptr;
71 
72  Qt3DRender::QMaterial *material = nullptr;
73  if ( texture )
74  {
75  if ( isShadingEnabled )
76  {
77  Qt3DExtras::QDiffuseSpecularMaterial *diffuseMapMaterial = new Qt3DExtras::QDiffuseSpecularMaterial;
78  diffuseMapMaterial->setDiffuse( QVariant::fromValue( texture ) );
79  diffuseMapMaterial->setAmbient( shadingMaterial.ambient() );
80  diffuseMapMaterial->setSpecular( shadingMaterial.specular() );
81  diffuseMapMaterial->setShininess( shadingMaterial.shininess() );
82  material = diffuseMapMaterial;
83  }
84  else
85  {
86  Qt3DExtras::QTextureMaterial *textureMaterial = new Qt3DExtras::QTextureMaterial;
87  textureMaterial->setTexture( texture );
88  material = textureMaterial;
89  }
90  }
91  else
92  {
93  Qt3DExtras::QPhongMaterial *phongMaterial = new Qt3DExtras::QPhongMaterial;
94  phongMaterial->setDiffuse( shadingMaterial.diffuse() );
95  phongMaterial->setAmbient( shadingMaterial.ambient() );
96  phongMaterial->setSpecular( shadingMaterial.specular() );
97  phongMaterial->setShininess( shadingMaterial.shininess() );
98  material = phongMaterial;
99  }
100 
101  // no backface culling on terrain, to allow terrain to be viewed from underground
102  const QVector<Qt3DRender::QTechnique *> techniques = material->effect()->techniques();
103  for ( Qt3DRender::QTechnique *techique : techniques )
104  {
105  const QVector<Qt3DRender::QRenderPass *> passes = techique->renderPasses();
106  for ( Qt3DRender::QRenderPass *pass : passes )
107  {
108  Qt3DRender::QCullFace *cullFace = new Qt3DRender::QCullFace;
109  cullFace->setMode( Qt3DRender::QCullFace::NoCulling );
110  pass->addRenderState( cullFace );
111  }
112  }
113 
114  entity->addComponent( material ); // takes ownership if the component has no parent
115 }
116 
117 Qt3DRender::QTexture2D *QgsTerrainTileLoader::createTexture( QgsTerrainTileEntity *entity )
118 {
119  Qt3DRender::QTexture2D *texture = new Qt3DRender::QTexture2D;
120  QgsTerrainTextureImage *textureImage = new QgsTerrainTextureImage( mTextureImage, mExtentMapCrs, mTileDebugText );
121  texture->addTextureImage( textureImage );//texture take the ownership of textureImage if has no parant
122  texture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
123  texture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
124 
125  entity->setTextureImage( textureImage );
126 
127  return texture;
128 }
129 
130 void QgsTerrainTileLoader::onImageReady( int jobId, const QImage &image )
131 {
132  if ( mTextureJobId == jobId )
133  {
134  mTextureImage = image;
135  mTextureJobId = -1;
136  emit finished(); // TODO: this should be left for derived class!
137  }
138 }
139 
QgsPhongMaterialSettings::ambient
QColor ambient() const
Returns ambient color component.
Definition: qgsphongmaterialsettings.h:68
QgsPhongMaterialSettings::diffuse
QColor diffuse() const
Returns diffuse color component.
Definition: qgsphongmaterialsettings.h:70
QgsPhongMaterialSettings::specular
QColor specular() const
Returns specular color component.
Definition: qgsphongmaterialsettings.h:72
QgsTerrainGenerator::type
virtual Type type() const =0
What texture generator implementation is this.
QgsCoordinateTransform::transformBoundingBox
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
Definition: qgscoordinatetransform.cpp:560
quantizedmeshterraingenerator.h
qgschunknode_p.h
qgsterraintileentity_p.h
QuantizedMeshTerrainGenerator::quadTreeTileToBaseTile
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.
Definition: quantizedmeshterraingenerator.cpp:124
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsPhongMaterialSettings
Basic shading material used for rendering based on the Phong shading model with three color component...
Definition: qgsphongmaterialsettings.h:44
QgsTerrainGenerator::mTerrain
QgsTerrainEntity * mTerrain
Definition: qgsterraingenerator.h:122
QgsCoordinateTransform::setBallparkTransformsAreAppropriate
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
Definition: qgscoordinatetransform.cpp:939
qgsterraingenerator.h
qgsterraintextureimage_p.h
qgscoordinatetransform.h
Qgs3DMapSettings
Definition of the world.
Definition: qgs3dmapsettings.h:57
qgsterraintileloader_p.h
QgsTilingScheme::tileToExtent
QgsRectangle tileToExtent(int x, int y, int z) const
Returns map coordinates of the extent of a tile.
Definition: qgstilingscheme.cpp:43
QuantizedMeshTerrainGenerator
Terrain generator using downloaded terrain tiles using quantized mesh specification.
Definition: quantizedmeshterraingenerator.h:26
Qgs3DMapSettings::terrainGenerator
QgsTerrainGenerator * terrainGenerator() const
Returns the terrain generator.
Definition: qgs3dmapsettings.h:277
qgsterrainentity_p.h
qgs3dmapsettings.h
QgsPhongMaterialSettings::shininess
float shininess() const
Returns shininess of the surface.
Definition: qgsphongmaterialsettings.h:74
qgsterraintexturegenerator_p.h
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
QgsTerrainGenerator::tilingScheme
const QgsTilingScheme & tilingScheme() const
Returns tiling scheme of the terrain.
Definition: qgsterraingenerator.h:103