Refactored CelestialBodyDefinition, with new sun/moon widget
This commit is contained in:
parent
06cd5e31fd
commit
61a43410db
34 changed files with 425 additions and 279 deletions
|
@ -5,29 +5,24 @@
|
|||
#include "RandomGenerator.h"
|
||||
#include "FloatNode.h"
|
||||
#include "GodRaysDefinition.h"
|
||||
#include "CelestialBodyDefinition.h"
|
||||
|
||||
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode *parent)
|
||||
: DefinitionNode(parent, "atmosphere", "atmosphere") {
|
||||
model = ATMOSPHERE_MODEL_DISABLED;
|
||||
godrays = new GodRaysDefinition(this);
|
||||
daytime = new FloatNode(this, "daytime");
|
||||
sun = new CelestialBodyDefinition(this, "sun");
|
||||
moon = new CelestialBodyDefinition(this, "moon");
|
||||
humidity = new FloatNode(this, "humidity");
|
||||
sun_radius = new FloatNode(this, "sun_radius");
|
||||
sun_color = COLOR_RED;
|
||||
}
|
||||
|
||||
AtmosphereDefinition::~AtmosphereDefinition() {
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::save(PackStream *stream) const {
|
||||
DefinitionNode::save(stream);
|
||||
|
||||
stream->write((int *)&model);
|
||||
sun_color.save(stream);
|
||||
stream->write(&dome_lighting);
|
||||
stream->write(&moon_radius);
|
||||
stream->write(&moon_theta);
|
||||
stream->write(&moon_phi);
|
||||
|
||||
int star_count = stars.size();
|
||||
stream->write(&star_count);
|
||||
|
@ -44,9 +39,6 @@ void AtmosphereDefinition::load(PackStream *stream) {
|
|||
stream->read((int *)&model);
|
||||
sun_color.load(stream);
|
||||
stream->read(&dome_lighting);
|
||||
stream->read(&moon_radius);
|
||||
stream->read(&moon_theta);
|
||||
stream->read(&moon_phi);
|
||||
|
||||
int star_count;
|
||||
stream->read(&star_count);
|
||||
|
@ -66,39 +58,41 @@ void AtmosphereDefinition::load(PackStream *stream) {
|
|||
void AtmosphereDefinition::copy(DefinitionNode *_destination) const {
|
||||
DefinitionNode::copy(_destination);
|
||||
|
||||
AtmosphereDefinition *destination = (AtmosphereDefinition *)_destination;
|
||||
AtmosphereDefinition *destination = static_cast<AtmosphereDefinition *>(_destination);
|
||||
if (destination) {
|
||||
destination->model = model;
|
||||
destination->sun_color = sun_color;
|
||||
destination->dome_lighting = dome_lighting;
|
||||
destination->stars = stars;
|
||||
|
||||
destination->model = model;
|
||||
destination->sun_color = sun_color;
|
||||
destination->dome_lighting = dome_lighting;
|
||||
destination->moon_radius = moon_radius;
|
||||
destination->moon_theta = moon_theta;
|
||||
destination->moon_phi = moon_phi;
|
||||
destination->stars = stars;
|
||||
|
||||
destination->validate();
|
||||
destination->validate();
|
||||
}
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::setDayTime(double value) {
|
||||
daytime->setValue(value);
|
||||
sun->propTheta()->setValue((value + 0.75) * M_2PI);
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::setDayTime(int hour, int minute, int second) {
|
||||
setDayTime(to_double(hour) / 24.0 + to_double(minute) / 1440.0 + to_double(second) / 86400.0);
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const {
|
||||
double value = daytime->getValue();
|
||||
double AtmosphereDefinition::getDaytime() const {
|
||||
double value = (sun->propTheta()->getValue() / M_2PI) - 0.75;
|
||||
if (value >= 0.0) {
|
||||
value = fmod(value, 1.0);
|
||||
} else {
|
||||
value = 1.0 - fmod(-value, 1.0);
|
||||
}
|
||||
value *= 86400.0;
|
||||
*hour = value / 3600.0;
|
||||
value -= 3600.0 * *hour;
|
||||
*minute = value / 60.0;
|
||||
*second = value - *minute * 60.0;
|
||||
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);
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::applyPreset(AtmospherePreset preset, RandomGenerator &random) {
|
||||
|
@ -106,10 +100,10 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset, RandomGenerator
|
|||
sun_color.g = 0.95;
|
||||
sun_color.b = 0.9;
|
||||
sun_color.a = 1.0;
|
||||
sun_radius->setValue(0.8);
|
||||
moon_radius = 1.0;
|
||||
moon_theta = 0.3;
|
||||
moon_phi = 0.5;
|
||||
sun->propRadius()->setValue(1.0);
|
||||
moon->propRadius()->setValue(1.0);
|
||||
moon->propPhi()->setValue(0.5);
|
||||
moon->propTheta()->setValue(0.3);
|
||||
|
||||
model = ATMOSPHERE_MODEL_BRUNETON;
|
||||
|
||||
|
@ -139,8 +133,6 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset, RandomGenerator
|
|||
humidity->setValue(0.9);
|
||||
dome_lighting = 0.05;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
generateStars(2000, random);
|
||||
|
|
|
@ -31,7 +31,6 @@ class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode {
|
|||
|
||||
public:
|
||||
AtmosphereDefinition(DefinitionNode *parent);
|
||||
virtual ~AtmosphereDefinition();
|
||||
|
||||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
|
@ -41,15 +40,15 @@ class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode {
|
|||
inline GodRaysDefinition *childGodRays() const {
|
||||
return godrays;
|
||||
}
|
||||
inline FloatNode *propDayTime() const {
|
||||
return daytime;
|
||||
inline CelestialBodyDefinition *childSun() const {
|
||||
return sun;
|
||||
}
|
||||
inline CelestialBodyDefinition *childMoon() const {
|
||||
return moon;
|
||||
}
|
||||
inline FloatNode *propHumidity() const {
|
||||
return humidity;
|
||||
}
|
||||
inline FloatNode *propSunRadius() const {
|
||||
return sun_radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the daytime from a 0.0-1.0 value.
|
||||
|
@ -59,6 +58,10 @@ class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode {
|
|||
* Set the daytime from hour/minute/second info.
|
||||
*/
|
||||
void setDayTime(int hour, int minute = 0, int second = 0);
|
||||
/**
|
||||
* Get the daytime info, in 0.0-1.0 value.
|
||||
*/
|
||||
double getDaytime() const;
|
||||
/**
|
||||
* Get the daytime info, in hour/minute/second.
|
||||
*/
|
||||
|
@ -73,17 +76,13 @@ class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode {
|
|||
Color sun_color;
|
||||
double dome_lighting;
|
||||
|
||||
double moon_radius;
|
||||
double moon_theta;
|
||||
double moon_phi;
|
||||
|
||||
vector<Star> stars;
|
||||
|
||||
private:
|
||||
GodRaysDefinition *godrays;
|
||||
CelestialBodyDefinition *sun;
|
||||
CelestialBodyDefinition *moon;
|
||||
FloatNode *humidity;
|
||||
FloatNode *daytime;
|
||||
FloatNode *sun_radius;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
18
src/definition/CelestialBodyDefinition.cpp
Normal file
18
src/definition/CelestialBodyDefinition.cpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include "CelestialBodyDefinition.h"
|
||||
|
||||
#include "Vector3.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
CelestialBodyDefinition::CelestialBodyDefinition(DefinitionNode *parent, const string &name)
|
||||
: DefinitionNode(parent, name) {
|
||||
phi = new FloatNode(this, "phi");
|
||||
theta = new FloatNode(this, "theta");
|
||||
radius = new FloatNode(this, "radius");
|
||||
}
|
||||
|
||||
Vector3 CelestialBodyDefinition::getDirection() const {
|
||||
VectorSpherical spc = {1.0, theta->getValue(), -phi->getValue()};
|
||||
return Vector3(spc);
|
||||
}
|
||||
|
||||
// VectorSpherical moon_location_s = {MOON_DISTANCE_SCALED, atmosphere->moon_theta, -atmosphere->moon_phi};
|
38
src/definition/CelestialBodyDefinition.h
Normal file
38
src/definition/CelestialBodyDefinition.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef CELESTIALBODYDEFINITION_H
|
||||
#define CELESTIALBODYDEFINITION_H
|
||||
|
||||
#include "definition_global.h"
|
||||
|
||||
#include "DefinitionNode.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
class DEFINITIONSHARED_EXPORT CelestialBodyDefinition : public DefinitionNode {
|
||||
public:
|
||||
CelestialBodyDefinition(DefinitionNode *parent, const string &name);
|
||||
|
||||
inline FloatNode *propPhi() const {
|
||||
return phi;
|
||||
}
|
||||
inline FloatNode *propTheta() const {
|
||||
return theta;
|
||||
}
|
||||
inline FloatNode *propRadius() const {
|
||||
return radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the normalized direction toward the celestial body (from the center of the earth).
|
||||
*/
|
||||
Vector3 getDirection() const;
|
||||
|
||||
private:
|
||||
FloatNode *phi;
|
||||
FloatNode *theta;
|
||||
FloatNode *radius;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CELESTIALBODYDEFINITION_H
|
|
@ -14,7 +14,7 @@ TimeManager::TimeManager() {
|
|||
|
||||
void TimeManager::moveForward(Scenery *scenery, double amount) {
|
||||
// Move the sun
|
||||
scenery->getAtmosphere()->setDayTime(scenery->getAtmosphere()->propDayTime()->getValue() + amount);
|
||||
scenery->getAtmosphere()->setDayTime(scenery->getAtmosphere()->getDaytime() + amount);
|
||||
|
||||
// Move the clouds
|
||||
int n = scenery->getClouds()->getLayerCount();
|
||||
|
|
|
@ -32,6 +32,7 @@ class LayersDiff;
|
|||
class CloudsDefinition;
|
||||
class CloudLayerDefinition;
|
||||
class AtmosphereDefinition;
|
||||
class CelestialBodyDefinition;
|
||||
class GodRaysDefinition;
|
||||
class TexturesDefinition;
|
||||
class TextureLayerDefinition;
|
||||
|
|
|
@ -270,7 +270,7 @@ static void testAtmosphereBruneton() {
|
|||
|
||||
for (int i = 0; i <= 60; i++) {
|
||||
double daytime = (i < 40) ? (0.24 + 0.0005 * to_double(i)) : (0.26 + 0.005 * to_double(i - 40));
|
||||
scenery.getAtmosphere()->propDayTime()->setValue(daytime);
|
||||
scenery.getAtmosphere()->setDayTime(daytime);
|
||||
startTestRender(&renderer, "atmosphere_bruneton", i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,19 +3,15 @@
|
|||
#include "MainModelerWindow.h"
|
||||
#include "Scenery.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "FloatPropertyBind.h"
|
||||
|
||||
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(MainModelerWindow *main) : BaseModelerTool(main) {
|
||||
addFloatBinding("atmosphere_humidity", "value", "/atmosphere/humidity");
|
||||
addFloatBinding("atmosphere_sun_direction", "phi", "/atmosphere/sun/phi");
|
||||
addFloatBinding("atmosphere_sun_direction", "theta", "/atmosphere/sun/theta");
|
||||
addFloatBinding("atmosphere_sun_radius", "value", "/atmosphere/sun/radius");
|
||||
addFloatBinding("atmosphere_moon_direction", "phi", "/atmosphere/moon/phi");
|
||||
addFloatBinding("atmosphere_moon_direction", "theta", "/atmosphere/moon/theta");
|
||||
// addFloatBinding("atmosphere_moon_radius", "value", "/atmosphere/moon/radius");
|
||||
|
||||
AtmosphereModeler::~AtmosphereModeler() {
|
||||
delete prop_daytime;
|
||||
delete prop_humidity;
|
||||
delete prop_sun_radius;
|
||||
main->setQmlProperty("atmosphere_daytime", "value", main->getScenery()->getAtmosphere()->getDaytime());
|
||||
}
|
||||
|
|
|
@ -3,18 +3,14 @@
|
|||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include "BaseModelerTool.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
class AtmosphereModeler {
|
||||
class AtmosphereModeler : protected BaseModelerTool {
|
||||
public:
|
||||
AtmosphereModeler(MainModelerWindow *main);
|
||||
~AtmosphereModeler();
|
||||
|
||||
private:
|
||||
FloatPropertyBind *prop_daytime;
|
||||
FloatPropertyBind *prop_humidity;
|
||||
FloatPropertyBind *prop_sun_radius;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
39
src/interface/modeler/BaseModelerTool.cpp
Normal file
39
src/interface/modeler/BaseModelerTool.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include "BaseModelerTool.h"
|
||||
|
||||
#include "MainModelerWindow.h"
|
||||
#include "Scenery.h"
|
||||
#include "IntNode.h"
|
||||
#include "IntPropertyBind.h"
|
||||
#include "FloatNode.h"
|
||||
#include "FloatPropertyBind.h"
|
||||
#include "Logs.h"
|
||||
|
||||
class BaseModelerTool::pimpl {
|
||||
public:
|
||||
vector<unique_ptr<IntPropertyBind>> int_bindings;
|
||||
vector<unique_ptr<FloatPropertyBind>> float_bindings;
|
||||
};
|
||||
|
||||
BaseModelerTool::BaseModelerTool(MainModelerWindow *main) : impl(new pimpl), main(main) {
|
||||
}
|
||||
|
||||
BaseModelerTool::~BaseModelerTool() {
|
||||
}
|
||||
|
||||
void BaseModelerTool::addIntBinding(const string &object, const string &property, const string &path) {
|
||||
auto node = static_cast<IntNode *>(main->getScenery()->findByPath(path));
|
||||
if (node) {
|
||||
impl->int_bindings.push_back(make_unique<IntPropertyBind>(main, object, property, node));
|
||||
} else {
|
||||
Logs::error("UI") << "Can't find int node for binding : " << path << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseModelerTool::addFloatBinding(const string &object, const string &property, const string &path) {
|
||||
auto node = static_cast<FloatNode *>(main->getScenery()->findByPath(path));
|
||||
if (node) {
|
||||
impl->float_bindings.push_back(make_unique<FloatPropertyBind>(main, object, property, node));
|
||||
} else {
|
||||
Logs::error("UI") << "Can't find float node for binding : " << path << endl;
|
||||
}
|
||||
}
|
35
src/interface/modeler/BaseModelerTool.h
Normal file
35
src/interface/modeler/BaseModelerTool.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef BASEMODELERTOOL_H
|
||||
#define BASEMODELERTOOL_H
|
||||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
class BaseModelerTool {
|
||||
public:
|
||||
BaseModelerTool(MainModelerWindow *main);
|
||||
virtual ~BaseModelerTool();
|
||||
|
||||
/**
|
||||
* Add an automated two-way binding between a QML int property and a scenery IntNode.
|
||||
*/
|
||||
void addIntBinding(const string &object, const string &property, const string &path);
|
||||
|
||||
/**
|
||||
* Add an automated two-way binding between a QML int property and a scenery IntNode.
|
||||
*/
|
||||
void addFloatBinding(const string &object, const string &property, const string &path);
|
||||
|
||||
private:
|
||||
class pimpl;
|
||||
unique_ptr<pimpl> impl;
|
||||
|
||||
MainModelerWindow *main;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BASEMODELERTOOL_H
|
|
@ -6,27 +6,30 @@
|
|||
|
||||
#include <cmath>
|
||||
|
||||
FloatPropertyBind::FloatPropertyBind(MainModelerWindow *window, const QString &object_name,
|
||||
const QString &property_name, FloatNode *node)
|
||||
FloatPropertyBind::FloatPropertyBind(MainModelerWindow *window, const string &object_name, const string &property_name,
|
||||
FloatNode *node)
|
||||
: QObject(window), node(node), property(property_name) {
|
||||
item = window->findQmlObject(object_name);
|
||||
if (item) {
|
||||
node->addWatcher(this, true);
|
||||
connect(item, SIGNAL(changed(double)), this, SLOT(propertyChanged(double)));
|
||||
string signal_name("2" + property_name + "Changed()");
|
||||
connect(item, signal_name.c_str(), this, SLOT(propertyChanged()));
|
||||
} else {
|
||||
item = NULL;
|
||||
Logs::error("UI") << "Can't find object :" << object_name.toStdString() << endl;
|
||||
Logs::error("UI") << "Can't find object :" << object_name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void FloatPropertyBind::nodeChanged(const DefinitionNode *, const DefinitionDiff *) {
|
||||
if (item) {
|
||||
item->setProperty(property.toLocal8Bit(), node->getValue());
|
||||
item->setProperty(property.c_str(), node->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
void FloatPropertyBind::propertyChanged(double value) {
|
||||
if (fabs(value - node->getValue()) > 0.00000001) {
|
||||
void FloatPropertyBind::propertyChanged() {
|
||||
bool ok;
|
||||
double value = item->property(property.c_str()).toDouble(&ok);
|
||||
if (ok and fabs(value - node->getValue()) > 0.00000001) {
|
||||
node->setValue(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,17 +17,17 @@ namespace modeler {
|
|||
class FloatPropertyBind : public QObject, public DefinitionWatcher {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FloatPropertyBind(MainModelerWindow *window, const QString &object_name, const QString &property_name,
|
||||
FloatPropertyBind(MainModelerWindow *window, const string &object_name, const string &property_name,
|
||||
FloatNode *node);
|
||||
|
||||
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
|
||||
|
||||
private slots:
|
||||
void propertyChanged(double value);
|
||||
void propertyChanged();
|
||||
|
||||
private:
|
||||
FloatNode *node;
|
||||
QString property;
|
||||
string property;
|
||||
QObject *item;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,27 +4,30 @@
|
|||
#include "IntNode.h"
|
||||
#include "Logs.h"
|
||||
|
||||
IntPropertyBind::IntPropertyBind(MainModelerWindow *window, const QString &object_name, const QString &property_name,
|
||||
IntPropertyBind::IntPropertyBind(MainModelerWindow *window, const string &object_name, const string &property_name,
|
||||
IntNode *node)
|
||||
: QObject(window), node(node), property(property_name) {
|
||||
item = window->findQmlObject(object_name);
|
||||
if (item) {
|
||||
node->addWatcher(this, true);
|
||||
connect(item, SIGNAL(changed(int)), this, SLOT(propertyChanged(int)));
|
||||
string signal_name("2" + property_name + "Changed()");
|
||||
connect(item, signal_name.c_str(), this, SLOT(propertyChanged()));
|
||||
} else {
|
||||
item = NULL;
|
||||
Logs::error("UI") << "Can't find object :" << object_name.toStdString() << endl;
|
||||
Logs::error("UI") << "Can't find object :" << object_name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void IntPropertyBind::nodeChanged(const DefinitionNode *, const DefinitionDiff *) {
|
||||
if (item) {
|
||||
item->setProperty(property.toLocal8Bit(), node->getValue());
|
||||
item->setProperty(property.c_str(), node->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
void IntPropertyBind::propertyChanged(int value) {
|
||||
if (value != node->getValue()) {
|
||||
void IntPropertyBind::propertyChanged() {
|
||||
bool ok;
|
||||
int value = item->property(property.c_str()).toInt(&ok);
|
||||
if (ok and value != node->getValue()) {
|
||||
node->setValue(value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,16 +17,16 @@ namespace modeler {
|
|||
class IntPropertyBind : public QObject, public DefinitionWatcher {
|
||||
Q_OBJECT
|
||||
public:
|
||||
IntPropertyBind(MainModelerWindow *window, const QString &object_name, const QString &property_name, IntNode *node);
|
||||
IntPropertyBind(MainModelerWindow *window, const string &object_name, const string &property_name, IntNode *node);
|
||||
|
||||
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
|
||||
|
||||
private slots:
|
||||
void propertyChanged(int value);
|
||||
void propertyChanged();
|
||||
|
||||
private:
|
||||
IntNode *node;
|
||||
QString property;
|
||||
string property;
|
||||
QObject *item;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -60,39 +60,39 @@ MainModelerWindow::~MainModelerWindow() {
|
|||
delete scenery;
|
||||
}
|
||||
|
||||
QObject *MainModelerWindow::findQmlObject(const QString &objectName) {
|
||||
QObject *MainModelerWindow::findQmlObject(const string &objectName) {
|
||||
if (objectName == "ui" || objectName == "root") {
|
||||
return rootObject();
|
||||
} else {
|
||||
return rootObject()->findChild<QObject *>(objectName);
|
||||
return rootObject()->findChild<QObject *>(QString::fromStdString(objectName));
|
||||
}
|
||||
}
|
||||
|
||||
void MainModelerWindow::setQmlProperty(const QString &objectName, const QString &propertyName, const QVariant &value) {
|
||||
void MainModelerWindow::setQmlProperty(const string &objectName, const string &propertyName, const QVariant &value) {
|
||||
QObject *item = findQmlObject(objectName);
|
||||
if (item) {
|
||||
item->setProperty(propertyName.toLocal8Bit(), value);
|
||||
item->setProperty(propertyName.c_str(), value);
|
||||
} else {
|
||||
Logs::error("UI") << "QML object not found :" << objectName.toStdString() << endl;
|
||||
Logs::error("UI") << "QML object not found :" << objectName << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void MainModelerWindow::connectQmlSignal(const QString &objectName, const char *signal, const QObject *receiver,
|
||||
void MainModelerWindow::connectQmlSignal(const string &objectName, const char *signal, const QObject *receiver,
|
||||
const char *method) {
|
||||
QObject *item = findQmlObject(objectName);
|
||||
if (item) {
|
||||
connect(item, signal, receiver, method);
|
||||
} else {
|
||||
Logs::error("UI") << "QML object not found :" << objectName.toStdString() << endl;
|
||||
Logs::error("UI") << "QML object not found :" << objectName << endl;
|
||||
}
|
||||
}
|
||||
|
||||
QString MainModelerWindow::getState() const {
|
||||
return rootObject()->property("state").toString();
|
||||
string MainModelerWindow::getState() const {
|
||||
return rootObject()->property("state").toString().toStdString();
|
||||
}
|
||||
|
||||
void MainModelerWindow::setState(const QString &stateName) {
|
||||
rootObject()->setProperty("state", stateName);
|
||||
void MainModelerWindow::setState(const string &stateName) {
|
||||
rootObject()->setProperty("state", QString::fromStdString(stateName));
|
||||
}
|
||||
|
||||
void MainModelerWindow::newFile() {
|
||||
|
|
|
@ -14,12 +14,12 @@ class MainModelerWindow : public QQuickView {
|
|||
MainModelerWindow();
|
||||
virtual ~MainModelerWindow();
|
||||
|
||||
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);
|
||||
QObject *findQmlObject(const string &objectName);
|
||||
void setQmlProperty(const string &objectName, const string &propertyName, const QVariant &value);
|
||||
void connectQmlSignal(const string &objectName, const char *signal, const QObject *receiver, const char *method);
|
||||
|
||||
QString getState() const;
|
||||
void setState(const QString &stateName);
|
||||
string getState() const;
|
||||
void setState(const string &stateName);
|
||||
|
||||
inline Scenery *getScenery() const {
|
||||
return scenery;
|
||||
|
|
|
@ -62,7 +62,8 @@ void ModelerCameras::startSunTool() {
|
|||
current->copy(tool);
|
||||
active = tool;
|
||||
|
||||
parent->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this, true);
|
||||
// FIXME
|
||||
// parent->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this, true);
|
||||
}
|
||||
|
||||
void ModelerCameras::endTool() {
|
||||
|
|
|
@ -149,7 +149,7 @@ void RenderProcess::stopRender() {
|
|||
renderer->interrupt();
|
||||
} else {
|
||||
destination->hide();
|
||||
window->setState(window->rootObject()->property("previous_state").toString());
|
||||
window->setState(window->rootObject()->property("previous_state").toString().toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace modeler {
|
|||
class MainModelerWindow;
|
||||
class OpenGLView;
|
||||
|
||||
class BaseModelerTool;
|
||||
|
||||
class AtmosphereModeler;
|
||||
class WaterModeler;
|
||||
|
||||
|
|
|
@ -2,7 +2,5 @@ import QtQuick 2.2
|
|||
import QtQuick.Controls 1.2
|
||||
|
||||
Slider {
|
||||
signal changed(real value)
|
||||
onValueChanged: changed(value)
|
||||
opacity: enabled ? 1.0 : 0.1
|
||||
}
|
||||
|
|
|
@ -1,148 +1,49 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
BasePanel {
|
||||
id: daytime
|
||||
width: 100
|
||||
width: 200
|
||||
|
||||
objectName: "atmosphere_daytime"
|
||||
default property real value: day_night.value == 2 ? 0.0 : slider.value * 0.54 + 0.23;
|
||||
signal changed(real value)
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - 10
|
||||
spacing: 30
|
||||
|
||||
onValueChanged: {
|
||||
changed(value);
|
||||
day_night.value = (value >= 0.23 && value <= 0.77) ? 1 : 2;
|
||||
if (day_night.value == 1)
|
||||
{
|
||||
slider.value = (value - 0.23) / 0.54;
|
||||
Text {
|
||||
text: "Sun location in the sky"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
WidgetSphericalCoords {
|
||||
id: atmosphere_sun_direction
|
||||
objectName: "atmosphere_sun_direction"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
icon: "images/icon_atmosphere_day.png"
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Time of day"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
WidgetDayTime {
|
||||
id: atmosphere_daytime
|
||||
objectName: "atmosphere_daytime"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
onValueChanged: atmosphere_sun_direction.theta = (atmosphere_daytime.value + 0.75) * Math.PI * 2.0
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Moon location in the sky"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
WidgetSphericalCoords {
|
||||
id: atmosphere_moon_direction
|
||||
objectName: "atmosphere_moon_direction"
|
||||
icon: "images/icon_atmosphere_night.png"
|
||||
width: parent.width
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
height: parent.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: 20
|
||||
|
||||
Item {height: 1}
|
||||
|
||||
BaseChoice {
|
||||
id: day_night
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 10
|
||||
width: 90
|
||||
height: 40
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
Grid {
|
||||
id: clock
|
||||
property int hour: daytime.value * 86400 / 3600
|
||||
property int minute: (daytime.value * 86400 - 3600 * hour) / 60
|
||||
property int second: daytime.value * 86400 - 3600 * hour - 60 * minute
|
||||
rows: 3
|
||||
columns: 5
|
||||
rowSpacing: 4
|
||||
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "qrc:/images/arrow_up.png"
|
||||
onClicked: slider.value += (1.0 / 24.0) / 0.54
|
||||
}
|
||||
Item {width: 1; height: 1}
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "qrc:/images/arrow_up.png"
|
||||
onClicked: slider.value += (1.0 / 1440.0) / 0.54
|
||||
}
|
||||
Item {width: 1; height: 1}
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "qrc:/images/arrow_up.png"
|
||||
onClicked: slider.value += (1.0 / 86400.0) / 0.54
|
||||
}
|
||||
|
||||
Text {
|
||||
text: (clock.hour > 9 ? "" : "0") + clock.hour.toString()
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
text: " : "
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
text: (clock.minute > 9 ? "" : "0") + clock.minute.toString()
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
text: " : "
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
text: (clock.second > 9 ? "" : "0") + clock.second.toString()
|
||||
font.pixelSize: 14
|
||||
}
|
||||
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "qrc:/images/arrow_down.png"
|
||||
onClicked: slider.value -= (1.0 / 24.0) / 0.54
|
||||
}
|
||||
Item {width: 1; height: 1}
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "qrc:/images/arrow_down.png"
|
||||
onClicked: slider.value -= (1.0 / 1440.0) / 0.54
|
||||
}
|
||||
Item {width: 1; height: 1}
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "qrc:/images/arrow_down.png"
|
||||
onClicked: slider.value -= (1.0 / 86400.0) / 0.54
|
||||
}
|
||||
}
|
||||
|
||||
Item {height: 1}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "night"
|
||||
when: day_night.value == 2
|
||||
PropertyChanges {
|
||||
target: slider
|
||||
enabled: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: clock
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ BasePanel {
|
|||
property alias items: container.children
|
||||
property int value: -1
|
||||
width: items[0].width + 10
|
||||
signal changed(int value)
|
||||
|
||||
ExclusiveGroup {
|
||||
id: exclusive_item
|
||||
|
@ -30,7 +29,6 @@ BasePanel {
|
|||
exclusive_item.current = null;
|
||||
}
|
||||
}
|
||||
changed(value);
|
||||
}
|
||||
|
||||
onItemsChanged: {
|
||||
|
|
77
src/interface/modeler/qml/WidgetDayTime.qml
Normal file
77
src/interface/modeler/qml/WidgetDayTime.qml
Normal file
|
@ -0,0 +1,77 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Grid {
|
||||
id: clock
|
||||
|
||||
property real value
|
||||
|
||||
property int hour: value * 86400 / 3600
|
||||
property int minute: (value * 86400 - 3600 * hour) / 60
|
||||
property int second: value * 86400 - 3600 * hour - 60 * minute
|
||||
rows: 3
|
||||
columns: 5
|
||||
rowSpacing: 4
|
||||
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "images/arrow_up.png"
|
||||
onClicked: value += 1.0 / 24.0
|
||||
}
|
||||
Item {width: 1; height: 1}
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "images/arrow_up.png"
|
||||
onClicked: value += 1.0 / 1440.0
|
||||
}
|
||||
Item {width: 1; height: 1}
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "images/arrow_up.png"
|
||||
onClicked: value += 1.0 / 86400.0
|
||||
}
|
||||
|
||||
Text {
|
||||
text: (clock.hour > 9 ? "" : "0") + clock.hour.toString()
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
text: " : "
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
text: (clock.minute > 9 ? "" : "0") + clock.minute.toString()
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
text: " : "
|
||||
font.pixelSize: 14
|
||||
}
|
||||
Text {
|
||||
text: (clock.second > 9 ? "" : "0") + clock.second.toString()
|
||||
font.pixelSize: 14
|
||||
}
|
||||
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "images/arrow_down.png"
|
||||
onClicked: value -= 1.0 / 24.0
|
||||
}
|
||||
Item {width: 1; height: 1}
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "images/arrow_down.png"
|
||||
onClicked: value -= 1.0 / 1440.0
|
||||
}
|
||||
Item {width: 1; height: 1}
|
||||
ClickableImage {
|
||||
width: 20
|
||||
height: 10
|
||||
source: "images/arrow_down.png"
|
||||
onClicked: value -= 1.0 / 86400.0
|
||||
}
|
||||
}
|
45
src/interface/modeler/qml/WidgetSphericalCoords.qml
Normal file
45
src/interface/modeler/qml/WidgetSphericalCoords.qml
Normal file
|
@ -0,0 +1,45 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
// Widget to edit spherical coordinates
|
||||
Row {
|
||||
id: widget
|
||||
property real theta: 0
|
||||
property real phi: 0
|
||||
property string icon
|
||||
|
||||
height: width / 2
|
||||
|
||||
Item {
|
||||
height: parent.height
|
||||
width: height
|
||||
Image {
|
||||
source: "images/bg_phi_coord.png"
|
||||
anchors.fill: parent
|
||||
}
|
||||
Image {
|
||||
source: widget.icon
|
||||
width: parent.width / 10
|
||||
height: parent.width / 10
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: width * 4 * Math.cos(phi) * Math.cos(theta)
|
||||
anchors.verticalCenterOffset: -width * 4 * Math.sin(phi) * Math.cos(theta)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
height: parent.height
|
||||
width: height
|
||||
Image {
|
||||
source: "images/bg_theta_coord.png"
|
||||
anchors.fill: parent
|
||||
}
|
||||
Image {
|
||||
source: widget.icon
|
||||
width: parent.width / 10
|
||||
height: parent.width / 10
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: width * 4.5 * Math.cos(theta)
|
||||
anchors.verticalCenterOffset: -width * 4.5 * Math.sin(theta)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,5 +53,9 @@
|
|||
<file>images/icon_render_final.png</file>
|
||||
<file>images/icon_cancel.png</file>
|
||||
<file>images/icon_sun_radius.png</file>
|
||||
<file>images/bg_phi_coord.png</file>
|
||||
<file>WidgetSphericalCoords.qml</file>
|
||||
<file>images/bg_theta_coord.png</file>
|
||||
<file>WidgetDayTime.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
BIN
src/interface/modeler/qml/images/bg_phi_coord.png
Normal file
BIN
src/interface/modeler/qml/images/bg_phi_coord.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
src/interface/modeler/qml/images/bg_theta_coord.png
Normal file
BIN
src/interface/modeler/qml/images/bg_theta_coord.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
|
@ -12,9 +12,10 @@
|
|||
#include "FloatNode.h"
|
||||
#include "Logs.h"
|
||||
|
||||
static const string path_daytime = "/atmosphere/daytime";
|
||||
static const string path_humidity = "/atmosphere/humidity";
|
||||
static const string path_sun_radius = "/atmosphere/sun_radius";
|
||||
static const string path_sun_phi = "/atmosphere/sun/phi";
|
||||
static const string path_sun_theta = "/atmosphere/sun/theta";
|
||||
static const string path_sun_radius = "/atmosphere/sun/radius";
|
||||
|
||||
OpenGLSkybox::OpenGLSkybox(OpenGLRenderer *renderer) : OpenGLPart(renderer, "skybox") {
|
||||
program = createShader("skybox");
|
||||
|
@ -56,9 +57,10 @@ OpenGLSkybox::~OpenGLSkybox() {
|
|||
void OpenGLSkybox::initialize() {
|
||||
// Watch for definition changes
|
||||
Scenery *scenery = renderer->getScenery();
|
||||
startWatching(scenery, path_daytime);
|
||||
startWatching(scenery, path_humidity);
|
||||
startWatching(scenery, path_sun_phi);
|
||||
startWatching(scenery, path_sun_theta);
|
||||
startWatching(scenery, path_sun_radius);
|
||||
startWatching(scenery, path_humidity);
|
||||
}
|
||||
|
||||
void OpenGLSkybox::update() {
|
||||
|
@ -79,14 +81,14 @@ void OpenGLSkybox::nodeChanged(const DefinitionNode *node, const DefinitionDiff
|
|||
OpenGLSharedState *state = renderer->getSharedState();
|
||||
AtmosphereDefinition *newdef = renderer->getScenery()->getAtmosphere();
|
||||
|
||||
if (node->getPath() == path_daytime) {
|
||||
if (node->getPath() == path_sun_phi or node->getPath() == path_sun_theta) {
|
||||
Vector3 sun_direction = renderer->getAtmosphereRenderer()->getSunDirection(false);
|
||||
state->set("sunDirection", sun_direction);
|
||||
|
||||
Color sun_color = newdef->sun_color;
|
||||
state->set("sunColor", sun_color);
|
||||
|
||||
state->set("dayTime", newdef->propDayTime()->getValue());
|
||||
state->set("dayTime", newdef->getDaytime());
|
||||
}
|
||||
|
||||
DefinitionWatcher::nodeChanged(node, diff);
|
||||
|
|
|
@ -9,12 +9,7 @@
|
|||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
#include "OpenGLTerrainChunk.h"
|
||||
#include "WaterRenderer.h"
|
||||
#include "CameraDefinition.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "Scenery.h"
|
||||
#include "FloatNode.h"
|
||||
#include "FloatDiff.h"
|
||||
|
||||
class ChunkMaintenanceThreads : public ParallelPool {
|
||||
public:
|
||||
|
@ -92,8 +87,11 @@ void OpenGLTerrain::initialize() {
|
|||
work->start();
|
||||
|
||||
// Watch for definition changes
|
||||
renderer->getScenery()->getTerrain()->propWaterHeight()->addWatcher(this);
|
||||
renderer->getScenery()->getAtmosphere()->propDayTime()->addWatcher(this);
|
||||
startWatching(renderer->getScenery(), "/terrain/water_height");
|
||||
startWatching(renderer->getScenery(), "/atmosphere/sun/phi");
|
||||
startWatching(renderer->getScenery(), "/atmosphere/sun/theta");
|
||||
startWatching(renderer->getScenery(), "/atmosphere/moon/phi");
|
||||
startWatching(renderer->getScenery(), "/atmosphere/moon/theta");
|
||||
}
|
||||
|
||||
void OpenGLTerrain::update() {
|
||||
|
@ -170,7 +168,7 @@ void OpenGLTerrain::performChunksMaintenance() {
|
|||
void OpenGLTerrain::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
||||
if (node->getPath() == "/terrain/water_height") {
|
||||
resetTextures();
|
||||
} else if (node->getPath() == "/atmosphere/daytime") {
|
||||
} else if (node->getPath().find("/atmosphere") == 0) {
|
||||
resetTextures();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "AtmosphereResult.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "WaterRenderer.h"
|
||||
#include "CelestialBodyDefinition.h"
|
||||
#include "LightComponent.h"
|
||||
#include "LightStatus.h"
|
||||
#include "Texture2D.h"
|
||||
|
@ -1079,7 +1080,7 @@ AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3
|
|||
AtmosphereResult result;
|
||||
Vector3 attenuation;
|
||||
Color sunColor =
|
||||
_sunColor(v, s, r, mu, parent->getScenery()->getAtmosphere()->propSunRadius()->getValue()); /* L0 */
|
||||
_sunColor(v, s, r, mu, parent->getScenery()->getAtmosphere()->childSun()->propRadius()->getValue()); /* L0 */
|
||||
|
||||
/*result.base.r = base.r + sunColor.r;
|
||||
result.base.g = base.g + sunColor.g;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "LightStatus.h"
|
||||
#include "Scenery.h"
|
||||
#include "NightSky.h"
|
||||
#include "CelestialBodyDefinition.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
/* Factor to convert software units to kilometers */
|
||||
|
@ -40,7 +41,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->propDayTime()->getValue());
|
||||
dayfactor = _getDayFactor(definition->getDaytime());
|
||||
|
||||
/* Fog masking */
|
||||
if (humidity > 0.3) {
|
||||
|
@ -87,9 +88,7 @@ AtmosphereResult BaseAtmosphereRenderer::getSkyColor(const Vector3 &) {
|
|||
}
|
||||
|
||||
Vector3 BaseAtmosphereRenderer::getSunDirection(bool) const {
|
||||
AtmosphereDefinition *atmosphere = getDefinition();
|
||||
double sun_angle = (atmosphere->propDayTime()->getValue() + 0.75) * M_PI * 2.0;
|
||||
return Vector3(cos(sun_angle), sin(sun_angle), 0.0);
|
||||
return getDefinition()->childSun()->getDirection();
|
||||
}
|
||||
|
||||
bool BaseAtmosphereRenderer::getLightsAt(vector<LightComponent> &, const Vector3 &) const {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "SurfaceMaterial.h"
|
||||
#include "LightComponent.h"
|
||||
#include "LightStatus.h"
|
||||
#include "CelestialBodyDefinition.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
#define WORLD_SCALING 0.05
|
||||
#define MOON_DISTANCE 384403.0
|
||||
|
@ -56,11 +58,10 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction) {
|
|||
}
|
||||
|
||||
// Get moon
|
||||
VectorSpherical moon_location_s = {MOON_DISTANCE_SCALED, atmosphere->moon_theta, -atmosphere->moon_phi};
|
||||
Vector3 moon_position(moon_location_s);
|
||||
Vector3 moon_direction = moon_position.normalize();
|
||||
Vector3 moon_direction = atmosphere->childMoon()->getDirection();
|
||||
Vector3 moon_position = moon_direction.scale(MOON_DISTANCE_SCALED);
|
||||
if (moon_direction.dotProduct(direction) >= 0) {
|
||||
double moon_radius = MOON_RADIUS_SCALED * 5.0 * atmosphere->moon_radius;
|
||||
double moon_radius = MOON_RADIUS_SCALED * 5.0 * atmosphere->childMoon()->propRadius()->getValue();
|
||||
Vector3 hit1, hit2;
|
||||
int hits = Geometry::rayIntersectSphere(location, direction, moon_position, moon_radius, &hit1, &hit2);
|
||||
if (hits > 1) {
|
||||
|
@ -87,10 +88,9 @@ bool NightSky::getLightsAt(vector<LightComponent> &result, const Vector3 &) cons
|
|||
LightComponent moon, sky;
|
||||
|
||||
AtmosphereDefinition *atmosphere = renderer->getScenery()->getAtmosphere();
|
||||
VectorSpherical moon_location_s = {MOON_DISTANCE_SCALED, atmosphere->moon_theta, -atmosphere->moon_phi};
|
||||
|
||||
moon.color = Color(0.03, 0.03, 0.03); // TODO take moon phase into account
|
||||
moon.direction = Vector3(moon_location_s).normalize().scale(-1.0);
|
||||
moon.direction = atmosphere->childMoon()->getDirection().scale(-1.0);
|
||||
moon.reflection = 0.2;
|
||||
moon.altered = 1;
|
||||
|
||||
|
|
|
@ -10,15 +10,15 @@ TEST(Scenery, saveGlobal) {
|
|||
Scenery scenery1;
|
||||
scenery1.autoPreset();
|
||||
scenery1.getTerrain()->propWaterHeight()->setValue(0.2);
|
||||
scenery1.getAtmosphere()->propDayTime()->setValue(0.53);
|
||||
scenery1.getAtmosphere()->setDayTime(0.53);
|
||||
|
||||
Scenery::FileOperationResult result = scenery1.saveGlobal("/tmp/test_paysages_scenery");
|
||||
EXPECT_EQ((int)Scenery::FILE_OPERATION_OK, result);
|
||||
EXPECT_EQ(Scenery::FILE_OPERATION_OK, result);
|
||||
|
||||
Scenery scenery2;
|
||||
result = scenery2.loadGlobal("/tmp/test_paysages_scenery");
|
||||
EXPECT_EQ((int)Scenery::FILE_OPERATION_OK, result);
|
||||
EXPECT_EQ(Scenery::FILE_OPERATION_OK, result);
|
||||
|
||||
EXPECT_DOUBLE_EQ(0.2, scenery2.getTerrain()->propWaterHeight()->getValue());
|
||||
EXPECT_DOUBLE_EQ(0.53, scenery2.getAtmosphere()->propDayTime()->getValue());
|
||||
EXPECT_DOUBLE_EQ(0.53, scenery2.getAtmosphere()->getDaytime());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue