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() {
}
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<const IntDiff *>(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<const FloatDiff *>(diff);
floatNodeChanged(node->getPath(), float_diff->getNewValue(), float_diff->getOldValue());
}
}

View file

@ -16,6 +16,7 @@ namespace definition {
class DEFINITIONSHARED_EXPORT DefinitionWatcher {
public:
DefinitionWatcher();
virtual ~DefinitionWatcher();
/**
* Abstract method called when a node changed.

View file

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

View file

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

View file

@ -14,25 +14,33 @@ class BaseModelerTool::pimpl {
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() {
}
void BaseModelerTool::addIntBinding(const string &object, const string &property, const string &path) {
auto node = static_cast<IntNode *>(main->getScenery()->findByPath(path));
void BaseModelerTool::addIntBinding(const string &object, const string &property, const string &path, bool monitor) {
auto node = static_cast<IntNode *>(window->getScenery()->findByPath(path));
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 {
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));
void BaseModelerTool::addFloatBinding(const string &object, const string &property, const string &path, bool monitor) {
auto node = static_cast<FloatNode *>(window->getScenery()->findByPath(path));
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 {
Logs::error("UI") << "Can't find float node for binding : " << path << endl;
}

View file

@ -3,31 +3,42 @@
#include "modeler_global.h"
#include "DefinitionWatcher.h"
#include <memory>
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<pimpl> impl;
MainModelerWindow *main;
MainModelerWindow *window;
};
}
}

View file

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

View file

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

View file

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