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() {
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace definition {
|
|||
class DEFINITIONSHARED_EXPORT DefinitionWatcher {
|
||||
public:
|
||||
DefinitionWatcher();
|
||||
virtual ~DefinitionWatcher();
|
||||
|
||||
/**
|
||||
* Abstract method called when a node changed.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
void ModelerCameras::startSunTool(unsigned long duration) {
|
||||
if (tool_mode != TOOL_SUN) {
|
||||
tool_mode = TOOL_SUN;
|
||||
|
||||
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 *) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue