Switched /atmosphere/daytime to new definition system

This commit is contained in:
Michaël Lemaire 2015-08-18 20:31:11 +02:00
parent e96fdd9721
commit db0be5204f
15 changed files with 125 additions and 112 deletions

View file

@ -2,10 +2,12 @@
#include "PackStream.h" #include "PackStream.h"
#include "RandomGenerator.h" #include "RandomGenerator.h"
#include "FloatNode.h"
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode* parent): AtmosphereDefinition::AtmosphereDefinition(DefinitionNode* parent):
DefinitionNode(parent, "atmosphere", "atmosphere") DefinitionNode(parent, "atmosphere", "atmosphere")
{ {
daytime = new FloatNode(this, "daytime");
} }
AtmosphereDefinition::~AtmosphereDefinition() AtmosphereDefinition::~AtmosphereDefinition()
@ -15,8 +17,6 @@ AtmosphereDefinition::~AtmosphereDefinition()
void AtmosphereDefinition::save(PackStream* stream) const void AtmosphereDefinition::save(PackStream* stream) const
{ {
stream->write((int*)&model); stream->write((int*)&model);
stream->write(&hour);
stream->write(&minute);
sun_color.save(stream); sun_color.save(stream);
stream->write(&sun_radius); stream->write(&sun_radius);
stream->write(&dome_lighting); stream->write(&dome_lighting);
@ -38,8 +38,6 @@ void AtmosphereDefinition::save(PackStream* stream) const
void AtmosphereDefinition::load(PackStream* stream) void AtmosphereDefinition::load(PackStream* stream)
{ {
stream->read((int*)&model); stream->read((int*)&model);
stream->read(&hour);
stream->read(&minute);
sun_color.load(stream); sun_color.load(stream);
stream->read(&sun_radius); stream->read(&sun_radius);
stream->read(&dome_lighting); stream->read(&dome_lighting);
@ -68,9 +66,9 @@ void AtmosphereDefinition::copy(DefinitionNode* _destination) const
{ {
AtmosphereDefinition* destination = (AtmosphereDefinition*)_destination; AtmosphereDefinition* destination = (AtmosphereDefinition*)_destination;
daytime->copy(destination->daytime);
destination->model = model; destination->model = model;
destination->hour = hour;
destination->minute = minute;
destination->sun_color = sun_color; destination->sun_color = sun_color;
destination->sun_radius = sun_radius; destination->sun_radius = sun_radius;
destination->dome_lighting = dome_lighting; destination->dome_lighting = dome_lighting;
@ -83,30 +81,19 @@ void AtmosphereDefinition::copy(DefinitionNode* _destination) const
destination->validate(); destination->validate();
} }
void AtmosphereDefinition::validate() void AtmosphereDefinition::setDayTime(double value)
{ {
if (hour < 0) daytime->setValue(value);
{
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; void AtmosphereDefinition::setDayTime(int hour, int minute, int second)
{
setDayTime((double)hour / 24.0 + (double)minute / 1440.0 + (double)second / 86400.0);
} }
void AtmosphereDefinition::setDaytime(double value) void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const
{ {
double value = daytime->getValue();
if (value >= 0.0) if (value >= 0.0)
{ {
value = fmod(value, 1.0); value = fmod(value, 1.0);
@ -115,10 +102,11 @@ void AtmosphereDefinition::setDaytime(double value)
{ {
value = 1.0 - fmod(-value, 1.0); value = 1.0 - fmod(-value, 1.0);
} }
value *= 1440.0; value *= 86400.0;
hour = value / 60.0; *hour = value / 3600.0;
minute = value - 60.0 * hour; value -= 3600.0 * *hour;
validate(); *minute = value / 60.0;
*second = value - *minute * 60.0;
} }
void AtmosphereDefinition::applyPreset(AtmospherePreset preset) void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
@ -138,31 +126,26 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
switch (preset) switch (preset)
{ {
case ATMOSPHERE_PRESET_CLEAR_DAY: case ATMOSPHERE_PRESET_CLEAR_DAY:
hour = 15; setDayTime(15);
minute = 0;
dome_lighting = 0.2; dome_lighting = 0.2;
break; break;
case ATMOSPHERE_PRESET_CLEAR_SUNSET: case ATMOSPHERE_PRESET_CLEAR_SUNSET:
hour = 17; setDayTime(17, 45);
minute = 45;
dome_lighting = 0.3; dome_lighting = 0.3;
sun_radius = 0.03; sun_radius = 0.03;
break; break;
case ATMOSPHERE_PRESET_HAZY_MORNING: case ATMOSPHERE_PRESET_HAZY_MORNING:
hour = 8; setDayTime(8, 30);
minute = 30;
dome_lighting = 0.25; dome_lighting = 0.25;
humidity = 0.4; humidity = 0.4;
break; break;
case ATMOSPHERE_PRESET_FOGGY: case ATMOSPHERE_PRESET_FOGGY:
hour = 15; setDayTime(15);
minute = 0;
dome_lighting = 0.1; dome_lighting = 0.1;
humidity = 0.7; humidity = 0.7;
break; break;
case ATMOSPHERE_PRESET_STORMY: case ATMOSPHERE_PRESET_STORMY:
hour = 15; setDayTime(15);
minute = 0;
dome_lighting = 0.05; dome_lighting = 0.05;
humidity = 0.9; humidity = 0.9;
break; break;

View file

@ -44,20 +44,27 @@ public:
virtual void load(PackStream* stream) override; virtual void load(PackStream* stream) override;
virtual void copy(DefinitionNode* destination) const 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. * 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 applyPreset(AtmospherePreset preset);
void generateStars(int count); void generateStars(int count);
public: public:
AtmosphereModel model; AtmosphereModel model;
int hour;
int minute;
double humidity; double humidity;
Color sun_color; Color sun_color;
double sun_radius; double sun_radius;
@ -67,9 +74,10 @@ public:
double moon_theta; double moon_theta;
double moon_phi; double moon_phi;
double _daytime;
std::vector<Star> stars; std::vector<Star> stars;
private:
FloatNode *daytime;
}; };
} }

View file

@ -52,7 +52,7 @@ void TerrainDefinition::copy(DefinitionNode* _destination) const
height_map->copy(destination->height_map); height_map->copy(destination->height_map);
destination->water_height = water_height; water_height->copy(destination->water_height);
_height_noise->copy(destination->_height_noise); _height_noise->copy(destination->_height_noise);

View file

@ -196,8 +196,7 @@ int main(int argc, char** argv)
for (outputcount = 0; outputcount < conf_first_picture + conf_nb_pictures; outputcount++) for (outputcount = 0; outputcount < conf_first_picture + conf_nb_pictures; outputcount++)
{ {
AtmosphereDefinition* atmo = scenery->getAtmosphere(); AtmosphereDefinition* atmo = scenery->getAtmosphere();
atmo->hour = (int)floor(conf_daytime_start * 24.0); atmo->setDayTime(conf_daytime_start);
atmo->minute = (int)floor(fmod(conf_daytime_start, 1.0 / 24.0) * 24.0 * 60.0);
atmo->validate(); atmo->validate();
CameraDefinition* camera = scenery->getCamera(); CameraDefinition* camera = scenery->getCamera();

View file

@ -6,6 +6,7 @@
#include "OpenGLRenderer.h" #include "OpenGLRenderer.h"
#include "OpenGLSkybox.h" #include "OpenGLSkybox.h"
#include "OpenGLTerrain.h" #include "OpenGLTerrain.h"
#include "FloatNode.h"
AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main): AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main):
main(main) main(main)
@ -13,18 +14,17 @@ AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main):
QObject *item = main->findQmlObject("atmosphere_daytime"); QObject *item = main->findQmlObject("atmosphere_daytime");
if (item) if (item)
{ {
item->setProperty("value", propDayTime()->getValue());
connect(item, SIGNAL(changed(double)), this, SLOT(daytimeChanged(double))); connect(item, SIGNAL(changed(double)), this, SLOT(daytimeChanged(double)));
} }
} }
void AtmosphereModeler::daytimeChanged(double value) void AtmosphereModeler::daytimeChanged(double value)
{ {
main->getScenery()->getAtmosphere()->setDaytime(value); propDayTime()->setValue(value);
}
main->getRenderer()->getScenery()->setAtmosphere(main->getScenery()->getAtmosphere());
FloatNode *AtmosphereModeler::propDayTime() const
main->getRenderer()->getSkybox()->update(); {
return main->getScenery()->getAtmosphere()->propDayTime();
// Update terrain textures according to new lighting
main->getRenderer()->getTerrain()->resetTextures();
} }

View file

@ -18,6 +18,8 @@ public slots:
void daytimeChanged(double value); void daytimeChanged(double value);
private: private:
FloatNode *propDayTime() const;
MainModelerWindow *main; MainModelerWindow *main;
}; };

View file

@ -17,12 +17,12 @@
MainModelerWindow::MainModelerWindow() MainModelerWindow::MainModelerWindow()
{ {
scenery = new Scenery(); Scenery scenery;
scenery->autoPreset(); 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(); render_preview_provider = new RenderPreviewProvider();
@ -51,7 +51,6 @@ MainModelerWindow::~MainModelerWindow()
delete render_process; delete render_process;
delete renderer; delete renderer;
delete scenery;
} }
QObject *MainModelerWindow::findQmlObject(const QString &objectName) QObject *MainModelerWindow::findQmlObject(const QString &objectName)
@ -78,6 +77,11 @@ void MainModelerWindow::setState(const QString &stateName)
rootObject()->setProperty("state", stateName); rootObject()->setProperty("state", stateName);
} }
Scenery *MainModelerWindow::getScenery() const
{
return renderer->getScenery();
}
void MainModelerWindow::keyReleaseEvent(QKeyEvent *event) void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
{ {
if (getState() == "Render Dialog") if (getState() == "Render Dialog")
@ -120,11 +124,11 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
{ {
if (event->modifiers() & Qt::ShiftModifier) if (event->modifiers() & Qt::ShiftModifier)
{ {
scenery->getDiffManager()->redo(); getScenery()->getDiffManager()->redo();
} }
else else
{ {
scenery->getDiffManager()->undo(); getScenery()->getDiffManager()->undo();
} }
} }
} }
@ -132,7 +136,7 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
{ {
if (event->modifiers() & Qt::ControlModifier) if (event->modifiers() & Qt::ControlModifier)
{ {
scenery->getDiffManager()->undo(); getScenery()->getDiffManager()->undo();
} }
} }
} }

