Added material node (and fixed change propagation in basic nodes)

This commit is contained in:
Michaël Lemaire 2016-02-07 23:17:58 +01:00
parent d68eaab5df
commit 457f0c6345
10 changed files with 161 additions and 11 deletions

View file

@ -24,12 +24,14 @@ void ColorNode::save(PackStream *stream) const {
} }
void ColorNode::load(PackStream *stream) { void ColorNode::load(PackStream *stream) {
value.load(stream); Color val;
val.load(stream);
setValue(val);
} }
void ColorNode::copy(DefinitionNode *destination) const { void ColorNode::copy(DefinitionNode *destination) const {
if (auto tdest = dynamic_cast<ColorNode *>(destination)) { if (auto tdest = dynamic_cast<ColorNode *>(destination)) {
tdest->value = value; tdest->setValue(value);
} else { } else {
Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName()
<< endl; << endl;
@ -62,6 +64,7 @@ bool ColorNode::applyDiff(const DefinitionDiff *diff, bool backward) {
if (value == previous) { if (value == previous) {
value = next; value = next;
tellChanged();
return true; return true;
} else { } else {
Logs::error("Definition") << "Can't apply color diff" << endl; Logs::error("Definition") << "Can't apply color diff" << endl;

View file

@ -27,8 +27,8 @@ DefinitionNode::DefinitionNode(DefinitionNode *parent, const string &name, const
: parent(parent), type_name(type_name), name(name) { : parent(parent), type_name(type_name), name(name) {
if (parent) { if (parent) {
root = parent->root; root = parent->root;
parent->addChild(this);
diffs = NULL; diffs = NULL;
parent->addChild(this);
} else { } else {
root = this; root = this;
diffs = new DiffManager(this); diffs = new DiffManager(this);
@ -207,9 +207,11 @@ void DefinitionNode::validate() {
void DefinitionNode::addChild(DefinitionNode *child) { void DefinitionNode::addChild(DefinitionNode *child) {
if (find(children.begin(), children.end(), child) == children.end()) { if (find(children.begin(), children.end(), child) == children.end()) {
children.push_back(child); if (child->parent != this) {
child->parent = this; child->parent = this;
child->root = this->root; child->setRoot(root);
}
children.push_back(child);
} }
} }
@ -260,3 +262,15 @@ void DefinitionNode::addDiff(const DefinitionDiff *diff) {
delete diff; delete diff;
} }
} }
void DefinitionNode::setRoot(DefinitionNode *root)
{
this->root = root;
if (diffs) {
delete diffs;
diffs = NULL;
}
for (auto &child: children) {
child->setRoot(root);
}
}

View file

@ -119,6 +119,9 @@ class DEFINITIONSHARED_EXPORT DefinitionNode {
*/ */
void addDiff(const DefinitionDiff *diff); void addDiff(const DefinitionDiff *diff);
private:
void setRoot(DefinitionNode *root);
private: private:
DefinitionNode *parent; DefinitionNode *parent;
DefinitionNode *root; DefinitionNode *root;

View file

@ -23,12 +23,14 @@ void FloatNode::save(PackStream *stream) const {
} }
void FloatNode::load(PackStream *stream) { void FloatNode::load(PackStream *stream) {
stream->read(&value); double val;
stream->read(&val);
setValue(val);
} }
void FloatNode::copy(DefinitionNode *destination) const { void FloatNode::copy(DefinitionNode *destination) const {
if (auto tdest = dynamic_cast<FloatNode *>(destination)) { if (auto tdest = dynamic_cast<FloatNode *>(destination)) {
tdest->value = value; tdest->setValue(value);
} else { } else {
Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName()
<< endl; << endl;

View file

@ -23,12 +23,14 @@ void IntNode::save(PackStream *stream) const {
} }
void IntNode::load(PackStream *stream) { void IntNode::load(PackStream *stream) {
stream->read(&value); int val;
stream->read(&val);
setValue(val);
} }
void IntNode::copy(DefinitionNode *destination) const { void IntNode::copy(DefinitionNode *destination) const {
if (auto tdest = dynamic_cast<IntNode *>(destination)) { if (auto tdest = dynamic_cast<IntNode *>(destination)) {
tdest->value = value; tdest->setValue(value);
} else { } else {
Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() Logs::error("Definition") << "Can't copy from " << getTypeName() << " to " << destination->getTypeName()
<< endl; << endl;

View file

@ -90,7 +90,7 @@ bool Layers::applyDiff(const DefinitionDiff *diff, bool backward) {
Logs::error("Definition") << "Add layer ignored because requested position was incorrect" << endl; Logs::error("Definition") << "Add layer ignored because requested position was incorrect" << endl;
return false; return false;
} else { } else {
DefinitionNode *layer = layer_constructor(this, "temp"); DefinitionNode *layer = layer_constructor(NULL, "temp");
layer_diff->restoreSavedLayer(layer); layer_diff->restoreSavedLayer(layer);
if (position == layer_count) { if (position == layer_count) {
layers.push_back(layer); layers.push_back(layer);
@ -134,7 +134,7 @@ void Layers::addLayer(const DefinitionNode &tocopy) {
} }
void Layers::addLayer(const string &name) { void Layers::addLayer(const string &name) {
auto layer = layer_constructor(this, name); auto layer = layer_constructor(NULL, name);
addLayer(*layer); addLayer(*layer);
delete layer; delete layer;
} }

View file

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

View file

@ -0,0 +1,63 @@
#ifndef MATERIALNODE_H
#define MATERIALNODE_H
#include "definition_global.h"
#include "DefinitionNode.h"
#include <memory>
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<SurfaceMaterial> material;
ColorNode *diffuse;
FloatNode *ambient;
FloatNode *hardness;
FloatNode *reflection;
FloatNode *shininess;
NoiseNode *bump;
};
}
}
#endif // MATERIALNODE_H

View file

@ -5,6 +5,7 @@
NoiseNode::NoiseNode(DefinitionNode *parent, const string &name) : DefinitionNode(parent, name) { NoiseNode::NoiseNode(DefinitionNode *parent, const string &name) : DefinitionNode(parent, name) {
noise = new NoiseFunctionSimplex(); noise = new NoiseFunctionSimplex();
noise->setScaling(0.0);
} }
NoiseNode::~NoiseNode() { NoiseNode::~NoiseNode() {

View file

@ -25,6 +25,7 @@ class DefinitionWatcher;
class Scenery; class Scenery;
class CameraDefinition; class CameraDefinition;
class SurfaceMaterial; class SurfaceMaterial;
class MaterialNode;
class Zone; class Zone;
class WaterDefinition; class WaterDefinition;
class Layers; class Layers;