Added camera focus on sun while moving it

This commit is contained in:
Michaël Lemaire 2015-12-30 20:14:16 +01:00
parent b9a51bb2be
commit 958fd0121b
9 changed files with 75 additions and 29 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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