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