Skip to content

Commit

Permalink
improve 3D ui for directional light
Browse files Browse the repository at this point in the history
  • Loading branch information
vcloarec authored and nyalldawson committed Oct 21, 2020
1 parent 139be61 commit 5130559
Show file tree
Hide file tree
Showing 3 changed files with 253 additions and 48 deletions.
111 changes: 108 additions & 3 deletions src/app/3d/qgslightswidget.cpp
Expand Up @@ -21,6 +21,8 @@

#include <QMessageBox>

#include "qwt_compass.h"
#include "qwt_dial_needle.h"

QgsLightsWidget::QgsLightsWidget( QWidget *parent )
: QWidget( parent )
Expand All @@ -30,6 +32,18 @@ QgsLightsWidget::QgsLightsWidget( QWidget *parent )
btnAddLight->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.svg" ) ) );
btnRemoveLight->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.svg" ) ) );

mDirectionCompass = new QwtCompass( this );
QwtCompassScaleDraw *scaleDraw = new QwtCompassScaleDraw();
scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, true );
scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false );
scaleDraw->setTickLength( QwtScaleDiv::MinorTick, 0 );
scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 0 );
scaleDraw->setTickLength( QwtScaleDiv::MajorTick, 4 );
QwtScaleDiv scaleDiv = scaleDraw->scaleDiv();
mDirectionCompass->setScaleDraw( scaleDraw );
mDirectionCompass->setNeedle( new QwtDialSimpleNeedle( QwtDialSimpleNeedle::Ray, true, Qt::darkYellow, Qt::gray ) );
directionLightLayout->insertWidget( 3, mDirectionCompass );

connect( btnAddLight, &QToolButton::clicked, this, &QgsLightsWidget::onAddLight );
connect( btnRemoveLight, &QToolButton::clicked, this, &QgsLightsWidget::onRemoveLight );

Expand All @@ -50,12 +64,17 @@ QgsLightsWidget::QgsLightsWidget( QWidget *parent )
connect( btnRemoveDirectionalLight, &QToolButton::clicked, this, &QgsLightsWidget::onRemoveDirectionalLight );

connect( cboDirectionalLights, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, &QgsLightsWidget::onCurrentDirectionalLightChanged );
connect( spinDirectionX, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentDirectionalLightParameters );
connect( spinDirectionY, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentDirectionalLightParameters );
connect( spinDirectionZ, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentDirectionalLightParameters );
connect( spinDirectionX, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onSpinBoxDirectionChanged );
connect( spinDirectionY, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onSpinBoxDirectionChanged );
connect( spinDirectionZ, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onSpinBoxDirectionChanged );
connect( spinDirectionalIntensity, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::updateCurrentDirectionalLightParameters );
connect( btnDirectionalColor, &QgsColorButton::colorChanged, this, &QgsLightsWidget::updateCurrentDirectionalLightParameters );

connect( mDirectionCompass, &QwtCompass::valueChanged, spinBoxAzimuth, &QgsDoubleSpinBox::setValue );
connect( spinBoxAzimuth, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onSpinBoxAzimuthChange );
connect( spinBoxAltitude, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsLightsWidget::onSpinBoxAltitudeChange );
connect( sliderAltitude, &QSlider::valueChanged, spinBoxAltitude, &QgsDoubleSpinBox::setValue );

tabWidget->setCurrentIndex( QgsSettings().value( QStringLiteral( "UI/last3DLightsTab" ), 1 ).toInt() );
}

Expand Down Expand Up @@ -117,6 +136,7 @@ void QgsLightsWidget::onCurrentDirectionalLightChanged( int index )
whileBlocking( spinDirectionZ )->setValue( light.direction().z() );
whileBlocking( btnDirectionalColor )->setColor( light.color() );
whileBlocking( spinDirectionalIntensity )->setValue( light.intensity() );
onSpinBoxDirectionChanged();
}


Expand Down Expand Up @@ -211,6 +231,91 @@ void QgsLightsWidget::onRemoveDirectionalLight()
emit directionalLightsCountChanged( cboDirectionalLights->count() );
}

