From db0be5204f9446e22ce23e1270de37aef602f33a Mon Sep 17 00:00:00 2001 From: Michael Lemaire Date: Tue, 18 Aug 2015 20:31:11 +0200 Subject: [PATCH] Switched /atmosphere/daytime to new definition system --- src/definition/AtmosphereDefinition.cpp | 63 +++++++------------ src/definition/AtmosphereDefinition.h | 20 ++++-- src/definition/TerrainDefinition.cpp | 2 +- src/interface/commandline/main.cpp | 3 +- .../modeler/quickapp/AtmosphereModeler.cpp | 16 ++--- .../modeler/quickapp/AtmosphereModeler.h | 2 + .../modeler/quickapp/MainModelerWindow.cpp | 20 +++--- .../modeler/quickapp/MainModelerWindow.h | 3 +- src/render/opengl/OpenGLSkybox.cpp | 23 ++++--- src/render/opengl/OpenGLSkybox.h | 6 +- src/render/opengl/OpenGLTerrain.cpp | 6 ++ src/render/software/AtmosphereRenderer.cpp | 11 ++-- src/render/software/AtmosphereRenderer.h | 4 +- src/render/software/SoftwareRenderer.cpp | 12 ++-- src/tests/AtmosphereDefinition_Test.cpp | 46 +++++++------- 15 files changed, 125 insertions(+), 112 deletions(-) diff --git a/src/definition/AtmosphereDefinition.cpp b/src/definition/AtmosphereDefinition.cpp index 42d3e66..627f74d 100644 --- a/src/definition/AtmosphereDefinition.cpp +++ b/src/definition/AtmosphereDefinition.cpp @@ -2,10 +2,12 @@ #include "PackStream.h" #include "RandomGenerator.h" +#include "FloatNode.h" AtmosphereDefinition::AtmosphereDefinition(DefinitionNode* parent): DefinitionNode(parent, "atmosphere", "atmosphere") { + daytime = new FloatNode(this, "daytime"); } AtmosphereDefinition::~AtmosphereDefinition() @@ -15,8 +17,6 @@ AtmosphereDefinition::~AtmosphereDefinition() void AtmosphereDefinition::save(PackStream* stream) const { stream->write((int*)&model); - stream->write(&hour); - stream->write(&minute); sun_color.save(stream); stream->write(&sun_radius); stream->write(&dome_lighting); @@ -38,8 +38,6 @@ void AtmosphereDefinition::save(PackStream* stream) const void AtmosphereDefinition::load(PackStream* stream) { stream->read((int*)&model); - stream->read(&hour); - stream->read(&minute); sun_color.load(stream); stream->read(&sun_radius); stream->read(&dome_lighting); @@ -68,9 +66,9 @@ void AtmosphereDefinition::copy(DefinitionNode* _destination) const { AtmosphereDefinition* destination = (AtmosphereDefinition*)_destination; + daytime->copy(destination->daytime); + destination->model = model; - destination->hour = hour; - destination->minute = minute; destination->sun_color = sun_color; destination->sun_radius = sun_radius; destination->dome_lighting = dome_lighting; @@ -83,30 +81,19 @@ void AtmosphereDefinition::copy(DefinitionNode* _destination) const destination->validate(); } -void AtmosphereDefinition::validate() +void AtmosphereDefinition::setDayTime(double value) { - if (hour < 0) - { - hour = 0; - } - if (hour > 23) - { - hour = 23; - } - if (minute < 0) - { - minute = 0; - } - if (minute > 59) - { - minute = 59; - } - - _daytime = (double)hour / 24.0 + (double)minute / 1440.0; + daytime->setValue(value); } -void AtmosphereDefinition::setDaytime(double value) +void AtmosphereDefinition::setDayTime(int hour, int minute, int second) { + setDayTime((double)hour / 24.0 + (double)minute / 1440.0 + (double)second / 86400.0); +} + +void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const +{ + double value = daytime->getValue(); if (value >= 0.0) { value = fmod(value, 1.0); @@ -115,10 +102,11 @@ void AtmosphereDefinition::setDaytime(double value) { value = 1.0 - fmod(-value, 1.0); } - value *= 1440.0; - hour = value / 60.0; - minute = value - 60.0 * hour; - validate(); + value *= 86400.0; + *hour = value / 3600.0; + value -= 3600.0 * *hour; + *minute = value / 60.0; + *second = value - *minute * 60.0; } void AtmosphereDefinition::applyPreset(AtmospherePreset preset) @@ -138,31 +126,26 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset) switch (preset) { case ATMOSPHERE_PRESET_CLEAR_DAY: - hour = 15; - minute = 0; + setDayTime(15); dome_lighting = 0.2; break; case ATMOSPHERE_PRESET_CLEAR_SUNSET: - hour = 17; - minute = 45; + setDayTime(17, 45); dome_lighting = 0.3; sun_radius = 0.03; break; case ATMOSPHERE_PRESET_HAZY_MORNING: - hour = 8; - minute = 30; + setDayTime(8, 30); dome_lighting = 0.25; humidity = 0.4; break; case ATMOSPHERE_PRESET_FOGGY: - hour = 15; - minute = 0; + setDayTime(15); dome_lighting = 0.1; humidity = 0.7; break; case ATMOSPHERE_PRESET_STORMY: - hour = 15; - minute = 0; + setDayTime(15); dome_lighting = 0.05; humidity = 0.9; break; diff --git a/src/definition/AtmosphereDefinition.h b/src/definition/AtmosphereDefinition.h index 1d384ef..233e849 100644 --- a/src/definition/AtmosphereDefinition.h +++ b/src/definition/AtmosphereDefinition.h @@ -44,20 +44,27 @@ public: virtual void load(PackStream* stream) override; virtual void copy(DefinitionNode* destination) const override; - virtual void validate() override; + + inline FloatNode *propDayTime() const {return daytime;} /** * Set the daytime from a 0.0-1.0 value. */ - void setDaytime(double value); + void setDayTime(double value); + /** + * Set the daytime from hour/minute/second info. + */ + void setDayTime(int hour, int minute=0, int second=0); + /** + * Get the daytime info, in hour/minute/second. + */ + void getHMS(int *hour, int *minute, int *second) const; void applyPreset(AtmospherePreset preset); void generateStars(int count); public: AtmosphereModel model; - int hour; - int minute; double humidity; Color sun_color; double sun_radius; @@ -67,9 +74,10 @@ public: double moon_theta; double moon_phi; - double _daytime; - std::vector stars; + +private: + FloatNode *daytime; }; } diff --git a/src/definition/TerrainDefinition.cpp b/src/definition/TerrainDefinition.cpp index ef00cc1..95328fd 100644 --- a/src/definition/TerrainDefinition.cpp +++ b/src/definition/TerrainDefinition.cpp @@ -52,7 +52,7 @@ void TerrainDefinition::copy(DefinitionNode* _destination) const height_map->copy(destination->height_map); - destination->water_height = water_height; + water_height->copy(destination->water_height); _height_noise->copy(destination->_height_noise); diff --git a/src/interface/commandline/main.cpp b/src/interface/commandline/main.cpp index 7047661..7cb35de 100644 --- a/src/interface/commandline/main.cpp +++ b/src/interface/commandline/main.cpp @@ -196,8 +196,7 @@ int main(int argc, char** argv) for (outputcount = 0; outputcount < conf_first_picture + conf_nb_pictures; outputcount++) { AtmosphereDefinition* atmo = scenery->getAtmosphere(); - atmo->hour = (int)floor(conf_daytime_start * 24.0); - atmo->minute = (int)floor(fmod(conf_daytime_start, 1.0 / 24.0) * 24.0 * 60.0); + atmo->setDayTime(conf_daytime_start); atmo->validate(); CameraDefinition* camera = scenery->getCamera(); diff --git a/src/interface/modeler/quickapp/AtmosphereModeler.cpp b/src/interface/modeler/quickapp/AtmosphereModeler.cpp index f562a61..091171a 100644 --- a/src/interface/modeler/quickapp/AtmosphereModeler.cpp +++ b/src/interface/modeler/quickapp/AtmosphereModeler.cpp @@ -6,6 +6,7 @@ #include "OpenGLRenderer.h" #include "OpenGLSkybox.h" #include "OpenGLTerrain.h" +#include "FloatNode.h" AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main): main(main) @@ -13,18 +14,17 @@ AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main): QObject *item = main->findQmlObject("atmosphere_daytime"); if (item) { + item->setProperty("value", propDayTime()->getValue()); 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(); - - // Update terrain textures according to new lighting - main->getRenderer()->getTerrain()->resetTextures(); + propDayTime()->setValue(value); +} + +FloatNode *AtmosphereModeler::propDayTime() const +{ + return main->getScenery()->getAtmosphere()->propDayTime(); } diff --git a/src/interface/modeler/quickapp/AtmosphereModeler.h b/src/interface/modeler/quickapp/AtmosphereModeler.h index 1a5b32d..25d6aa6 100644 --- a/src/interface/modeler/quickapp/AtmosphereModeler.h +++ b/src/interface/modeler/quickapp/AtmosphereModeler.h @@ -18,6 +18,8 @@ public slots: void daytimeChanged(double value); private: + FloatNode *propDayTime() const; + MainModelerWindow *main; }; diff --git a/src/interface/modeler/quickapp/MainModelerWindow.cpp b/src/interface/modeler/quickapp/MainModelerWindow.cpp index c25208f..b5db284 100644 --- a/src/interface/modeler/quickapp/MainModelerWindow.cpp +++ b/src/interface/modeler/quickapp/MainModelerWindow.cpp @@ -17,12 +17,12 @@ MainModelerWindow::MainModelerWindow() { - scenery = new Scenery(); - scenery->autoPreset(); + Scenery scenery; + scenery.autoPreset(); - Logs::debug() << "Initialized scenery:\n" << scenery->toString() << std::endl; + Logs::debug() << "Initialized scenery:\n" << scenery.toString() << std::endl; - renderer = new OpenGLRenderer(scenery); + renderer = new OpenGLRenderer(&scenery); render_preview_provider = new RenderPreviewProvider(); @@ -51,7 +51,6 @@ MainModelerWindow::~MainModelerWindow() delete render_process; delete renderer; - delete scenery; } QObject *MainModelerWindow::findQmlObject(const QString &objectName) @@ -78,6 +77,11 @@ void MainModelerWindow::setState(const QString &stateName) rootObject()->setProperty("state", stateName); } +Scenery *MainModelerWindow::getScenery() const +{ + return renderer->getScenery(); +} + void MainModelerWindow::keyReleaseEvent(QKeyEvent *event) { if (getState() == "Render Dialog") @@ -120,11 +124,11 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event) { if (event->modifiers() & Qt::ShiftModifier) { - scenery->getDiffManager()->redo(); + getScenery()->getDiffManager()->redo(); } else { - scenery->getDiffManager()->undo(); + getScenery()->getDiffManager()->undo(); } } } @@ -132,7 +136,7 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event) { if (event->modifiers() & Qt::ControlModifier) { - scenery->getDiffManager()->undo(); + getScenery()->getDiffManager()->undo(); } } } diff --git a/src/interface/modeler/quickapp/MainModelerWindow.h b/src/interface/modeler/quickapp/MainModelerWindow.h index 0f235d3..0f55752 100644 --- a/src/interface/modeler/quickapp/MainModelerWindow.h +++ b/src/interface/modeler/quickapp/MainModelerWindow.h @@ -21,7 +21,7 @@ public: QString getState() const; void setState(const QString &stateName); - inline Scenery *getScenery() const {return scenery;} + Scenery *getScenery() const; inline OpenGLRenderer *getRenderer() const {return renderer;} inline ModelerCameras *getCamera() const {return cameras;} @@ -30,7 +30,6 @@ protected: private: OpenGLRenderer *renderer; - Scenery *scenery; AtmosphereModeler *atmosphere; WaterModeler *water; diff --git a/src/render/opengl/OpenGLSkybox.cpp b/src/render/opengl/OpenGLSkybox.cpp index 6b6e879..8be2f05 100644 --- a/src/render/opengl/OpenGLSkybox.cpp +++ b/src/render/opengl/OpenGLSkybox.cpp @@ -8,12 +8,12 @@ #include "AtmosphereDefinition.h" #include "AtmosphereRenderer.h" #include "AtmosphereModelBruneton.h" +#include "FloatNode.h" OpenGLSkybox::OpenGLSkybox(OpenGLRenderer* renderer): OpenGLPart(renderer) { vertices = new float[14 * 3]; - daytime = renderer->getScenery()->getAtmosphere()->_daytime; } OpenGLSkybox::~OpenGLSkybox() @@ -50,16 +50,13 @@ void OpenGLSkybox::initialize() setVertex(11, 1.0f, 1.0f, -1.0f); setVertex(9, -1.0f, 1.0f, -1.0f); + + // Watch for definition changes + renderer->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this, true); } void OpenGLSkybox::update() { - Vector3 sun_direction = renderer->getAtmosphereRenderer()->getSunDirection(); - renderer->getSharedState()->set("sunDirection", sun_direction); - - Color sun_color = renderer->getScenery()->getAtmosphere()->sun_color; - renderer->getSharedState()->set("sunColor", sun_color); - SoftwareBrunetonAtmosphereRenderer* bruneton = (SoftwareBrunetonAtmosphereRenderer*)renderer->getAtmosphereRenderer(); renderer->getSharedState()->set("transmittanceTexture", bruneton->getModel()->getTextureTransmittance()); renderer->getSharedState()->set("inscatterTexture", bruneton->getModel()->getTextureInscatter()); @@ -70,6 +67,18 @@ void OpenGLSkybox::render() program->drawTriangleStrip(vertices, 14); } +void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) +{ + if (node->getPath() == "/atmosphere/daytime") + { + Vector3 sun_direction = renderer->getAtmosphereRenderer()->getSunDirection(false); + renderer->getSharedState()->set("sunDirection", sun_direction); + + Color sun_color = renderer->getScenery()->getAtmosphere()->sun_color; + renderer->getSharedState()->set("sunColor", sun_color); + } +} + void OpenGLSkybox::setVertex(int i, float x, float y, float z) { vertices[i * 3] = x; diff --git a/src/render/opengl/OpenGLSkybox.h b/src/render/opengl/OpenGLSkybox.h index 9ff5409..7b36cc8 100644 --- a/src/render/opengl/OpenGLSkybox.h +++ b/src/render/opengl/OpenGLSkybox.h @@ -4,11 +4,12 @@ #include "opengl_global.h" #include "OpenGLPart.h" +#include "DefinitionWatcher.h" namespace paysages { namespace opengl { -class OPENGLSHARED_EXPORT OpenGLSkybox: public OpenGLPart +class OPENGLSHARED_EXPORT OpenGLSkybox: public OpenGLPart, public DefinitionWatcher { public: OpenGLSkybox(OpenGLRenderer* renderer); @@ -18,13 +19,12 @@ public: virtual void update() override; virtual void render() override; + virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override; private: void setVertex(int i, float x, float y, float z); OpenGLShaderProgram* program; float* vertices; - - double daytime; }; } diff --git a/src/render/opengl/OpenGLTerrain.cpp b/src/render/opengl/OpenGLTerrain.cpp index 33acb1b..070e330 100644 --- a/src/render/opengl/OpenGLTerrain.cpp +++ b/src/render/opengl/OpenGLTerrain.cpp @@ -8,6 +8,7 @@ #include "ExplorerChunkTerrain.h" #include "WaterRenderer.h" #include "CameraDefinition.h" +#include "AtmosphereDefinition.h" #include "Scenery.h" #include "FloatNode.h" #include "FloatDiff.h" @@ -84,6 +85,7 @@ void OpenGLTerrain::initialize() // Watch for definition changes renderer->getScenery()->getTerrain()->propWaterHeight()->addWatcher(this); + renderer->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this); } void OpenGLTerrain::update() @@ -174,4 +176,8 @@ void OpenGLTerrain::nodeChanged(const DefinitionNode *node, const DefinitionDiff { resetTextures(); } + else if (node->getPath() == "/atmosphere/daytime") + { + resetTextures(); + } } diff --git a/src/render/software/AtmosphereRenderer.cpp b/src/render/software/AtmosphereRenderer.cpp index 49e8d5f..1532b89 100644 --- a/src/render/software/AtmosphereRenderer.cpp +++ b/src/render/software/AtmosphereRenderer.cpp @@ -9,6 +9,7 @@ #include "LightStatus.h" #include "Scenery.h" #include "NightSky.h" +#include "FloatNode.h" /* Factor to convert software units to kilometers */ #define WORLD_SCALING 0.05 @@ -41,7 +42,7 @@ static inline void _applyWeatherEffects(AtmosphereDefinition* definition, Atmosp } distancefactor = (distance > max_distance ? max_distance : distance) / max_distance; /* TODO Get day lighting from model */ - dayfactor = _getDayFactor(definition->_daytime); + dayfactor = _getDayFactor(definition->propDayTime()->getValue()); /* Fog masking */ if (definition->humidity > 0.3) @@ -105,16 +106,16 @@ AtmosphereResult BaseAtmosphereRenderer::getSkyColor(Vector3) return result; } -Vector3 BaseAtmosphereRenderer::getSunDirection() +Vector3 BaseAtmosphereRenderer::getSunDirection(bool cache) const { - if (lights.size() > 0) + if (cache and lights.size() > 0) { return lights[0].direction.scale(-1.0); } else { AtmosphereDefinition* atmosphere = getDefinition(); - double sun_angle = (atmosphere->_daytime + 0.75) * M_PI * 2.0; + double sun_angle = (atmosphere->propDayTime()->getValue() + 0.75) * M_PI * 2.0; return Vector3(cos(sun_angle), sin(sun_angle), 0.0); } } @@ -153,7 +154,7 @@ void BaseAtmosphereRenderer::setStaticLights(const std::vector & this->lights = lights; } -AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition() +AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition() const { return parent->getScenery()->getAtmosphere(); } diff --git a/src/render/software/AtmosphereRenderer.h b/src/render/software/AtmosphereRenderer.h index bdda48f..48969e0 100644 --- a/src/render/software/AtmosphereRenderer.h +++ b/src/render/software/AtmosphereRenderer.h @@ -18,13 +18,13 @@ public: virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque); virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base); virtual AtmosphereResult getSkyColor(Vector3 direction); - virtual Vector3 getSunDirection(); + virtual Vector3 getSunDirection(bool cache=true) const; void setBasicLights(); void setStaticLights(const std::vector &lights); protected: - virtual AtmosphereDefinition* getDefinition(); + virtual AtmosphereDefinition* getDefinition() const; SoftwareRenderer* parent; std::vector lights; }; diff --git a/src/render/software/SoftwareRenderer.cpp b/src/render/software/SoftwareRenderer.cpp index b53ba5d..3dd6a01 100644 --- a/src/render/software/SoftwareRenderer.cpp +++ b/src/render/software/SoftwareRenderer.cpp @@ -22,6 +22,12 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery) { + this->scenery = new Scenery; + if (scenery) + { + scenery->copy(this->scenery); + } + render_quality = 5; render_camera = new CameraDefinition; @@ -39,12 +45,6 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery) lighting->registerFilter(water_renderer); lighting->registerFilter(terrain_renderer); lighting->registerFilter(clouds_renderer); - - this->scenery = new Scenery; - if (scenery) - { - scenery->copy(this->scenery); - } } SoftwareRenderer::~SoftwareRenderer() diff --git a/src/tests/AtmosphereDefinition_Test.cpp b/src/tests/AtmosphereDefinition_Test.cpp index 5e151a0..a8f921a 100644 --- a/src/tests/AtmosphereDefinition_Test.cpp +++ b/src/tests/AtmosphereDefinition_Test.cpp @@ -2,35 +2,37 @@ #include "AtmosphereDefinition.h" -TEST(AtmosphereDefinition, setDaytime) +static void check_daytime(const AtmosphereDefinition &atmo, int expected_hour, int expected_minute=0, int expected_second=0) +{ + int hour, minute, second; + atmo.getHMS(&hour, &minute, &second); + EXPECT_EQ(expected_hour, hour); + EXPECT_EQ(expected_minute, minute); + EXPECT_EQ(expected_second, second); +} + +TEST(AtmosphereDefinition, setDayTime) { AtmosphereDefinition atmo(NULL); - atmo.setDaytime(0.0); - EXPECT_EQ(atmo.hour, 0); - EXPECT_EQ(atmo.minute, 0); + atmo.setDayTime(0.0); + check_daytime(atmo, 0); - atmo.setDaytime(0.1); - EXPECT_EQ(atmo.hour, 2); - EXPECT_EQ(atmo.minute, 24); + atmo.setDayTime(0.1); + check_daytime(atmo, 2, 24); - atmo.setDaytime(0.25); - EXPECT_EQ(atmo.hour, 6); - EXPECT_EQ(atmo.minute, 0); + atmo.setDayTime(0.25); + check_daytime(atmo, 6); - atmo.setDaytime(0.5); - EXPECT_EQ(atmo.hour, 12); - EXPECT_EQ(atmo.minute, 0); + atmo.setDayTime(0.5); + check_daytime(atmo, 12); - atmo.setDaytime(1.0); - EXPECT_EQ(atmo.hour, 0); - EXPECT_EQ(atmo.minute, 0); + atmo.setDayTime(1.0); + check_daytime(atmo, 0); - atmo.setDaytime(-0.5); - EXPECT_EQ(atmo.hour, 12); - EXPECT_EQ(atmo.minute, 0); + atmo.setDayTime(-0.5); + check_daytime(atmo, 12); - atmo.setDaytime(1.5); - EXPECT_EQ(atmo.hour, 12); - EXPECT_EQ(atmo.minute, 0); + atmo.setDayTime(1.5); + check_daytime(atmo, 12); }