2013-11-15 23:27:40 +00:00
|
|
|
#include "AtmosphereDefinition.h"
|
|
|
|
|
2015-12-08 23:32:29 +00:00
|
|
|
#include <cmath>
|
2015-12-30 23:36:22 +00:00
|
|
|
#include "Maths.h"
|
2013-11-15 23:27:40 +00:00
|
|
|
#include "PackStream.h"
|
2013-12-26 16:30:22 +00:00
|
|
|
#include "RandomGenerator.h"
|
2015-08-18 18:31:11 +00:00
|
|
|
#include "FloatNode.h"
|
2015-09-29 23:08:15 +00:00
|
|
|
#include "GodRaysDefinition.h"
|
2015-12-29 23:20:20 +00:00
|
|
|
#include "CelestialBodyDefinition.h"
|
2013-11-15 23:27:40 +00:00
|
|
|
|
2016-01-14 23:07:02 +00:00
|
|
|
#define WORLD_SCALING 0.05
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode *parent)
|
|
|
|
: DefinitionNode(parent, "atmosphere", "atmosphere") {
|
2015-11-23 23:58:09 +00:00
|
|
|
model = ATMOSPHERE_MODEL_DISABLED;
|
2015-09-29 23:08:15 +00:00
|
|
|
godrays = new GodRaysDefinition(this);
|
2015-12-29 23:20:20 +00:00
|
|
|
sun = new CelestialBodyDefinition(this, "sun");
|
|
|
|
moon = new CelestialBodyDefinition(this, "moon");
|
2015-08-23 23:19:19 +00:00
|
|
|
humidity = new FloatNode(this, "humidity");
|
2015-12-16 09:36:21 +00:00
|
|
|
sun_color = COLOR_RED;
|
2013-11-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void AtmosphereDefinition::save(PackStream *stream) const {
|
2015-08-19 20:07:44 +00:00
|
|
|
DefinitionNode::save(stream);
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
stream->write((int *)&model);
|
2013-11-15 23:27:40 +00:00
|
|
|
sun_color.save(stream);
|
|
|
|
stream->write(&dome_lighting);
|
2013-12-26 16:30:22 +00:00
|
|
|
|
|
|
|
int star_count = stars.size();
|
|
|
|
stream->write(&star_count);
|
2015-11-09 21:30:46 +00:00
|
|
|
for (const auto &star : stars) {
|
2013-12-26 16:30:22 +00:00
|
|
|
star.location.save(stream);
|
|
|
|
star.col.save(stream);
|
|
|
|
stream->write(&star.radius);
|
|
|
|
}
|
2013-11-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void AtmosphereDefinition::load(PackStream *stream) {
|
2015-08-19 20:07:44 +00:00
|
|
|
DefinitionNode::load(stream);
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
stream->read((int *)&model);
|
2013-11-15 23:27:40 +00:00
|
|
|
sun_color.load(stream);
|
|
|
|
stream->read(&dome_lighting);
|
|
|
|
|
2013-12-26 16:30:22 +00:00
|
|
|
int star_count;
|
|
|
|
stream->read(&star_count);
|
2015-11-09 21:30:46 +00:00
|
|
|
for (int i = 0; i < star_count; i++) {
|
2013-12-26 16:30:22 +00:00
|
|
|
Star star;
|
|
|
|
|
|
|
|
star.location.load(stream);
|
|
|
|
star.col.load(stream);
|
|
|
|
stream->read(&star.radius);
|
|
|
|
|
|
|
|
stars.push_back(star);
|
|
|
|
}
|
|
|
|
|
2013-11-15 23:27:40 +00:00
|
|
|
validate();
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void AtmosphereDefinition::copy(DefinitionNode *_destination) const {
|
2015-08-19 20:07:44 +00:00
|
|
|
DefinitionNode::copy(_destination);
|
|
|
|
|
2015-12-29 23:20:20 +00:00
|
|
|
AtmosphereDefinition *destination = static_cast<AtmosphereDefinition *>(_destination);
|
|
|
|
if (destination) {
|
|
|
|
destination->model = model;
|
|
|
|
destination->sun_color = sun_color;
|
|
|
|
destination->dome_lighting = dome_lighting;
|
|
|
|
destination->stars = stars;
|
2013-11-15 23:27:40 +00:00
|
|
|
|
2015-12-29 23:20:20 +00:00
|
|
|
destination->validate();
|
|
|
|
}
|
2013-11-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void AtmosphereDefinition::setDayTime(double value) {
|
2015-12-30 23:36:22 +00:00
|
|
|
sun->propTheta()->setValue((value + 0.75) * Maths::TWOPI);
|
2015-08-18 18:31:11 +00:00
|
|
|
}
|
2013-11-15 23:27:40 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void AtmosphereDefinition::setDayTime(int hour, int minute, int second) {
|
2015-12-30 18:29:15 +00:00
|
|
|
setDayTime(to_double(hour) / 24.0 + to_double(minute) / 1440.0 + (to_double(second) + 0.1) / 86400.0);
|
2013-11-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
|
2015-12-29 23:20:20 +00:00
|
|
|
double AtmosphereDefinition::getDaytime() const {
|
2015-12-30 23:36:22 +00:00
|
|
|
double value = (sun->propTheta()->getValue() / Maths::TWOPI) - 0.75;
|
2015-11-09 21:30:46 +00:00
|
|
|
if (value >= 0.0) {
|
2014-08-28 13:09:47 +00:00
|
|
|
value = fmod(value, 1.0);
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2014-08-28 13:09:47 +00:00
|
|
|
value = 1.0 - fmod(-value, 1.0);
|
|
|
|
}
|
2015-12-29 23:20:20 +00:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const {
|
|
|
|
double value = getDaytime() * 86400.0;
|
|
|
|
*hour = round_to_int(value / 3600.0);
|
|
|
|
value -= 3600.0 * to_double(*hour);
|
|
|
|
*minute = round_to_int(value / 60.0);
|
|
|
|
*second = round_to_int(value - to_double(*minute) * 60.0);
|
2014-08-28 13:09:47 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 18:40:39 +00:00
|
|
|
void AtmosphereDefinition::applyPreset(AtmospherePreset preset, RandomGenerator &random) {
|
2013-11-15 23:27:40 +00:00
|
|
|
sun_color.r = 1.0;
|
|
|
|
sun_color.g = 0.95;
|
|
|
|
sun_color.b = 0.9;
|
|
|
|
sun_color.a = 1.0;
|
2015-12-29 23:20:20 +00:00
|
|
|
sun->propRadius()->setValue(1.0);
|
2016-01-14 23:07:02 +00:00
|
|
|
sun->propDistance()->setValue(149597870.0 / WORLD_SCALING);
|
|
|
|
moon->propDistance()->setValue(384403.0 / WORLD_SCALING);
|
|
|
|
moon->propRadius()->setValue(1737.4 / WORLD_SCALING);
|
2015-12-29 23:20:20 +00:00
|
|
|
moon->propPhi()->setValue(0.5);
|
|
|
|
moon->propTheta()->setValue(0.3);
|
2013-11-15 23:27:40 +00:00
|
|
|
|
|
|
|
model = ATMOSPHERE_MODEL_BRUNETON;
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
switch (preset) {
|
|
|
|
case ATMOSPHERE_PRESET_CLEAR_DAY:
|
|
|
|
setDayTime(15);
|
|
|
|
humidity->setValue(0.1);
|
|
|
|
dome_lighting = 0.2;
|
|
|
|
break;
|
|
|
|
case ATMOSPHERE_PRESET_CLEAR_SUNSET:
|
|
|
|
setDayTime(17, 45);
|
|
|
|
humidity->setValue(0.1);
|
|
|
|
dome_lighting = 0.3;
|
|
|
|
break;
|
|
|
|
case ATMOSPHERE_PRESET_HAZY_MORNING:
|
|
|
|
setDayTime(8, 30);
|
|
|
|
humidity->setValue(0.4);
|
|
|
|
dome_lighting = 0.25;
|
|
|
|
break;
|
|
|
|
case ATMOSPHERE_PRESET_FOGGY:
|
|
|
|
setDayTime(15);
|
|
|
|
humidity->setValue(0.7);
|
|
|
|
dome_lighting = 0.1;
|
|
|
|
break;
|
|
|
|
case ATMOSPHERE_PRESET_STORMY:
|
|
|
|
setDayTime(15);
|
|
|
|
humidity->setValue(0.9);
|
|
|
|
dome_lighting = 0.05;
|
|
|
|
break;
|
2013-11-15 23:27:40 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 18:40:39 +00:00
|
|
|
generateStars(2000, random);
|
2013-12-26 16:30:22 +00:00
|
|
|
|
2013-11-15 23:27:40 +00:00
|
|
|
validate();
|
|
|
|
}
|
2013-12-26 16:30:22 +00:00
|
|
|
|
2015-12-10 18:40:39 +00:00
|
|
|
void AtmosphereDefinition::generateStars(int count, RandomGenerator &random) {
|
2013-12-26 16:30:22 +00:00
|
|
|
stars.clear();
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
for (int i = 0; i < count; ++i) {
|
2013-12-26 16:30:22 +00:00
|
|
|
Star star;
|
|
|
|
|
2015-12-10 22:41:42 +00:00
|
|
|
star.location = Vector3((random.genDouble() - 0.5) * 100000.0, (random.genDouble() * 0.5) * 100000.0,
|
|
|
|
(random.genDouble() - 0.5) * 100000.0);
|
2015-11-09 21:30:46 +00:00
|
|
|
if (star.location.getNorm() < 30000.0) {
|
2013-12-26 16:30:22 +00:00
|
|
|
i--;
|
|
|
|
continue;
|
|
|
|
}
|
2015-12-10 18:40:39 +00:00
|
|
|
double brillance = random.genDouble() * 0.05 + 0.1;
|
|
|
|
star.col = Color(brillance + random.genDouble() * 0.03, brillance + random.genDouble() * 0.03,
|
|
|
|
brillance + random.genDouble() * 0.03, 1.0);
|
|
|
|
star.radius = 30.0 + random.genDouble() * 20.0;
|
2013-12-26 16:30:22 +00:00
|
|
|
|
|
|
|
stars.push_back(star);
|
|
|
|
}
|
|
|
|
}
|