View file

@ -21,7 +21,7 @@ public:
QString getState() const; QString getState() const;
void setState(const QString &stateName); void setState(const QString &stateName);
inline Scenery *getScenery() const {return scenery;} Scenery *getScenery() const;
inline OpenGLRenderer *getRenderer() const {return renderer;} inline OpenGLRenderer *getRenderer() const {return renderer;}
inline ModelerCameras *getCamera() const {return cameras;} inline ModelerCameras *getCamera() const {return cameras;}
@ -30,7 +30,6 @@ protected:
private: private:
OpenGLRenderer *renderer; OpenGLRenderer *renderer;
Scenery *scenery;
AtmosphereModeler *atmosphere; AtmosphereModeler *atmosphere;
WaterModeler *water; WaterModeler *water;

View file

@ -8,12 +8,12 @@
#include "AtmosphereDefinition.h" #include "AtmosphereDefinition.h"
#include "AtmosphereRenderer.h" #include "AtmosphereRenderer.h"
#include "AtmosphereModelBruneton.h" #include "AtmosphereModelBruneton.h"
#include "FloatNode.h"
OpenGLSkybox::OpenGLSkybox(OpenGLRenderer* renderer): OpenGLSkybox::OpenGLSkybox(OpenGLRenderer* renderer):
OpenGLPart(renderer) OpenGLPart(renderer)
{ {
vertices = new float[14 * 3]; vertices = new float[14 * 3];
daytime = renderer->getScenery()->getAtmosphere()->_daytime;
} }
OpenGLSkybox::~OpenGLSkybox() OpenGLSkybox::~OpenGLSkybox()
@ -50,16 +50,13 @@ void OpenGLSkybox::initialize()
setVertex(11, 1.0f, 1.0f, -1.0f); setVertex(11, 1.0f, 1.0f, -1.0f);
setVertex(9, -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() 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(); SoftwareBrunetonAtmosphereRenderer* bruneton = (SoftwareBrunetonAtmosphereRenderer*)renderer->getAtmosphereRenderer();
renderer->getSharedState()->set("transmittanceTexture", bruneton->getModel()->getTextureTransmittance()); renderer->getSharedState()->set("transmittanceTexture", bruneton->getModel()->getTextureTransmittance());
renderer->getSharedState()->set("inscatterTexture", bruneton->getModel()->getTextureInscatter()); renderer->getSharedState()->set("inscatterTexture", bruneton->getModel()->getTextureInscatter());
@ -70,6 +67,18 @@ void OpenGLSkybox::render()
program->drawTriangleStrip(vertices, 14); 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) void OpenGLSkybox::setVertex(int i, float x, float y, float z)
{ {
vertices[i * 3] = x; vertices[i * 3] = x;

View file

@ -4,11 +4,12 @@
#include "opengl_global.h" #include "opengl_global.h"
#include "OpenGLPart.h" #include "OpenGLPart.h"
#include "DefinitionWatcher.h"
namespace paysages { namespace paysages {
namespace opengl { namespace opengl {
class OPENGLSHARED_EXPORT OpenGLSkybox: public OpenGLPart class OPENGLSHARED_EXPORT OpenGLSkybox: public OpenGLPart, public DefinitionWatcher
{ {
public: public:
OpenGLSkybox(OpenGLRenderer* renderer); OpenGLSkybox(OpenGLRenderer* renderer);
@ -18,13 +19,12 @@ public:
virtual void update() override; virtual void update() override;
virtual void render() override; virtual void render() override;
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
private: private:
void setVertex(int i, float x, float y, float z); void setVertex(int i, float x, float y, float z);
OpenGLShaderProgram* program; OpenGLShaderProgram* program;
float* vertices; float* vertices;
double daytime;
}; };
} }

View file

@ -8,6 +8,7 @@
#include "ExplorerChunkTerrain.h" #include "ExplorerChunkTerrain.h"
#include "WaterRenderer.h" #include "WaterRenderer.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
#include "AtmosphereDefinition.h"
#include "Scenery.h" #include "Scenery.h"
#include "FloatNode.h" #include "FloatNode.h"
#include "FloatDiff.h" #include "FloatDiff.h"
@ -84,6 +85,7 @@ void OpenGLTerrain::initialize()
// Watch for definition changes // Watch for definition changes
renderer->getScenery()->getTerrain()->propWaterHeight()->addWatcher(this); renderer->getScenery()->getTerrain()->propWaterHeight()->addWatcher(this);
renderer->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this);
} }
void OpenGLTerrain::update() void OpenGLTerrain::update()
@ -174,4 +176,8 @@ void OpenGLTerrain::nodeChanged(const DefinitionNode *node, const DefinitionDiff
{ {
resetTextures(); resetTextures();
} }
else if (node->getPath() == "/atmosphere/daytime")
{
resetTextures();
}
} }

