QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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
17
18#include "qgs3dmapsettings.h"
19#include "qgschunknode_p.h"
20#include "qgsterrainentity_p.h"
21#include "qgsterraingenerator.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
39QgsTerrainTileLoader::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
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();
58 mExtentMapCrs = transform.transformBoundingBox( extentTerrainCrs );
59 mTileDebugText = nodeId.text();
60}
61
62void QgsTerrainTileLoader::loadTexture()
63{
64 connect( mTerrain->textureGenerator(), &QgsTerrainTextureGenerator::tileReady, this, &QgsTerrainTileLoader::onImageReady );
65 mTextureJobId = mTerrain->textureGenerator()->render( mExtentMapCrs, mNode->tileId(), mTileDebugText );
66}
67
68void 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
117Qt3DRender::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
130void 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
QgsTerrainGenerator * terrainGenerator() const
Returns the terrain generator.
Class for doing transforms between two map coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
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.
QColor diffuse() const
Returns diffuse color component.
QColor specular() const
Returns specular color component.
QColor ambient() const
Returns ambient color component.
float shininess() const
Returns shininess of the surface.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
virtual Type type() const =0
What texture generator implementation is this.
const QgsTilingScheme & tilingScheme() const
Returns tiling scheme of the terrain.
QgsRectangle tileToExtent(int x, int y, int z) const
Returns map coordinates of the extent of a tile.
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.