2013-11-17 21:36:18 +00:00
|
|
|
#include "TerrainDefinition.h"
|
|
|
|
|
|
|
|
#include "TerrainHeightMap.h"
|
|
|
|
#include "NoiseGenerator.h"
|
|
|
|
#include "PackStream.h"
|
2015-08-13 21:46:50 +00:00
|
|
|
#include "FloatNode.h"
|
2013-11-17 21:36:18 +00:00
|
|
|
|
2015-08-12 20:21:10 +00:00
|
|
|
TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
|
2015-08-16 21:01:56 +00:00
|
|
|
DefinitionNode(parent, "terrain", "terrain")
|
2013-11-17 21:36:18 +00:00
|
|
|
{
|
|
|
|
height = 1.0;
|
|
|
|
scaling = 1.0;
|
|
|
|
shadow_smoothing = 0.0;
|
|
|
|
|
|
|
|
height_map = new TerrainHeightMap(this);
|
|
|
|
addChild(height_map);
|
|
|
|
|
2015-08-17 20:55:30 +00:00
|
|
|
water_height = new FloatNode(this, "water_height", -0.3);
|
2013-11-17 21:36:18 +00:00
|
|
|
|
|
|
|
_height_noise = new NoiseGenerator;
|
|
|
|
}
|
|
|
|
|
|
|
|
TerrainDefinition::~TerrainDefinition()
|
|
|
|
{
|
|
|
|
delete _height_noise;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TerrainDefinition::validate()
|
|
|
|
{
|
|
|
|
_height_noise->validate();
|
|
|
|
|
|
|
|
if (height < 1.0)
|
|
|
|
{
|
|
|
|
height = 1.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get minimal and maximal height */
|
|
|
|
_height_noise->getRange(&_min_height, &_max_height);
|
|
|
|
_min_height *= height * scaling;
|
|
|
|
_max_height *= height * scaling;
|
|
|
|
|
|
|
|
/* TODO Alter with heightmap min/max */
|
|
|
|
}
|
|
|
|
|
2015-08-12 20:21:10 +00:00
|
|
|
void TerrainDefinition::copy(DefinitionNode* _destination) const
|
2013-11-17 21:36:18 +00:00
|
|
|
{
|
|
|
|
TerrainDefinition* destination = (TerrainDefinition*)_destination;
|
|
|
|
|
|
|
|
destination->height = height;
|
|
|
|
destination->scaling = scaling;
|
|
|
|
destination->shadow_smoothing = shadow_smoothing;
|
|
|
|
|
|
|
|
height_map->copy(destination->height_map);
|
|
|
|
|
|
|
|
destination->water_height = water_height;
|
|
|
|
|
|
|
|
_height_noise->copy(destination->_height_noise);
|
|
|
|
|
|
|
|
destination->validate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TerrainDefinition::save(PackStream* stream) const
|
|
|
|
{
|
2015-08-12 20:21:10 +00:00
|
|
|
DefinitionNode::save(stream);
|
2013-11-17 21:36:18 +00:00
|
|
|
|
|
|
|
stream->write(&height);
|
|
|
|
stream->write(&scaling);
|
|
|
|
stream->write(&shadow_smoothing);
|
|
|
|
_height_noise->save(stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TerrainDefinition::load(PackStream* stream)
|
|
|
|
{
|
2015-08-12 20:21:10 +00:00
|
|
|
DefinitionNode::load(stream);
|
2013-11-17 21:36:18 +00:00
|
|
|
|
|
|
|
stream->read(&height);
|
|
|
|
stream->read(&scaling);
|
|
|
|
stream->read(&shadow_smoothing);
|
|
|
|
_height_noise->load(stream);
|
|
|
|
|
|
|
|
validate();
|
|
|
|
}
|
|
|
|
|
2014-11-21 08:45:19 +00:00
|
|
|
double TerrainDefinition::getGridHeight(int x, int z, bool with_painting)
|
2013-11-17 21:36:18 +00:00
|
|
|
{
|
|
|
|
double h;
|
|
|
|
|
2014-09-15 10:32:27 +00:00
|
|
|
if (!with_painting || !height_map->getGridValue(x, z, &h))
|
2013-11-17 21:36:18 +00:00
|
|
|
{
|
|
|
|
h = _height_noise->get2DTotal((double)x, (double)z);
|
|
|
|
}
|
|
|
|
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
2015-08-17 20:55:30 +00:00
|
|
|
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset)
|
2013-11-17 21:36:18 +00:00
|
|
|
{
|
|
|
|
double h;
|
|
|
|
x /= scaling;
|
|
|
|
z /= scaling;
|
|
|
|
|
2014-09-15 10:32:27 +00:00
|
|
|
if (!with_painting || !height_map->getInterpolatedValue(x, z, &h))
|
2013-11-17 21:36:18 +00:00
|
|
|
{
|
|
|
|
h = _height_noise->get2DTotal(x, z);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scaled)
|
|
|
|
{
|
2015-08-17 20:55:30 +00:00
|
|
|
return (water_offset ? (h - water_height->getValue()) : h) * height * scaling;
|
2013-11-17 21:36:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-17 20:55:30 +00:00
|
|
|
double TerrainDefinition::getWaterOffset() const
|
|
|
|
{
|
|
|
|
return -water_height->getValue() * height * scaling;
|
|
|
|
}
|
|
|
|
|
2013-11-17 21:36:18 +00:00
|
|
|
HeightInfo TerrainDefinition::getHeightInfo()
|
|
|
|
{
|
|
|
|
HeightInfo result;
|
|
|
|
|
|
|
|
result.min_height = _min_height;
|
|
|
|
result.max_height = _max_height;
|
|
|
|
/* TODO This is duplicated in ter_render.c (_realGetWaterHeight) */
|
2015-08-17 20:55:30 +00:00
|
|
|
result.base_height = water_height->getValue() * height * scaling;
|
2013-11-17 21:36:18 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long TerrainDefinition::getMemoryStats()
|
|
|
|
{
|
|
|
|
return height_map->getMemoryStats();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TerrainDefinition::applyPreset(TerrainPreset preset)
|
|
|
|
{
|
|
|
|
int resolution = 8;
|
|
|
|
switch (preset)
|
|
|
|
{
|
|
|
|
case TERRAIN_PRESET_STANDARD:
|
|
|
|
_height_noise->randomizeOffsets();
|
|
|
|
_height_noise->clearLevels();
|
|
|
|
_height_noise->addLevelSimple(pow(2.0, resolution + 1), -1.0, 1.0);
|
|
|
|
_height_noise->addLevelsSimple(resolution - 2, pow(2.0, resolution - 1), -0.7, 0.7, 0.5);
|
|
|
|
_height_noise->normalizeAmplitude(-1.0, 1.0, 0);
|
2013-12-31 14:50:28 +00:00
|
|
|
_height_noise->setFunctionParams(NoiseGenerator::NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
|
2013-11-17 21:36:18 +00:00
|
|
|
scaling = 1.0;
|
|
|
|
height = 30.0;
|
|
|
|
shadow_smoothing = 0.03;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
height_map->clearPainting();
|
|
|
|
validate();
|
|
|
|
}
|