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