View file

@ -9,6 +9,7 @@
#include "LightStatus.h" #include "LightStatus.h"
#include "Scenery.h" #include "Scenery.h"
#include "NightSky.h" #include "NightSky.h"
#include "FloatNode.h"
/* Factor to convert software units to kilometers */ /* Factor to convert software units to kilometers */
#define WORLD_SCALING 0.05 #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; distancefactor = (distance > max_distance ? max_distance : distance) / max_distance;
/* TODO Get day lighting from model */ /* TODO Get day lighting from model */
dayfactor = _getDayFactor(definition->_daytime); dayfactor = _getDayFactor(definition->propDayTime()->getValue());
/* Fog masking */ /* Fog masking */
if (definition->humidity > 0.3) if (definition->humidity > 0.3)
@ -105,16 +106,16 @@ AtmosphereResult BaseAtmosphereRenderer::getSkyColor(Vector3)
return result; 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); return lights[0].direction.scale(-1.0);
} }
else else
{ {
AtmosphereDefinition* atmosphere = getDefinition(); 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); return Vector3(cos(sun_angle), sin(sun_angle), 0.0);
} }
} }
@ -153,7 +154,7 @@ void BaseAtmosphereRenderer::setStaticLights(const std::vector<LightComponent> &
this->lights = lights; this->lights = lights;
} }
AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition() AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition() const
{ {
return parent->getScenery()->getAtmosphere(); return parent->getScenery()->getAtmosphere();
} }

