QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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 
26 #include <Qt3DRender/QTexture>
27 
28 #include <Qt3DExtras/QTextureMaterial>
29 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
30 #include <Qt3DExtras/QDiffuseMapMaterial>
31 #else
32 #include <Qt3DExtras/QDiffuseSpecularMaterial>
33 #endif
34 #include <Qt3DExtras/QPhongMaterial>
35 
37 
39 
40 QgsTerrainTileLoader::QgsTerrainTileLoader( QgsTerrainEntity *terrain, QgsChunkNode *node )
41  : QgsChunkLoader( node )
42  , mTerrain( terrain )
43 {
44  const Qgs3DMapSettings &map = mTerrain->map3D();
45 #if 0
46  int tx, ty, tz;
47  if ( map.terrainGenerator->type() == TerrainGenerator::QuantizedMesh )
48  {
49  // TODO: sort out - should not be here
50  QuantizedMeshTerrainGenerator *generator = static_cast<QuantizedMeshTerrainGenerator *>( map.terrainGenerator.get() );
51  generator->quadTreeTileToBaseTile( node->x, node->y, node->z, tx, ty, tz );
52  }
53 #endif
54 
55  QgsChunkNodeId nodeId = node->tileId();
56  QgsRectangle extentTerrainCrs = map.terrainGenerator()->tilingScheme().tileToExtent( nodeId );
57  mExtentMapCrs = terrain->terrainToMapTransform().transformBoundingBox( extentTerrainCrs );
58  mTileDebugText = nodeId.text();
59 }
60 
61 void QgsTerrainTileLoader::loadTexture()
62 {
63  connect( mTerrain->textureGenerator(), &QgsTerrainTextureGenerator::tileReady, this, &QgsTerrainTileLoader::onImageReady );
64  mTextureJobId = mTerrain->textureGenerator()->render( mExtentMapCrs, mNode->tileId(), mTileDebugText );
65 }
66 
67 void QgsTerrainTileLoader::createTextureComponent( QgsTerrainTileEntity *entity, bool isShadingEnabled, const QgsPhongMaterialSettings &shadingMaterial, bool useTexture )
68 {
69  Qt3DRender::QTexture2D *texture = useTexture || !isShadingEnabled ? createTexture( entity ) : nullptr;
70 
71  Qt3DRender::QMaterial *material = nullptr;
72  if ( texture )
73  {
74  if ( isShadingEnabled )
75  {
76 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
77  Qt3DExtras::QDiffuseMapMaterial *diffuseMapMaterial;
78  diffuseMapMaterial = new Qt3DExtras::QDiffuseMapMaterial;
79  diffuseMapMaterial->setDiffuse( texture );
80 #else
81  Qt3DExtras::QDiffuseSpecularMaterial *diffuseMapMaterial = new Qt3DExtras::QDiffuseSpecularMaterial;
82  diffuseMapMaterial->setDiffuse( QVariant::fromValue( texture ) );
83  material = diffuseMapMaterial;
84 #endif
85  diffuseMapMaterial->setAmbient( shadingMaterial.ambient() );
86  diffuseMapMaterial->setSpecular( shadingMaterial.specular() );
87  diffuseMapMaterial->setShininess( shadingMaterial.shininess() );
88  material = diffuseMapMaterial;
89  }
90  else
91  {
92  Qt3DExtras::QTextureMaterial *textureMaterial = new Qt3DExtras::QTextureMaterial;
93  textureMaterial->setTexture( texture );
94  material = textureMaterial;
95  }
96  }
97  else
98  {
99  Qt3DExtras::QPhongMaterial *phongMaterial = new Qt3DExtras::QPhongMaterial;
100  phongMaterial->setDiffuse( shadingMaterial.diffuse() );
101  phongMaterial->setAmbient( shadingMaterial.ambient() );
102  phongMaterial->setSpecular( shadingMaterial.specular() );
103  phongMaterial->setShininess( shadingMaterial.shininess() );
104  material = phongMaterial;
105  }
106 
107  entity->addComponent( material ); // takes ownership if the component has no parent
108 }
109 
110 Qt3DRender::QTexture2D *QgsTerrainTileLoader::createTexture( QgsTerrainTileEntity *entity )
111 {
112  Qt3DRender::QTexture2D *texture = new Qt3DRender::QTexture2D;
113  QgsTerrainTextureImage *textureImage = new QgsTerrainTextureImage( mTextureImage, mExtentMapCrs, mTileDebugText );
114  texture->addTextureImage( textureImage );//texture take the ownership of textureImage if has no parant
115  texture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
116  texture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
117 
118  entity->setTextureImage( textureImage );
119 
120  return texture;
121 }
122 
123 void QgsTerrainTileLoader::onImageReady( int jobId, const QImage &image )
124 {
125  if ( mTextureJobId == jobId )
126  {
127  mTextureImage = image;
128  mTextureJobId = -1;
129  emit finished(); // TODO: this should be left for derived class!
130  }
131 }
132 
QgsTerrainGenerator * terrainGenerator() const
Returns terrain generator. It takes care of producing terrain tiles from the input data.
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
const QgsTilingScheme & tilingScheme() const
Returns tiling scheme of the terrain.
virtual Type type() const =0
What texture generator implementation is this.
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.