Added /atmosphere/sun_radius property

Also added the tool camera mode to focus on the sun while altering its radius
This commit is contained in:
Michaël Lemaire 2015-09-21 23:12:43 +02:00
parent 63eb7b53eb
commit 8a9c3d4b83
17 changed files with 158 additions and 17 deletions

2
TODO
View file

@ -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.

View file

@ -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);

View file

@ -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;
};
}

View file

@ -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;
}

View file

@ -15,6 +15,7 @@ public:
private:
FloatPropertyBind *prop_daytime;
FloatPropertyBind *prop_humidity;
FloatPropertyBind *prop_sun_radius;
};
}

View file

@ -72,7 +72,14 @@ MainModelerWindow::~MainModelerWindow()
QObject *MainModelerWindow::findQmlObject(const QString &objectName)
{
return rootObject()->findChild<QObject *>(objectName);
if (objectName == "ui" || objectName == "root")
{
return rootObject();
}
else
{
return rootObject()->findChild<QObject *>(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

View file

@ -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);

View file

@ -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();
}
}

View file

@ -4,6 +4,7 @@
#include "modeler_global.h"
#include <QObject>
#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;
};
}

View file

@ -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

View file

@ -1,6 +1,8 @@
import QtQuick 2.0
BaseRectangle {
property string tool: ""
anchors.bottom: main_ui.bottom
height: main_ui.height - primary_toolbar.height
}

View file

@ -52,5 +52,6 @@
<file>images/icon_render_medium.png</file>
<file>images/icon_render_final.png</file>
<file>images/icon_cancel.png</file>
<file>images/icon_sun_radius.png</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -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"

View file

@ -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)

View file

@ -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;

View file

@ -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;