improve 3D ui for directional light

This commit is contained in:
vcloarec 2020-10-18 21:17:52 -04:00 committed by Nyall Dawson
parent 139be61b29
commit 51305598a5
3 changed files with 275 additions and 70 deletions

View File

@ -21,6 +21,8 @@
#include <QMessageBox>
#include "qwt_compass.h"
#include "qwt_dial_needle.h"
QgsLightsWidget::QgsLightsWidget( QWidget *parent )
: QWidget( parent )
@ -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 );
@ -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() );
}
@ -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();
}
@ -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 );

View File

@ -23,6 +23,7 @@
#include "qgspointlightsettings.h"
#include "qgsdirectionallightsettings.h"
class QwtCompass;
/**
* Widget for configuration of lights in 3D map scene
@ -53,6 +54,9 @@ class QgsLightsWidget : public QWidget, private Ui::QgsLightsWidget
void updateCurrentDirectionalLightParameters();
void onAddDirectionalLight();
void onRemoveDirectionalLight();
void onSpinBoxDirectionChanged();
void onSpinBoxAzimuthChange();
void onSpinBoxAltitudeChange();
private:
void updateLightsList();
void updateDirectionalLightsList();
@ -60,6 +64,7 @@ class QgsLightsWidget : public QWidget, private Ui::QgsLightsWidget
private:
QList<QgsPointLightSettings> mPointLights;
QList<QgsDirectionalLightSettings> mDirectionalLights;
QwtCompass *mDirectionCompass = nullptr;
};
#endif // QGSLIGHTSWIDGET_H

View File

@ -216,10 +216,10 @@
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="0" colspan="3">
<layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="1">
<item row="4" column="1">
<widget class="QgsDoubleSpinBox" name="spinDirectionZ">
<property name="decimals">
<number>1</number>
<number>2</number>
</property>
<property name="minimum">
<double>-9999999.000000000000000</double>
@ -229,7 +229,64 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="4" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Z</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsDoubleSpinBox" name="spinDirectionX">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-9999999.000000000000000</double>
</property>
<property name="maximum">
<double>9999999.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QgsDoubleSpinBox" name="spinDirectionalIntensity">
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QgsDoubleSpinBox" name="spinDirectionY">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>-9999999.000000000000000</double>
</property>
<property name="maximum">
<double>9999999.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QgsColorButton" name="btnDirectionalColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -245,71 +302,7 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Intensity</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Z</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsDoubleSpinBox" name="spinDirectionY">
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-9999999.000000000000000</double>
</property>
<property name="maximum">
<double>9999999.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsDoubleSpinBox" name="spinDirectionX">
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-9999999.000000000000000</double>
</property>
<property name="maximum">
<double>9999999.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QgsDoubleSpinBox" name="spinDirectionalIntensity">
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>X</string>
@ -323,6 +316,108 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Intensity</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="directionLightLayout">
<property name="topMargin">
<number>11</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_12">
<property name="text">
<string>Azimuth</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinBoxAzimuth">
<property name="suffix">
<string>°</string>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="directionCmpassWidget" native="true"/>
</item>
<item>
<widget class="QLabel" name="altitudeSpinBox">
<property name="text">
<string>Altitude</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinBoxAltitude">
<property name="suffix">
<string>°</string>
</property>
<property name="minimum">
<double>-90.000000000000000</double>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="sliderAltitude">
<property name="minimum">
<number>-90</number>
</property>
<property name="maximum">
<number>90</number>
</property>
<property name="tracking">
<bool>true</bool>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>2</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item row="0" column="2">