void QgsLightsWidget::onSpinBoxDirectionChanged()
{
double x = spinDirectionX->value();
double y = spinDirectionY->value();
double z = spinDirectionZ->value();
double azimuthAngle;
double altitudeAngle;

double horizontalVectorMagnitude = sqrt( x * x + z * z );
if ( horizontalVectorMagnitude == 0 )
azimuthAngle = 0;
else
{
azimuthAngle = ( asin( -x / horizontalVectorMagnitude ) ) / M_PI * 180;
if ( z < 0 )
azimuthAngle = 180 - azimuthAngle;
azimuthAngle = std::fmod( azimuthAngle + 360.0, 360.0 );
}


mDirectionCompass->setValue( azimuthAngle );
spinBoxAzimuth->setValue( azimuthAngle );

if ( horizontalVectorMagnitude == 0 )
altitudeAngle = y >= 0 ? 90 : -90;
else
altitudeAngle = -atan( y / horizontalVectorMagnitude ) / M_PI * 180;

spinBoxAltitude->setValue( altitudeAngle );
sliderAltitude->setValue( altitudeAngle );

updateCurrentDirectionalLightParameters();
}

void QgsLightsWidget::onSpinBoxAzimuthChange()
{
double x = spinDirectionX->value();
double z = spinDirectionZ->value();
double horizontalVectorMagnitude = sqrt( x * x + z * z );

double azimuthValue = spinBoxAzimuth->value();
x = -horizontalVectorMagnitude * sin( azimuthValue / 180 * M_PI );
z = horizontalVectorMagnitude * cos( azimuthValue / 180 * M_PI );

whileBlocking( mDirectionCompass )->setValue( azimuthValue );
whileBlocking( spinDirectionX )->setValue( x );
whileBlocking( spinDirectionZ )->setValue( z );

updateCurrentDirectionalLightParameters();
}

void QgsLightsWidget::onSpinBoxAltitudeChange()
{
double x = spinDirectionX->value();
double y = spinDirectionY->value();
double z = spinDirectionZ->value();
double horizontalVectorMagnitude = sqrt( x * x + z * z );
double vectorMagnitude = sqrt( x * x + y * y + z * z );

double altitudeValue = spinBoxAltitude->value();
double azimuthValue = spinBoxAzimuth->value();
if ( fabs( altitudeValue ) == 90 )
{
x = 0;
z = 0;
y = -vectorMagnitude * fabs( altitudeValue ) / altitudeValue;
}
else
{
if ( horizontalVectorMagnitude == 0 )
horizontalVectorMagnitude = vectorMagnitude * cos( altitudeValue / 180 * M_PI );;

x = -horizontalVectorMagnitude * sin( azimuthValue / 180 * M_PI );
z = horizontalVectorMagnitude * cos( azimuthValue / 180 * M_PI );
y = -tan( altitudeValue / 180 * M_PI ) * horizontalVectorMagnitude;
}

whileBlocking( spinDirectionX )->setValue( x );
whileBlocking( spinDirectionZ )->setValue( z );
whileBlocking( spinDirectionY )->setValue( y );
whileBlocking( sliderAltitude )->setValue( altitudeValue );

updateCurrentDirectionalLightParameters();
}

void QgsLightsWidget::updateLightsList()
{
cboLights->blockSignals( true );
Expand Down
5 changes: 5 additions & 0 deletions src/app/3d/qgslightswidget.h
Expand Up @@ -23,6 +23,7 @@
#include "qgspointlightsettings.h"
#include "qgsdirectionallightsettings.h"

class QwtCompass;

/**
* Widget for configuration of lights in 3D map scene
Expand Down Expand Up @@ -53,13 +54,17 @@ class QgsLightsWidget : public QWidget, private Ui::QgsLightsWidget
void updateCurrentDirectionalLightParameters();
void onAddDirectionalLight();
void onRemoveDirectionalLight();
void onSpinBoxDirectionChanged();
void onSpinBoxAzimuthChange();
void onSpinBoxAltitudeChange();
private:
void updateLightsList();
void updateDirectionalLightsList();

private:
QList<QgsPointLightSettings> mPointLights;
QList<QgsDirectionalLightSettings> mDirectionalLights;
QwtCompass *mDirectionCompass = nullptr;
};

#endif // QGSLIGHTSWIDGET_H

0 comments on commit 5130559

Please sign in to comment.