Added DefinitionWatcher system
Also switched to the new definition system for /terrain/water_height
This commit is contained in:
parent
67bd80fba5
commit
8fa0d8af29
23 changed files with 201 additions and 36 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
|
#include "DefinitionWatcher.h"
|
||||||
#include "DefinitionDiff.h"
|
#include "DefinitionDiff.h"
|
||||||
#include "DiffManager.h"
|
#include "DiffManager.h"
|
||||||
|
|
||||||
|
@ -157,10 +158,25 @@ bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionNode::addWatcher(DefinitionWatcher *watcher)
|
void DefinitionNode::generateInitDiffs(std::vector<const DefinitionDiff *> *) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff)
|
||||||
{
|
{
|
||||||
if (root && root->diffs)
|
if (root && root->diffs)
|
||||||
{
|
{
|
||||||
|
if (init_diff)
|
||||||
|
{
|
||||||
|
std::vector<const DefinitionDiff *> diffs;
|
||||||
|
generateInitDiffs(&diffs);
|
||||||
|
|
||||||
|
for (auto diff: diffs)
|
||||||
|
{
|
||||||
|
watcher->nodeChanged(this, diff);
|
||||||
|
delete diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
root->diffs->addWatcher(this, watcher);
|
root->diffs->addWatcher(this, watcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,12 +61,21 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false);
|
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill a diff array to be applied to initialize a proper state for a watcher.
|
||||||
|
*
|
||||||
|
* This method should be overridden by subclasses.
|
||||||
|
*/
|
||||||
|
virtual void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a watcher over this node.
|
* Add a watcher over this node.
|
||||||
*
|
*
|
||||||
* The watcher will receive DefinitionDiff objects when this node changes.
|
* The watcher will receive DefinitionDiff objects when this node changes.
|
||||||
|
*
|
||||||
|
* If *init_diff* is set to true, a first diff (or several) will be be pushed immediately to initialize the state.
|
||||||
*/
|
*/
|
||||||
void addWatcher(DefinitionWatcher *watcher);
|
void addWatcher(DefinitionWatcher *watcher, bool init_diff=false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addChild(DefinitionNode* child);
|
void addChild(DefinitionNode* child);
|
||||||
|
|
|
@ -15,6 +15,11 @@ class DEFINITIONSHARED_EXPORT DefinitionWatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DefinitionWatcher();
|
DefinitionWatcher();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract method called when a node changed.
|
||||||
|
*/
|
||||||
|
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "DefinitionNode.h"
|
#include "DefinitionNode.h"
|
||||||
#include "DefinitionDiff.h"
|
#include "DefinitionDiff.h"
|
||||||
|
#include "DefinitionWatcher.h"
|
||||||
|
|
||||||
DiffManager::DiffManager(DefinitionNode *tree):
|
DiffManager::DiffManager(DefinitionNode *tree):
|
||||||
tree(tree)
|
tree(tree)
|
||||||
|
@ -9,6 +10,15 @@ DiffManager::DiffManager(DefinitionNode *tree):
|
||||||
undone = 0;
|
undone = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiffManager::~DiffManager()
|
||||||
|
{
|
||||||
|
for (auto diff: diffs)
|
||||||
|
{
|
||||||
|
delete diff;
|
||||||
|
}
|
||||||
|
diffs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher)
|
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher)
|
||||||
{
|
{
|
||||||
watchers[node].push_back(watcher);
|
watchers[node].push_back(watcher);
|
||||||
|
@ -19,6 +29,7 @@ void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff)
|
||||||
while (undone > 0)
|
while (undone > 0)
|
||||||
{
|
{
|
||||||
// truncate diffs ahead
|
// truncate diffs ahead
|
||||||
|
delete diffs.back();
|
||||||
diffs.pop_back();
|
diffs.pop_back();
|
||||||
undone--;
|
undone--;
|
||||||
}
|
}
|
||||||
|
@ -28,9 +39,9 @@ void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff)
|
||||||
// TODO Delayed commit (with merge of consecutive diffs)
|
// TODO Delayed commit (with merge of consecutive diffs)
|
||||||
node->applyDiff(diff);
|
node->applyDiff(diff);
|
||||||
|
|
||||||
for (auto &watcher: watchers[node])
|
for (auto watcher: watchers[node])
|
||||||
{
|
{
|
||||||
// TODO
|
watcher->nodeChanged(node, diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ class DEFINITIONSHARED_EXPORT DiffManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DiffManager(DefinitionNode *tree);
|
DiffManager(DefinitionNode *tree);
|
||||||
|
~DiffManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a watcher for a specific node.
|
* Add a watcher for a specific node.
|
||||||
|
|
|
@ -52,6 +52,11 @@ const FloatDiff *FloatNode::produceDiff(double new_value) const
|
||||||
return new FloatDiff(this, value, new_value);
|
return new FloatDiff(this, value, new_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FloatNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const
|
||||||
|
{
|
||||||
|
diffs->push_back(produceDiff(value));
|
||||||
|
}
|
||||||
|
|
||||||
bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward)
|
bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward)
|
||||||
{
|
{
|
||||||
if (!DefinitionNode::applyDiff(diff, backward))
|
if (!DefinitionNode::applyDiff(diff, backward))
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void setValue(double new_value);
|
void setValue(double new_value);
|
||||||
const FloatDiff *produceDiff(double new_value) const;
|
const FloatDiff *produceDiff(double new_value) const;
|
||||||
|
void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
|
||||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false) override;
|
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false) override;
|
||||||
private:
|
private:
|
||||||
double value;
|
double value;
|
||||||
|
|
|
@ -15,8 +15,7 @@ TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
|
||||||
height_map = new TerrainHeightMap(this);
|
height_map = new TerrainHeightMap(this);
|
||||||
addChild(height_map);
|
addChild(height_map);
|
||||||
|
|
||||||
water_height = -0.3;
|
water_height = new FloatNode(this, "water_height", -0.3);
|
||||||
_water_height = new FloatNode(this, "water_height", -0.3);
|
|
||||||
|
|
||||||
_height_noise = new NoiseGenerator;
|
_height_noise = new NoiseGenerator;
|
||||||
}
|
}
|
||||||
|
@ -67,7 +66,6 @@ void TerrainDefinition::save(PackStream* stream) const
|
||||||
stream->write(&height);
|
stream->write(&height);
|
||||||
stream->write(&scaling);
|
stream->write(&scaling);
|
||||||
stream->write(&shadow_smoothing);
|
stream->write(&shadow_smoothing);
|
||||||
stream->write(&water_height);
|
|
||||||
_height_noise->save(stream);
|
_height_noise->save(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +76,6 @@ void TerrainDefinition::load(PackStream* stream)
|
||||||
stream->read(&height);
|
stream->read(&height);
|
||||||
stream->read(&scaling);
|
stream->read(&scaling);
|
||||||
stream->read(&shadow_smoothing);
|
stream->read(&shadow_smoothing);
|
||||||
stream->read(&water_height);
|
|
||||||
_height_noise->load(stream);
|
_height_noise->load(stream);
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
|
@ -96,7 +93,7 @@ double TerrainDefinition::getGridHeight(int x, int z, bool with_painting)
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled, bool with_painting)
|
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset)
|
||||||
{
|
{
|
||||||
double h;
|
double h;
|
||||||
x /= scaling;
|
x /= scaling;
|
||||||
|
@ -109,7 +106,7 @@ double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled,
|
||||||
|
|
||||||
if (scaled)
|
if (scaled)
|
||||||
{
|
{
|
||||||
return (h - water_height) * height * scaling;
|
return (water_offset ? (h - water_height->getValue()) : h) * height * scaling;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -117,6 +114,11 @@ double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double TerrainDefinition::getWaterOffset() const
|
||||||
|
{
|
||||||
|
return -water_height->getValue() * height * scaling;
|
||||||
|
}
|
||||||
|
|
||||||
HeightInfo TerrainDefinition::getHeightInfo()
|
HeightInfo TerrainDefinition::getHeightInfo()
|
||||||
{
|
{
|
||||||
HeightInfo result;
|
HeightInfo result;
|
||||||
|
@ -124,7 +126,7 @@ HeightInfo TerrainDefinition::getHeightInfo()
|
||||||
result.min_height = _min_height;
|
result.min_height = _min_height;
|
||||||
result.max_height = _max_height;
|
result.max_height = _max_height;
|
||||||
/* TODO This is duplicated in ter_render.c (_realGetWaterHeight) */
|
/* TODO This is duplicated in ter_render.c (_realGetWaterHeight) */
|
||||||
result.base_height = water_height * height * scaling;
|
result.base_height = water_height->getValue() * height * scaling;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,11 @@ public:
|
||||||
virtual void copy(DefinitionNode* destination) const override;
|
virtual void copy(DefinitionNode* destination) const override;
|
||||||
virtual void validate() override;
|
virtual void validate() override;
|
||||||
|
|
||||||
|
inline FloatNode *propWaterHeight() const {return water_height;}
|
||||||
|
|
||||||
double getGridHeight(int x, int z, bool with_painting);
|
double getGridHeight(int x, int z, bool with_painting);
|
||||||
double getInterpolatedHeight(double x, double z, bool scaled, bool with_painting);
|
double getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset=true);
|
||||||
|
double getWaterOffset() const;
|
||||||
unsigned long getMemoryStats();
|
unsigned long getMemoryStats();
|
||||||
HeightInfo getHeightInfo();
|
HeightInfo getHeightInfo();
|
||||||
|
|
||||||
|
@ -46,15 +49,13 @@ public:
|
||||||
|
|
||||||
TerrainHeightMap* height_map;
|
TerrainHeightMap* height_map;
|
||||||
|
|
||||||
double water_height;
|
|
||||||
|
|
||||||
double _detail;
|
double _detail;
|
||||||
NoiseGenerator* _height_noise;
|
NoiseGenerator* _height_noise;
|
||||||
double _min_height;
|
double _min_height;
|
||||||
double _max_height;
|
double _max_height;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FloatNode *_water_height;
|
FloatNode *water_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "RenderPreviewProvider.h"
|
#include "RenderPreviewProvider.h"
|
||||||
#include "RenderProcess.h"
|
#include "RenderProcess.h"
|
||||||
#include "RenderConfig.h"
|
#include "RenderConfig.h"
|
||||||
|
#include "DiffManager.h"
|
||||||
|
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
@ -103,4 +104,25 @@ void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
|
||||||
QGuiApplication::instance()->exit();
|
QGuiApplication::instance()->exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event->key() == Qt::Key_Z)
|
||||||
|
{
|
||||||
|
if (event->modifiers() & Qt::ControlModifier)
|
||||||
|
{
|
||||||
|
if (event->modifiers() & Qt::ShiftModifier)
|
||||||
|
{
|
||||||
|
scenery->getDiffManager()->redo();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scenery->getDiffManager()->undo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event->key() == Qt::Key_Y)
|
||||||
|
{
|
||||||
|
if (event->modifiers() & Qt::ControlModifier)
|
||||||
|
{
|
||||||
|
scenery->getDiffManager()->undo();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#include "WaterModeler.h"
|
#include "WaterModeler.h"
|
||||||
|
|
||||||
#include "MainModelerWindow.h"
|
#include "MainModelerWindow.h"
|
||||||
|
#include "Scenery.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
#include "FloatNode.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
WaterModeler::WaterModeler(MainModelerWindow *main):
|
WaterModeler::WaterModeler(MainModelerWindow *main):
|
||||||
main(main)
|
main(main)
|
||||||
|
@ -8,12 +12,17 @@ WaterModeler::WaterModeler(MainModelerWindow *main):
|
||||||
QObject *item = main->findQmlObject("water_level");
|
QObject *item = main->findQmlObject("water_level");
|
||||||
if (item)
|
if (item)
|
||||||
{
|
{
|
||||||
|
item->setProperty("value", propWaterHeight()->getValue() * 0.5 + 0.5);
|
||||||
connect(item, SIGNAL(changed(double)), this, SLOT(waterLevelChanged(double)));
|
connect(item, SIGNAL(changed(double)), this, SLOT(waterLevelChanged(double)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterModeler::waterLevelChanged(double)
|
void WaterModeler::waterLevelChanged(double value)
|
||||||
{
|
{
|
||||||
// TODO
|
propWaterHeight()->setValue(value * 2.0 - 1.0);
|
||||||
//qDebug() << "water level : " << value;
|
}
|
||||||
|
|
||||||
|
FloatNode *WaterModeler::propWaterHeight() const
|
||||||
|
{
|
||||||
|
return main->getScenery()->getTerrain()->propWaterHeight();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ public slots:
|
||||||
void waterLevelChanged(double value);
|
void waterLevelChanged(double value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
FloatNode *propWaterHeight() const;
|
||||||
MainModelerWindow *main;
|
MainModelerWindow *main;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "TerrainRenderer.h"
|
#include "TerrainRenderer.h"
|
||||||
#include "VertexArray.h"
|
#include "VertexArray.h"
|
||||||
|
|
||||||
ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height):
|
ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks):
|
||||||
_renderer(renderer)
|
_renderer(renderer)
|
||||||
{
|
{
|
||||||
priority = 0.0;
|
priority = 0.0;
|
||||||
|
@ -32,7 +32,6 @@ ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, d
|
||||||
|
|
||||||
distance_to_camera = 0.0;
|
distance_to_camera = 0.0;
|
||||||
|
|
||||||
_water_height = water_height;
|
|
||||||
overwater = false;
|
overwater = false;
|
||||||
|
|
||||||
tessellation_count = 33;
|
tessellation_count = 33;
|
||||||
|
@ -90,8 +89,8 @@ bool ExplorerChunkTerrain::maintain()
|
||||||
double x = _startx + _tessellation_step * (float)i;
|
double x = _startx + _tessellation_step * (float)i;
|
||||||
double z = _startz + _tessellation_step * (float)j;
|
double z = _startz + _tessellation_step * (float)j;
|
||||||
|
|
||||||
double height = _renderer->getTerrainRenderer()->getHeight(x, z, true);
|
double height = _renderer->getTerrainRenderer()->getHeight(x, z, true, false);
|
||||||
if (height >= _water_height)
|
if (height >= 0.0)
|
||||||
{
|
{
|
||||||
overwater = true;
|
overwater = true;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +269,7 @@ void ExplorerChunkTerrain::render(QOpenGLShaderProgram* program, OpenGLFunctions
|
||||||
int tessellation_size = _tessellation_current_size;
|
int tessellation_size = _tessellation_current_size;
|
||||||
_lock_data.unlock();
|
_lock_data.unlock();
|
||||||
|
|
||||||
if (tessellation_size <= 1 or not overwater)
|
if (tessellation_size <= 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
} TerrainVertex;
|
} TerrainVertex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height);
|
ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks);
|
||||||
~ExplorerChunkTerrain();
|
~ExplorerChunkTerrain();
|
||||||
|
|
||||||
bool maintain();
|
bool maintain();
|
||||||
|
@ -42,8 +42,6 @@ private:
|
||||||
double _size;
|
double _size;
|
||||||
double _overall_step;
|
double _overall_step;
|
||||||
|
|
||||||
double _water_height;
|
|
||||||
|
|
||||||
int tessellation_count;
|
int tessellation_count;
|
||||||
VertexArray<TerrainVertex> *tessellated;
|
VertexArray<TerrainVertex> *tessellated;
|
||||||
int _tessellation_max_size;
|
int _tessellation_max_size;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "WaterRenderer.h"
|
#include "WaterRenderer.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
|
#include "FloatNode.h"
|
||||||
|
#include "FloatDiff.h"
|
||||||
|
|
||||||
class ChunkMaintenanceThreads:public ParallelPool
|
class ChunkMaintenanceThreads:public ParallelPool
|
||||||
{
|
{
|
||||||
|
@ -62,12 +64,11 @@ void OpenGLTerrain::initialize()
|
||||||
double size = 800.0;
|
double size = 800.0;
|
||||||
double chunksize = size / (double) chunks;
|
double chunksize = size / (double) chunks;
|
||||||
double start = -size / 2.0;
|
double start = -size / 2.0;
|
||||||
double water_height = renderer->getWaterRenderer()->getHeightInfo().base_height;
|
|
||||||
for (int i = 0; i < chunks; i++)
|
for (int i = 0; i < chunks; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < chunks; j++)
|
for (int j = 0; j < chunks; j++)
|
||||||
{
|
{
|
||||||
ExplorerChunkTerrain* chunk = new ExplorerChunkTerrain(renderer, start + chunksize * (double) i, start + chunksize * (double) j, chunksize, chunks, water_height);
|
ExplorerChunkTerrain* chunk = new ExplorerChunkTerrain(renderer, start + chunksize * (double) i, start + chunksize * (double) j, chunksize, chunks);
|
||||||
_chunks.append(chunk);
|
_chunks.append(chunk);
|
||||||
_updateQueue.append(chunk);
|
_updateQueue.append(chunk);
|
||||||
}
|
}
|
||||||
|
@ -75,6 +76,9 @@ void OpenGLTerrain::initialize()
|
||||||
|
|
||||||
// Start chunks maintenance
|
// Start chunks maintenance
|
||||||
work->start();
|
work->start();
|
||||||
|
|
||||||
|
// Watch for definition changes
|
||||||
|
renderer->getScenery()->getTerrain()->propWaterHeight()->addWatcher(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLTerrain::update()
|
void OpenGLTerrain::update()
|
||||||
|
@ -142,3 +146,12 @@ void OpenGLTerrain::performChunksMaintenance()
|
||||||
qSort(_updateQueue.begin(), _updateQueue.end(), _cmpChunks);
|
qSort(_updateQueue.begin(), _updateQueue.end(), _cmpChunks);
|
||||||
_lock_chunks.unlock();
|
_lock_chunks.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpenGLTerrain::nodeChanged(const DefinitionNode *node, const DefinitionDiff *)
|
||||||
|
{
|
||||||
|
if (node->getPath() == "/terrain/water_height")
|
||||||
|
{
|
||||||
|
resetTextures();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "opengl_global.h"
|
#include "opengl_global.h"
|
||||||
|
|
||||||
#include "OpenGLPart.h"
|
#include "OpenGLPart.h"
|
||||||
|
#include "DefinitionWatcher.h"
|
||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
@ -12,7 +13,7 @@
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
|
|
||||||
class OPENGLSHARED_EXPORT OpenGLTerrain:public OpenGLPart
|
class OPENGLSHARED_EXPORT OpenGLTerrain: public OpenGLPart, public DefinitionWatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OpenGLTerrain(OpenGLRenderer* renderer);
|
OpenGLTerrain(OpenGLRenderer* renderer);
|
||||||
|
@ -30,6 +31,7 @@ public:
|
||||||
|
|
||||||
void performChunksMaintenance();
|
void performChunksMaintenance();
|
||||||
|
|
||||||
|
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
|
||||||
private:
|
private:
|
||||||
OpenGLShaderProgram* program;
|
OpenGLShaderProgram* program;
|
||||||
|
|
||||||
|
@ -38,6 +40,7 @@ private:
|
||||||
QVector<ExplorerChunkTerrain*> _chunks;
|
QVector<ExplorerChunkTerrain*> _chunks;
|
||||||
QList<ExplorerChunkTerrain*> _updateQueue;
|
QList<ExplorerChunkTerrain*> _updateQueue;
|
||||||
QMutex _lock_chunks;
|
QMutex _lock_chunks;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
#include "SurfaceMaterial.h"
|
#include "SurfaceMaterial.h"
|
||||||
#include "NoiseFunctionSimplex.h"
|
#include "NoiseFunctionSimplex.h"
|
||||||
|
#include "FloatNode.h"
|
||||||
|
#include "FloatDiff.h"
|
||||||
|
|
||||||
OpenGLWater::OpenGLWater(OpenGLRenderer *renderer):
|
OpenGLWater::OpenGLWater(OpenGLRenderer *renderer):
|
||||||
OpenGLPart(renderer)
|
OpenGLPart(renderer)
|
||||||
|
@ -34,6 +36,9 @@ void OpenGLWater::initialize()
|
||||||
setVertex(1, -1.0f, 0.0f, 1.0f);
|
setVertex(1, -1.0f, 0.0f, 1.0f);
|
||||||
setVertex(2, 1.0f, 0.0f, -1.0f);
|
setVertex(2, 1.0f, 0.0f, -1.0f);
|
||||||
setVertex(3, 1.0f, 0.0f, 1.0f);
|
setVertex(3, 1.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// Watch for definition changes
|
||||||
|
renderer->getScenery()->getTerrain()->propWaterHeight()->addWatcher(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLWater::update()
|
void OpenGLWater::update()
|
||||||
|
@ -58,3 +63,11 @@ void OpenGLWater::setVertex(int i, float x, float y, float z)
|
||||||
vertices[i * 3 + 1] = y;
|
vertices[i * 3 + 1] = y;
|
||||||
vertices[i * 3 + 2] = z;
|
vertices[i * 3 + 2] = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLWater::nodeChanged(const DefinitionNode *node, const DefinitionDiff *)
|
||||||
|
{
|
||||||
|
if (node->getPath() == "/terrain/water_height")
|
||||||
|
{
|
||||||
|
renderer->getSharedState()->set("waterOffset", renderer->getScenery()->getTerrain()->getWaterOffset());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
#include "opengl_global.h"
|
#include "opengl_global.h"
|
||||||
|
|
||||||
#include "OpenGLPart.h"
|
#include "OpenGLPart.h"
|
||||||
|
#include "DefinitionWatcher.h"
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
|
|
||||||
class OPENGLSHARED_EXPORT OpenGLWater: public OpenGLPart
|
class OPENGLSHARED_EXPORT OpenGLWater: public OpenGLPart, public DefinitionWatcher
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OpenGLWater(OpenGLRenderer* renderer);
|
OpenGLWater(OpenGLRenderer* renderer);
|
||||||
|
@ -18,6 +19,7 @@ public:
|
||||||
virtual void update() override;
|
virtual void update() override;
|
||||||
virtual void render() override;
|
virtual void render() override;
|
||||||
|
|
||||||
|
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override;
|
||||||
private:
|
private:
|
||||||
void setVertex(int i, float x, float y, float z);
|
void setVertex(int i, float x, float y, float z);
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@ attribute highp vec2 uv;
|
||||||
uniform highp mat4 viewMatrix;
|
uniform highp mat4 viewMatrix;
|
||||||
varying vec3 unprojected;
|
varying vec3 unprojected;
|
||||||
varying vec2 texcoord;
|
varying vec2 texcoord;
|
||||||
|
uniform float waterOffset;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
unprojected = vertex.xyz;
|
vec4 final = vertex + vec4(0, waterOffset, 0, 0);
|
||||||
|
unprojected = final.xyz;
|
||||||
texcoord = uv;
|
texcoord = uv;
|
||||||
gl_Position = viewMatrix * vertex;
|
gl_Position = viewMatrix * final;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@ void TerrainRenderer::update()
|
||||||
walker->update();
|
walker->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
double TerrainRenderer::getHeight(double x, double z, bool with_painting)
|
double TerrainRenderer::getHeight(double x, double z, bool with_painting, bool water_offset)
|
||||||
{
|
{
|
||||||
return parent->getScenery()->getTerrain()->getInterpolatedHeight(x, z, true, with_painting);
|
return parent->getScenery()->getTerrain()->getInterpolatedHeight(x, z, true, with_painting, water_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
|
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction);
|
virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction);
|
||||||
virtual double getHeight(double x, double z, bool with_painting);
|
virtual double getHeight(double x, double z, bool with_painting, bool water_offset=true);
|
||||||
virtual TerrainResult getResult(double x, double z, bool with_painting, bool with_textures);
|
virtual TerrainResult getResult(double x, double z, bool with_painting, bool with_textures);
|
||||||
virtual Color getFinalColor(const Vector3 &location, double precision);
|
virtual Color getFinalColor(const Vector3 &location, double precision);
|
||||||
virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override;
|
virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "DiffManager.h"
|
#include "DiffManager.h"
|
||||||
#include "DefinitionNode.h"
|
#include "DefinitionNode.h"
|
||||||
|
#include "DefinitionWatcher.h"
|
||||||
|
#include "FloatDiff.h"
|
||||||
#include "FloatNode.h"
|
#include "FloatNode.h"
|
||||||
|
|
||||||
TEST(DiffManager, undoRedo)
|
TEST(DiffManager, undoRedo)
|
||||||
|
@ -111,3 +113,52 @@ TEST(DiffManager, undoBranch)
|
||||||
diffs->redo();
|
diffs->redo();
|
||||||
EXPECT_DOUBLE_EQ(4.4, leaf.getValue());
|
EXPECT_DOUBLE_EQ(4.4, leaf.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestWatcher: public DefinitionWatcher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestWatcher(DefinitionNode* expected_node, double expected_old_value, double expected_new_value):
|
||||||
|
DefinitionWatcher(), expected_node(expected_node), expected_old_value(expected_old_value), expected_new_value(expected_new_value)
|
||||||
|
{
|
||||||
|
calls = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) override
|
||||||
|
{
|
||||||
|
EXPECT_EQ(expected_node, node);
|
||||||
|
ASSERT_EQ("float", diff->getTypeName());
|
||||||
|
const FloatDiff *float_diff = (const FloatDiff *)diff;
|
||||||
|
EXPECT_EQ(expected_old_value, float_diff->getOldValue());
|
||||||
|
EXPECT_EQ(expected_new_value, float_diff->getNewValue());
|
||||||
|
calls++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int calls;
|
||||||
|
DefinitionNode* expected_node;
|
||||||
|
double expected_old_value;
|
||||||
|
double expected_new_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(DiffManager, addWatcher)
|
||||||
|
{
|
||||||
|
FloatNode node(NULL, "node");
|
||||||
|
TestWatcher watcher(&node, 1.3, -4.0);
|
||||||
|
|
||||||
|
node.setValue(1.3);
|
||||||
|
EXPECT_EQ(0, watcher.calls);
|
||||||
|
|
||||||
|
node.addWatcher(&watcher);
|
||||||
|
EXPECT_EQ(0, watcher.calls);
|
||||||
|
|
||||||
|
node.setValue(-4.0);
|
||||||
|
EXPECT_EQ(1, watcher.calls);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DiffManager, addWatcherWithInitDiffs)
|
||||||
|
{
|
||||||
|
FloatNode node(NULL, "node", 1.3);
|
||||||
|
TestWatcher watcher(&node, 1.3, 1.3);
|
||||||
|
|
||||||
|
node.addWatcher(&watcher, true);
|
||||||
|
EXPECT_EQ(1, watcher.calls);
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "TerrainDefinition.h"
|
#include "TerrainDefinition.h"
|
||||||
#include "TerrainHeightMap.h"
|
#include "TerrainHeightMap.h"
|
||||||
#include "PaintedGridBrush.h"
|
#include "PaintedGridBrush.h"
|
||||||
|
#include "FloatNode.h"
|
||||||
|
|
||||||
/* Noise sin period is defined at 20.0 */
|
/* Noise sin period is defined at 20.0 */
|
||||||
#define X_FACTOR (M_PI / 10.0)
|
#define X_FACTOR (M_PI / 10.0)
|
||||||
|
@ -31,7 +32,7 @@ protected:
|
||||||
terrain->height = 3.0;
|
terrain->height = 3.0;
|
||||||
terrain->scaling = 1.0;
|
terrain->scaling = 1.0;
|
||||||
terrain->_height_noise->clearLevels();
|
terrain->_height_noise->clearLevels();
|
||||||
terrain->water_height = 0.0;
|
terrain->propWaterHeight()->setValue(0.0);
|
||||||
NoiseGenerator::NoiseLevel level = {1.0, 2.0, -1.0};
|
NoiseGenerator::NoiseLevel level = {1.0, 2.0, -1.0};
|
||||||
terrain->_height_noise->addLevel(level);
|
terrain->_height_noise->addLevel(level);
|
||||||
noise_state.resetOffsets();
|
noise_state.resetOffsets();
|
||||||
|
|
Loading…
Reference in a new issue