View file

@ -18,13 +18,13 @@ public:
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque); virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque);
virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base); virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base);
virtual AtmosphereResult getSkyColor(Vector3 direction); virtual AtmosphereResult getSkyColor(Vector3 direction);
virtual Vector3 getSunDirection(); virtual Vector3 getSunDirection(bool cache=true) const;
void setBasicLights(); void setBasicLights();
void setStaticLights(const std::vector<LightComponent> &lights); void setStaticLights(const std::vector<LightComponent> &lights);
protected: protected:
virtual AtmosphereDefinition* getDefinition(); virtual AtmosphereDefinition* getDefinition() const;
SoftwareRenderer* parent; SoftwareRenderer* parent;
std::vector<LightComponent> lights; std::vector<LightComponent> lights;
}; };

View file

@ -22,6 +22,12 @@
SoftwareRenderer::SoftwareRenderer(Scenery* scenery) SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
{ {
this->scenery = new Scenery;
if (scenery)
{
scenery->copy(this->scenery);
}
render_quality = 5; render_quality = 5;
render_camera = new CameraDefinition; render_camera = new CameraDefinition;
@ -39,12 +45,6 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
lighting->registerFilter(water_renderer); lighting->registerFilter(water_renderer);
lighting->registerFilter(terrain_renderer); lighting->registerFilter(terrain_renderer);
lighting->registerFilter(clouds_renderer); lighting->registerFilter(clouds_renderer);
this->scenery = new Scenery;
if (scenery)
{
scenery->copy(this->scenery);
}
} }
SoftwareRenderer::~SoftwareRenderer() SoftwareRenderer::~SoftwareRenderer()

