diff --git a/src/definition/ColorNode.cpp b/src/definition/ColorNode.cpp index 68f9014..cd6a9f7 100644 --- a/src/definition/ColorNode.cpp +++ b/src/definition/ColorNode.cpp @@ -24,12 +24,14 @@ void ColorNode::save(PackStream *stream) const { } void ColorNode::load(PackStream *stream) { - value.load(stream); + Color val; + val.load(stream); + setValue(val); } void ColorNode::copy(DefinitionNode *destination) const { if (auto tdest = dynamic_cast(destination)) { - tdest->value = value; + tdest->setValue(value); } else { Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; @@ -62,6 +64,7 @@ bool ColorNode::applyDiff(const DefinitionDiff *diff, bool backward) { if (value == previous) { value = next; + tellChanged(); return true; } else { Logs::error("Definition") << "Can't apply color diff" << endl; diff --git a/src/definition/DefinitionNode.cpp b/src/definition/DefinitionNode.cpp index ecd9783..8466a00 100644 --- a/src/definition/DefinitionNode.cpp +++ b/src/definition/DefinitionNode.cpp @@ -27,8 +27,8 @@ DefinitionNode::DefinitionNode(DefinitionNode *parent, const string &name, const : parent(parent), type_name(type_name), name(name) { if (parent) { root = parent->root; - parent->addChild(this); diffs = NULL; + parent->addChild(this); } else { root = this; diffs = new DiffManager(this); @@ -207,9 +207,11 @@ void DefinitionNode::validate() { void DefinitionNode::addChild(DefinitionNode *child) { if (find(children.begin(), children.end(), child) == children.end()) { + if (child->parent != this) { + child->parent = this; + child->setRoot(root); + } children.push_back(child); - child->parent = this; - child->root = this->root; } } @@ -260,3 +262,15 @@ void DefinitionNode::addDiff(const DefinitionDiff *diff) { delete diff; } } + +void DefinitionNode::setRoot(DefinitionNode *root) +{ + this->root = root; + if (diffs) { + delete diffs; + diffs = NULL; + } + for (auto &child: children) { + child->setRoot(root); + } +} diff --git a/src/definition/DefinitionNode.h b/src/definition/DefinitionNode.h index 53c13b0..57b1ae6 100644 --- a/src/definition/DefinitionNode.h +++ b/src/definition/DefinitionNode.h @@ -119,6 +119,9 @@ class DEFINITIONSHARED_EXPORT DefinitionNode { */ void addDiff(const DefinitionDiff *diff); + private: + void setRoot(DefinitionNode *root); + private: DefinitionNode *parent; DefinitionNode *root; diff --git a/src/definition/FloatNode.cpp b/src/definition/FloatNode.cpp index c216440..f384ed3 100644 --- a/src/definition/FloatNode.cpp +++ b/src/definition/FloatNode.cpp @@ -23,12 +23,14 @@ void FloatNode::save(PackStream *stream) const { } void FloatNode::load(PackStream *stream) { - stream->read(&value); + double val; + stream->read(&val); + setValue(val); } void FloatNode::copy(DefinitionNode *destination) const { if (auto tdest = dynamic_cast(destination)) { - tdest->value = value; + tdest->setValue(value); } else { Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; diff --git a/src/definition/IntNode.cpp b/src/definition/IntNode.cpp index 9fb2e1a..f2c2f35 100644 --- a/src/definition/IntNode.cpp +++ b/src/definition/IntNode.cpp @@ -23,12 +23,14 @@ void IntNode::save(PackStream *stream) const { } void IntNode::load(PackStream *stream) { - stream->read(&value); + int val; + stream->read(&val); + setValue(val); } void IntNode::copy(DefinitionNode *destination) const { if (auto tdest = dynamic_cast(destination)) { - tdest->value = value; + tdest->setValue(value); } else { Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << endl; diff --git a/src/definition/Layers.cpp b/src/definition/Layers.cpp index 76dec3f..485cb8a 100644 --- a/src/definition/Layers.cpp +++ b/src/definition/Layers.cpp @@ -90,7 +90,7 @@ bool Layers::applyDiff(const DefinitionDiff *diff, bool backward) { Logs::error("Definition") << "Add layer ignored because requested position was incorrect" << endl; return false; } else { - DefinitionNode *layer = layer_constructor(this, "temp"); + DefinitionNode *layer = layer_constructor(NULL, "temp"); layer_diff->restoreSavedLayer(layer); if (position == layer_count) { layers.push_back(layer); @@ -134,7 +134,7 @@ void Layers::addLayer(const DefinitionNode &tocopy) { } void Layers::addLayer(const string &name) { - auto layer = layer_constructor(this, name); + auto layer = layer_constructor(NULL, name); addLayer(*layer); delete layer; } diff --git a/src/definition/MaterialNode.cpp b/src/definition/MaterialNode.cpp new file mode 100644 index 0000000..7c69649 --- /dev/null +++ b/src/definition/MaterialNode.cpp @@ -0,0 +1,61 @@ +#include "MaterialNode.h" + +#include "ColorNode.h" +#include "FloatNode.h" +#include "NoiseNode.h" +#include "SurfaceMaterial.h" +#include "FractalNoise.h" + +MaterialNode::MaterialNode(DefinitionNode *parent, const string &name) : DefinitionNode(parent, name, "material") { + material = make_unique(); + + diffuse = new ColorNode(this, "diffuse"); + ambient = new FloatNode(this, "ambient"); + hardness = new FloatNode(this, "hardness"); + reflection = new FloatNode(this, "reflection"); + shininess = new FloatNode(this, "shininess"); + bump = new NoiseNode(this, "bump"); +} + +const SurfaceMaterial &MaterialNode::getSurfaceMaterial() const { + return *material; +} + +void MaterialNode::setSurfaceMaterial(const SurfaceMaterial &material) { + diffuse->setValue(*material.base); + ambient->setValue(material.ambient); + hardness->setValue(material.hardness); + reflection->setValue(material.reflection); + shininess->setValue(material.shininess); +} + +void MaterialNode::setSurfaceMaterial(const Color &color, double reflection, double shininess, double hardness, + double ambient) { + this->diffuse->setValue(color); + this->reflection->setValue(reflection); + this->shininess->setValue(shininess); + this->hardness->setValue(hardness); + this->ambient->setValue(ambient); +} + +bool MaterialNode::hasBump() const { + return bump->getGenerator()->getHeight() > 0.0; +} + +const FractalNoise *MaterialNode::getBumpGenerator() const { + return bump->getGenerator(); +} + +void MaterialNode::onChildChanged(int depth, const string &relpath) { + updateMaterial(); + + DefinitionNode::onChildChanged(depth, relpath); +} + +void MaterialNode::updateMaterial() { + *material->base = diffuse->getValue(); + material->ambient = ambient->getValue(); + material->hardness = hardness->getValue(); + material->reflection = reflection->getValue(); + material->shininess = shininess->getValue(); +} diff --git a/src/definition/MaterialNode.h b/src/definition/MaterialNode.h new file mode 100644 index 0000000..07d85d9 --- /dev/null +++ b/src/definition/MaterialNode.h @@ -0,0 +1,63 @@ +#ifndef MATERIALNODE_H +#define MATERIALNODE_H + +#include "definition_global.h" + +#include "DefinitionNode.h" +#include + +namespace paysages { +namespace definition { + +/** + * Raw surface material for the definition tree, with an optional bump mapping noise. + */ +class DEFINITIONSHARED_EXPORT MaterialNode : public DefinitionNode { + public: + MaterialNode(DefinitionNode *parent, const string &name); + + const SurfaceMaterial &getSurfaceMaterial() const; + void setSurfaceMaterial(const SurfaceMaterial &material); + void setSurfaceMaterial(const Color &color, double reflection, double shininess, double hardness=0.5, double ambient=0.5); + + bool hasBump() const; + const FractalNoise *getBumpGenerator() const; + + inline const ColorNode *propDiffuse() const { + return diffuse; + } + inline const FloatNode *propAmbient() const { + return ambient; + } + inline const FloatNode *propHardness() const { + return hardness; + } + inline const FloatNode *propReflection() const { + return reflection; + } + inline const FloatNode *propShininess() const { + return shininess; + } + inline NoiseNode *propBump() const { + return bump; + } + + protected: + virtual void onChildChanged(int depth, const string &relpath) override; + + private: + void updateMaterial(); + + private: + unique_ptr material; + ColorNode *diffuse; + FloatNode *ambient; + FloatNode *hardness; + FloatNode *reflection; + FloatNode *shininess; + NoiseNode *bump; +}; +} +} + +#endif // MATERIALNODE_H diff --git a/src/definition/NoiseNode.cpp b/src/definition/NoiseNode.cpp index 309e9f1..1a4ff90 100644 --- a/src/definition/NoiseNode.cpp +++ b/src/definition/NoiseNode.cpp @@ -5,6 +5,7 @@ NoiseNode::NoiseNode(DefinitionNode *parent, const string &name) : DefinitionNode(parent, name) { noise = new NoiseFunctionSimplex(); + noise->setScaling(0.0); } NoiseNode::~NoiseNode() { diff --git a/src/definition/definition_global.h b/src/definition/definition_global.h index 1645a76..5398299 100644 --- a/src/definition/definition_global.h +++ b/src/definition/definition_global.h @@ -25,6 +25,7 @@ class DefinitionWatcher; class Scenery; class CameraDefinition; class SurfaceMaterial; +class MaterialNode; class Zone; class WaterDefinition; class Layers;