QGIS API Documentation  3.24.2-Tisler (13c1a02865)
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  QgsCoordinateTransform transform = terrain->terrainToMapTransform();
55  transform.setBallparkTransformsAreAppropriate( true );
56  mExtentMapCrs = transform.transformBoundingBox( extentTerrainCrs );
57  mTileDebugText = nodeId.text();
58 }
59 
60 void QgsTerrainTileLoader::loadTexture()
61 {
62  connect( mTerrain->textureGenerator(), &QgsTerrainTextureGenerator::tileReady, this, &QgsTerrainTileLoader::onImageReady );
63  mTextureJobId = mTerrain->textureGenerator()->render( mExtentMapCrs, mNode->tileId(), mTileDebugText );
64 }
65 
66 void QgsTerrainTileLoader::createTextureComponent( QgsTerrainTileEntity *entity, bool isShadingEnabled, const QgsPhongMaterialSettings &shadingMaterial, bool useTexture )
67 {
68  Qt3DRender::QTexture2D *texture = useTexture || !isShadingEnabled ? createTexture( entity ) : nullptr;
69 
70  Qt3DRender::QMaterial *material = nullptr;
71  if ( texture )
72  {
73  if ( isShadingEnabled )
74  {
75  Qt3DExtras::QDiffuseSpecularMaterial *diffuseMapMaterial = new Qt3DExtras::QDiffuseSpecularMaterial;
76  diffuseMapMaterial->setDiffuse( QVariant::fromValue( texture ) );
77  material = diffuseMapMaterial;
78  diffuseMapMaterial->setAmbient( shadingMaterial.ambient() );
79  diffuseMapMaterial->setSpecular( shadingMaterial.specular() );
80  diffuseMapMaterial->setShininess( shadingMaterial.shininess() );
81  material = diffuseMapMaterial;
82  }
83  else
84  {
85  Qt3DExtras::QTextureMaterial *textureMaterial = new Qt3DExtras::QTextureMaterial;
86  textureMaterial->setTexture( texture );
87  material = textureMaterial;
88  }
89  }
90  else
91  {
92  Qt3DExtras::QPhongMaterial *phongMaterial = new Qt3DExtras::QPhongMaterial;
93  phongMaterial->setDiffuse( shadingMaterial.diffuse() );
94  phongMaterial->setAmbient( shadingMaterial.ambient() );
95  phongMaterial->setSpecular( shadingMaterial.specular() );
96  phongMaterial->setShininess( shadingMaterial.shininess() );
97  material = phongMaterial;
98  }
99 
100  entity->addComponent( material ); // takes ownership if the component has no parent
101 }
102 
103 Qt3DRender::QTexture2D *QgsTerrainTileLoader::createTexture( QgsTerrainTileEntity *entity )
104 {
105  Qt3DRender::QTexture2D *texture = new Qt3DRender::QTexture2D;
106  QgsTerrainTextureImage *textureImage = new QgsTerrainTextureImage( mTextureImage, mExtentMapCrs, mTileDebugText );
107  texture->addTextureImage( textureImage );//texture take the ownership of textureImage if has no parant
108  texture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
109  texture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
110 
111  entity->setTextureImage( textureImage );
112 
113  return texture;
114 }
115 
116 void QgsTerrainTileLoader::onImageReady( int jobId, const QImage &image )
117 {
118  if ( mTextureJobId == jobId )
119  {
120  mTextureImage = image;
121  mTextureJobId = -1;
122  emit finished(); // TODO: this should be left for derived class!
123  }
124 }
125 
QgsTerrainGenerator * terrainGenerator() const
Returns terrain generator. It takes care of producing terrain tiles from the input data.
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
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.