diff --git a/graphics/icons.png b/graphics/icons.png
index 77dbd89..b3e56b0 100644
Binary files a/graphics/icons.png and b/graphics/icons.png differ
diff --git a/graphics/icons.svg b/graphics/icons.svg
index d57fe81..ab65164 100644
--- a/graphics/icons.svg
+++ b/graphics/icons.svg
@@ -7,6 +7,7 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
@@ -27,18 +28,19 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="3.959798"
- inkscape:cx="170.49504"
- inkscape:cy="957.94588"
+ inkscape:zoom="1.979899"
+ inkscape:cx="468.77289"
+ inkscape:cy="831.55692"
inkscape:document-units="px"
- inkscape:current-layer="layer1"
+ inkscape:current-layer="g3986"
showgrid="true"
inkscape:window-width="1920"
inkscape:window-height="1030"
inkscape:window-x="1440"
inkscape:window-y="25"
inkscape:window-maximized="1"
- showguides="true">
+ showguides="true"
+ inkscape:snap-object-midpoints="false">
@@ -51,7 +53,7 @@
image/svg+xml
-
+
@@ -95,5 +97,100 @@
id="path3807"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/definition/AtmosphereDefinition.cpp b/src/definition/AtmosphereDefinition.cpp
index 0cbb27f..7e74e9c 100644
--- a/src/definition/AtmosphereDefinition.cpp
+++ b/src/definition/AtmosphereDefinition.cpp
@@ -105,6 +105,22 @@ void AtmosphereDefinition::validate()
_daytime = (double)hour / 24.0 + (double)minute / 1440.0;
}
+void AtmosphereDefinition::setDaytime(double value)
+{
+ if (value >= 0.0)
+ {
+ value = fmod(value, 1.0);
+ }
+ else
+ {
+ value = 1.0 - fmod(-value, 1.0);
+ }
+ value *= 1440.0;
+ hour = value / 60.0;
+ minute = value - 60.0 * hour;
+ validate();
+}
+
void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
{
sun_color.r = 1.0;
diff --git a/src/definition/AtmosphereDefinition.h b/src/definition/AtmosphereDefinition.h
index 0067ecf..0fbfa92 100644
--- a/src/definition/AtmosphereDefinition.h
+++ b/src/definition/AtmosphereDefinition.h
@@ -46,6 +46,11 @@ public:
virtual void copy(BaseDefinition* destination) const override;
virtual void validate() override;
+ /**
+ * Set the daytime from a 0.0-1.0 value.
+ */
+ void setDaytime(double value);
+
void applyPreset(AtmospherePreset preset);
void generateStars(int count);
diff --git a/src/interface/modeler/quickapp/AtmosphereModeler.cpp b/src/interface/modeler/quickapp/AtmosphereModeler.cpp
new file mode 100644
index 0000000..5dcf86d
--- /dev/null
+++ b/src/interface/modeler/quickapp/AtmosphereModeler.cpp
@@ -0,0 +1,26 @@
+#include "AtmosphereModeler.h"
+
+#include "MainModelerWindow.h"
+#include "Scenery.h"
+#include "AtmosphereDefinition.h"
+#include "OpenGLRenderer.h"
+#include "OpenGLSkybox.h"
+
+AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main):
+ main(main)
+{
+ QObject *item = main->findQmlObject("atmosphere_daytime");
+ if (item)
+ {
+ connect(item, SIGNAL(changed(double)), this, SLOT(daytimeChanged(double)));
+ }
+}
+
+void AtmosphereModeler::daytimeChanged(double value)
+{
+ main->getScenery()->getAtmosphere()->setDaytime(value);
+
+ main->getRenderer()->getScenery()->setAtmosphere(main->getScenery()->getAtmosphere());
+
+ main->getRenderer()->getSkybox()->update();
+}
diff --git a/src/interface/modeler/quickapp/AtmosphereModeler.h b/src/interface/modeler/quickapp/AtmosphereModeler.h
new file mode 100644
index 0000000..1a5b32d
--- /dev/null
+++ b/src/interface/modeler/quickapp/AtmosphereModeler.h
@@ -0,0 +1,27 @@
+#ifndef ATMOSPHEREMODELER_H
+#define ATMOSPHEREMODELER_H
+
+#include "modeler_global.h"
+
+#include
+
+namespace paysages {
+namespace modeler {
+
+class AtmosphereModeler : public QObject
+{
+ Q_OBJECT
+public:
+ AtmosphereModeler(MainModelerWindow *main);
+
+public slots:
+ void daytimeChanged(double value);
+
+private:
+ MainModelerWindow *main;
+};
+
+}
+}
+
+#endif // ATMOSPHEREMODELER_H
diff --git a/src/interface/modeler/quickapp/MainModelerWindow.cpp b/src/interface/modeler/quickapp/MainModelerWindow.cpp
index f8cca47..9148218 100644
--- a/src/interface/modeler/quickapp/MainModelerWindow.cpp
+++ b/src/interface/modeler/quickapp/MainModelerWindow.cpp
@@ -3,6 +3,8 @@
#include "OpenGLView.h"
#include "Scenery.h"
#include "OpenGLRenderer.h"
+#include "AtmosphereModeler.h"
+#include "WaterModeler.h"
MainModelerWindow::MainModelerWindow()
{
@@ -15,10 +17,21 @@ MainModelerWindow::MainModelerWindow()
setTitle(QObject::tr("Paysages 3D"));
setResizeMode(QQuickView::SizeRootObjectToView);
setSource(QUrl("qrc:///main.qml"));
+
+ atmosphere = new AtmosphereModeler(this);
+ water = new WaterModeler(this);
}
MainModelerWindow::~MainModelerWindow()
{
+ delete atmosphere;
+ delete water;
+
delete renderer;
delete scenery;
}
+
+QObject *MainModelerWindow::findQmlObject(const QString &objectName)
+{
+ return rootObject()->findChild(objectName);
+}
diff --git a/src/interface/modeler/quickapp/MainModelerWindow.h b/src/interface/modeler/quickapp/MainModelerWindow.h
index f599381..5d7b5f2 100644
--- a/src/interface/modeler/quickapp/MainModelerWindow.h
+++ b/src/interface/modeler/quickapp/MainModelerWindow.h
@@ -15,11 +15,17 @@ public:
MainModelerWindow();
virtual ~MainModelerWindow();
+ QObject *findQmlObject(const QString& objectName);
+
+ inline Scenery *getScenery() const {return scenery;}
inline OpenGLRenderer *getRenderer() const {return renderer;}
private:
OpenGLRenderer *renderer;
Scenery *scenery;
+
+ AtmosphereModeler *atmosphere;
+ WaterModeler *water;
};
}
diff --git a/src/interface/modeler/quickapp/WaterModeler.cpp b/src/interface/modeler/quickapp/WaterModeler.cpp
new file mode 100644
index 0000000..a0057db
--- /dev/null
+++ b/src/interface/modeler/quickapp/WaterModeler.cpp
@@ -0,0 +1,19 @@
+#include "WaterModeler.h"
+
+#include "MainModelerWindow.h"
+
+WaterModeler::WaterModeler(MainModelerWindow *main):
+ main(main)
+{
+ QObject *item = main->findQmlObject("water_level");
+ if (item)
+ {
+ connect(item, SIGNAL(changed(double)), this, SLOT(waterLevelChanged(double)));
+ }
+}
+
+void WaterModeler::waterLevelChanged(double value)
+{
+ // TODO
+ //qDebug() << "water level : " << value;
+}
diff --git a/src/interface/modeler/quickapp/WaterModeler.h b/src/interface/modeler/quickapp/WaterModeler.h
new file mode 100644
index 0000000..fac513e
--- /dev/null
+++ b/src/interface/modeler/quickapp/WaterModeler.h
@@ -0,0 +1,27 @@
+#ifndef WATERMODELER_H
+#define WATERMODELER_H
+
+#include "modeler_global.h"
+
+#include
+
+namespace paysages {
+namespace modeler {
+
+class WaterModeler: public QObject
+{
+ Q_OBJECT
+public:
+ WaterModeler(MainModelerWindow *main);
+
+public slots:
+ void waterLevelChanged(double value);
+
+private:
+ MainModelerWindow *main;
+};
+
+}
+}
+
+#endif // WATERMODELER_H
diff --git a/src/interface/modeler/quickapp/modeler_global.h b/src/interface/modeler/quickapp/modeler_global.h
index f8088b8..d2be172 100644
--- a/src/interface/modeler/quickapp/modeler_global.h
+++ b/src/interface/modeler/quickapp/modeler_global.h
@@ -9,6 +9,9 @@ namespace paysages {
namespace modeler {
class MainModelerWindow;
class OpenGLView;
+
+ class AtmosphereModeler;
+ class WaterModeler;
}
}
diff --git a/src/interface/modeler/quickapp/qml/BaseChoice.qml b/src/interface/modeler/quickapp/qml/BaseChoice.qml
new file mode 100644
index 0000000..165164d
--- /dev/null
+++ b/src/interface/modeler/quickapp/qml/BaseChoice.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.1
+import QtQuick.Layouts 1.1
+
+Item {
+ default property alias children : inner_layout.children
+ property int value
+ width: 100
+ height: 32
+
+ ExclusiveGroup {
+ id: choice_group
+
+ onCurrentChanged: value = current.value
+ }
+
+ Row {
+ id: inner_layout
+ spacing: 5
+ anchors.fill: parent
+ }
+
+ onChildrenChanged: {
+ for (var i = 0; i < children.length; i++)
+ {
+ children[i].exclusiveGroup = choice_group;
+ }
+ }
+}
diff --git a/src/interface/modeler/quickapp/qml/BaseChoiceItem.qml b/src/interface/modeler/quickapp/qml/BaseChoiceItem.qml
new file mode 100644
index 0000000..7e87197
--- /dev/null
+++ b/src/interface/modeler/quickapp/qml/BaseChoiceItem.qml
@@ -0,0 +1,50 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.1
+
+Rectangle {
+ id: choice_item
+ property string icon
+ property bool checked: false
+ property ExclusiveGroup exclusiveGroup: null
+ property int value
+
+ color: "#333333"
+
+ signal toggled(bool value)
+
+ width: 20
+ height: 20
+
+ Image {
+ anchors.fill: parent
+ source: parent.icon
+ antialiasing: true
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onClicked: checked = true
+ }
+
+ onExclusiveGroupChanged: {
+ if (exclusiveGroup) {
+ exclusiveGroup.bindCheckable(choice_item);
+ }
+ }
+
+ onCheckedChanged: choice_item.toggled(checked)
+
+ states: [
+ State {
+ name: "Checked"
+ when: checked
+
+ PropertyChanges {
+ target: choice_item
+ color: "#999999"
+ }
+ }
+
+ ]
+}
diff --git a/src/interface/modeler/quickapp/qml/BasePanel.qml b/src/interface/modeler/quickapp/qml/BasePanel.qml
index 82872d6..14ce20d 100644
--- a/src/interface/modeler/quickapp/qml/BasePanel.qml
+++ b/src/interface/modeler/quickapp/qml/BasePanel.qml
@@ -4,14 +4,21 @@ Rectangle {
property ToolbarButton tool
id: panel
+ opacity: 0
width: 200
height: parent.height - 100
- color: "red"
+ color: "#a0909090"
enabled: visible
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
+ Behavior on opacity {
+ PropertyAnimation {
+ duration: 200
+ }
+ }
+
states: [
State {
name: "Active"
@@ -20,6 +27,7 @@ Rectangle {
PropertyChanges {
target: panel
visible: true
+ opacity: 1
}
}
diff --git a/src/interface/modeler/quickapp/qml/BaseSlider.qml b/src/interface/modeler/quickapp/qml/BaseSlider.qml
new file mode 100644
index 0000000..58cc14e
--- /dev/null
+++ b/src/interface/modeler/quickapp/qml/BaseSlider.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.2
+import QtQuick.Controls 1.2
+
+Slider {
+ signal changed(real value)
+ onValueChanged: changed(value)
+}
diff --git a/src/interface/modeler/quickapp/qml/PanelAtmosphereDaytime.qml b/src/interface/modeler/quickapp/qml/PanelAtmosphereDaytime.qml
new file mode 100644
index 0000000..08dab9f
--- /dev/null
+++ b/src/interface/modeler/quickapp/qml/PanelAtmosphereDaytime.qml
@@ -0,0 +1,46 @@
+import QtQuick 2.0
+import QtQuick.Controls 1.1
+import QtQuick.Layouts 1.1
+
+BasePanel {
+ width: 70
+
+ objectName: "atmosphere_daytime"
+ default property real value: day_night.value == 2 ? 1.0 : slider.value * 0.54 + 0.23;
+ signal changed(real value)
+
+ onValueChanged: changed(value)
+
+ ColumnLayout
+ {
+ anchors.fill: parent
+ anchors.margins: 10
+ spacing: 20
+
+ BaseChoice {
+ id: day_night
+ width: parent.width
+
+ Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
+
+ BaseChoiceItem {
+ icon: "images/icon_atmosphere_day.png"
+ value: 1
+ checked: true
+ }
+ BaseChoiceItem {
+ icon: "images/icon_atmosphere_night.png"
+ value: 2
+ }
+ }
+
+ BaseSlider {
+ id: slider
+ orientation: Qt.Vertical
+ Layout.maximumWidth: 15
+ Layout.fillHeight: true
+ Layout.alignment: Qt.AlignHCenter
+ visible: day_night.value == 1
+ }
+ }
+}
diff --git a/src/interface/modeler/quickapp/qml/PanelWaterLevel.qml b/src/interface/modeler/quickapp/qml/PanelWaterLevel.qml
index e84bd6e..444ae97 100644
--- a/src/interface/modeler/quickapp/qml/PanelWaterLevel.qml
+++ b/src/interface/modeler/quickapp/qml/PanelWaterLevel.qml
@@ -1,10 +1,10 @@
import QtQuick 2.2
-import QtQuick.Controls 1.2
BasePanel {
width: 20
- Slider {
+ BaseSlider {
+ objectName: "water_level"
orientation: Qt.Vertical
anchors.fill: parent
}
diff --git a/src/interface/modeler/quickapp/qml/Toolbar.qml b/src/interface/modeler/quickapp/qml/Toolbar.qml
index b8a1424..9abfbc2 100644
--- a/src/interface/modeler/quickapp/qml/Toolbar.qml
+++ b/src/interface/modeler/quickapp/qml/Toolbar.qml
@@ -19,4 +19,14 @@ Rectangle {
duration: 200
}
}
+
+ onEnabledChanged: {
+ if (!enabled)
+ {
+ for (var i = 0; i < children.length; i++)
+ {
+ children[i].selected = false;
+ }
+ }
+ }
}
diff --git a/src/interface/modeler/quickapp/qml/app.qrc b/src/interface/modeler/quickapp/qml/app.qrc
index a216b39..3c32d54 100644
--- a/src/interface/modeler/quickapp/qml/app.qrc
+++ b/src/interface/modeler/quickapp/qml/app.qrc
@@ -17,5 +17,13 @@
images/icon_water_level.png
BasePanel.qml
PanelWaterLevel.qml
+ images/icon_atmosphere.png
+ images/icon_atmosphere_daytime.png
+ BaseSlider.qml
+ PanelAtmosphereDaytime.qml
+ images/icon_atmosphere_day.png
+ images/icon_atmosphere_night.png
+ BaseChoice.qml
+ BaseChoiceItem.qml
diff --git a/src/interface/modeler/quickapp/qml/images/icon_atmosphere.png b/src/interface/modeler/quickapp/qml/images/icon_atmosphere.png
new file mode 100644
index 0000000..5514dfb
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/icon_atmosphere.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/icon_atmosphere_day.png b/src/interface/modeler/quickapp/qml/images/icon_atmosphere_day.png
new file mode 100644
index 0000000..90721c2
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/icon_atmosphere_day.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/icon_atmosphere_daytime.png b/src/interface/modeler/quickapp/qml/images/icon_atmosphere_daytime.png
new file mode 100644
index 0000000..97bed42
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/icon_atmosphere_daytime.png differ
diff --git a/src/interface/modeler/quickapp/qml/images/icon_atmosphere_night.png b/src/interface/modeler/quickapp/qml/images/icon_atmosphere_night.png
new file mode 100644
index 0000000..6f0aaee
Binary files /dev/null and b/src/interface/modeler/quickapp/qml/images/icon_atmosphere_night.png differ
diff --git a/src/interface/modeler/quickapp/qml/main.qml b/src/interface/modeler/quickapp/qml/main.qml
index 66dc103..422f7ca 100644
--- a/src/interface/modeler/quickapp/qml/main.qml
+++ b/src/interface/modeler/quickapp/qml/main.qml
@@ -41,7 +41,8 @@ OpenGLView {
}
ToolbarButton {
id: tool_atmosphere
- picture: "images/tab_atmosphere.png"
+ picture: "images/icon_atmosphere.png"
+ hovertext: "Atmosphere/weather tools"
}
ToolbarButton {
id: tool_clouds
@@ -78,11 +79,26 @@ OpenGLView {
}
}
+ Toolbar {
+ id: atmosphere_toolbar
+ opacity: 0
+ anchors.left: primary_toolbar.right
+
+ ToolbarButton {
+ id: tool_atmosphere_daytime
+ picture: "images/icon_atmosphere_daytime.png"
+ hovertext: qsTr("Change the time of day")
+ }
+ }
+
PanelWaterLevel {
id: panel_water_level
- visible: false
tool: tool_water_level
}
+ PanelAtmosphereDaytime {
+ id: panel_atmosphere_daytime
+ tool: tool_atmosphere_daytime
+ }
states: [
State {
@@ -102,6 +118,15 @@ OpenGLView {
target: water_toolbar
opacity: 1
}
+ },
+ State {
+ name: "Atmosphere Mode"
+ when: tool_atmosphere.selected
+
+ PropertyChanges {
+ target: atmosphere_toolbar
+ opacity: 1
+ }
}
]
diff --git a/src/interface/modeler/quickapp/quickapp.pro b/src/interface/modeler/quickapp/quickapp.pro
index ec7c6dc..d1502b4 100644
--- a/src/interface/modeler/quickapp/quickapp.pro
+++ b/src/interface/modeler/quickapp/quickapp.pro
@@ -6,7 +6,9 @@ include(../../../common.pri)
SOURCES += main.cpp \
OpenGLView.cpp \
- MainModelerWindow.cpp
+ MainModelerWindow.cpp \
+ WaterModeler.cpp \
+ AtmosphereModeler.cpp
RESOURCES += \
qml/app.qrc
@@ -22,7 +24,9 @@ include(deployment.pri)
HEADERS += \
OpenGLView.h \
modeler_global.h \
- MainModelerWindow.h
+ MainModelerWindow.h \
+ WaterModeler.h \
+ AtmosphereModeler.h
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../../system/release/ -lpaysages_system
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../../system/debug/ -lpaysages_system
@@ -61,4 +65,8 @@ OTHER_FILES += \
qml/Toolbar.qml \
qml/Tooltip.qml \
qml/BasePanel.qml \
- qml/PanelWaterLevel.qml
+ qml/PanelWaterLevel.qml \
+ qml/PanelAtmosphereDaytime.qml \
+ qml/BaseSlider.qml \
+ qml/BaseChoice.qml \
+ qml/BaseChoiceItem.qml
diff --git a/src/render/opengl/OpenGLRenderer.h b/src/render/opengl/OpenGLRenderer.h
index 5a3e90c..57ef059 100644
--- a/src/render/opengl/OpenGLRenderer.h
+++ b/src/render/opengl/OpenGLRenderer.h
@@ -17,6 +17,10 @@ public:
OpenGLRenderer(Scenery* scenery=0);
virtual ~OpenGLRenderer();
+ inline OpenGLSkybox *getSkybox() const {return skybox;}
+ inline OpenGLWater *getWater() const {return water;}
+ inline OpenGLTerrain *getTerrain() const {return terrain;}
+
void initialize();
void prepareOpenGLState();
void resize(int width, int height);
diff --git a/src/tests/AtmosphereDefinition_Test.cpp b/src/tests/AtmosphereDefinition_Test.cpp
new file mode 100644
index 0000000..5e151a0
--- /dev/null
+++ b/src/tests/AtmosphereDefinition_Test.cpp
@@ -0,0 +1,36 @@
+#include "BaseTestCase.h"
+
+#include "AtmosphereDefinition.h"
+
+TEST(AtmosphereDefinition, setDaytime)
+{
+ AtmosphereDefinition atmo(NULL);
+
+ atmo.setDaytime(0.0);
+ EXPECT_EQ(atmo.hour, 0);
+ EXPECT_EQ(atmo.minute, 0);
+
+ atmo.setDaytime(0.1);
+ EXPECT_EQ(atmo.hour, 2);
+ EXPECT_EQ(atmo.minute, 24);
+
+ atmo.setDaytime(0.25);
+ EXPECT_EQ(atmo.hour, 6);
+ EXPECT_EQ(atmo.minute, 0);
+
+ atmo.setDaytime(0.5);
+ EXPECT_EQ(atmo.hour, 12);
+ EXPECT_EQ(atmo.minute, 0);
+
+ atmo.setDaytime(1.0);
+ EXPECT_EQ(atmo.hour, 0);
+ EXPECT_EQ(atmo.minute, 0);
+
+ atmo.setDaytime(-0.5);
+ EXPECT_EQ(atmo.hour, 12);
+ EXPECT_EQ(atmo.minute, 0);
+
+ atmo.setDaytime(1.5);
+ EXPECT_EQ(atmo.hour, 12);
+ EXPECT_EQ(atmo.minute, 0);
+}
diff --git a/src/tests/tests.pro b/src/tests/tests.pro
index 863ddff..4668460 100644
--- a/src/tests/tests.pro
+++ b/src/tests/tests.pro
@@ -20,7 +20,8 @@ SOURCES += main.cpp \
FractalNoise_Test.cpp \
Canvas_Test.cpp \
CanvasPortion_Test.cpp \
- CanvasPreview_Test.cpp
+ CanvasPreview_Test.cpp \
+ AtmosphereDefinition_Test.cpp
HEADERS += \
BaseTestCase.h