View file

@ -2,35 +2,37 @@
#include "AtmosphereDefinition.h" #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); AtmosphereDefinition atmo(NULL);
atmo.setDaytime(0.0); atmo.setDayTime(0.0);
EXPECT_EQ(atmo.hour, 0); check_daytime(atmo, 0);
EXPECT_EQ(atmo.minute, 0);
atmo.setDaytime(0.1); atmo.setDayTime(0.1);
EXPECT_EQ(atmo.hour, 2); check_daytime(atmo, 2, 24);
EXPECT_EQ(atmo.minute, 24);
atmo.setDaytime(0.25); atmo.setDayTime(0.25);
EXPECT_EQ(atmo.hour, 6); check_daytime(atmo, 6);
EXPECT_EQ(atmo.minute, 0);
atmo.setDaytime(0.5); atmo.setDayTime(0.5);
EXPECT_EQ(atmo.hour, 12); check_daytime(atmo, 12);
EXPECT_EQ(atmo.minute, 0);
atmo.setDaytime(1.0); atmo.setDayTime(1.0);
EXPECT_EQ(atmo.hour, 0); check_daytime(atmo, 0);
EXPECT_EQ(atmo.minute, 0);
atmo.setDaytime(-0.5); atmo.setDayTime(-0.5);
EXPECT_EQ(atmo.hour, 12); check_daytime(atmo, 12);
EXPECT_EQ(atmo.minute, 0);
atmo.setDaytime(1.5); atmo.setDayTime(1.5);
EXPECT_EQ(atmo.hour, 12); check_daytime(atmo, 12);
EXPECT_EQ(atmo.minute, 0);
} }