From 8a9c3d4b834840d5e884dd1dd219f1e3b83bbcaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Mon, 21 Sep 2015 23:12:43 +0200 Subject: [PATCH] Added /atmosphere/sun_radius property Also added the tool camera mode to focus on the sun while altering its radius --- TODO | 2 + src/definition/AtmosphereDefinition.cpp | 7 +-- src/definition/AtmosphereDefinition.h | 3 +- .../modeler/quickapp/AtmosphereModeler.cpp | 2 + .../modeler/quickapp/AtmosphereModeler.h | 1 + .../modeler/quickapp/MainModelerWindow.cpp | 26 ++++++++- .../modeler/quickapp/MainModelerWindow.h | 1 + .../modeler/quickapp/ModelerCameras.cpp | 51 ++++++++++++++++-- .../modeler/quickapp/ModelerCameras.h | 24 ++++++++- .../quickapp/qml/AtmosphereSection.qml | 27 ++++++++++ .../modeler/quickapp/qml/BaseSection.qml | 2 + src/interface/modeler/quickapp/qml/app.qrc | 1 + .../quickapp/qml/images/icon_sun_radius.png | Bin 0 -> 1930 bytes src/interface/modeler/quickapp/qml/main.qml | 14 +++++ src/render/opengl/OpenGLSkybox.cpp | 5 ++ src/render/opengl/shaders/atmosphere.frag | 4 +- .../software/AtmosphereModelBruneton.cpp | 5 +- 17 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 src/interface/modeler/quickapp/qml/images/icon_sun_radius.png diff --git a/TODO b/TODO index 019b19c..778caed 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,8 @@ Technlology Preview 2 : - Add clouds to OpenGL with 3d textures. - Fix potential holes in land rendering (OpenGL and software). - Fix polygon culling near the camera in low-res renders (automatic tessellation ?). +- Fix sun size not being consistent between opengl and software +- Fix tool camera not reverting to previous camera Technology Preview 3 : - Alter aerial perspective using estimation of the amount of light left after cloud layers traversal. diff --git a/src/definition/AtmosphereDefinition.cpp b/src/definition/AtmosphereDefinition.cpp index 07c730d..cd7935f 100644 --- a/src/definition/AtmosphereDefinition.cpp +++ b/src/definition/AtmosphereDefinition.cpp @@ -9,6 +9,7 @@ AtmosphereDefinition::AtmosphereDefinition(DefinitionNode* parent): { daytime = new FloatNode(this, "daytime"); humidity = new FloatNode(this, "humidity"); + sun_radius = new FloatNode(this, "sun_radius"); } AtmosphereDefinition::~AtmosphereDefinition() @@ -21,7 +22,6 @@ void AtmosphereDefinition::save(PackStream* stream) const stream->write((int*)&model); sun_color.save(stream); - stream->write(&sun_radius); stream->write(&dome_lighting); stream->write(&moon_radius); stream->write(&moon_theta); @@ -43,7 +43,6 @@ void AtmosphereDefinition::load(PackStream* stream) stream->read((int*)&model); sun_color.load(stream); - stream->read(&sun_radius); stream->read(&dome_lighting); stream->read(&moon_radius); stream->read(&moon_theta); @@ -73,7 +72,6 @@ void AtmosphereDefinition::copy(DefinitionNode* _destination) const destination->model = model; destination->sun_color = sun_color; - destination->sun_radius = sun_radius; destination->dome_lighting = dome_lighting; destination->moon_radius = moon_radius; destination->moon_theta = moon_theta; @@ -117,7 +115,7 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset) sun_color.g = 0.95; sun_color.b = 0.9; sun_color.a = 1.0; - sun_radius = 1.0; + sun_radius->setValue(0.7); moon_radius = 1.0; moon_theta = 0.3; moon_phi = 0.5; @@ -135,7 +133,6 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset) setDayTime(17, 45); humidity->setValue(0.1); dome_lighting = 0.3; - sun_radius = 0.03; break; case ATMOSPHERE_PRESET_HAZY_MORNING: setDayTime(8, 30); diff --git a/src/definition/AtmosphereDefinition.h b/src/definition/AtmosphereDefinition.h index ce1b624..0d61340 100644 --- a/src/definition/AtmosphereDefinition.h +++ b/src/definition/AtmosphereDefinition.h @@ -47,6 +47,7 @@ public: inline FloatNode *propDayTime() const {return daytime;} inline FloatNode *propHumidity() const {return humidity;} + inline FloatNode *propSunRadius() const {return sun_radius;} /** * Set the daytime from a 0.0-1.0 value. @@ -68,7 +69,6 @@ public: AtmosphereModel model; Color sun_color; - double sun_radius; double dome_lighting; double moon_radius; @@ -80,6 +80,7 @@ public: private: FloatNode *humidity; FloatNode *daytime; + FloatNode *sun_radius; }; } diff --git a/src/interface/modeler/quickapp/AtmosphereModeler.cpp b/src/interface/modeler/quickapp/AtmosphereModeler.cpp index 4fd34eb..7985ef1 100644 --- a/src/interface/modeler/quickapp/AtmosphereModeler.cpp +++ b/src/interface/modeler/quickapp/AtmosphereModeler.cpp @@ -9,10 +9,12 @@ AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main) { prop_daytime = new FloatPropertyBind(main, "atmosphere_daytime", "value", main->getScenery()->getAtmosphere()->propDayTime()); prop_humidity = new FloatPropertyBind(main, "atmosphere_humidity", "value", main->getScenery()->getAtmosphere()->propHumidity()); + prop_sun_radius = new FloatPropertyBind(main, "atmosphere_sun_radius", "value", main->getScenery()->getAtmosphere()->propSunRadius()); } AtmosphereModeler::~AtmosphereModeler() { delete prop_daytime; delete prop_humidity; + delete prop_sun_radius; } diff --git a/src/interface/modeler/quickapp/AtmosphereModeler.h b/src/interface/modeler/quickapp/AtmosphereModeler.h index af98b00..5b1e31d 100644 --- a/src/interface/modeler/quickapp/AtmosphereModeler.h +++ b/src/interface/modeler/quickapp/AtmosphereModeler.h @@ -15,6 +15,7 @@ public: private: FloatPropertyBind *prop_daytime; FloatPropertyBind *prop_humidity; + FloatPropertyBind *prop_sun_radius; }; } diff --git a/src/interface/modeler/quickapp/MainModelerWindow.cpp b/src/interface/modeler/quickapp/MainModelerWindow.cpp index f6cfd75..87f472b 100644 --- a/src/interface/modeler/quickapp/MainModelerWindow.cpp +++ b/src/interface/modeler/quickapp/MainModelerWindow.cpp @@ -72,7 +72,14 @@ MainModelerWindow::~MainModelerWindow() QObject *MainModelerWindow::findQmlObject(const QString &objectName) { - return rootObject()->findChild(objectName); + if (objectName == "ui" || objectName == "root") + { + return rootObject(); + } + else + { + return rootObject()->findChild(objectName); + } } void MainModelerWindow::setQmlProperty(const QString &objectName, const QString &propertyName, const QVariant &value) @@ -82,6 +89,23 @@ void MainModelerWindow::setQmlProperty(const QString &objectName, const QString { item->setProperty(propertyName.toLocal8Bit(), value); } + else + { + Logs::error() << "QML object not found :" << objectName.toStdString() << std::endl; + } +} + +void MainModelerWindow::connectQmlSignal(const QString &objectName, const char *signal, const QObject *receiver, const char *method) +{ + QObject *item = findQmlObject(objectName); + if (item) + { + connect(item, signal, receiver, method); + } + else + { + Logs::error() << "QML object not found :" << objectName.toStdString() << std::endl; + } } QString MainModelerWindow::getState() const diff --git a/src/interface/modeler/quickapp/MainModelerWindow.h b/src/interface/modeler/quickapp/MainModelerWindow.h index 6f37fcb..c882828 100644 --- a/src/interface/modeler/quickapp/MainModelerWindow.h +++ b/src/interface/modeler/quickapp/MainModelerWindow.h @@ -17,6 +17,7 @@ public: QObject *findQmlObject(const QString &objectName); void setQmlProperty(const QString &objectName, const QString &propertyName, const QVariant &value); + void connectQmlSignal(const QString &objectName, const char *signal, const QObject *receiver, const char *method); QString getState() const; void setState(const QString &stateName); diff --git a/src/interface/modeler/quickapp/ModelerCameras.cpp b/src/interface/modeler/quickapp/ModelerCameras.cpp index 44349ab..ad55484 100644 --- a/src/interface/modeler/quickapp/ModelerCameras.cpp +++ b/src/interface/modeler/quickapp/ModelerCameras.cpp @@ -4,6 +4,9 @@ #include "OpenGLRenderer.h" #include "Scenery.h" #include "CameraDefinition.h" +#include "AtmosphereDefinition.h" +#include "FloatNode.h" +#include "AtmosphereRenderer.h" ModelerCameras::ModelerCameras(MainModelerWindow *parent): QObject(parent), parent(parent) @@ -11,11 +14,13 @@ ModelerCameras::ModelerCameras(MainModelerWindow *parent): render = new CameraDefinition(); topdown = new CameraDefinition(); current = new CameraDefinition(); + tool = new CameraDefinition(); active = render; + tool_mode = TOOL_NONE; // Watch GUI choice - QObject *widget = parent->findQmlObject("camera_choice"); - connect(widget, SIGNAL(stateChanged(QString)), this, SLOT(changeActiveCamera(QString))); + parent->connectQmlSignal("camera_choice", SIGNAL(stateChanged(QString)), this, SLOT(changeActiveCamera(QString))); + parent->connectQmlSignal("ui", SIGNAL(mainToolChanged(QString)), this, SLOT(toolChanged(QString))); // Validate to apply initial camera to scenery validate(); @@ -29,6 +34,7 @@ ModelerCameras::~ModelerCameras() delete current; delete render; delete topdown; + delete tool; } void ModelerCameras::processZoom(double value) @@ -54,6 +60,23 @@ void ModelerCameras::processPanning(double xvalue, double yvalue) validate(); } +void ModelerCameras::startSunTool() +{ + tool_mode = TOOL_SUN; + current->copy(tool); + active = tool; + + parent->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this, true); +} + +void ModelerCameras::endTool() +{ + active = render; + tool_mode = TOOL_NONE; + + validate(); +} + void ModelerCameras::timerEvent(QTimerEvent *) { current->transitionToAnother(active, 0.5); @@ -61,6 +84,15 @@ void ModelerCameras::timerEvent(QTimerEvent *) parent->getRenderer()->setCamera(current); } +void ModelerCameras::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) +{ + if (node->getPath() == "/atmosphere/daytime" && tool_mode == TOOL_SUN) + { + Vector3 direction = parent->getRenderer()->getAtmosphereRenderer()->getSunDirection(); + tool->setTarget(tool->getLocation().add(direction)); + } +} + void ModelerCameras::validate() { parent->getScenery()->keepCameraAboveGround(active); @@ -68,7 +100,8 @@ void ModelerCameras::validate() parent->getScenery()->keepCameraAboveGround(current); parent->getRenderer()->setCamera(current); - if (active == render) { + if (active == render) + { parent->getScenery()->setCamera(active); } } @@ -92,3 +125,15 @@ void ModelerCameras::changeActiveCamera(const QString &name) active = topdown; } } + +void ModelerCameras::toolChanged(const QString &tool) +{ + if (tool.isEmpty()) + { + endTool(); + } + else if (tool == "sun") + { + startSunTool(); + } +} diff --git a/src/interface/modeler/quickapp/ModelerCameras.h b/src/interface/modeler/quickapp/ModelerCameras.h index 40d851b..5de385c 100644 --- a/src/interface/modeler/quickapp/ModelerCameras.h +++ b/src/interface/modeler/quickapp/ModelerCameras.h @@ -4,6 +4,7 @@ #include "modeler_global.h" #include +#include "DefinitionWatcher.h" namespace paysages { namespace modeler { @@ -11,7 +12,7 @@ namespace modeler { /** * Storage for modeler cameras. */ -class ModelerCameras: public QObject +class ModelerCameras: public QObject, public DefinitionWatcher { Q_OBJECT @@ -34,9 +35,21 @@ public: */ void processPanning(double xvalue, double yvalue); + /** + * Start a sun tool, the camera will follow the sun. + */ + void startSunTool(); + + /** + * End the tool mode. + */ + void endTool(); + protected: void timerEvent(QTimerEvent *event); + virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override; + /** * Validate current camera, pushing it to rendered scenery if needed. */ @@ -44,6 +57,7 @@ protected: public slots: void changeActiveCamera(const QString &name); + void toolChanged(const QString &tool); private: MainModelerWindow *parent; @@ -51,6 +65,14 @@ private: CameraDefinition *current; CameraDefinition *render; CameraDefinition *topdown; + CameraDefinition *tool; + + typedef enum + { + TOOL_NONE, + TOOL_SUN + } CameraToolMode; + CameraToolMode tool_mode; }; } diff --git a/src/interface/modeler/quickapp/qml/AtmosphereSection.qml b/src/interface/modeler/quickapp/qml/AtmosphereSection.qml index 08014d6..cfb3dbf 100644 --- a/src/interface/modeler/quickapp/qml/AtmosphereSection.qml +++ b/src/interface/modeler/quickapp/qml/AtmosphereSection.qml @@ -14,6 +14,12 @@ BaseSection { hovertext: qsTr("Change the time of day") } + ToolbarButton { + id: tool_sun_radius + picture: "images/icon_sun_radius.png" + hovertext: qsTr("Radius of the sun") + } + ToolbarButton { id: tool_humidity picture: "images/icon_atmosphere.png" @@ -34,6 +40,15 @@ BaseSection { objectName: "atmosphere_humidity" } + PanelSimpleFloat { + id: panel_sun_radius + anchors.left: toolbar.right + minimumValue: 0 + maximumValue: 3 + enabled: false + objectName: "atmosphere_sun_radius" + } + states: [ State { name: "DayTime" @@ -43,6 +58,18 @@ BaseSection { enabled: true } }, + State { + name: "Sun radius" + when: tool_sun_radius.checked + PropertyChanges { + target: panel_sun_radius + enabled: true + } + PropertyChanges { + target: section + tool: "sun" + } + }, State { name: "Humidity" when: tool_humidity.checked diff --git a/src/interface/modeler/quickapp/qml/BaseSection.qml b/src/interface/modeler/quickapp/qml/BaseSection.qml index 1d492e5..8ca09d1 100644 --- a/src/interface/modeler/quickapp/qml/BaseSection.qml +++ b/src/interface/modeler/quickapp/qml/BaseSection.qml @@ -1,6 +1,8 @@ import QtQuick 2.0 BaseRectangle { + property string tool: "" + anchors.bottom: main_ui.bottom height: main_ui.height - primary_toolbar.height } diff --git a/src/interface/modeler/quickapp/qml/app.qrc b/src/interface/modeler/quickapp/qml/app.qrc index 81d6070..cea9132 100644 --- a/src/interface/modeler/quickapp/qml/app.qrc +++ b/src/interface/modeler/quickapp/qml/app.qrc @@ -52,5 +52,6 @@ images/icon_render_medium.png images/icon_render_final.png images/icon_cancel.png + images/icon_sun_radius.png diff --git a/src/interface/modeler/quickapp/qml/images/icon_sun_radius.png b/src/interface/modeler/quickapp/qml/images/icon_sun_radius.png new file mode 100644 index 0000000000000000000000000000000000000000..cea67dce1a8dba5b0faf3acc381958512825280d GIT binary patch literal 1930 zcmV;52X**~P)g?gpzikv1^@$%Gyuo}vX%E#>gG}JIZdaN%1;2#MG=5BU^(!tMs5MHyM^-EN?FEr zPXXklK|nsxH-dfkl-05W<-ph!>qysh=>l{YFon`8D{39?q`4k5?!BOf{;m-WLb8Bj z)teI~0G0xmfhDf{o7C7Nz|a8R6VsHkfPyFi@R1tzmg{~O;7vU%0d5H3UGJ;DTix@e zJ;m_=n_TxBfJMMw;3iz z)H0W<)Ou+^W`sMRCp$1*Al$3vF;%JSNC5N(-UBAewVei>_E~4Gj9^}r0BAA-A+z)E zsPjL{A-WX6yJ}^0^P*$}K9q;HPrrxi-XvfTFd?AMn*j8Rnz}oNZInjb0(Qtl3{s{5 z_3|qMYji3y7+3{-22^Tp|7pz8gFfmWkl@)E8N$jS;&%)95*RLjKA8aJHsEuE_(+tF z12eHHvt;6lF~Ilw@BMMg6^MB{;}?LL#%NipVv z1DU|>Vp|+8?=&!8&vQjnSplSSskt+kPZ=FPDRb#S_km^2VbaWN4)&OF&uFq<4+)}2PU|bl>*+^i8=KNh+zpa4Nqart!1EYbLb^oZL zA*(&K#*stVH2l;s*Y)e<#8@GuOR_UDd5g}9;Wm^{>RFlm3rF^;j=5n1Ff63bJ87*! zZXAo_*`))os!W9^fV(eqa_Y?+ncXwrh&Kp+QcIM~v zBTK&Dr>~#W1{%>ZDsj$ieY{+sJ3eWs5J^t zl0(zIl`PK3ZP58fd4j1-&B-!|o?5y}>a_*fsq3O7EAOv0wk@o`-)L?qu*TE^N0w=c z*r+AruwJ+`3Fh{o5hBkI8Gxbyw5T&4r(+h&N!X^}g>oV+`Pg2^Y0Q9UuROFYO{1^? zm>kyJnu~oJW1n&F79-kQ?J7S)o|q-0X_6OfLhAg1FpbMp1qz2esH8F%2&0XW-y;8f zA@G5ipTXFN5rXV|qX>{ua)s{;8h~+H3d=m6O_cGmfY-3Mt}WncQBB2Knk+?VU>|b0 z5+DG}Rj(5cUr~rWBq#t1wG_s)vh!S2*k-Xn&hN{>C#I93snF=N<4xE*L@|Sq-KF-qMX7ZDBCsKj0lr7fvQzem+Lv-r*Tvw> zdM7Bi!S&JwNx07AwS2Xv^Is{LNhH0*0v|X2x5SSYoKZ}W=oH0hX~4=>s$EQOc6|#S z-wn)2k`i|$5Bq@CX&K?9#eHI`QWkx(;_VRkU6CC5mH_ah0oB0IMl@MRgeBd>5yFctX@%4S4`A;Kk5zb`-qAF` z@BVqE!s8P86kA)UGcrfm3k-KO7C?PNfL~oE%s>$O&J9Irh3p;o{Dp!u7>a+<#ZbX?y((yFC#>_WQ(kggaZ z!^krf(G_5Syf9SPg>g8!CYrzfb3Rq8Q5f6<`;e8x>J&u{fK(&C0s|l?A42mcg!BDh zrrztk`%aoap6svyv=k9KpRwf|*Zr`mw64HI;tBqh0JH>7j@ogG|E2BaZ&VLKhZ|%} Qu>b%707*qoM6N<$f@L9rRsaA1 literal 0 HcmV?d00001 diff --git a/src/interface/modeler/quickapp/qml/main.qml b/src/interface/modeler/quickapp/qml/main.qml index 969f138..b998fa9 100644 --- a/src/interface/modeler/quickapp/qml/main.qml +++ b/src/interface/modeler/quickapp/qml/main.qml @@ -5,10 +5,16 @@ OpenGLView { id: main_ui state: "Loading" property string previous_state + property var current: null + property string tool: (current && current.tool) ? current.tool : "" + + signal mainToolChanged(string tool) width: 1280 height: 720 + onToolChanged: mainToolChanged(tool) + Tooltip { id: tooltip_widget @@ -194,6 +200,10 @@ OpenGLView { target: water_section enabled: true } + PropertyChanges { + target: main_ui + current: water_section + } }, State { name: "Atmosphere Mode" @@ -203,6 +213,10 @@ OpenGLView { target: atmosphere_section enabled: true } + PropertyChanges { + target: main_ui + current: atmosphere_section + } }, State { name: "Render Mode" diff --git a/src/render/opengl/OpenGLSkybox.cpp b/src/render/opengl/OpenGLSkybox.cpp index a510f8a..5c45a7e 100644 --- a/src/render/opengl/OpenGLSkybox.cpp +++ b/src/render/opengl/OpenGLSkybox.cpp @@ -54,6 +54,7 @@ void OpenGLSkybox::initialize() // Watch for definition changes renderer->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this, true); renderer->getScenery()->getAtmosphere()->propHumidity()->addWatcher(this, true); + renderer->getScenery()->getAtmosphere()->propSunRadius()->addWatcher(this, true); } void OpenGLSkybox::update() @@ -84,6 +85,10 @@ void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff { renderer->getSharedState()->set("atmosphereHumidity", renderer->getScenery()->getAtmosphere()->propHumidity()->getValue()); } + else if (node->getPath() == "/atmosphere/sun_radius") + { + renderer->getSharedState()->set("sunRadius", renderer->getScenery()->getAtmosphere()->propSunRadius()->getValue()); + } } void OpenGLSkybox::setVertex(int i, float x, float y, float z) diff --git a/src/render/opengl/shaders/atmosphere.frag b/src/render/opengl/shaders/atmosphere.frag index 0ca341e..1fca38f 100644 --- a/src/render/opengl/shaders/atmosphere.frag +++ b/src/render/opengl/shaders/atmosphere.frag @@ -14,8 +14,6 @@ const float SPHERE_SIZE = 20000.0; const float WORLD_SCALING = 0.05; const float SUN_DISTANCE = 149597870.0; const float SUN_DISTANCE_SCALED = (SUN_DISTANCE / WORLD_SCALING); -const float SUN_RADIUS = 6.955e5; -const float SUN_RADIUS_SCALED = (SUN_RADIUS / WORLD_SCALING); const float M_PI = 3.141592657; const int RES_MU = 128; @@ -29,7 +27,7 @@ uniform vec3 cameraLocation; uniform vec3 sunDirection; uniform vec4 sunColor; uniform float dayTime; -const float sunRadius = 1.0; // TODO -> uniform +uniform float sunRadius; varying vec3 unprojected; diff --git a/src/render/software/AtmosphereModelBruneton.cpp b/src/render/software/AtmosphereModelBruneton.cpp index fa1eb81..d8efadc 100644 --- a/src/render/software/AtmosphereModelBruneton.cpp +++ b/src/render/software/AtmosphereModelBruneton.cpp @@ -22,6 +22,7 @@ #include "Texture2D.h" #include "Texture4D.h" #include "CacheFile.h" +#include "FloatNode.h" /* Factor to convert software units to kilometers */ // TODO This is copied in AtmosphereRenderer @@ -29,8 +30,6 @@ #define WORLD_SCALING 0.05 #define SUN_DISTANCE 149597870.0 #define SUN_DISTANCE_SCALED (SUN_DISTANCE / WORLD_SCALING) -#define SUN_RADIUS 6.955e5 -#define SUN_RADIUS_SCALED (SUN_RADIUS / WORLD_SCALING) #define WORKAROUND_OFFSET 0.2 /*********************** Constants ***********************/ @@ -1166,7 +1165,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 AtmosphereResult result; Vector3 attenuation; - Color sunColor = _sunColor(v, s, r, mu, parent->getScenery()->getAtmosphere()->sun_radius); /* L0 */ + Color sunColor = _sunColor(v, s, r, mu, parent->getScenery()->getAtmosphere()->propSunRadius()->getValue()); /* L0 */ /*result.base.r = base.r + sunColor.r; result.base.g = base.g + sunColor.g;