Added camera focus on sun while moving it
This commit is contained in:
parent
b9a51bb2be
commit
958fd0121b
9 changed files with 75 additions and 29 deletions
|
@ -8,14 +8,17 @@
|
||||||
DefinitionWatcher::DefinitionWatcher() {
|
DefinitionWatcher::DefinitionWatcher() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefinitionWatcher::~DefinitionWatcher() {
|
||||||
|
}
|
||||||
|
|
||||||
void DefinitionWatcher::nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) {
|
void DefinitionWatcher::nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) {
|
||||||
string type_name = node->getTypeName();
|
string type_name = node->getTypeName();
|
||||||
|
|
||||||
if (type_name == "int") {
|
if (type_name == "int") {
|
||||||
IntDiff *int_diff = (IntDiff *)diff;
|
auto int_diff = static_cast<const IntDiff *>(diff);
|
||||||
intNodeChanged(node->getPath(), int_diff->getNewValue(), int_diff->getOldValue());
|
intNodeChanged(node->getPath(), int_diff->getNewValue(), int_diff->getOldValue());
|
||||||
} else if (type_name == "float") {
|
} else if (type_name == "float") {
|
||||||
FloatDiff *float_diff = (FloatDiff *)diff;
|
auto float_diff = static_cast<const FloatDiff *>(diff);
|
||||||
floatNodeChanged(node->getPath(), float_diff->getNewValue(), float_diff->getOldValue());
|
floatNodeChanged(node->getPath(), float_diff->getNewValue(), float_diff->getOldValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace definition {
|
||||||
class DEFINITIONSHARED_EXPORT DefinitionWatcher {
|
class DEFINITIONSHARED_EXPORT DefinitionWatcher {
|
||||||
public:
|
public:
|
||||||
DefinitionWatcher();
|
DefinitionWatcher();
|
||||||
|
virtual ~DefinitionWatcher();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract method called when a node changed.
|
* Abstract method called when a node changed.
|
||||||
|
|
|
@ -3,15 +3,23 @@
|
||||||
#include "MainModelerWindow.h"
|
#include "MainModelerWindow.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
|
#include "DefinitionNode.h"
|
||||||
|
#include "ModelerCameras.h"
|
||||||
|
|
||||||
AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main) : BaseModelerTool(main) {
|
AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main) : BaseModelerTool(main) {
|
||||||
addFloatBinding("atmosphere_humidity", "value", "/atmosphere/humidity");
|
addFloatBinding("atmosphere_humidity", "value", "/atmosphere/humidity");
|
||||||
addFloatBinding("atmosphere_sun_direction", "phi", "/atmosphere/sun/phi");
|
addFloatBinding("atmosphere_sun_direction", "phi", "/atmosphere/sun/phi", true);
|
||||||
addFloatBinding("atmosphere_sun_direction", "theta", "/atmosphere/sun/theta");
|
addFloatBinding("atmosphere_sun_direction", "theta", "/atmosphere/sun/theta", true);
|
||||||
addFloatBinding("atmosphere_sun_radius", "value", "/atmosphere/sun/radius");
|
addFloatBinding("atmosphere_sun_radius", "value", "/atmosphere/sun/radius");
|
||||||
addFloatBinding("atmosphere_moon_direction", "phi", "/atmosphere/moon/phi");
|
addFloatBinding("atmosphere_moon_direction", "phi", "/atmosphere/moon/phi", true);
|
||||||
addFloatBinding("atmosphere_moon_direction", "theta", "/atmosphere/moon/theta");
|
addFloatBinding("atmosphere_moon_direction", "theta", "/atmosphere/moon/theta", true);
|
||||||
// addFloatBinding("atmosphere_moon_radius", "value", "/atmosphere/moon/radius");
|
// addFloatBinding("atmosphere_moon_radius", "value", "/atmosphere/moon/radius");
|
||||||
|
|
||||||
main->setQmlProperty("atmosphere_daytime", "value", main->getScenery()->getAtmosphere()->getDaytime());
|
main->setQmlProperty("atmosphere_daytime", "value", main->getScenery()->getAtmosphere()->getDaytime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AtmosphereModeler::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
||||||
|
if (node->getPath().find("/atmosphere/sun/") == 0) {
|
||||||
|
getWindow()->getCamera()->startSunTool(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@ namespace modeler {
|
||||||
|
|
||||||
class AtmosphereModeler : protected BaseModelerTool {
|
class AtmosphereModeler : protected BaseModelerTool {
|
||||||
public:
|
public:
|
||||||
AtmosphereModeler(MainModelerWindow *main);
|
AtmosphereModeler(MainModelerWindow *window);
|
||||||
|
|
||||||
|
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,25 +14,33 @@ class BaseModelerTool::pimpl {
|
||||||
vector<unique_ptr<FloatPropertyBind>> float_bindings;
|
vector<unique_ptr<FloatPropertyBind>> float_bindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
BaseModelerTool::BaseModelerTool(MainModelerWindow *main) : impl(new pimpl), main(main) {
|
BaseModelerTool::BaseModelerTool(MainModelerWindow *main) : impl(new pimpl), window(main) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseModelerTool::~BaseModelerTool() {
|
BaseModelerTool::~BaseModelerTool() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseModelerTool::addIntBinding(const string &object, const string &property, const string &path) {
|
void BaseModelerTool::addIntBinding(const string &object, const string &property, const string &path, bool monitor) {
|
||||||
auto node = static_cast<IntNode *>(main->getScenery()->findByPath(path));
|
auto node = static_cast<IntNode *>(window->getScenery()->findByPath(path));
|
||||||
if (node) {
|
if (node) {
|
||||||
impl->int_bindings.push_back(make_unique<IntPropertyBind>(main, object, property, node));
|
impl->int_bindings.push_back(make_unique<IntPropertyBind>(window, object, property, node));
|
||||||
|
|
||||||
|
if (monitor) {
|
||||||
|
startWatching(window->getScenery(), path, false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logs::error("UI") << "Can't find int node for binding : " << path << endl;
|
Logs::error("UI") << "Can't find int node for binding : " << path << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseModelerTool::addFloatBinding(const string &object, const string &property, const string &path) {
|
void BaseModelerTool::addFloatBinding(const string &object, const string &property, const string &path, bool monitor) {
|
||||||
auto node = static_cast<FloatNode *>(main->getScenery()->findByPath(path));
|
auto node = static_cast<FloatNode *>(window->getScenery()->findByPath(path));
|
||||||
if (node) {
|
if (node) {
|
||||||
impl->float_bindings.push_back(make_unique<FloatPropertyBind>(main, object, property, node));
|
impl->float_bindings.push_back(make_unique<FloatPropertyBind>(window, object, property, node));
|
||||||
|
|
||||||
|
if (monitor) {
|
||||||
|
startWatching(window->getScenery(), path, false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logs::error("UI") << "Can't find float node for binding : " << path << endl;
|
Logs::error("UI") << "Can't find float node for binding : " << path << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,31 +3,42 @@
|
||||||
|
|
||||||
#include "modeler_global.h"
|
#include "modeler_global.h"
|
||||||
|
|
||||||
|
#include "DefinitionWatcher.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace modeler {
|
namespace modeler {
|
||||||
|
|
||||||
class BaseModelerTool {
|
class BaseModelerTool : public DefinitionWatcher {
|
||||||
public:
|
public:
|
||||||
BaseModelerTool(MainModelerWindow *main);
|
BaseModelerTool(MainModelerWindow *window);
|
||||||
virtual ~BaseModelerTool();
|
virtual ~BaseModelerTool();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an automated two-way binding between a QML int property and a scenery IntNode.
|
* Add an automated two-way binding between a QML int property and a scenery IntNode.
|
||||||
|
*
|
||||||
|
* If *monitor* is true, this tool will also receive the node changes, via the DefinitionWatcher mechanism.
|
||||||
*/
|
*/
|
||||||
void addIntBinding(const string &object, const string &property, const string &path);
|
void addIntBinding(const string &object, const string &property, const string &path, bool monitor = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an automated two-way binding between a QML int property and a scenery IntNode.
|
* Add an automated two-way binding between a QML int property and a scenery IntNode.
|
||||||
|
*
|
||||||
|
* If *monitor* is true, this tool will also receive the node changes, via the DefinitionWatcher mechanism.
|
||||||
*/
|
*/
|
||||||
void addFloatBinding(const string &object, const string &property, const string &path);
|
void addFloatBinding(const string &object, const string &property, const string &path, bool monitor = false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline MainModelerWindow *getWindow() const {
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class pimpl;
|
class pimpl;
|
||||||
unique_ptr<pimpl> impl;
|
unique_ptr<pimpl> impl;
|
||||||
|
|
||||||
MainModelerWindow *main;
|
MainModelerWindow *window;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
#include "FloatNode.h"
|
#include "FloatNode.h"
|
||||||
#include "AtmosphereRenderer.h"
|
#include "AtmosphereRenderer.h"
|
||||||
|
#include "Time.h"
|
||||||
|
|
||||||
ModelerCameras::ModelerCameras(MainModelerWindow *parent) : QObject(parent), parent(parent) {
|
ModelerCameras::ModelerCameras(MainModelerWindow *parent) : QObject(parent), parent(parent) {
|
||||||
render = new CameraDefinition();
|
render = new CameraDefinition();
|
||||||
|
@ -21,6 +22,10 @@ ModelerCameras::ModelerCameras(MainModelerWindow *parent) : QObject(parent), par
|
||||||
parent->connectQmlSignal("camera_choice", 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)));
|
parent->connectQmlSignal("ui", SIGNAL(mainToolChanged(QString)), this, SLOT(toolChanged(QString)));
|
||||||
|
|
||||||
|
// Watch definition changes
|
||||||
|
startWatching(parent->getScenery(), "/atmosphere/sun/phi");
|
||||||
|
startWatching(parent->getScenery(), "/atmosphere/sun/theta");
|
||||||
|
|
||||||
// Validate to apply initial camera to scenery
|
// Validate to apply initial camera to scenery
|
||||||
validate();
|
validate();
|
||||||
|
|
||||||
|
@ -55,15 +60,16 @@ void ModelerCameras::processPanning(double xvalue, double yvalue) {
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelerCameras::startSunTool() {
|
void ModelerCameras::startSunTool(unsigned long duration) {
|
||||||
tool_mode = TOOL_SUN;
|
if (tool_mode != TOOL_SUN) {
|
||||||
|
tool_mode = TOOL_SUN;
|
||||||
|
|
||||||
previous = active;
|
previous = active;
|
||||||
current->copy(tool);
|
current->copy(tool);
|
||||||
active = tool;
|
active = tool;
|
||||||
|
}
|
||||||
|
|
||||||
startWatching(parent->getScenery(), "/atmosphere/sun/phi");
|
tool_auto_end = duration ? (Time::getRelativeTimeMs() + duration) : 0;
|
||||||
startWatching(parent->getScenery(), "/atmosphere/sun/theta");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelerCameras::endTool() {
|
void ModelerCameras::endTool() {
|
||||||
|
@ -78,6 +84,9 @@ void ModelerCameras::timerEvent(QTimerEvent *) {
|
||||||
parent->getScenery()->keepCameraAboveGround(current);
|
parent->getScenery()->keepCameraAboveGround(current);
|
||||||
parent->getRenderer()->setCamera(current);
|
parent->getRenderer()->setCamera(current);
|
||||||
}
|
}
|
||||||
|
if (tool_auto_end > 0 and Time::getRelativeTimeMs() >= tool_auto_end) {
|
||||||
|
endTool();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelerCameras::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
void ModelerCameras::nodeChanged(const DefinitionNode *node, const DefinitionDiff *) {
|
||||||
|
|
|
@ -36,8 +36,11 @@ class ModelerCameras : public QObject, public DefinitionWatcher {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a sun tool, the camera will follow the sun.
|
* Start a sun tool, the camera will follow the sun.
|
||||||
|
*
|
||||||
|
* *duration* is the duration in milliseconds before calling endTool() automatically (0 to disable to wait for
|
||||||
|
*manual call).
|
||||||
*/
|
*/
|
||||||
void startSunTool();
|
void startSunTool(unsigned long duration = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* End the tool mode.
|
* End the tool mode.
|
||||||
|
@ -45,7 +48,7 @@ class ModelerCameras : public QObject, public DefinitionWatcher {
|
||||||
void endTool();
|
void endTool();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent *event);
|
virtual void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
|
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
|
||||||
|
|
||||||
|
@ -69,6 +72,7 @@ class ModelerCameras : public QObject, public DefinitionWatcher {
|
||||||
|
|
||||||
typedef enum { TOOL_NONE, TOOL_SUN } CameraToolMode;
|
typedef enum { TOOL_NONE, TOOL_SUN } CameraToolMode;
|
||||||
CameraToolMode tool_mode;
|
CameraToolMode tool_mode;
|
||||||
|
unsigned long tool_auto_end;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ static void check_daytime(const AtmosphereDefinition &atmo, int expected_hour, i
|
||||||
EXPECT_EQ(expected_second, second);
|
EXPECT_EQ(expected_second, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_auto_daytime(AtmosphereDefinition &atmo, int hour, int minute=0, int second=0) {
|
static void check_auto_daytime(AtmosphereDefinition &atmo, int hour, int minute = 0, int second = 0) {
|
||||||
atmo.setDayTime(hour, minute, second);
|
atmo.setDayTime(hour, minute, second);
|
||||||
check_daytime(atmo, hour, minute, second);
|
check_daytime(atmo, hour, minute, second);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue