Skip to content
Permalink
Browse files

Update layer 3D entities when terrain generator or scale change

  • Loading branch information
wonder-sk committed Jul 28, 2017
1 parent 2e03f5d commit 04b00aad6ea86a47b014ce1829642c4f22ed3d88
@@ -17,10 +17,10 @@ Map3D::Map3D()
, originY( 0 )
, originZ( 0 )
, backgroundColor( Qt::black )
, zExaggeration( 1 )
, tileTextureSize( 512 )
, maxTerrainError( 3.f )
, skybox( false )
, mTerrainVerticalScale( 1 )
, mShowTerrainBoundingBoxes( false )
, mShowTerrainTileInfo( false )
{
@@ -33,12 +33,12 @@ Map3D::Map3D( const Map3D &other )
, originZ( other.originZ )
, crs( other.crs )
, backgroundColor( other.backgroundColor )
, zExaggeration( other.zExaggeration )
, tileTextureSize( other.tileTextureSize )
, maxTerrainError( other.maxTerrainError )
, skybox( other.skybox )
, skyboxFileBase( other.skyboxFileBase )
, skyboxFileExtension( other.skyboxFileExtension )
, mTerrainVerticalScale( other.mTerrainVerticalScale )
, mTerrainGenerator( other.mTerrainGenerator ? other.mTerrainGenerator->clone() : nullptr )
, mShowTerrainBoundingBoxes( other.mShowTerrainBoundingBoxes )
, mShowTerrainTileInfo( other.mShowTerrainTileInfo )
@@ -68,7 +68,7 @@ void Map3D::readXml( const QDomElement &elem, const QgsReadWriteContext &context
crs.readXml( elemCrs );

QDomElement elemTerrain = elem.firstChildElement( "terrain" );
zExaggeration = elemTerrain.attribute( "exaggeration", "1" ).toFloat();
mTerrainVerticalScale = elemTerrain.attribute( "exaggeration", "1" ).toFloat();
tileTextureSize = elemTerrain.attribute( "texture-size", "512" ).toInt();
maxTerrainError = elemTerrain.attribute( "max-terrain-error", "3" ).toFloat();
QDomElement elemMapLayers = elemTerrain.firstChildElement( "layers" );
@@ -149,7 +149,7 @@ QDomElement Map3D::writeXml( QDomDocument &doc, const QgsReadWriteContext &conte
elem.appendChild( elemCrs );

QDomElement elemTerrain = doc.createElement( "terrain" );
elemTerrain.setAttribute( "exaggeration", QString::number( zExaggeration ) );
elemTerrain.setAttribute( "exaggeration", QString::number( mTerrainVerticalScale ) );
elemTerrain.setAttribute( "texture-size", tileTextureSize );
elemTerrain.setAttribute( "max-terrain-error", QString::number( maxTerrainError ) );
QDomElement elemMapLayers = doc.createElement( "layers" );
@@ -208,6 +208,20 @@ void Map3D::resolveReferences( const QgsProject &project )
}
}

void Map3D::setTerrainVerticalScale( double zScale )
{
if ( zScale == mTerrainVerticalScale )
return;

mTerrainVerticalScale = zScale;
emit terrainVerticalScaleChanged();
}

double Map3D::terrainVerticalScale() const
{
return mTerrainVerticalScale;
}

void Map3D::setLayers( const QList<QgsMapLayer *> &layers )
{
QList<QgsMapLayerRef> lst;
@@ -45,7 +45,8 @@ class _3D_EXPORT Map3D : public QObject
// terrain related config
//

double zExaggeration; //!< Multiplier of terrain heights to make the terrain shape more pronounced
void setTerrainVerticalScale( double zScale );
double terrainVerticalScale() const;

void setLayers( const QList<QgsMapLayer *> &layers );
QList<QgsMapLayer *> layers() const;
@@ -75,10 +76,12 @@ class _3D_EXPORT Map3D : public QObject
signals:
void layersChanged();
void terrainGeneratorChanged();
void terrainVerticalScaleChanged();
void showTerrainBoundingBoxesChanged();
void showTerrainTilesInfoChanged();

private:
double mTerrainVerticalScale; //!< Multiplier of terrain heights to make the terrain shape more pronounced
std::unique_ptr<TerrainGenerator> mTerrainGenerator; //!< Implementation of the terrain generation
bool mShowTerrainBoundingBoxes; //!< Whether to show bounding boxes of entities - useful for debugging
bool mShowTerrainTileInfo; //!< Whether to draw extra information about terrain tiles to the textures - useful for debugging
@@ -53,7 +53,7 @@ PointEntity::PointEntity( const Map3D &map, QgsVectorLayer *layer, const Point3D
{
QgsPoint *pt = static_cast<QgsPoint *>( g );
// TODO: use Z coordinates if the point is 3D
float h = map.terrainGenerator()->heightAt( pt->x(), pt->y(), map ) * map.zExaggeration;
float h = map.terrainGenerator()->heightAt( pt->x(), pt->y(), map ) * map.terrainVerticalScale();
positions.append( QVector3D( pt->x() - map.originX, h, -( pt->y() - map.originY ) ) );
//qDebug() << positions.last();
}
@@ -56,6 +56,7 @@ Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph,

createTerrain();
connect( &map, &Map3D::terrainGeneratorChanged, this, &Scene::createTerrain );
connect( &map, &Map3D::terrainVerticalScaleChanged, this, &Scene::createTerrain );

// create entities of renderers

@@ -65,14 +66,6 @@ Scene::Scene( const Map3D &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph,
p->setParent( this );
}

// create entities of renderers of layers

Q_FOREACH ( QgsMapLayer *layer, map.layers() )
{
addLayerEntity( layer );
// TODO: connect( layer, &QgsMapLayer::willBeDeleted, this, &Scene::onLayerWillBeDeleted );
}

// listen to changes of layers in order to add/remove 3D renderer entities
connect( &map, &Map3D::layersChanged, this, &Scene::onLayersChanged );

@@ -200,6 +193,16 @@ void Scene::createTerrain()
chunkEntities << mTerrain;

onCameraChanged(); // force update of the new terrain

// make sure that renderers for layers are re-created as well
Q_FOREACH ( QgsMapLayer *layer, mMap.layers() )
{
// remove old entity - if any
removeLayerEntity( layer );

// add new entity - if any 3D renderer
addLayerEntity( layer );
}
}

void Scene::onLayerRenderer3DChanged()
@@ -93,10 +93,10 @@ class DemTerrainChunkLoader : public TerrainChunkLoader
double side = extent.width();
double half = side / 2;

transform->setScale3D( QVector3D( side, map.zExaggeration, side ) );
transform->setScale3D( QVector3D( side, map.terrainVerticalScale(), side ) );
transform->setTranslation( QVector3D( x0 + half, 0, - ( y0 + half ) ) );

node->setExactBbox( AABB( x0, zMin * map.zExaggeration, -y0, x0 + side, zMax * map.zExaggeration, -( y0 + side ) ) );
node->setExactBbox( AABB( x0, zMin * map.terrainVerticalScale(), -y0, x0 + side, zMax * map.terrainVerticalScale(), -( y0 + side ) ) );

entity->setEnabled( false );
entity->setParent( parent );
@@ -12,8 +12,8 @@ AABB TerrainGenerator::rootChunkBbox( const Map3D &map ) const

float hMin, hMax;
rootChunkHeightRange( hMin, hMax );
return AABB( te.xMinimum() - map.originX, hMin * map.zExaggeration, -te.yMaximum() + map.originY,
te.xMaximum() - map.originX, hMax * map.zExaggeration, -te.yMinimum() + map.originY );
return AABB( te.xMinimum() - map.originX, hMin * map.terrainVerticalScale(), -te.yMaximum() + map.originY,
te.xMaximum() - map.originX, hMax * map.terrainVerticalScale(), -te.yMinimum() + map.originY );
}

float TerrainGenerator::rootChunkError( const Map3D &map ) const
@@ -67,7 +67,7 @@ int main( int argc, char *argv[] )
Map3D map;
map.setLayers( QList<QgsMapLayer *>() << rlSat );
map.crs = rlSat->crs();
map.zExaggeration = 3;
map.setTerrainVerticalScale( 3 );
map.setShowTerrainBoundingBoxes( true );
map.setShowTerrainTilesInfo( true );

@@ -74,7 +74,7 @@ void Utils::clampAltitudes( QgsLineString *lineString, AltitudeClamping altClamp
if ( altClamp == AltClampAbsolute || altClamp == AltClampRelative )
geomZ = lineString->zAt( i );

float z = ( terrainZ + geomZ ) * map.zExaggeration + height;
float z = ( terrainZ + geomZ ) * map.terrainVerticalScale() + height;
lineString->setZAt( i, z );
}
}
@@ -35,7 +35,7 @@ Qgs3DMapConfigWidget::Qgs3DMapConfigWidget( Map3D *map, QgsMapCanvas *mainCanvas
spinTerrainResolution->setValue( 16 );
}

spinTerrainScale->setValue( mMap->zExaggeration );
spinTerrainScale->setValue( mMap->terrainVerticalScale() );
spinMapResolution->setValue( mMap->tileTextureSize );
spinScreenError->setValue( mMap->maxTerrainError );
chkShowTileInfo->setChecked( mMap->showTerrainTilesInfo() );
@@ -68,7 +68,7 @@ void Qgs3DMapConfigWidget::apply()
mMap->setTerrainGenerator( flatTerrainGen );
}

mMap->zExaggeration = spinTerrainScale->value();
mMap->setTerrainVerticalScale( spinTerrainScale->value() );
mMap->tileTextureSize = spinMapResolution->value();
mMap->maxTerrainError = spinScreenError->value();
mMap->setShowTerrainTilesInfo( chkShowTileInfo->isChecked() );

0 comments on commit 04b00aa

Please sign in to comment.
You can’t perform that action at this time.