2013-11-16 18:12:42 +00:00
|
|
|
#include "Zone.h"
|
|
|
|
|
2013-12-10 21:32:58 +00:00
|
|
|
#include <cstring>
|
2013-11-16 18:12:42 +00:00
|
|
|
#include "Curve.h"
|
|
|
|
#include "PackStream.h"
|
|
|
|
#include "Vector3.h"
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Zone::Zone(DefinitionNode *parent) : DefinitionNode(parent, "zone", "zone") {
|
2013-11-16 18:12:42 +00:00
|
|
|
value_by_height = new Curve;
|
|
|
|
absolute_height = 1;
|
|
|
|
value_by_height->setDefault(1.0);
|
|
|
|
value_by_slope = new Curve;
|
|
|
|
value_by_slope->setDefault(1.0);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Zone::~Zone() {
|
2013-11-16 18:12:42 +00:00
|
|
|
delete value_by_height;
|
|
|
|
delete value_by_slope;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::save(PackStream *stream) const {
|
2013-11-16 18:12:42 +00:00
|
|
|
stream->write(&absolute_height);
|
|
|
|
stream->write(&relative_height_min);
|
|
|
|
stream->write(&relative_height_middle);
|
|
|
|
stream->write(&relative_height_max);
|
|
|
|
|
|
|
|
value_by_height->save(stream);
|
|
|
|
value_by_slope->save(stream);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::load(PackStream *stream) {
|
2013-11-16 18:12:42 +00:00
|
|
|
stream->read(&absolute_height);
|
|
|
|
stream->read(&relative_height_min);
|
|
|
|
stream->read(&relative_height_middle);
|
|
|
|
stream->read(&relative_height_max);
|
|
|
|
|
|
|
|
value_by_height->load(stream);
|
|
|
|
value_by_slope->load(stream);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::copy(DefinitionNode *_destination) const {
|
|
|
|
Zone *destination = (Zone *)_destination;
|
2013-11-16 18:12:42 +00:00
|
|
|
|
|
|
|
destination->absolute_height = absolute_height;
|
|
|
|
destination->relative_height_min = relative_height_min;
|
|
|
|
destination->relative_height_middle = relative_height_middle;
|
|
|
|
destination->relative_height_max = relative_height_max;
|
|
|
|
|
|
|
|
value_by_height->copy(destination->value_by_height);
|
|
|
|
value_by_slope->copy(destination->value_by_slope);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::clear() {
|
2013-11-16 18:12:42 +00:00
|
|
|
value_by_height->clear();
|
|
|
|
value_by_slope->clear();
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::setAbsoluteHeight() {
|
2013-11-16 18:12:42 +00:00
|
|
|
absolute_height = 1;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::setRelativeHeight(double min, double middle, double max) {
|
|
|
|
if (max < min) {
|
2013-11-16 18:12:42 +00:00
|
|
|
max = min;
|
|
|
|
}
|
2015-11-09 21:30:46 +00:00
|
|
|
if (middle < min) {
|
2013-11-16 18:12:42 +00:00
|
|
|
middle = min;
|
|
|
|
}
|
2015-11-09 21:30:46 +00:00
|
|
|
if (middle > max) {
|
2013-11-16 18:12:42 +00:00
|
|
|
middle = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
absolute_height = 0;
|
|
|
|
relative_height_min = min;
|
|
|
|
relative_height_middle = middle;
|
|
|
|
relative_height_max = max;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::getHeightCurve(Curve *curve) const {
|
2013-11-16 18:12:42 +00:00
|
|
|
value_by_height->copy(curve);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::setHeightCurve(Curve *curve) {
|
2013-11-16 18:12:42 +00:00
|
|
|
curve->copy(value_by_height);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::addHeightRangeQuick(double value, double hardmin, double softmin, double softmax, double hardmax) {
|
2013-11-16 18:12:42 +00:00
|
|
|
value_by_height->addPoint(hardmin, 0.0);
|
|
|
|
value_by_height->addPoint(softmin, value);
|
|
|
|
value_by_height->addPoint(softmax, value);
|
|
|
|
value_by_height->addPoint(hardmax, 0.0);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::getSlopeCurve(Curve *curve) const {
|
2013-11-16 18:12:42 +00:00
|
|
|
value_by_slope->copy(curve);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::setSlopeCurve(Curve *curve) {
|
2013-11-16 18:12:42 +00:00
|
|
|
curve->copy(value_by_slope);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Zone::addSlopeRangeQuick(double value, double hardmin, double softmin, double softmax, double hardmax) {
|
2013-11-16 18:12:42 +00:00
|
|
|
value_by_slope->addPoint(hardmin, 0.0);
|
|
|
|
value_by_slope->addPoint(softmin, value);
|
|
|
|
value_by_slope->addPoint(softmax, value);
|
|
|
|
value_by_slope->addPoint(hardmax, 0.0);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
double Zone::getValue(const Vector3 &location, const Vector3 &normal) const {
|
2013-11-16 18:12:42 +00:00
|
|
|
double final_height;
|
2014-09-15 07:36:48 +00:00
|
|
|
double value_height, value_steepness;
|
2013-11-16 18:12:42 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (absolute_height) {
|
2013-11-16 18:12:42 +00:00
|
|
|
final_height = location.y;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
|
|
|
if (location.y >= relative_height_max) {
|
2013-11-16 18:12:42 +00:00
|
|
|
final_height = 1.0;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else if (location.y <= relative_height_min) {
|
2013-11-16 18:12:42 +00:00
|
|
|
final_height = 0.0;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else if (location.y <= relative_height_middle) {
|
2013-11-16 18:12:42 +00:00
|
|
|
final_height = 0.5 * (location.y - relative_height_min) / (relative_height_middle - relative_height_min);
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
|
|
|
final_height =
|
|
|
|
0.5 + 0.5 * (location.y - relative_height_middle) / (relative_height_max - relative_height_middle);
|
2013-11-16 18:12:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
value_height = value_by_height->getValue(final_height);
|
|
|
|
value_steepness = value_by_slope->getValue(1.0 - normal.y);
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (value_steepness < value_height) {
|
2014-09-15 07:36:48 +00:00
|
|
|
return value_steepness;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2014-09-15 07:36:48 +00:00
|
|
|
return value_height;
|
2013-11-16 18:12:42 +00:00
|
|
|
}
|
|
|
|
}
|