From 958fd0121bfc67a2cf349e6661bce277f930cdb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Wed, 30 Dec 2015 20:14:16 +0100 Subject: [PATCH] Added camera focus on sun while moving it --- src/definition/DefinitionWatcher.cpp | 7 +++++-- src/definition/DefinitionWatcher.h | 1 + src/interface/modeler/AtmosphereModeler.cpp | 16 ++++++++++---- src/interface/modeler/AtmosphereModeler.h | 4 +++- src/interface/modeler/BaseModelerTool.cpp | 22 +++++++++++++------- src/interface/modeler/BaseModelerTool.h | 21 ++++++++++++++----- src/interface/modeler/ModelerCameras.cpp | 23 ++++++++++++++------- src/interface/modeler/ModelerCameras.h | 8 +++++-- src/tests/AtmosphereDefinition_Test.cpp | 2 +- 9 files changed, 75 insertions(+), 29 deletions(-) diff --git a/src/definition/DefinitionWatcher.cpp b/src/definition/DefinitionWatcher.cpp index d484ec3..c94c233 100644 --- a/src/definition/DefinitionWatcher.cpp +++ b/src/definition/DefinitionWatcher.cpp @@ -8,14 +8,17 @@ DefinitionWatcher::DefinitionWatcher() { } +DefinitionWatcher::~DefinitionWatcher() { +} + void DefinitionWatcher::nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) { string type_name = node->getTypeName(); if (type_name == "int") { - IntDiff *int_diff = (IntDiff *)diff; + auto int_diff = static_cast(diff); intNodeChanged(node->getPath(), int_diff->getNewValue(), int_diff->getOldValue()); } else if (type_name == "float") { - FloatDiff *float_diff = (FloatDiff *)diff; + auto float_diff = static_cast(diff); floatNodeChanged(node->getPath(), float_diff->getNewValue(), float_diff->getOldValue()); } } diff --git a/src/definition/DefinitionWatcher.h b/src/definition/DefinitionWatcher.h index 9de0940..784c2f9 100644 --- a/src/definition/DefinitionWatcher.h +++ b/src/definition/DefinitionWatcher.h @@ -16,6 +16,7 @@ namespace definition { class DEFINITIONSHARED_EXPORT DefinitionWatcher { public: DefinitionWatcher(); + virtual ~DefinitionWatcher(); /** * Abstract method called when a node changed. diff --git a/src/interface/modeler/AtmosphereModeler.cpp b/src/interface/modeler/AtmosphereModeler.cpp index a63783f..0b75562 100644 --- a/src/interface/modeler/AtmosphereModeler.cpp +++ b/src/interface/modeler/AtmosphereModeler.cpp @@ -3,15 +3,23 @@ #include "MainModelerWindow.h" #include "Scenery.h" #include "AtmosphereDefinition.h" +#include "DefinitionNode.h" +#include "ModelerCameras.h" 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_direction", "phi", "/atmosphere/sun/phi", true); + addFloatBinding("atmosphere_sun_direction", "theta", "/atmosphere/sun/theta", true); 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_direction", "phi", "/atmosphere/moon/phi", true); + addFloatBinding("atmosphere_moon_direction", "theta", "/atmosphere/moon/theta", true); // addFloatBinding("atmosphere_moon_radius", "value", "/atmosphere/moon/radius"); 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); + } +} diff --git a/src/interface/modeler/AtmosphereModeler.h b/src/interface/modeler/AtmosphereModeler.h index 88ce375..810c425 100644 --- a/src/interface/modeler/AtmosphereModeler.h +++ b/src/interface/modeler/AtmosphereModeler.h @@ -10,7 +10,9 @@ namespace modeler { class AtmosphereModeler : protected BaseModelerTool { public: - AtmosphereModeler(MainModelerWindow *main); + AtmosphereModeler(MainModelerWindow *window); + + virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override; }; } } diff --git a/src/interface/modeler/BaseModelerTool.cpp b/src/interface/modeler/BaseModelerTool.cpp index 0b0d129..716cf36 100644 --- a/src/interface/modeler/BaseModelerTool.cpp +++ b/src/interface/modeler/BaseModelerTool.cpp @@ -14,25 +14,33 @@ class BaseModelerTool::pimpl { vector> float_bindings; }; -BaseModelerTool::BaseModelerTool(MainModelerWindow *main) : impl(new pimpl), main(main) { +BaseModelerTool::BaseModelerTool(MainModelerWindow *main) : impl(new pimpl), window(main) { } BaseModelerTool::~BaseModelerTool() { } -void BaseModelerTool::addIntBinding(const string &object, const string &property, const string &path) { - auto node = static_cast(main->getScenery()->findByPath(path)); +void BaseModelerTool::addIntBinding(const string &object, const string &property, const string &path, bool monitor) { + auto node = static_cast(window->getScenery()->findByPath(path)); if (node) { - impl->int_bindings.push_back(make_unique(main, object, property, node)); + impl->int_bindings.push_back(make_unique(window, object, property, node)); + + if (monitor) { + startWatching(window->getScenery(), path, false); + } } 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(main->getScenery()->findByPath(path)); +void BaseModelerTool::addFloatBinding(const string &object, const string &property, const string &path, bool monitor) { + auto node = static_cast(window->getScenery()->findByPath(path)); if (node) { - impl->float_bindings.push_back(make_unique(main, object, property, node)); + impl->float_bindings.push_back(make_unique(window, object, property, node)); + + if (monitor) { + startWatching(window->getScenery(), path, false); + } } else { Logs::error("UI") << "Can't find float node for binding : " << path << endl; } diff --git a/src/interface/modeler/BaseModelerTool.h b/src/interface/modeler/BaseModelerTool.h index 8efeab1..25bffee 100644 --- a/src/interface/modeler/BaseModelerTool.h +++ b/src/interface/modeler/BaseModelerTool.h @@ -3,31 +3,42 @@ #include "modeler_global.h" +#include "DefinitionWatcher.h" + #include namespace paysages { namespace modeler { -class BaseModelerTool { +class BaseModelerTool : public DefinitionWatcher { public: - BaseModelerTool(MainModelerWindow *main); + BaseModelerTool(MainModelerWindow *window); virtual ~BaseModelerTool(); /** * 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. + * + * 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: class pimpl; unique_ptr impl; - MainModelerWindow *main; + MainModelerWindow *window; }; } } diff --git a/src/interface/modeler/ModelerCameras.cpp b/src/interface/modeler/ModelerCameras.cpp index fb5c247..e12b836 100644 --- a/src/interface/modeler/ModelerCameras.cpp +++ b/src/interface/modeler/ModelerCameras.cpp @@ -7,6 +7,7 @@ #include "AtmosphereDefinition.h" #include "FloatNode.h" #include "AtmosphereRenderer.h" +#include "Time.h" ModelerCameras::ModelerCameras(MainModelerWindow *parent) : QObject(parent), parent(parent) { 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("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(); @@ -55,15 +60,16 @@ void ModelerCameras::processPanning(double xvalue, double yvalue) { validate(); } -void ModelerCameras::startSunTool() { - tool_mode = TOOL_SUN; +void ModelerCameras::startSunTool(unsigned long duration) { + if (tool_mode != TOOL_SUN) { + tool_mode = TOOL_SUN; - previous = active; - current->copy(tool); - active = tool; + previous = active; + current->copy(tool); + active = tool; + } - startWatching(parent->getScenery(), "/atmosphere/sun/phi"); - startWatching(parent->getScenery(), "/atmosphere/sun/theta"); + tool_auto_end = duration ? (Time::getRelativeTimeMs() + duration) : 0; } void ModelerCameras::endTool() { @@ -78,6 +84,9 @@ void ModelerCameras::timerEvent(QTimerEvent *) { parent->getScenery()->keepCameraAboveGround(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 *) { diff --git a/src/interface/modeler/ModelerCameras.h b/src/interface/modeler/ModelerCameras.h index 47f20cb..a1035fc 100644 --- a/src/interface/modeler/ModelerCameras.h +++ b/src/interface/modeler/ModelerCameras.h @@ -36,8 +36,11 @@ class ModelerCameras : public QObject, public DefinitionWatcher { /** * 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. @@ -45,7 +48,7 @@ class ModelerCameras : public QObject, public DefinitionWatcher { void endTool(); protected: - void timerEvent(QTimerEvent *event); + virtual void timerEvent(QTimerEvent *event) 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; CameraToolMode tool_mode; + unsigned long tool_auto_end; }; } } diff --git a/src/tests/AtmosphereDefinition_Test.cpp b/src/tests/AtmosphereDefinition_Test.cpp index 182f3e4..e9f7845 100644 --- a/src/tests/AtmosphereDefinition_Test.cpp +++ b/src/tests/AtmosphereDefinition_Test.cpp @@ -11,7 +11,7 @@ static void check_daytime(const AtmosphereDefinition &atmo, int expected_hour, i 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); check_daytime(atmo, hour, minute, second); }