TerrainDefinition and Scenery refactoring
This commit is contained in:
parent
fa5c0041af
commit
9e6838f733
57 changed files with 1545 additions and 1341 deletions
|
@ -1,5 +1,13 @@
|
||||||
#include "Interpolation.h"
|
#include "Interpolation.h"
|
||||||
|
|
||||||
Interpolation::Interpolation()
|
double Interpolation::bicubic(double stencil[16], double x, double y)
|
||||||
{
|
{
|
||||||
|
double buf_cubic_y[4];
|
||||||
|
|
||||||
|
buf_cubic_y[0] = Interpolation::cubic(stencil, x);
|
||||||
|
buf_cubic_y[1] = Interpolation::cubic(stencil + 4, x);
|
||||||
|
buf_cubic_y[2] = Interpolation::cubic(stencil + 8, x);
|
||||||
|
buf_cubic_y[3] = Interpolation::cubic(stencil + 12, x);
|
||||||
|
|
||||||
|
return Interpolation::cubic(buf_cubic_y, y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,14 @@
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace basics {
|
namespace basics {
|
||||||
|
|
||||||
class Interpolation
|
class BASICSSHARED_EXPORT Interpolation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Interpolation();
|
|
||||||
|
|
||||||
static inline double cubic(double p[4], double x)
|
static inline double cubic(double p[4], double x)
|
||||||
{
|
{
|
||||||
return p[1] + 0.5 * x * (p[2] - p[0] + x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
|
return p[1] + 0.5 * x * (p[2] - p[0] + x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
|
||||||
}
|
}
|
||||||
|
static double bicubic(double stencil[16], double x, double y);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,18 @@ void BaseDefinition::setName(QString name)
|
||||||
this->name = name;
|
this->name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scenery* BaseDefinition::getScenery()
|
||||||
|
{
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
return parent->getScenery();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BaseDefinition::save(PackStream* stream) const
|
void BaseDefinition::save(PackStream* stream) const
|
||||||
{
|
{
|
||||||
stream->write(name);
|
stream->write(name);
|
||||||
|
|
|
@ -28,6 +28,8 @@ public:
|
||||||
inline const QString& getName() const {return name;}
|
inline const QString& getName() const {return name;}
|
||||||
virtual void setName(QString name);
|
virtual void setName(QString name);
|
||||||
|
|
||||||
|
virtual Scenery* getScenery();
|
||||||
|
|
||||||
inline const BaseDefinition* getParent() const {return parent;}
|
inline const BaseDefinition* getParent() const {return parent;}
|
||||||
inline const BaseDefinition* getRoot() const {return root;}
|
inline const BaseDefinition* getRoot() const {return root;}
|
||||||
|
|
||||||
|
|
144
src/definition/Scenery.cpp
Normal file
144
src/definition/Scenery.cpp
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
#include "Scenery.h"
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#include "NoiseGenerator.h"
|
||||||
|
#include "PackStream.h"
|
||||||
|
#include "AtmosphereDefinition.h"
|
||||||
|
#include "CameraDefinition.h"
|
||||||
|
#include "CloudsDefinition.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
#include "TexturesDefinition.h"
|
||||||
|
#include "WaterDefinition.h"
|
||||||
|
|
||||||
|
Scenery::Scenery():
|
||||||
|
BaseDefinition(NULL)
|
||||||
|
{
|
||||||
|
addChild(atmosphere = new AtmosphereDefinition(this));
|
||||||
|
addChild(camera = new CameraDefinition);
|
||||||
|
addChild(clouds = new CloudsDefinition(this));
|
||||||
|
addChild(terrain = new TerrainDefinition(this));
|
||||||
|
addChild(textures = new TexturesDefinition(this));
|
||||||
|
addChild(water = new WaterDefinition(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::save(PackStream* stream) const
|
||||||
|
{
|
||||||
|
BaseDefinition::save(stream);
|
||||||
|
|
||||||
|
noiseSave(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::load(PackStream* stream)
|
||||||
|
{
|
||||||
|
BaseDefinition::load(stream);
|
||||||
|
|
||||||
|
noiseLoad(stream);
|
||||||
|
|
||||||
|
validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::validate()
|
||||||
|
{
|
||||||
|
BaseDefinition::validate();
|
||||||
|
|
||||||
|
checkCameraAboveGround();
|
||||||
|
}
|
||||||
|
|
||||||
|
Scenery* Scenery::getScenery()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::autoPreset(int seed)
|
||||||
|
{
|
||||||
|
if (!seed)
|
||||||
|
{
|
||||||
|
seed = time(NULL);
|
||||||
|
}
|
||||||
|
srand(seed);
|
||||||
|
|
||||||
|
terrain->applyPreset(TerrainDefinition::TERRAIN_PRESET_STANDARD);
|
||||||
|
textures->applyPreset(TexturesDefinition::TEXTURES_PRESET_FULL);
|
||||||
|
atmosphere->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_DAY);
|
||||||
|
water->applyPreset(WaterDefinition::WATER_PRESET_LAKE);
|
||||||
|
clouds->applyPreset(CloudsDefinition::CLOUDS_PRESET_PARTLY_CLOUDY);
|
||||||
|
|
||||||
|
camera->setLocation(VECTOR_ZERO);
|
||||||
|
camera->setTarget(VECTOR_NORTH);
|
||||||
|
|
||||||
|
validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::setAtmosphere(AtmosphereDefinition* atmosphere)
|
||||||
|
{
|
||||||
|
atmosphere->copy(this->atmosphere);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::getAtmosphere(AtmosphereDefinition* atmosphere)
|
||||||
|
{
|
||||||
|
this->atmosphere->copy(atmosphere);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::setCamera(CameraDefinition* camera)
|
||||||
|
{
|
||||||
|
camera->copy(this->camera);
|
||||||
|
checkCameraAboveGround();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::getCamera(CameraDefinition* camera)
|
||||||
|
{
|
||||||
|
this->camera->copy(camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::setClouds(CloudsDefinition* clouds)
|
||||||
|
{
|
||||||
|
clouds->copy(this->clouds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::getClouds(CloudsDefinition* clouds)
|
||||||
|
{
|
||||||
|
this->clouds->copy(clouds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::setTerrain(TerrainDefinition* terrain)
|
||||||
|
{
|
||||||
|
terrain->copy(this->terrain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::getTerrain(TerrainDefinition* terrain)
|
||||||
|
{
|
||||||
|
this->terrain->copy(terrain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::setTextures(TexturesDefinition* textures)
|
||||||
|
{
|
||||||
|
textures->copy(this->textures);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::getTextures(TexturesDefinition* textures)
|
||||||
|
{
|
||||||
|
this->textures->copy(textures);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::setWater(WaterDefinition* water)
|
||||||
|
{
|
||||||
|
water->copy(this->water);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::getWater(WaterDefinition* water)
|
||||||
|
{
|
||||||
|
this->water->copy(water);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::checkCameraAboveGround()
|
||||||
|
{
|
||||||
|
Vector3 camera_location = camera->getLocation();
|
||||||
|
double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, 1, 1) + 0.5;
|
||||||
|
double water_height = terrain->getWaterHeight() + 0.5;
|
||||||
|
if (camera_location.y < water_height || camera_location.y < terrain_height)
|
||||||
|
{
|
||||||
|
double diff = ((water_height > terrain_height) ? water_height : terrain_height) - camera_location.y;
|
||||||
|
camera->setLocation(camera_location.add(Vector3(0.0, diff, 0.0)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,34 +1,28 @@
|
||||||
#ifndef SCENERY_H
|
#ifndef SCENERY_H
|
||||||
#define SCENERY_H
|
#define SCENERY_H
|
||||||
|
|
||||||
#include "rendering_global.h"
|
#include "definition_global.h"
|
||||||
|
|
||||||
#include "BaseDefinition.h"
|
#include "BaseDefinition.h"
|
||||||
|
|
||||||
class TerrainDefinition;
|
namespace paysages {
|
||||||
class Renderer;
|
namespace definition {
|
||||||
|
|
||||||
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Global scenery management
|
* @brief Global scenery management
|
||||||
*
|
*
|
||||||
* This class contains the whole scenery definition.
|
* This class contains the whole scenery definition.
|
||||||
*/
|
*/
|
||||||
class RENDERINGSHARED_EXPORT Scenery: private BaseDefinition
|
class DEFINITIONSHARED_EXPORT Scenery: public BaseDefinition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scenery();
|
Scenery();
|
||||||
virtual ~Scenery();
|
|
||||||
|
|
||||||
static Scenery* getCurrent();
|
|
||||||
|
|
||||||
void setCustomSaveCallbacks(SceneryCustomDataCallback callback_save, SceneryCustomDataCallback callback_load, void* data);
|
|
||||||
|
|
||||||
virtual void save(PackStream* stream) const override;
|
virtual void save(PackStream* stream) const override;
|
||||||
virtual void load(PackStream* stream) override;
|
virtual void load(PackStream* stream) override;
|
||||||
|
|
||||||
virtual void validate() override;
|
virtual void validate() override;
|
||||||
|
virtual Scenery* getScenery() override;
|
||||||
|
|
||||||
void autoPreset(int seed);
|
void autoPreset(int seed);
|
||||||
|
|
||||||
|
@ -56,8 +50,6 @@ public:
|
||||||
inline WaterDefinition* getWater() const {return water;}
|
inline WaterDefinition* getWater() const {return water;}
|
||||||
void getWater(WaterDefinition* water);
|
void getWater(WaterDefinition* water);
|
||||||
|
|
||||||
void bindToRenderer(Renderer* renderer);
|
|
||||||
|
|
||||||
void checkCameraAboveGround();
|
void checkCameraAboveGround();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -67,14 +59,9 @@ private:
|
||||||
TerrainDefinition* terrain;
|
TerrainDefinition* terrain;
|
||||||
TexturesDefinition* textures;
|
TexturesDefinition* textures;
|
||||||
WaterDefinition* water;
|
WaterDefinition* water;
|
||||||
|
|
||||||
SceneryCustomDataCallback _custom_save;
|
|
||||||
SceneryCustomDataCallback _custom_load;
|
|
||||||
void* _custom_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Transitional C-API
|
}
|
||||||
|
}
|
||||||
RENDERINGSHARED_EXPORT void sceneryRenderFirstPass(Renderer* renderer);
|
|
||||||
|
|
||||||
#endif // SCENERY_H
|
#endif // SCENERY_H
|
162
src/definition/TerrainDefinition.cpp
Normal file
162
src/definition/TerrainDefinition.cpp
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
|
||||||
|
#include "TerrainHeightMap.h"
|
||||||
|
#include "NoiseGenerator.h"
|
||||||
|
#include "PackStream.h"
|
||||||
|
|
||||||
|
TerrainDefinition::TerrainDefinition(BaseDefinition* parent):
|
||||||
|
BaseDefinition(parent)
|
||||||
|
{
|
||||||
|
height = 1.0;
|
||||||
|
scaling = 1.0;
|
||||||
|
shadow_smoothing = 0.0;
|
||||||
|
|
||||||
|
height_map = new TerrainHeightMap(this);
|
||||||
|
addChild(height_map);
|
||||||
|
|
||||||
|
water_height = -0.3;
|
||||||
|
|
||||||
|
_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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainDefinition::copy(BaseDefinition* _destination) const
|
||||||
|
{
|
||||||
|
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
|
||||||
|
{
|
||||||
|
BaseDefinition::save(stream);
|
||||||
|
|
||||||
|
stream->write(&height);
|
||||||
|
stream->write(&scaling);
|
||||||
|
stream->write(&shadow_smoothing);
|
||||||
|
stream->write(&water_height);
|
||||||
|
_height_noise->save(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainDefinition::load(PackStream* stream)
|
||||||
|
{
|
||||||
|
BaseDefinition::load(stream);
|
||||||
|
|
||||||
|
stream->read(&height);
|
||||||
|
stream->read(&scaling);
|
||||||
|
stream->read(&shadow_smoothing);
|
||||||
|
stream->read(&water_height);
|
||||||
|
_height_noise->load(stream);
|
||||||
|
|
||||||
|
validate();
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainDefinition::getGridHeight(int x, int z, int with_painting)
|
||||||
|
{
|
||||||
|
double h;
|
||||||
|
|
||||||
|
if (!with_painting || !height_map->getGridHeight(x, z, &h))
|
||||||
|
{
|
||||||
|
h = _height_noise->get2DTotal((double)x, (double)z);
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainDefinition::getInterpolatedHeight(double x, double z, int scaled, int with_painting)
|
||||||
|
{
|
||||||
|
double h;
|
||||||
|
x /= scaling;
|
||||||
|
z /= scaling;
|
||||||
|
|
||||||
|
if (!with_painting || !height_map->getInterpolatedHeight(x, z, &h))
|
||||||
|
{
|
||||||
|
h = _height_noise->get2DTotal(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scaled)
|
||||||
|
{
|
||||||
|
return h * height * scaling;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeightInfo TerrainDefinition::getHeightInfo()
|
||||||
|
{
|
||||||
|
HeightInfo result;
|
||||||
|
|
||||||
|
result.min_height = _min_height;
|
||||||
|
result.max_height = _max_height;
|
||||||
|
/* TODO This is duplicated in ter_render.c (_realGetWaterHeight) */
|
||||||
|
result.base_height = water_height * height * scaling;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainDefinition::getWaterHeight()
|
||||||
|
{
|
||||||
|
return water_height * height * scaling;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
_height_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
|
||||||
|
scaling = 1.0;
|
||||||
|
height = 30.0;
|
||||||
|
shadow_smoothing = 0.03;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
height_map->clearPainting();
|
||||||
|
validate();
|
||||||
|
}
|
61
src/definition/TerrainDefinition.h
Normal file
61
src/definition/TerrainDefinition.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef TERRAINDEFINITION_H
|
||||||
|
#define TERRAINDEFINITION_H
|
||||||
|
|
||||||
|
#include "definition_global.h"
|
||||||
|
|
||||||
|
#include "BaseDefinition.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace definition {
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
double min_height;
|
||||||
|
double max_height;
|
||||||
|
double base_height;
|
||||||
|
} HeightInfo;
|
||||||
|
|
||||||
|
class DEFINITIONSHARED_EXPORT TerrainDefinition : public BaseDefinition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerrainDefinition(BaseDefinition* parent);
|
||||||
|
virtual ~TerrainDefinition();
|
||||||
|
|
||||||
|
virtual void save(PackStream* stream) const override;
|
||||||
|
virtual void load(PackStream* stream) override;
|
||||||
|
|
||||||
|
virtual void copy(BaseDefinition* destination) const override;
|
||||||
|
virtual void validate() override;
|
||||||
|
|
||||||
|
double getGridHeight(int x, int z, int with_painting);
|
||||||
|
double getInterpolatedHeight(double x, double z, int scaled, int with_painting);
|
||||||
|
unsigned long getMemoryStats();
|
||||||
|
HeightInfo getHeightInfo();
|
||||||
|
double getWaterHeight();
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TERRAIN_PRESET_STANDARD
|
||||||
|
} TerrainPreset;
|
||||||
|
void applyPreset(TerrainPreset preset);
|
||||||
|
|
||||||
|
public:
|
||||||
|
double height;
|
||||||
|
double scaling;
|
||||||
|
double shadow_smoothing;
|
||||||
|
|
||||||
|
TerrainHeightMap* height_map;
|
||||||
|
|
||||||
|
double water_height;
|
||||||
|
|
||||||
|
double _detail;
|
||||||
|
NoiseGenerator* _height_noise;
|
||||||
|
double _min_height;
|
||||||
|
double _max_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TERRAINDEFINITION_H
|
484
src/definition/TerrainHeightMap.cpp
Normal file
484
src/definition/TerrainHeightMap.cpp
Normal file
|
@ -0,0 +1,484 @@
|
||||||
|
#include "TerrainHeightMap.h"
|
||||||
|
|
||||||
|
#include "PackStream.h"
|
||||||
|
#include "Memory.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
#include "TerrainHeightMapBrush.h"
|
||||||
|
#include "Interpolation.h"
|
||||||
|
#include "NoiseGenerator.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int xstart;
|
||||||
|
int xend;
|
||||||
|
double* height;
|
||||||
|
} HeightMapPixelGroup;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int z;
|
||||||
|
int pixel_groups_count;
|
||||||
|
HeightMapPixelGroup* pixel_groups;
|
||||||
|
} HeightMapRow;
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace definition {
|
||||||
|
class TerrainHeightMapData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int memsize;
|
||||||
|
int rows_count;
|
||||||
|
HeightMapRow* rows;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _initData(TerrainHeightMapData* data)
|
||||||
|
{
|
||||||
|
data->rows_count = 0;
|
||||||
|
data->rows = new HeightMapRow[1];
|
||||||
|
data->memsize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _clearData(TerrainHeightMapData* data)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for (i = 0; i < data->rows_count; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
||||||
|
{
|
||||||
|
free(data->rows[i].pixel_groups[j].height);
|
||||||
|
}
|
||||||
|
free(data->rows[i].pixel_groups);
|
||||||
|
}
|
||||||
|
data->rows_count = 0;
|
||||||
|
delete[] data->rows;
|
||||||
|
data->rows = new HeightMapRow[1];
|
||||||
|
data->memsize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _deleteData(TerrainHeightMapData* data)
|
||||||
|
{
|
||||||
|
_clearData(data);
|
||||||
|
delete[] data->rows;
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _copyData(TerrainHeightMapData* source, TerrainHeightMapData* destination)
|
||||||
|
{
|
||||||
|
int i, j, n;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
_clearData(destination);
|
||||||
|
|
||||||
|
destination->rows_count = source->rows_count;
|
||||||
|
if (destination->rows_count > 0)
|
||||||
|
{
|
||||||
|
size = sizeof(HeightMapRow) * destination->rows_count;
|
||||||
|
destination->rows = (HeightMapRow*)realloc(destination->rows, size);
|
||||||
|
destination->memsize += size;
|
||||||
|
for (i = 0; i < destination->rows_count; i++)
|
||||||
|
{
|
||||||
|
destination->rows[i].z = source->rows[i].z;
|
||||||
|
destination->rows[i].pixel_groups_count = source->rows[i].pixel_groups_count;
|
||||||
|
size = sizeof(HeightMapPixelGroup) * destination->rows[i].pixel_groups_count;
|
||||||
|
destination->rows[i].pixel_groups = (HeightMapPixelGroup*)malloc(size);
|
||||||
|
destination->memsize += size;
|
||||||
|
for (j = 0; j < destination->rows[i].pixel_groups_count; j++)
|
||||||
|
{
|
||||||
|
destination->rows[i].pixel_groups[j].xstart = source->rows[i].pixel_groups[j].xstart;
|
||||||
|
destination->rows[i].pixel_groups[j].xend = source->rows[i].pixel_groups[j].xend;
|
||||||
|
n = destination->rows[i].pixel_groups[j].xend - destination->rows[i].pixel_groups[j].xstart + 1;
|
||||||
|
size = sizeof(double) * n;
|
||||||
|
destination->rows[i].pixel_groups[j].height = (double*)malloc(size);
|
||||||
|
destination->memsize += size;
|
||||||
|
memcpy(destination->rows[i].pixel_groups[j].height, source->rows[i].pixel_groups[j].height, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _saveData(PackStream* stream, TerrainHeightMapData* data)
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
stream->write(&data->rows_count);
|
||||||
|
for (i = 0; i < data->rows_count; i++)
|
||||||
|
{
|
||||||
|
stream->write(&data->rows[i].z);
|
||||||
|
stream->write(&data->rows[i].pixel_groups_count);
|
||||||
|
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
||||||
|
{
|
||||||
|
stream->write(&data->rows[i].pixel_groups[j].xstart);
|
||||||
|
stream->write(&data->rows[i].pixel_groups[j].xend);
|
||||||
|
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart; k++)
|
||||||
|
{
|
||||||
|
stream->write(&data->rows[i].pixel_groups[j].height[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _loadData(PackStream* stream, TerrainHeightMapData* data)
|
||||||
|
{
|
||||||
|
int i, j, k, n;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
_clearData(data);
|
||||||
|
|
||||||
|
stream->read(&data->rows_count);
|
||||||
|
if (data->rows_count > 0)
|
||||||
|
{
|
||||||
|
size = sizeof(HeightMapRow) * data->rows_count;
|
||||||
|
data->rows = (HeightMapRow*)realloc(data->rows, size);
|
||||||
|
data->memsize += size;
|
||||||
|
for (i = 0; i < data->rows_count; i++)
|
||||||
|
{
|
||||||
|
stream->read(&data->rows[i].z);
|
||||||
|
stream->read(&data->rows[i].pixel_groups_count);
|
||||||
|
size = sizeof(HeightMapPixelGroup) * data->rows[i].pixel_groups_count;
|
||||||
|
data->rows[i].pixel_groups = (HeightMapPixelGroup*)malloc(size);
|
||||||
|
data->memsize += size;
|
||||||
|
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
||||||
|
{
|
||||||
|
stream->read(&data->rows[i].pixel_groups[j].xstart);
|
||||||
|
stream->read(&data->rows[i].pixel_groups[j].xend);
|
||||||
|
n = data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart;
|
||||||
|
size = sizeof(double) * n;
|
||||||
|
data->rows[i].pixel_groups[j].height = (double*)malloc(size);
|
||||||
|
data->memsize += size;
|
||||||
|
for (k = 0; k < n; k++)
|
||||||
|
{
|
||||||
|
stream->read(&data->rows[i].pixel_groups[j].height[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a pointer to the data in a heightmap, to a certain location.
|
||||||
|
* If the location is not already in the heightmap, it is initialized with the terrain height.
|
||||||
|
* This method will grow the heightmap as necessary (if 'grow' is set to false, NULL will be returned on missing pixels).
|
||||||
|
*/
|
||||||
|
inline double* TerrainHeightMap::getDataPointer(TerrainHeightMapData* data, int x, int z, TerrainHeightMapData* fallback, TerrainDefinition* terrain, int grow)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Find row */
|
||||||
|
/* TODO Dichotomic search */
|
||||||
|
HeightMapRow* row;
|
||||||
|
i = 0;
|
||||||
|
while (i < data->rows_count && data->rows[i].z < z)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i < data->rows_count && data->rows[i].z == z)
|
||||||
|
{
|
||||||
|
row = data->rows + i;
|
||||||
|
}
|
||||||
|
else if (grow)
|
||||||
|
{
|
||||||
|
row = (HeightMapRow*)Memory::naiveArrayInsert((void**)&data->rows, sizeof(HeightMapRow), data->rows_count, i);
|
||||||
|
|
||||||
|
row->z = z;
|
||||||
|
row->pixel_groups_count = 0;
|
||||||
|
row->pixel_groups = (HeightMapPixelGroup*)malloc(1);
|
||||||
|
|
||||||
|
data->rows_count++;
|
||||||
|
data->memsize += sizeof(HeightMapRow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/* Check rows */
|
||||||
|
for (i = 1; i < data->rows_count; i++)
|
||||||
|
{
|
||||||
|
assert(data->rows[i].z > data->rows[i - 1].z);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Find pixel group */
|
||||||
|
HeightMapPixelGroup* pixel_group = NULL;
|
||||||
|
for (i = 0; i < row->pixel_groups_count; i++)
|
||||||
|
{
|
||||||
|
if (x < row->pixel_groups[i].xstart - 1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (x <= row->pixel_groups[i].xend + 1)
|
||||||
|
{
|
||||||
|
if (x == row->pixel_groups[i].xend + 1 && i < row->pixel_groups_count - 1 && x == row->pixel_groups[i + 1].xstart)
|
||||||
|
{
|
||||||
|
/* Choose next group if it already includes the pixel */
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
pixel_group = row->pixel_groups + i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alter pixel group */
|
||||||
|
double* pixel;
|
||||||
|
int added = 1;
|
||||||
|
if (!pixel_group)
|
||||||
|
{
|
||||||
|
if (!grow)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the pixel group with one pixel */
|
||||||
|
pixel_group = (HeightMapPixelGroup*)Memory::naiveArrayInsert((void**)&row->pixel_groups, sizeof(HeightMapPixelGroup), row->pixel_groups_count, i);
|
||||||
|
|
||||||
|
pixel_group->xstart = x;
|
||||||
|
pixel_group->xend = x;
|
||||||
|
pixel_group->height = (double*)malloc(sizeof(double));
|
||||||
|
|
||||||
|
pixel = pixel_group->height;
|
||||||
|
|
||||||
|
row->pixel_groups_count++;
|
||||||
|
data->memsize += sizeof(HeightMapPixelGroup) + sizeof(double);
|
||||||
|
}
|
||||||
|
else if (x == pixel_group->xstart - 1)
|
||||||
|
{
|
||||||
|
if (!grow)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extend the rowgroup at start */
|
||||||
|
pixel_group->xstart--;
|
||||||
|
pixel = (double*)Memory::naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, 0);
|
||||||
|
data->memsize += sizeof(double);
|
||||||
|
}
|
||||||
|
else if (x == pixel_group->xend + 1)
|
||||||
|
{
|
||||||
|
if (!grow)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extend the rowgroup at end */
|
||||||
|
pixel_group->xend++;
|
||||||
|
pixel = (double*)Memory::naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, pixel_group->xend - pixel_group->xstart);
|
||||||
|
data->memsize += sizeof(double);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(x >= pixel_group->xstart);
|
||||||
|
assert(x <= pixel_group->xend);
|
||||||
|
pixel = pixel_group->height + x - pixel_group->xstart;
|
||||||
|
added = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
/* Check pixel groups */
|
||||||
|
for (i = 0; i < row->pixel_groups_count; i++)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
assert(row->pixel_groups[i].xstart > row->pixel_groups[i - 1].xend);
|
||||||
|
}
|
||||||
|
if (i < row->pixel_groups_count - 1)
|
||||||
|
{
|
||||||
|
assert(row->pixel_groups[i].xend < row->pixel_groups[i + 1].xstart);
|
||||||
|
}
|
||||||
|
assert(row->pixel_groups[i].xend >= row->pixel_groups[i].xstart);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Reset pixel if it had been added */
|
||||||
|
if (added && (terrain || fallback))
|
||||||
|
{
|
||||||
|
if (fallback)
|
||||||
|
{
|
||||||
|
double* dpointer = getDataPointer(fallback, x, z, NULL, terrain, 0);
|
||||||
|
if (dpointer)
|
||||||
|
{
|
||||||
|
*pixel = *dpointer;
|
||||||
|
}
|
||||||
|
else if (terrain)
|
||||||
|
{
|
||||||
|
*pixel = terrain->getGridHeight(x, z, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (terrain)
|
||||||
|
{
|
||||||
|
*pixel = terrain->getGridHeight(x, z, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
TerrainHeightMap::TerrainHeightMap(TerrainDefinition* terrain):
|
||||||
|
BaseDefinition(terrain), terrain(terrain)
|
||||||
|
{
|
||||||
|
merged_data = new TerrainHeightMapData;
|
||||||
|
brush_data = new TerrainHeightMapData;
|
||||||
|
_initData(merged_data);
|
||||||
|
_initData(brush_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
TerrainHeightMap::~TerrainHeightMap()
|
||||||
|
{
|
||||||
|
_deleteData(merged_data);
|
||||||
|
_deleteData(brush_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::copy(BaseDefinition* _destination) const
|
||||||
|
{
|
||||||
|
TerrainHeightMap* destination = (TerrainHeightMap*)_destination;
|
||||||
|
|
||||||
|
destination->terrain = terrain;
|
||||||
|
|
||||||
|
_copyData(merged_data, destination->merged_data);
|
||||||
|
_clearData(destination->brush_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::save(PackStream* stream) const
|
||||||
|
{
|
||||||
|
_saveData(stream, merged_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::load(PackStream* stream)
|
||||||
|
{
|
||||||
|
_loadData(stream, merged_data);
|
||||||
|
_clearData(brush_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TerrainHeightMap::getGridHeight(int x, int z, double* result)
|
||||||
|
{
|
||||||
|
double* dpointer;
|
||||||
|
dpointer = getDataPointer(brush_data, x, z, NULL, NULL, 0);
|
||||||
|
if (dpointer)
|
||||||
|
{
|
||||||
|
*result = *dpointer;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dpointer = getDataPointer(merged_data, x, z, NULL, NULL, 0);
|
||||||
|
if (dpointer)
|
||||||
|
{
|
||||||
|
*result = *dpointer;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int TerrainHeightMap::getInterpolatedHeight(double x, double z, double* result)
|
||||||
|
{
|
||||||
|
int ix, iz;
|
||||||
|
int xlow;
|
||||||
|
int zlow;
|
||||||
|
|
||||||
|
xlow = floor(x);
|
||||||
|
zlow = floor(z);
|
||||||
|
|
||||||
|
int hit = 0;
|
||||||
|
for (ix = xlow - 1; ix <= xlow + 2 && !hit; ix++)
|
||||||
|
{
|
||||||
|
for (iz = zlow - 1; iz <= zlow + 2 && !hit; iz++)
|
||||||
|
{
|
||||||
|
if (getDataPointer(brush_data, x, z, NULL, NULL, 0) || getDataPointer(merged_data, x, z, NULL, NULL, 0))
|
||||||
|
{
|
||||||
|
hit = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit && result)
|
||||||
|
{
|
||||||
|
double stencil[16];
|
||||||
|
double value;
|
||||||
|
for (ix = xlow - 1; ix <= xlow + 2; ix++)
|
||||||
|
{
|
||||||
|
for (iz = zlow - 1; iz <= zlow + 2; iz++)
|
||||||
|
{
|
||||||
|
if (!getGridHeight(ix, iz, &value))
|
||||||
|
{
|
||||||
|
value = terrain->getGridHeight(ix, iz, 0);
|
||||||
|
}
|
||||||
|
stencil[(iz - (zlow - 1)) * 4 + ix - (xlow - 1)] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = Interpolation::bicubic(stencil, x - (double)xlow, z - (double)zlow);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long TerrainHeightMap::getMemoryStats() const
|
||||||
|
{
|
||||||
|
return merged_data->memsize + brush_data->memsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TerrainHeightMap::isPainted(int x, int z)
|
||||||
|
{
|
||||||
|
return getDataPointer(brush_data, x, z, NULL, NULL, 0) || getDataPointer(merged_data, x, z, NULL, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::clearPainting()
|
||||||
|
{
|
||||||
|
_clearData(merged_data);
|
||||||
|
_clearData(brush_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::brushElevation(const TerrainHeightMapBrush &brush, double value)
|
||||||
|
{
|
||||||
|
TerrainHeightMapBrushElevation sbrush(brush);
|
||||||
|
sbrush.apply(this, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::brushFlatten(const TerrainHeightMapBrush &brush, double height, double force)
|
||||||
|
{
|
||||||
|
TerrainHeightMapBrushFlatten sbrush(brush, height);
|
||||||
|
sbrush.apply(this, force);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::brushSmooth(const TerrainHeightMapBrush &brush, double value)
|
||||||
|
{
|
||||||
|
TerrainHeightMapBrushSmooth sbrush(brush);
|
||||||
|
sbrush.apply(this, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::brushAddNoise(const TerrainHeightMapBrush &brush, NoiseGenerator* generator, double value)
|
||||||
|
{
|
||||||
|
TerrainHeightMapBrushAddNoise sbrush(brush, generator);
|
||||||
|
sbrush.apply(this, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::brushReset(const TerrainHeightMapBrush &brush, double value)
|
||||||
|
{
|
||||||
|
TerrainHeightMapBrushReset sbrush(brush);
|
||||||
|
sbrush.apply(this, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMap::endBrushStroke()
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
TerrainHeightMapData* data = brush_data;
|
||||||
|
|
||||||
|
for (i = 0; i < data->rows_count; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
||||||
|
{
|
||||||
|
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart + 1; k++)
|
||||||
|
{
|
||||||
|
double* dpointer = getDataPointer(merged_data, data->rows[i].pixel_groups[j].xstart + k, data->rows[i].z, NULL, NULL, 1);
|
||||||
|
*dpointer = data->rows[i].pixel_groups[j].height[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearData(brush_data);
|
||||||
|
}
|
54
src/definition/TerrainHeightMap.h
Normal file
54
src/definition/TerrainHeightMap.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef TERRAINHEIGHTMAP_H
|
||||||
|
#define TERRAINHEIGHTMAP_H
|
||||||
|
|
||||||
|
#include "definition_global.h"
|
||||||
|
|
||||||
|
#include "BaseDefinition.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace definition {
|
||||||
|
|
||||||
|
class TerrainHeightMapData;
|
||||||
|
|
||||||
|
class DEFINITIONSHARED_EXPORT TerrainHeightMap : public BaseDefinition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerrainHeightMap(TerrainDefinition* terrain);
|
||||||
|
virtual ~TerrainHeightMap();
|
||||||
|
|
||||||
|
virtual void copy(BaseDefinition* destination) const override;
|
||||||
|
virtual void save(PackStream* stream) const override;
|
||||||
|
virtual void load(PackStream* stream) override;
|
||||||
|
|
||||||
|
inline TerrainDefinition* getTerrain() const {return terrain;}
|
||||||
|
int getInterpolatedHeight(double x, double z, double* result);
|
||||||
|
int getGridHeight(int x, int z, double* result);
|
||||||
|
|
||||||
|
bool isPainted(int x, int z);
|
||||||
|
unsigned long getMemoryStats() const;
|
||||||
|
|
||||||
|
void clearPainting();
|
||||||
|
void brushElevation(const TerrainHeightMapBrush &brush, double value);
|
||||||
|
void brushSmooth(const TerrainHeightMapBrush &brush, double value);
|
||||||
|
void brushAddNoise(const TerrainHeightMapBrush &brush, NoiseGenerator* generator, double value);
|
||||||
|
void brushReset(const TerrainHeightMapBrush &brush, double value);
|
||||||
|
void brushFlatten(const TerrainHeightMapBrush &brush, double height, double force);
|
||||||
|
void endBrushStroke();
|
||||||
|
|
||||||
|
friend class TerrainHeightMapBrush;
|
||||||
|
friend class TerrainHeightMapBrushSmooth;
|
||||||
|
friend class TerrainHeightMapBrushReset;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double* getDataPointer(TerrainHeightMapData* data, int x, int z, TerrainHeightMapData* fallback, TerrainDefinition* terrain, int grow);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TerrainDefinition* terrain;
|
||||||
|
TerrainHeightMapData* merged_data;
|
||||||
|
TerrainHeightMapData* brush_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TERRAINHEIGHTMAP_H
|
119
src/definition/TerrainHeightMapBrush.cpp
Normal file
119
src/definition/TerrainHeightMapBrush.cpp
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#include "TerrainHeightMapBrush.h"
|
||||||
|
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
#include "TerrainHeightMap.h"
|
||||||
|
#include "NoiseGenerator.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int xstart;
|
||||||
|
int xend;
|
||||||
|
int xsize;
|
||||||
|
int zstart;
|
||||||
|
int zend;
|
||||||
|
int zsize;
|
||||||
|
} IntegerRect;
|
||||||
|
|
||||||
|
static inline IntegerRect _getBrushRect(TerrainHeightMapBrush* brush)
|
||||||
|
{
|
||||||
|
IntegerRect result;
|
||||||
|
double s = brush->smoothed_size + brush->hard_radius;
|
||||||
|
|
||||||
|
result.xstart = (int)floor(brush->relative_x - s);
|
||||||
|
result.xend = (int)ceil(brush->relative_x + s);
|
||||||
|
result.zstart = (int)floor(brush->relative_z - s);
|
||||||
|
result.zend = (int)ceil(brush->relative_z + s);
|
||||||
|
|
||||||
|
result.xsize = result.xend - result.xstart + 1;
|
||||||
|
result.zsize = result.zend - result.zstart + 1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int _isInRect(const IntegerRect &rect, int x, int z)
|
||||||
|
{
|
||||||
|
return (x >= rect.xstart && x <= rect.xend && z >= rect.zstart && z <= rect.zend);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerrainHeightMapBrush::apply(TerrainHeightMap* heightmap, double force)
|
||||||
|
{
|
||||||
|
IntegerRect brush_rect = _getBrushRect(this);
|
||||||
|
int x, z;
|
||||||
|
double dx, dz, distance, influence;
|
||||||
|
|
||||||
|
force /= heightmap->terrain->height;
|
||||||
|
|
||||||
|
for (x = brush_rect.xstart; x <= brush_rect.xend; x++)
|
||||||
|
{
|
||||||
|
dx = (double)x;
|
||||||
|
for (z = brush_rect.zstart; z <= brush_rect.zend; z++)
|
||||||
|
{
|
||||||
|
dz = (double)z;
|
||||||
|
distance = sqrt((relative_x - dx) * (relative_x - dx) + (relative_z - dz) * (relative_z - dz));
|
||||||
|
|
||||||
|
if (distance > hard_radius)
|
||||||
|
{
|
||||||
|
if (distance <= hard_radius + smoothed_size)
|
||||||
|
{
|
||||||
|
influence = (1.0 - (distance - hard_radius) / smoothed_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
influence = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double* dpointer = heightmap->getDataPointer(heightmap->brush_data, x, z, heightmap->merged_data, heightmap->terrain, 1);
|
||||||
|
*dpointer = getBrushValue(heightmap, dx, dz, *dpointer, influence, force);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainHeightMapBrush::getBrushValue(TerrainHeightMap*, double, double, double basevalue, double, double) const
|
||||||
|
{
|
||||||
|
return basevalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainHeightMapBrushElevation::getBrushValue(TerrainHeightMap*, double, double, double basevalue, double influence, double force) const
|
||||||
|
{
|
||||||
|
return basevalue + influence * force;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainHeightMapBrushSmooth::getBrushValue(TerrainHeightMap* heightmap, double x, double z, double basevalue, double influence, double force) const
|
||||||
|
{
|
||||||
|
TerrainDefinition* terrain = heightmap->terrain;
|
||||||
|
double ideal, factor;
|
||||||
|
ideal = terrain->getInterpolatedHeight((x + total_radius * 0.5) * terrain->scaling, z * terrain->scaling, 0, 1);
|
||||||
|
ideal += terrain->getInterpolatedHeight((x - total_radius * 0.5) * terrain->scaling, z * terrain->scaling, 0, 1);
|
||||||
|
ideal += terrain->getInterpolatedHeight(x * terrain->scaling, (z - total_radius * 0.5) * terrain->scaling, 0, 1);
|
||||||
|
ideal += terrain->getInterpolatedHeight(x * terrain->scaling, (z + total_radius * 0.5) * terrain->scaling, 0, 1);
|
||||||
|
ideal /= 4.0;
|
||||||
|
factor = influence * force;
|
||||||
|
if (factor > 1.0)
|
||||||
|
{
|
||||||
|
factor = 0.0;
|
||||||
|
}
|
||||||
|
return basevalue + (ideal - basevalue) * factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainHeightMapBrushAddNoise::getBrushValue(TerrainHeightMap*, double x, double z, double basevalue, double influence, double force) const
|
||||||
|
{
|
||||||
|
return basevalue + generator->get2DTotal(x / total_radius, z / total_radius) * influence * force * total_radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainHeightMapBrushReset::getBrushValue(TerrainHeightMap* heightmap, double x, double z, double basevalue, double influence, double force) const
|
||||||
|
{
|
||||||
|
TerrainDefinition* terrain = heightmap->terrain;
|
||||||
|
double ideal = terrain->getInterpolatedHeight(x * terrain->scaling, z * terrain->scaling, 0, 0);
|
||||||
|
return basevalue + (ideal - basevalue) * influence * force;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TerrainHeightMapBrushFlatten::getBrushValue(TerrainHeightMap*, double, double, double basevalue, double influence, double force) const
|
||||||
|
{
|
||||||
|
double ideal = height;
|
||||||
|
return basevalue + (ideal - basevalue) * influence * force;
|
||||||
|
}
|
78
src/definition/TerrainHeightMapBrush.h
Normal file
78
src/definition/TerrainHeightMapBrush.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#ifndef TERRAINHEIGHTMAPBRUSH_H
|
||||||
|
#define TERRAINHEIGHTMAPBRUSH_H
|
||||||
|
|
||||||
|
#include "definition_global.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace definition {
|
||||||
|
|
||||||
|
class DEFINITIONSHARED_EXPORT TerrainHeightMapBrush
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerrainHeightMapBrush() {}
|
||||||
|
TerrainHeightMapBrush(double relative_x, double relative_z, double hard_radius, double smoothed_size, double total_radius):
|
||||||
|
relative_x(relative_x), relative_z(relative_z), hard_radius(hard_radius), smoothed_size(smoothed_size), total_radius(total_radius) {}
|
||||||
|
|
||||||
|
void apply(TerrainHeightMap* heightmap, double force);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual double getBrushValue(TerrainHeightMap* heightmap, double x, double z, double basevalue, double influence, double force) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
double relative_x;
|
||||||
|
double relative_z;
|
||||||
|
double hard_radius;
|
||||||
|
double smoothed_size;
|
||||||
|
double total_radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DEFINITIONSHARED_EXPORT TerrainHeightMapBrushElevation: public TerrainHeightMapBrush
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerrainHeightMapBrushElevation(const TerrainHeightMapBrush& brush) : TerrainHeightMapBrush(brush) {}
|
||||||
|
protected:
|
||||||
|
double getBrushValue(TerrainHeightMap* heightmap, double x, double z, double basevalue, double influence, double force) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DEFINITIONSHARED_EXPORT TerrainHeightMapBrushSmooth: public TerrainHeightMapBrush
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerrainHeightMapBrushSmooth(const TerrainHeightMapBrush& brush) : TerrainHeightMapBrush(brush) {}
|
||||||
|
protected:
|
||||||
|
double getBrushValue(TerrainHeightMap* heightmap, double x, double z, double basevalue, double influence, double force) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DEFINITIONSHARED_EXPORT TerrainHeightMapBrushAddNoise: public TerrainHeightMapBrush
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerrainHeightMapBrushAddNoise(NoiseGenerator* generator) : generator(generator) {}
|
||||||
|
TerrainHeightMapBrushAddNoise(const TerrainHeightMapBrush& brush, NoiseGenerator* generator) : TerrainHeightMapBrush(brush), generator(generator) {}
|
||||||
|
protected:
|
||||||
|
double getBrushValue(TerrainHeightMap* heightmap, double x, double z, double basevalue, double influence, double force) const override;
|
||||||
|
private:
|
||||||
|
NoiseGenerator* generator;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DEFINITIONSHARED_EXPORT TerrainHeightMapBrushReset: public TerrainHeightMapBrush
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerrainHeightMapBrushReset(const TerrainHeightMapBrush& brush) : TerrainHeightMapBrush(brush) {}
|
||||||
|
protected:
|
||||||
|
double getBrushValue(TerrainHeightMap* heightmap, double x, double z, double basevalue, double influence, double force) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DEFINITIONSHARED_EXPORT TerrainHeightMapBrushFlatten: public TerrainHeightMapBrush
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerrainHeightMapBrushFlatten(double height) : height(height) {}
|
||||||
|
TerrainHeightMapBrushFlatten(const TerrainHeightMapBrush& brush, double height) : TerrainHeightMapBrush(brush), height(height) {}
|
||||||
|
protected:
|
||||||
|
double getBrushValue(TerrainHeightMap* heightmap, double x, double z, double basevalue, double influence, double force) const override;
|
||||||
|
private:
|
||||||
|
double height;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TERRAINHEIGHTMAPBRUSH_H
|
|
@ -4,6 +4,8 @@
|
||||||
#include "NoiseGenerator.h"
|
#include "NoiseGenerator.h"
|
||||||
#include "SurfaceMaterial.h"
|
#include "SurfaceMaterial.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
|
#include "Scenery.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
|
||||||
TextureLayerDefinition::TextureLayerDefinition(BaseDefinition* parent):
|
TextureLayerDefinition::TextureLayerDefinition(BaseDefinition* parent):
|
||||||
BaseDefinition(parent)
|
BaseDefinition(parent)
|
||||||
|
@ -42,13 +44,13 @@ void TextureLayerDefinition::validate()
|
||||||
materialValidate(material);
|
materialValidate(material);
|
||||||
|
|
||||||
/* Update zone height range */
|
/* Update zone height range */
|
||||||
// TODO
|
Scenery* scenery = getScenery();
|
||||||
/*TerrainDefinition* terrain = Scenery::getCurrent()->getTerrain();
|
if (scenery)
|
||||||
if (terrain)
|
|
||||||
{
|
{
|
||||||
HeightInfo height_info = terrainGetHeightInfo(terrain);
|
TerrainDefinition* terrain = scenery->getTerrain();
|
||||||
zoneSetRelativeHeight(terrain_zone, height_info.min_height, height_info.base_height, height_info.max_height);
|
HeightInfo height_info = terrain->getHeightInfo();
|
||||||
}*/
|
terrain_zone->setRelativeHeight(height_info.min_height, height_info.base_height, height_info.max_height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureLayerDefinition::copy(BaseDefinition *_destination) const
|
void TextureLayerDefinition::copy(BaseDefinition *_destination) const
|
||||||
|
|
|
@ -8,12 +8,6 @@
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace definition {
|
namespace definition {
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
WATER_PRESET_LAKE,
|
|
||||||
WATER_PRESET_SEA
|
|
||||||
} WaterPreset;
|
|
||||||
|
|
||||||
class WaterDefinition: public BaseDefinition
|
class WaterDefinition: public BaseDefinition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -26,6 +20,12 @@ public:
|
||||||
virtual void copy(BaseDefinition* destination) const override;
|
virtual void copy(BaseDefinition* destination) const override;
|
||||||
virtual void validate() override;
|
virtual void validate() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
WATER_PRESET_LAKE,
|
||||||
|
WATER_PRESET_SEA
|
||||||
|
} WaterPreset;
|
||||||
void applyPreset(WaterPreset preset);
|
void applyPreset(WaterPreset preset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -24,7 +24,11 @@ SOURCES += \
|
||||||
AtmosphereDefinition.cpp \
|
AtmosphereDefinition.cpp \
|
||||||
TexturesDefinition.cpp \
|
TexturesDefinition.cpp \
|
||||||
TextureLayerDefinition.cpp \
|
TextureLayerDefinition.cpp \
|
||||||
Zone.cpp
|
Zone.cpp \
|
||||||
|
TerrainDefinition.cpp \
|
||||||
|
TerrainHeightMap.cpp \
|
||||||
|
TerrainHeightMapBrush.cpp \
|
||||||
|
Scenery.cpp
|
||||||
|
|
||||||
HEADERS +=\
|
HEADERS +=\
|
||||||
definition_global.h \
|
definition_global.h \
|
||||||
|
@ -38,7 +42,11 @@ HEADERS +=\
|
||||||
AtmosphereDefinition.h \
|
AtmosphereDefinition.h \
|
||||||
TexturesDefinition.h \
|
TexturesDefinition.h \
|
||||||
TextureLayerDefinition.h \
|
TextureLayerDefinition.h \
|
||||||
Zone.h
|
Zone.h \
|
||||||
|
TerrainDefinition.h \
|
||||||
|
TerrainHeightMap.h \
|
||||||
|
TerrainHeightMapBrush.h \
|
||||||
|
Scenery.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace definition {
|
namespace definition {
|
||||||
class BaseDefinition;
|
class BaseDefinition;
|
||||||
|
class Scenery;
|
||||||
class CameraDefinition;
|
class CameraDefinition;
|
||||||
class SurfaceMaterial;
|
class SurfaceMaterial;
|
||||||
class Zone;
|
class Zone;
|
||||||
|
@ -23,6 +24,14 @@ namespace definition {
|
||||||
class AtmosphereDefinition;
|
class AtmosphereDefinition;
|
||||||
class TexturesDefinition;
|
class TexturesDefinition;
|
||||||
class TextureLayerDefinition;
|
class TextureLayerDefinition;
|
||||||
|
class TerrainDefinition;
|
||||||
|
class TerrainHeightMap;
|
||||||
|
class TerrainHeightMapBrush;
|
||||||
|
class TerrainHeightMapBrushElevation;
|
||||||
|
class TerrainHeightMapBrushSmooth;
|
||||||
|
class TerrainHeightMapBrushAddNoise;
|
||||||
|
class TerrainHeightMapBrushReset;
|
||||||
|
class TerrainHeightMapBrushFlatten;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using namespace paysages::definition;
|
using namespace paysages::definition;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
|
|
||||||
void startRender(Renderer* renderer, char* outputpath, RenderParams params)
|
void startRender(Renderer* renderer, char* outputpath, RenderParams params)
|
||||||
{
|
{
|
||||||
|
@ -167,16 +167,16 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
for (outputcount = 0; outputcount < conf_first_picture + conf_nb_pictures; outputcount++)
|
for (outputcount = 0; outputcount < conf_first_picture + conf_nb_pictures; outputcount++)
|
||||||
{
|
{
|
||||||
AtmosphereDefinition* atmo = Scenery::getCurrent()->getAtmosphere();
|
AtmosphereDefinition* atmo = RenderingScenery::getCurrent()->getAtmosphere();
|
||||||
atmo->hour = (int)floor(conf_daytime_start * 24.0);
|
atmo->hour = (int)floor(conf_daytime_start * 24.0);
|
||||||
atmo->minute = (int)floor(fmod(conf_daytime_start, 1.0 / 24.0) * 24.0 * 60.0);
|
atmo->minute = (int)floor(fmod(conf_daytime_start, 1.0 / 24.0) * 24.0 * 60.0);
|
||||||
atmo->validate();
|
atmo->validate();
|
||||||
|
|
||||||
CameraDefinition* camera = Scenery::getCurrent()->getCamera();
|
CameraDefinition* camera = RenderingScenery::getCurrent()->getCamera();
|
||||||
Vector3 step = {conf_camera_step_x, conf_camera_step_y, conf_camera_step_z};
|
Vector3 step = {conf_camera_step_x, conf_camera_step_y, conf_camera_step_z};
|
||||||
camera->setLocation(camera->getLocation().add(step));
|
camera->setLocation(camera->getLocation().add(step));
|
||||||
|
|
||||||
renderer = new SoftwareRenderer(Scenery::getCurrent());
|
renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||||
rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate);
|
rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate);
|
||||||
|
|
||||||
if (outputcount >= conf_first_picture)
|
if (outputcount >= conf_first_picture)
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "dialogrender.h"
|
#include "dialogrender.h"
|
||||||
#include "dialogexplorer.h"
|
#include "dialogexplorer.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
|
@ -232,12 +232,12 @@ void FreeFormHelper::processApplyClicked()
|
||||||
|
|
||||||
void FreeFormHelper::processExploreClicked()
|
void FreeFormHelper::processExploreClicked()
|
||||||
{
|
{
|
||||||
SoftwareRenderer renderer(Scenery::getCurrent());
|
SoftwareRenderer renderer(RenderingScenery::getCurrent());
|
||||||
|
|
||||||
emit needAlterRenderer(&renderer);
|
emit needAlterRenderer(&renderer);
|
||||||
|
|
||||||
CameraDefinition camera;
|
CameraDefinition camera;
|
||||||
Scenery::getCurrent()->getCamera(&camera);
|
RenderingScenery::getCurrent()->getCamera(&camera);
|
||||||
|
|
||||||
DialogExplorer* dialog = new DialogExplorer(_form_widget, &camera, false, &renderer);
|
DialogExplorer* dialog = new DialogExplorer(_form_widget, &camera, false, &renderer);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
|
@ -246,7 +246,7 @@ void FreeFormHelper::processExploreClicked()
|
||||||
|
|
||||||
void FreeFormHelper::processRenderClicked()
|
void FreeFormHelper::processRenderClicked()
|
||||||
{
|
{
|
||||||
SoftwareRenderer renderer(Scenery::getCurrent());
|
SoftwareRenderer renderer(RenderingScenery::getCurrent());
|
||||||
|
|
||||||
emit needAlterRenderer(&renderer);
|
emit needAlterRenderer(&renderer);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include "dialogexplorer.h"
|
#include "dialogexplorer.h"
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
|
@ -127,11 +127,11 @@ MainWindow::MainWindow() :
|
||||||
ui->tool_panel->hide();
|
ui->tool_panel->hide();
|
||||||
//ui->menuBar->hide();
|
//ui->menuBar->hide();
|
||||||
|
|
||||||
Scenery::getCurrent()->setCustomSaveCallbacks(MainWindow::guiSaveCallback, MainWindow::guiLoadCallback, this);
|
RenderingScenery::getCurrent()->setCustomSaveCallbacks(MainWindow::guiSaveCallback, MainWindow::guiLoadCallback, this);
|
||||||
|
|
||||||
// FIXME AutoPreset has already been called by paysagesInit but we need to redo it here because
|
// FIXME AutoPreset has already been called by paysagesInit but we need to redo it here because
|
||||||
// the auto apply on FormRender overwrites the camera. Delete this when the render form is no longer a BaseForm.
|
// the auto apply on FormRender overwrites the camera. Delete this when the render form is no longer a BaseForm.
|
||||||
Scenery::getCurrent()->autoPreset(0);
|
RenderingScenery::getCurrent()->autoPreset(0);
|
||||||
refreshAll();
|
refreshAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ void MainWindow::refreshAll()
|
||||||
PreviewOsd* osd = PreviewOsd::getInstance(QString("geolocation"));
|
PreviewOsd* osd = PreviewOsd::getInstance(QString("geolocation"));
|
||||||
osd->clearItems();
|
osd->clearItems();
|
||||||
PreviewOsdItem* item = osd->newItem(50, 50);
|
PreviewOsdItem* item = osd->newItem(50, 50);
|
||||||
item->drawCamera(Scenery::getCurrent()->getCamera());
|
item->drawCamera(RenderingScenery::getCurrent()->getCamera());
|
||||||
item->setToolTip(QString(tr("Camera")));
|
item->setToolTip(QString(tr("Camera")));
|
||||||
|
|
||||||
emit refreshed();
|
emit refreshed();
|
||||||
|
@ -179,7 +179,7 @@ void MainWindow::fileNew()
|
||||||
{
|
{
|
||||||
if (QMessageBox::question(this, tr("Paysages 3D - New scenery"), tr("Do you want to start a new scenery ? Any unsaved changes will be lost."), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)
|
if (QMessageBox::question(this, tr("Paysages 3D - New scenery"), tr("Do you want to start a new scenery ? Any unsaved changes will be lost."), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->autoPreset(0);
|
RenderingScenery::getCurrent()->autoPreset(0);
|
||||||
refreshAll();
|
refreshAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ void MainWindow::explore3D()
|
||||||
CameraDefinition* camera = new CameraDefinition;
|
CameraDefinition* camera = new CameraDefinition;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
Scenery::getCurrent()->getCamera(camera);
|
RenderingScenery::getCurrent()->getCamera(camera);
|
||||||
|
|
||||||
DialogExplorer* dialog = new DialogExplorer(this, camera, true);
|
DialogExplorer* dialog = new DialogExplorer(this, camera, true);
|
||||||
result = dialog->exec();
|
result = dialog->exec();
|
||||||
|
@ -271,7 +271,7 @@ void MainWindow::explore3D()
|
||||||
|
|
||||||
if (result == QDialog::Accepted)
|
if (result == QDialog::Accepted)
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->setCamera(camera);
|
RenderingScenery::getCurrent()->setCamera(camera);
|
||||||
refreshAll();
|
refreshAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "AtmosphereColorPreviewRenderer.h"
|
#include "AtmosphereColorPreviewRenderer.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
@ -78,13 +78,13 @@ FormAtmosphere::~FormAtmosphere()
|
||||||
|
|
||||||
void FormAtmosphere::revertConfig()
|
void FormAtmosphere::revertConfig()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->getAtmosphere(_definition);
|
RenderingScenery::getCurrent()->getAtmosphere(_definition);
|
||||||
BaseForm::revertConfig();
|
BaseForm::revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormAtmosphere::applyConfig()
|
void FormAtmosphere::applyConfig()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->setAtmosphere(_definition);
|
RenderingScenery::getCurrent()->setAtmosphere(_definition);
|
||||||
BaseForm::applyConfig();
|
BaseForm::applyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "clouds/clo_preview.h"
|
#include "clouds/clo_preview.h"
|
||||||
#include "tools/color.h"
|
#include "tools/color.h"
|
||||||
#include "tools/euclid.h"
|
#include "tools/euclid.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "CloudsDefinition.h"
|
#include "CloudsDefinition.h"
|
||||||
|
@ -127,14 +127,14 @@ FormClouds::~FormClouds()
|
||||||
|
|
||||||
void FormClouds::revertConfig()
|
void FormClouds::revertConfig()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->getClouds(_definition);
|
RenderingScenery::getCurrent()->getClouds(_definition);
|
||||||
BaseFormLayer::revertConfig();
|
BaseFormLayer::revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormClouds::applyConfig()
|
void FormClouds::applyConfig()
|
||||||
{
|
{
|
||||||
BaseFormLayer::applyConfig();
|
BaseFormLayer::applyConfig();
|
||||||
Scenery::getCurrent()->setClouds(_definition);
|
RenderingScenery::getCurrent()->setClouds(_definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormClouds::layerReadCurrentFrom(void* layer_definition)
|
void FormClouds::layerReadCurrentFrom(void* layer_definition)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "clouds/public.h"
|
#include "clouds/public.h"
|
||||||
#include "terrain/public.h"
|
#include "terrain/public.h"
|
||||||
#include "water/public.h"
|
#include "water/public.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
|
@ -64,7 +64,7 @@ protected:
|
||||||
|
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->bindToRenderer(_renderer);
|
RenderingScenery::getCurrent()->bindToRenderer(_renderer);
|
||||||
if (!_clouds_enabled)
|
if (!_clouds_enabled)
|
||||||
{
|
{
|
||||||
CloudsRendererClass.bind(_renderer, _no_clouds);
|
CloudsRendererClass.bind(_renderer, _no_clouds);
|
||||||
|
@ -171,13 +171,13 @@ void FormRender::loadPack(PackStream* stream)
|
||||||
|
|
||||||
void FormRender::revertConfig()
|
void FormRender::revertConfig()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->getCamera(_camera);
|
RenderingScenery::getCurrent()->getCamera(_camera);
|
||||||
BaseForm::revertConfig();
|
BaseForm::revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormRender::applyConfig()
|
void FormRender::applyConfig()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->setCamera(_camera);
|
RenderingScenery::getCurrent()->setCamera(_camera);
|
||||||
BaseForm::applyConfig();
|
BaseForm::applyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ void FormRender::startQuickRender()
|
||||||
{
|
{
|
||||||
rendererDelete(_renderer);
|
rendererDelete(_renderer);
|
||||||
}
|
}
|
||||||
_renderer = new SoftwareRenderer(Scenery::getCurrent());
|
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||||
_renderer_inited = true;
|
_renderer_inited = true;
|
||||||
|
|
||||||
DialogRender* dialog = new DialogRender(this, _renderer);
|
DialogRender* dialog = new DialogRender(this, _renderer);
|
||||||
|
@ -209,7 +209,7 @@ void FormRender::startRender()
|
||||||
{
|
{
|
||||||
rendererDelete(_renderer);
|
rendererDelete(_renderer);
|
||||||
}
|
}
|
||||||
_renderer = new SoftwareRenderer(Scenery::getCurrent());
|
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||||
_renderer_inited = true;
|
_renderer_inited = true;
|
||||||
|
|
||||||
DialogRender* dialog = new DialogRender(this, _renderer);
|
DialogRender* dialog = new DialogRender(this, _renderer);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "formtextures.h"
|
#include "formtextures.h"
|
||||||
|
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
@ -47,7 +47,7 @@ protected:
|
||||||
|
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
TerrainRendererClass.bind(_renderer, Scenery::getCurrent()->getTerrain());
|
TerrainRendererClass.bind(_renderer, RenderingScenery::getCurrent()->getTerrain());
|
||||||
|
|
||||||
//TexturesDefinitionClass.copy(_original_layer, _preview_layer);
|
//TexturesDefinitionClass.copy(_original_layer, _preview_layer);
|
||||||
}
|
}
|
||||||
|
@ -140,14 +140,14 @@ FormTextures::~FormTextures()
|
||||||
|
|
||||||
void FormTextures::revertConfig()
|
void FormTextures::revertConfig()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->getTextures(_definition);
|
RenderingScenery::getCurrent()->getTextures(_definition);
|
||||||
BaseFormLayer::revertConfig();
|
BaseFormLayer::revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormTextures::applyConfig()
|
void FormTextures::applyConfig()
|
||||||
{
|
{
|
||||||
BaseFormLayer::applyConfig();
|
BaseFormLayer::applyConfig();
|
||||||
Scenery::getCurrent()->setTextures(_definition);
|
RenderingScenery::getCurrent()->setTextures(_definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormTextures::layerReadCurrentFrom(void* layer_definition)
|
void FormTextures::layerReadCurrentFrom(void* layer_definition)
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "terrain/public.h"
|
#include "terrain/public.h"
|
||||||
#include "atmosphere/public.h"
|
#include "atmosphere/public.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "BasePreview.h"
|
#include "BasePreview.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
|
@ -45,7 +45,7 @@ protected:
|
||||||
void updateData()
|
void updateData()
|
||||||
{
|
{
|
||||||
WaterRendererClass.bind(_renderer, _definition);
|
WaterRendererClass.bind(_renderer, _definition);
|
||||||
TerrainRendererClass.bind(_renderer, Scenery::getCurrent()->getTerrain());
|
TerrainRendererClass.bind(_renderer, RenderingScenery::getCurrent()->getTerrain());
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleChangeEvent(QString key, bool value)
|
void toggleChangeEvent(QString key, bool value)
|
||||||
|
@ -257,13 +257,13 @@ BaseForm(parent)
|
||||||
|
|
||||||
void FormWater::revertConfig()
|
void FormWater::revertConfig()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->getWater(_definition);
|
RenderingScenery::getCurrent()->getWater(_definition);
|
||||||
BaseForm::revertConfig();
|
BaseForm::revertConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormWater::applyConfig()
|
void FormWater::applyConfig()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->setWater(_definition);
|
RenderingScenery::getCurrent()->setWater(_definition);
|
||||||
BaseForm::applyConfig();
|
BaseForm::applyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ void FormWater::configChangeEvent()
|
||||||
|
|
||||||
void FormWater::autoPresetSelected(int preset)
|
void FormWater::autoPresetSelected(int preset)
|
||||||
{
|
{
|
||||||
_definition->applyPreset((WaterPreset)preset);
|
_definition->applyPreset((WaterDefinition::WaterPreset)preset);
|
||||||
BaseForm::autoPresetSelected(preset);
|
BaseForm::autoPresetSelected(preset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "dialogterrainpainting.h"
|
#include "dialogterrainpainting.h"
|
||||||
#include "ui_dialogterrainpainting.h"
|
#include "ui_dialogterrainpainting.h"
|
||||||
|
|
||||||
#include "tools.h"
|
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include "tools.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
|
||||||
DialogTerrainPainting::DialogTerrainPainting(QWidget*parent, TerrainDefinition* terrain) :
|
DialogTerrainPainting::DialogTerrainPainting(QWidget*parent, TerrainDefinition* terrain) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
|
@ -16,7 +17,7 @@ DialogTerrainPainting::DialogTerrainPainting(QWidget*parent, TerrainDefinition*
|
||||||
ui->brush_preview->hide();
|
ui->brush_preview->hide();
|
||||||
|
|
||||||
_terrain_original = terrain;
|
_terrain_original = terrain;
|
||||||
_terrain_modified = (TerrainDefinition*)TerrainDefinitionClass.create();
|
_terrain_modified = new TerrainDefinition(NULL);
|
||||||
|
|
||||||
ui->widget_commands->hide();
|
ui->widget_commands->hide();
|
||||||
|
|
||||||
|
@ -80,13 +81,13 @@ void DialogTerrainPainting::wheelEvent(QWheelEvent* event)
|
||||||
|
|
||||||
void DialogTerrainPainting::accept()
|
void DialogTerrainPainting::accept()
|
||||||
{
|
{
|
||||||
TerrainDefinitionClass.copy(_terrain_modified, _terrain_original);
|
_terrain_modified->copy(_terrain_original);
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogTerrainPainting::revert()
|
void DialogTerrainPainting::revert()
|
||||||
{
|
{
|
||||||
TerrainDefinitionClass.copy(_terrain_original, _terrain_modified);
|
_terrain_original->copy(_terrain_modified);
|
||||||
|
|
||||||
ui->widget_heightmap->setTerrain(_terrain_modified);
|
ui->widget_heightmap->setTerrain(_terrain_modified);
|
||||||
ui->widget_heightmap->setBrush(&_brush);
|
ui->widget_heightmap->setBrush(&_brush);
|
||||||
|
@ -112,7 +113,7 @@ void DialogTerrainPainting::brushConfigChanged()
|
||||||
|
|
||||||
void DialogTerrainPainting::heightmapChanged()
|
void DialogTerrainPainting::heightmapChanged()
|
||||||
{
|
{
|
||||||
qint64 memused = terrainGetMemoryStats(_terrain_modified);
|
unsigned long memused = _terrain_modified->getMemoryStats();
|
||||||
ui->label_memory_consumption->setText(tr("Memory used: %1").arg(getHumanMemory(memused)));
|
ui->label_memory_consumption->setText(tr("Memory used: %1").arg(getHumanMemory(memused)));
|
||||||
ui->progress_memory_consumption->setMaximum(1024);
|
ui->progress_memory_consumption->setMaximum(1024);
|
||||||
ui->progress_memory_consumption->setValue(memused / 1024);
|
ui->progress_memory_consumption->setValue(memused / 1024);
|
||||||
|
|
|
@ -7,14 +7,16 @@
|
||||||
#include "previewterrainshape.h"
|
#include "previewterrainshape.h"
|
||||||
#include "common/freeformhelper.h"
|
#include "common/freeformhelper.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
#include "TerrainHeightMap.h"
|
||||||
#include "textures/public.h"
|
#include "textures/public.h"
|
||||||
|
|
||||||
MainTerrainForm::MainTerrainForm(QWidget *parent) :
|
MainTerrainForm::MainTerrainForm(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
ui(new Ui::MainTerrainForm)
|
ui(new Ui::MainTerrainForm)
|
||||||
{
|
{
|
||||||
_terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
|
_terrain = new TerrainDefinition(NULL);
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
@ -49,12 +51,12 @@ MainTerrainForm::~MainTerrainForm()
|
||||||
delete ui;
|
delete ui;
|
||||||
delete _renderer_shape;
|
delete _renderer_shape;
|
||||||
|
|
||||||
TerrainDefinitionClass.destroy(_terrain);
|
delete _terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTerrainForm::refreshFromLocalData()
|
void MainTerrainForm::refreshFromLocalData()
|
||||||
{
|
{
|
||||||
qint64 memused = terrainGetMemoryStats(_terrain);
|
unsigned long memused = _terrain->getMemoryStats();
|
||||||
if (memused > 0)
|
if (memused > 0)
|
||||||
{
|
{
|
||||||
_form_helper->setLabelText(ui->label_painting_info, tr("Memory used by sculpted data: %1").arg(getHumanMemory(memused)));
|
_form_helper->setLabelText(ui->label_painting_info, tr("Memory used by sculpted data: %1").arg(getHumanMemory(memused)));
|
||||||
|
@ -69,7 +71,7 @@ void MainTerrainForm::refreshFromLocalData()
|
||||||
|
|
||||||
void MainTerrainForm::refreshFromFellowData()
|
void MainTerrainForm::refreshFromFellowData()
|
||||||
{
|
{
|
||||||
double disp = texturesGetMaximalDisplacement(Scenery::getCurrent()->getTextures());
|
double disp = texturesGetMaximalDisplacement(RenderingScenery::getCurrent()->getTextures());
|
||||||
|
|
||||||
if (disp == 0.0)
|
if (disp == 0.0)
|
||||||
{
|
{
|
||||||
|
@ -83,12 +85,12 @@ void MainTerrainForm::refreshFromFellowData()
|
||||||
|
|
||||||
void MainTerrainForm::updateLocalDataFromScenery()
|
void MainTerrainForm::updateLocalDataFromScenery()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->getTerrain(_terrain);
|
RenderingScenery::getCurrent()->getTerrain(_terrain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTerrainForm::commitLocalDataToScenery()
|
void MainTerrainForm::commitLocalDataToScenery()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->setTerrain(_terrain);
|
RenderingScenery::getCurrent()->setTerrain(_terrain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTerrainForm::alterRenderer(Renderer* renderer)
|
void MainTerrainForm::alterRenderer(Renderer* renderer)
|
||||||
|
@ -99,7 +101,7 @@ void MainTerrainForm::alterRenderer(Renderer* renderer)
|
||||||
void MainTerrainForm::buttonBaseNoisePressed()
|
void MainTerrainForm::buttonBaseNoisePressed()
|
||||||
{
|
{
|
||||||
int erase;
|
int erase;
|
||||||
if (terrainGetMemoryStats(_terrain) > 0)
|
if (_terrain->getMemoryStats() > 0)
|
||||||
{
|
{
|
||||||
erase = QMessageBox::question(this, tr("Paysages 3D - Base noise edition"), tr("You have manual modifications on this terrain, regenerating base noise may produce weird results."), tr("Keep my changes anyway"), tr("Erase my changes"));
|
erase = QMessageBox::question(this, tr("Paysages 3D - Base noise edition"), tr("You have manual modifications on this terrain, regenerating base noise may produce weird results."), tr("Keep my changes anyway"), tr("Erase my changes"));
|
||||||
}
|
}
|
||||||
|
@ -112,7 +114,7 @@ void MainTerrainForm::buttonBaseNoisePressed()
|
||||||
{
|
{
|
||||||
if (erase)
|
if (erase)
|
||||||
{
|
{
|
||||||
terrainClearPainting(_terrain->height_map);
|
_terrain->height_map->clearPainting();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <QAbstractSlider>
|
#include <QAbstractSlider>
|
||||||
#include "NoiseGenerator.h"
|
#include "NoiseGenerator.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
#include "TerrainHeightMap.h"
|
||||||
|
#include "TerrainHeightMapBrush.h"
|
||||||
|
|
||||||
PaintingBrush::PaintingBrush()
|
PaintingBrush::PaintingBrush()
|
||||||
{
|
{
|
||||||
|
@ -101,7 +104,7 @@ QString PaintingBrush::getHelpText()
|
||||||
void PaintingBrush::applyToTerrain(TerrainDefinition* terrain, double x, double z, double duration, bool reverse)
|
void PaintingBrush::applyToTerrain(TerrainDefinition* terrain, double x, double z, double duration, bool reverse)
|
||||||
{
|
{
|
||||||
double brush_strength;
|
double brush_strength;
|
||||||
TerrainBrush brush;
|
TerrainHeightMapBrush brush;
|
||||||
|
|
||||||
brush.relative_x = x;
|
brush.relative_x = x;
|
||||||
brush.relative_z = z;
|
brush.relative_z = z;
|
||||||
|
@ -118,30 +121,30 @@ void PaintingBrush::applyToTerrain(TerrainDefinition* terrain, double x, double
|
||||||
{
|
{
|
||||||
brush_strength = -brush_strength;
|
brush_strength = -brush_strength;
|
||||||
}
|
}
|
||||||
terrainBrushElevation(terrain->height_map, &brush, brush_strength * 2.0);
|
terrain->height_map->brushElevation(brush, brush_strength * 2.0);
|
||||||
break;
|
break;
|
||||||
case PAINTING_BRUSH_SMOOTH:
|
case PAINTING_BRUSH_SMOOTH:
|
||||||
if (reverse)
|
if (reverse)
|
||||||
{
|
{
|
||||||
terrainBrushSmooth(terrain->height_map, &brush, brush_strength * 30.0);
|
terrain->height_map->brushSmooth(brush, brush_strength * 30.0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
terrainBrushAddNoise(terrain->height_map, &brush, _noise, brush_strength * 0.3);
|
terrain->height_map->brushAddNoise(brush, _noise, brush_strength * 0.3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PAINTING_BRUSH_FLATTEN:
|
case PAINTING_BRUSH_FLATTEN:
|
||||||
if (reverse)
|
if (reverse)
|
||||||
{
|
{
|
||||||
_height = terrainGetInterpolatedHeight(terrain, x * terrain->scaling, z * terrain->scaling, 0, 1);
|
_height = terrain->getInterpolatedHeight(x * terrain->scaling, z * terrain->scaling, 0, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
terrainBrushFlatten(terrain->height_map, &brush, _height, brush_strength * 30.0);
|
terrain->height_map->brushFlatten(brush, _height, brush_strength * 30.0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PAINTING_BRUSH_RESTORE:
|
case PAINTING_BRUSH_RESTORE:
|
||||||
terrainBrushReset(terrain->height_map, &brush, brush_strength * 30.0);
|
terrain->height_map->brushReset(brush, brush_strength * 30.0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
#include "TerrainHeightMap.h"
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
|
|
||||||
#define HEIGHTMAP_RESOLUTION 256
|
#define HEIGHTMAP_RESOLUTION 256
|
||||||
|
@ -174,7 +176,7 @@ void WidgetHeightMap::mouseReleaseEvent(QMouseEvent*)
|
||||||
_last_brush_action = 0;
|
_last_brush_action = 0;
|
||||||
if (_terrain)
|
if (_terrain)
|
||||||
{
|
{
|
||||||
terrainEndBrushStroke(_terrain->height_map);
|
_terrain->height_map->endBrushStroke();
|
||||||
}
|
}
|
||||||
if (_brush)
|
if (_brush)
|
||||||
{
|
{
|
||||||
|
@ -214,7 +216,7 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
||||||
_last_time = new_time;
|
_last_time = new_time;
|
||||||
|
|
||||||
// Update top camera
|
// Update top camera
|
||||||
Vector3 target = {_target_x, terrainGetInterpolatedHeight(_terrain, _target_x, _target_z, 1, 1), _target_z};
|
Vector3 target = {_target_x, _terrain->getInterpolatedHeight(_target_x, _target_z, 1, 1), _target_z};
|
||||||
_top_camera->setLocationCoords(target.x, target.y + 1.0, target.z + 0.1);
|
_top_camera->setLocationCoords(target.x, target.y + 1.0, target.z + 0.1);
|
||||||
_top_camera->setTarget(target);
|
_top_camera->setTarget(target);
|
||||||
_top_camera->setZoomToTarget(_zoom);
|
_top_camera->setZoomToTarget(_zoom);
|
||||||
|
@ -533,9 +535,9 @@ void WidgetHeightMap::updateVertexInfo()
|
||||||
vertex->point.x = (double) dx;
|
vertex->point.x = (double) dx;
|
||||||
vertex->point.z = (double) dz;
|
vertex->point.z = (double) dz;
|
||||||
|
|
||||||
vertex->point.y = terrainGetGridHeight(_terrain, dx, dz, 1) * _terrain->height;
|
vertex->point.y = _terrain->getGridHeight(dx, dz, 1) * _terrain->height;
|
||||||
|
|
||||||
vertex->painted = terrainIsPainted(_terrain->height_map, dx, dz);
|
vertex->painted = _terrain->height_map->isPainted(dx, dz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "../common/freeformhelper.h"
|
#include "../common/freeformhelper.h"
|
||||||
#include "../common/freelayerhelper.h"
|
#include "../common/freelayerhelper.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "TexturesDefinition.h"
|
#include "TexturesDefinition.h"
|
||||||
#include "TextureLayerDefinition.h"
|
#include "TextureLayerDefinition.h"
|
||||||
#include "previewmaterial.h"
|
#include "previewmaterial.h"
|
||||||
|
@ -133,12 +133,12 @@ void MainTexturesForm::selectPreset(int preset)
|
||||||
|
|
||||||
void MainTexturesForm::updateLocalDataFromScenery()
|
void MainTexturesForm::updateLocalDataFromScenery()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->getTextures(textures);
|
RenderingScenery::getCurrent()->getTextures(textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTexturesForm::commitLocalDataToScenery()
|
void MainTexturesForm::commitLocalDataToScenery()
|
||||||
{
|
{
|
||||||
Scenery::getCurrent()->setTextures(textures);
|
RenderingScenery::getCurrent()->setTextures(textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTexturesForm::refreshFromLocalData()
|
void MainTexturesForm::refreshFromLocalData()
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
|
@ -90,7 +90,7 @@ QGLWidget(parent)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_renderer = new SoftwareRenderer(Scenery::getCurrent());
|
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||||
_renderer_created = true;
|
_renderer_created = true;
|
||||||
}
|
}
|
||||||
_opengl_renderer = new OpenGLRenderer(NULL);
|
_opengl_renderer = new OpenGLRenderer(NULL);
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "tools/color.h"
|
#include "tools/color.h"
|
||||||
|
|
||||||
class Scenery;
|
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace preview {
|
namespace preview {
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,6 @@
|
||||||
|
|
||||||
#include "software_global.h"
|
#include "software_global.h"
|
||||||
|
|
||||||
// TEMP
|
|
||||||
class Scenery;
|
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace preview {
|
namespace preview {
|
||||||
class PreviewOsd;
|
class PreviewOsd;
|
||||||
|
|
|
@ -8,6 +8,11 @@
|
||||||
|
|
||||||
|
|
||||||
// Legacy compatibility
|
// Legacy compatibility
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "terrain/public.h"
|
||||||
|
#include "clouds/public.h"
|
||||||
|
#include "textures/public.h"
|
||||||
|
#include "water/public.h"
|
||||||
static AtmosphereResult _legacyApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
|
static AtmosphereResult _legacyApplyAerialPerspective(Renderer* renderer, Vector3 location, Color base)
|
||||||
{
|
{
|
||||||
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->applyAerialPerspective(location, base);
|
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->applyAerialPerspective(location, base);
|
||||||
|
@ -24,7 +29,33 @@ static Vector3 _legacyGetSunDirection(Renderer* renderer)
|
||||||
{
|
{
|
||||||
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->getSunDirection();
|
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->getSunDirection();
|
||||||
}
|
}
|
||||||
|
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int, int, int, int)
|
||||||
|
{
|
||||||
|
RayCastingResult result;
|
||||||
|
Color sky_color;
|
||||||
|
|
||||||
|
result = renderer->terrain->castRay(renderer, location, direction);
|
||||||
|
if (!result.hit)
|
||||||
|
{
|
||||||
|
sky_color = renderer->atmosphere->getSkyColor(renderer, direction).final;
|
||||||
|
|
||||||
|
result.hit = 1;
|
||||||
|
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
||||||
|
result.hit_color = renderer->clouds->getColor(renderer, sky_color, location, result.hit_location);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
static double _getPrecision(Renderer* renderer, Vector3 location)
|
||||||
|
{
|
||||||
|
Vector3 projected;
|
||||||
|
|
||||||
|
projected = renderer->render_camera->project(location);
|
||||||
|
projected.x += 1.0;
|
||||||
|
//projected.y += 1.0;
|
||||||
|
|
||||||
|
return v3Norm(v3Sub(renderer->render_camera->unproject(projected), location)); // / (double)render_quality;
|
||||||
|
}
|
||||||
|
|
||||||
SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
||||||
{
|
{
|
||||||
|
@ -42,7 +73,6 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
||||||
this->scenery = new Scenery;
|
this->scenery = new Scenery;
|
||||||
own_scenery = true;
|
own_scenery = true;
|
||||||
}
|
}
|
||||||
this->scenery->bindToRenderer(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftwareRenderer::~SoftwareRenderer()
|
SoftwareRenderer::~SoftwareRenderer()
|
||||||
|
@ -57,6 +87,16 @@ SoftwareRenderer::~SoftwareRenderer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoftwareRenderer::setScenery(Scenery* scenery)
|
||||||
|
{
|
||||||
|
if (!own_scenery)
|
||||||
|
{
|
||||||
|
this->scenery = new Scenery;
|
||||||
|
own_scenery = true;
|
||||||
|
}
|
||||||
|
scenery->copy(this->scenery);
|
||||||
|
}
|
||||||
|
|
||||||
void SoftwareRenderer::prepare()
|
void SoftwareRenderer::prepare()
|
||||||
{
|
{
|
||||||
// Prepare sub renderers
|
// Prepare sub renderers
|
||||||
|
@ -64,12 +104,21 @@ void SoftwareRenderer::prepare()
|
||||||
atmosphere_renderer = new SoftwareBrunetonAtmosphereRenderer(this);
|
atmosphere_renderer = new SoftwareBrunetonAtmosphereRenderer(this);
|
||||||
|
|
||||||
// Setup transitional renderers (for C-legacy subsystems)
|
// Setup transitional renderers (for C-legacy subsystems)
|
||||||
|
rayWalking = _rayWalking;
|
||||||
|
getPrecision = _getPrecision;
|
||||||
|
|
||||||
scenery->getAtmosphere()->copy(atmosphere->definition);
|
scenery->getAtmosphere()->copy(atmosphere->definition);
|
||||||
atmosphere->applyAerialPerspective = _legacyApplyAerialPerspective;
|
atmosphere->applyAerialPerspective = _legacyApplyAerialPerspective;
|
||||||
atmosphere->getSkyColor = _legacyGetSkyColor;
|
atmosphere->getSkyColor = _legacyGetSkyColor;
|
||||||
atmosphere->getLightingStatus = _legacyGetLightingStatus;
|
atmosphere->getLightingStatus = _legacyGetLightingStatus;
|
||||||
atmosphere->getSunDirection = _legacyGetSunDirection;
|
atmosphere->getSunDirection = _legacyGetSunDirection;
|
||||||
|
|
||||||
|
scenery->getCamera()->copy(render_camera);
|
||||||
|
TerrainRendererClass.bind(this, scenery->getTerrain());
|
||||||
|
TexturesRendererClass.bind(this, scenery->getTextures());
|
||||||
|
CloudsRendererClass.bind(this, scenery->getClouds());
|
||||||
|
WaterRendererClass.bind(this, scenery->getWater());
|
||||||
|
|
||||||
// Prepare global tools
|
// Prepare global tools
|
||||||
fluid_medium->clearMedia();
|
fluid_medium->clearMedia();
|
||||||
//fluid_medium->registerMedium(water_renderer);
|
//fluid_medium->registerMedium(water_renderer);
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
|
||||||
class Scenery;
|
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace software {
|
namespace software {
|
||||||
|
|
||||||
|
@ -20,13 +18,20 @@ public:
|
||||||
SoftwareRenderer(Scenery* scenery=0);
|
SoftwareRenderer(Scenery* scenery=0);
|
||||||
virtual ~SoftwareRenderer();
|
virtual ~SoftwareRenderer();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set the scenery to render.
|
||||||
|
*
|
||||||
|
* Don't call this after rendering has already started.
|
||||||
|
*/
|
||||||
|
virtual void setScenery(Scenery* scenery) override;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Prepare the renderer sub-systems.
|
* \brief Prepare the renderer sub-systems.
|
||||||
*
|
*
|
||||||
* This will clear the caches and connect elements together.
|
* This will clear the caches and connect elements together.
|
||||||
* After this call, don't update the scenery when renderer is in use.
|
* After this call, don't update the scenery when renderer is in use.
|
||||||
*/
|
*/
|
||||||
virtual void prepare();
|
virtual void prepare() override;
|
||||||
|
|
||||||
inline Scenery* getScenery() const {return scenery;}
|
inline Scenery* getScenery() const {return scenery;}
|
||||||
inline BaseAtmosphereRenderer* getAtmosphereRenderer() const {return atmosphere_renderer;}
|
inline BaseAtmosphereRenderer* getAtmosphereRenderer() const {return atmosphere_renderer;}
|
||||||
|
|
67
src/rendering/RenderingScenery.cpp
Normal file
67
src/rendering/RenderingScenery.cpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "RenderingScenery.h"
|
||||||
|
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "terrain/public.h"
|
||||||
|
#include "textures/public.h"
|
||||||
|
#include "terrain/ter_raster.h"
|
||||||
|
#include "water/public.h"
|
||||||
|
#include "atmosphere/public.h"
|
||||||
|
#include "CameraDefinition.h"
|
||||||
|
|
||||||
|
static RenderingScenery _main_scenery;
|
||||||
|
|
||||||
|
RenderingScenery::RenderingScenery()
|
||||||
|
{
|
||||||
|
_custom_load = NULL;
|
||||||
|
_custom_save = NULL;
|
||||||
|
_custom_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderingScenery* RenderingScenery::getCurrent()
|
||||||
|
{
|
||||||
|
return &_main_scenery;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingScenery::setCustomSaveCallbacks(SceneryCustomDataCallback callback_save, SceneryCustomDataCallback callback_load, void* data)
|
||||||
|
{
|
||||||
|
_custom_save = callback_save;
|
||||||
|
_custom_load = callback_load;
|
||||||
|
_custom_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingScenery::save(PackStream* stream) const
|
||||||
|
{
|
||||||
|
if (_custom_save)
|
||||||
|
{
|
||||||
|
_custom_save(stream, _custom_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scenery::save(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingScenery::load(PackStream* stream)
|
||||||
|
{
|
||||||
|
if (_custom_load)
|
||||||
|
{
|
||||||
|
_custom_load(stream, _custom_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scenery::load(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RenderingScenery::bindToRenderer(Renderer* renderer)
|
||||||
|
{
|
||||||
|
renderer->setScenery(this);
|
||||||
|
renderer->prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Transitional C-API
|
||||||
|
|
||||||
|
void sceneryRenderFirstPass(Renderer* renderer)
|
||||||
|
{
|
||||||
|
terrainRenderSurface(renderer);
|
||||||
|
waterRenderSurface(renderer);
|
||||||
|
atmosphereRenderSkydome(renderer);
|
||||||
|
}
|
41
src/rendering/RenderingScenery.h
Normal file
41
src/rendering/RenderingScenery.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef RENDERINGSCENERY_H
|
||||||
|
#define RENDERINGSCENERY_H
|
||||||
|
|
||||||
|
#include "rendering_global.h"
|
||||||
|
|
||||||
|
#include "Scenery.h"
|
||||||
|
|
||||||
|
class Renderer;
|
||||||
|
|
||||||
|
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Global scenery management
|
||||||
|
*
|
||||||
|
* This class contains the whole scenery definition.
|
||||||
|
*/
|
||||||
|
class RENDERINGSHARED_EXPORT RenderingScenery: public Scenery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RenderingScenery();
|
||||||
|
|
||||||
|
static RenderingScenery* getCurrent();
|
||||||
|
|
||||||
|
void setCustomSaveCallbacks(SceneryCustomDataCallback callback_save, SceneryCustomDataCallback callback_load, void* data);
|
||||||
|
|
||||||
|
virtual void save(PackStream* stream) const override;
|
||||||
|
virtual void load(PackStream* stream) override;
|
||||||
|
|
||||||
|
void bindToRenderer(Renderer* renderer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SceneryCustomDataCallback _custom_save;
|
||||||
|
SceneryCustomDataCallback _custom_load;
|
||||||
|
void* _custom_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Transitional C-API
|
||||||
|
|
||||||
|
RENDERINGSHARED_EXPORT void sceneryRenderFirstPass(Renderer* renderer);
|
||||||
|
|
||||||
|
#endif // SCENERY_H
|
|
@ -1,244 +0,0 @@
|
||||||
#include "Scenery.h"
|
|
||||||
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#include "NoiseGenerator.h"
|
|
||||||
#include "PackStream.h"
|
|
||||||
#include "atmosphere/public.h"
|
|
||||||
#include "terrain/public.h"
|
|
||||||
#include "textures/public.h"
|
|
||||||
#include "renderer.h"
|
|
||||||
#include "terrain/ter_raster.h"
|
|
||||||
#include "AtmosphereDefinition.h"
|
|
||||||
#include "CameraDefinition.h"
|
|
||||||
#include "CloudsDefinition.h"
|
|
||||||
#include "TexturesDefinition.h"
|
|
||||||
#include "WaterDefinition.h"
|
|
||||||
|
|
||||||
static Scenery _main_scenery;
|
|
||||||
|
|
||||||
Scenery::Scenery():
|
|
||||||
BaseDefinition(NULL)
|
|
||||||
{
|
|
||||||
atmosphere = new AtmosphereDefinition(this);
|
|
||||||
camera = new CameraDefinition;
|
|
||||||
clouds = new CloudsDefinition(this);
|
|
||||||
terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
|
|
||||||
textures = new TexturesDefinition(this);
|
|
||||||
water = new WaterDefinition(this);
|
|
||||||
|
|
||||||
addChild(atmosphere);
|
|
||||||
addChild(camera);
|
|
||||||
addChild(clouds);
|
|
||||||
addChild(textures);
|
|
||||||
addChild(water);
|
|
||||||
|
|
||||||
_custom_load = NULL;
|
|
||||||
_custom_save = NULL;
|
|
||||||
_custom_data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scenery::~Scenery()
|
|
||||||
{
|
|
||||||
TerrainDefinitionClass.destroy(terrain);
|
|
||||||
}
|
|
||||||
|
|
||||||
Scenery* Scenery::getCurrent()
|
|
||||||
{
|
|
||||||
return &_main_scenery;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::setCustomSaveCallbacks(SceneryCustomDataCallback callback_save, SceneryCustomDataCallback callback_load, void* data)
|
|
||||||
{
|
|
||||||
_custom_save = callback_save;
|
|
||||||
_custom_load = callback_load;
|
|
||||||
_custom_data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::save(PackStream* stream) const
|
|
||||||
{
|
|
||||||
BaseDefinition::save(stream);
|
|
||||||
|
|
||||||
noiseSave(stream);
|
|
||||||
|
|
||||||
TerrainDefinitionClass.save(stream, terrain);
|
|
||||||
|
|
||||||
if (_custom_save)
|
|
||||||
{
|
|
||||||
_custom_save(stream, _custom_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::load(PackStream* stream)
|
|
||||||
{
|
|
||||||
BaseDefinition::load(stream);
|
|
||||||
|
|
||||||
noiseLoad(stream);
|
|
||||||
|
|
||||||
TerrainDefinitionClass.load(stream, terrain);
|
|
||||||
|
|
||||||
if (_custom_load)
|
|
||||||
{
|
|
||||||
_custom_load(stream, _custom_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::validate()
|
|
||||||
{
|
|
||||||
BaseDefinition::validate();
|
|
||||||
|
|
||||||
checkCameraAboveGround();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::autoPreset(int seed)
|
|
||||||
{
|
|
||||||
if (!seed)
|
|
||||||
{
|
|
||||||
seed = time(NULL);
|
|
||||||
}
|
|
||||||
srand(seed);
|
|
||||||
|
|
||||||
terrainAutoPreset(terrain, TERRAIN_PRESET_STANDARD);
|
|
||||||
textures->applyPreset(TexturesDefinition::TEXTURES_PRESET_FULL);
|
|
||||||
atmosphere->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_DAY);
|
|
||||||
water->applyPreset(WATER_PRESET_LAKE);
|
|
||||||
clouds->applyPreset(CloudsDefinition::CLOUDS_PRESET_PARTLY_CLOUDY);
|
|
||||||
|
|
||||||
camera->setLocation(VECTOR_ZERO);
|
|
||||||
camera->setTarget(VECTOR_NORTH);
|
|
||||||
|
|
||||||
validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::setAtmosphere(AtmosphereDefinition* atmosphere)
|
|
||||||
{
|
|
||||||
atmosphere->copy(this->atmosphere);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::getAtmosphere(AtmosphereDefinition* atmosphere)
|
|
||||||
{
|
|
||||||
this->atmosphere->copy(atmosphere);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::setCamera(CameraDefinition* camera)
|
|
||||||
{
|
|
||||||
camera->copy(this->camera);
|
|
||||||
checkCameraAboveGround();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::getCamera(CameraDefinition* camera)
|
|
||||||
{
|
|
||||||
this->camera->copy(camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::setClouds(CloudsDefinition* clouds)
|
|
||||||
{
|
|
||||||
clouds->copy(this->clouds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::getClouds(CloudsDefinition* clouds)
|
|
||||||
{
|
|
||||||
this->clouds->copy(clouds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::setTerrain(TerrainDefinition* terrain)
|
|
||||||
{
|
|
||||||
TerrainDefinitionClass.copy(terrain, this->terrain);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::getTerrain(TerrainDefinition* terrain)
|
|
||||||
{
|
|
||||||
TerrainDefinitionClass.copy(this->terrain, terrain);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::setTextures(TexturesDefinition* textures)
|
|
||||||
{
|
|
||||||
textures->copy(this->textures);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::getTextures(TexturesDefinition* textures)
|
|
||||||
{
|
|
||||||
this->textures->copy(textures);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::setWater(WaterDefinition* water)
|
|
||||||
{
|
|
||||||
water->copy(this->water);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::getWater(WaterDefinition* water)
|
|
||||||
{
|
|
||||||
this->water->copy(water);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "clouds/public.h"
|
|
||||||
#include "water/public.h"
|
|
||||||
|
|
||||||
static RayCastingResult _rayWalking(Renderer* renderer, Vector3 location, Vector3 direction, int, int, int, int)
|
|
||||||
{
|
|
||||||
RayCastingResult result;
|
|
||||||
Color sky_color;
|
|
||||||
|
|
||||||
result = renderer->terrain->castRay(renderer, location, direction);
|
|
||||||
if (!result.hit)
|
|
||||||
{
|
|
||||||
sky_color = renderer->atmosphere->getSkyColor(renderer, direction).final;
|
|
||||||
|
|
||||||
result.hit = 1;
|
|
||||||
result.hit_location = v3Add(location, v3Scale(direction, 1000.0));
|
|
||||||
result.hit_color = renderer->clouds->getColor(renderer, sky_color, location, result.hit_location);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static double _getPrecision(Renderer* renderer, Vector3 location)
|
|
||||||
{
|
|
||||||
Vector3 projected;
|
|
||||||
|
|
||||||
projected = renderer->render_camera->project(location);
|
|
||||||
projected.x += 1.0;
|
|
||||||
//projected.y += 1.0;
|
|
||||||
|
|
||||||
return v3Norm(v3Sub(renderer->render_camera->unproject(projected), location)); // / (double)render_quality;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::bindToRenderer(Renderer* renderer)
|
|
||||||
{
|
|
||||||
// TODO Get rid of this !
|
|
||||||
renderer->rayWalking = _rayWalking;
|
|
||||||
renderer->getPrecision = _getPrecision;
|
|
||||||
|
|
||||||
camera->copy(renderer->render_camera);
|
|
||||||
AtmosphereRendererClass.bind(renderer, atmosphere);
|
|
||||||
TerrainRendererClass.bind(renderer, terrain);
|
|
||||||
TexturesRendererClass.bind(renderer, textures);
|
|
||||||
CloudsRendererClass.bind(renderer, clouds);
|
|
||||||
WaterRendererClass.bind(renderer, water);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scenery::checkCameraAboveGround()
|
|
||||||
{
|
|
||||||
Vector3 camera_location = camera->getLocation();
|
|
||||||
double terrain_height = terrainGetInterpolatedHeight(terrain, camera_location.x, camera_location.z, 1, 1) + 0.5;
|
|
||||||
double water_height = terrainGetWaterHeight(terrain) + 0.5;
|
|
||||||
if (camera_location.y < water_height || camera_location.y < terrain_height)
|
|
||||||
{
|
|
||||||
double diff = ((water_height > terrain_height) ? water_height : terrain_height) - camera_location.y;
|
|
||||||
camera->setLocation(camera_location.add(Vector3(0.0, diff, 0.0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transitional C-API
|
|
||||||
|
|
||||||
void sceneryRenderFirstPass(Renderer* renderer)
|
|
||||||
{
|
|
||||||
terrainRenderSurface(renderer);
|
|
||||||
waterRenderSurface(renderer);
|
|
||||||
atmosphereRenderSkydome(renderer);
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "tools/data.h"
|
#include "tools/data.h"
|
||||||
|
#include "RenderingScenery.h"
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
@ -45,7 +46,7 @@ FileOperationResult paysagesSave(char* filepath)
|
||||||
version_header = (double)PAYSAGES_CURRENT_DATA_VERSION;
|
version_header = (double)PAYSAGES_CURRENT_DATA_VERSION;
|
||||||
stream.write(&version_header);
|
stream.write(&version_header);
|
||||||
|
|
||||||
Scenery::getCurrent()->save(&stream);
|
RenderingScenery::getCurrent()->save(&stream);
|
||||||
|
|
||||||
return FILE_OPERATION_OK;
|
return FILE_OPERATION_OK;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +73,7 @@ FileOperationResult paysagesLoad(char* filepath)
|
||||||
return FILE_OPERATION_VERSION_MISMATCH;
|
return FILE_OPERATION_VERSION_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scenery::getCurrent()->load(&stream);
|
RenderingScenery::getCurrent()->load(&stream);
|
||||||
|
|
||||||
return FILE_OPERATION_OK;
|
return FILE_OPERATION_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "CameraDefinition.h"
|
#include "CameraDefinition.h"
|
||||||
#include "atmosphere/public.h"
|
#include "atmosphere/public.h"
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
virtual ~Renderer();
|
virtual ~Renderer();
|
||||||
|
|
||||||
virtual void prepare() {}
|
virtual void prepare() {}
|
||||||
|
virtual void setScenery(Scenery*) {}
|
||||||
|
|
||||||
/* Render base configuration */
|
/* Render base configuration */
|
||||||
int render_quality;
|
int render_quality;
|
||||||
|
|
|
@ -24,9 +24,7 @@ SOURCES += main.cpp \
|
||||||
terrain/ter_render.cpp \
|
terrain/ter_render.cpp \
|
||||||
terrain/ter_raster.cpp \
|
terrain/ter_raster.cpp \
|
||||||
terrain/ter_preview.cpp \
|
terrain/ter_preview.cpp \
|
||||||
terrain/ter_presets.cpp \
|
|
||||||
terrain/ter_painting.cpp \
|
terrain/ter_painting.cpp \
|
||||||
terrain/ter_definition.cpp \
|
|
||||||
textures/tex_tools.cpp \
|
textures/tex_tools.cpp \
|
||||||
textures/tex_rendering.cpp \
|
textures/tex_rendering.cpp \
|
||||||
textures/tex_preview.cpp \
|
textures/tex_preview.cpp \
|
||||||
|
@ -42,7 +40,7 @@ SOURCES += main.cpp \
|
||||||
water/wat_raster.cpp \
|
water/wat_raster.cpp \
|
||||||
water/wat_preview.cpp \
|
water/wat_preview.cpp \
|
||||||
water/wat_definition.cpp \
|
water/wat_definition.cpp \
|
||||||
Scenery.cpp
|
RenderingScenery.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
tools.h \
|
tools.h \
|
||||||
|
@ -76,7 +74,7 @@ HEADERS += \
|
||||||
water/public.h \
|
water/public.h \
|
||||||
water/private.h \
|
water/private.h \
|
||||||
rendering_global.h \
|
rendering_global.h \
|
||||||
Scenery.h
|
RenderingScenery.h
|
||||||
|
|
||||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../system/release/ -lpaysages_system
|
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../system/release/ -lpaysages_system
|
||||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../system/debug/ -lpaysages_system
|
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../system/debug/ -lpaysages_system
|
||||||
|
|
|
@ -3,22 +3,6 @@
|
||||||
|
|
||||||
#include "public.h"
|
#include "public.h"
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int xstart;
|
|
||||||
int xend;
|
|
||||||
int xsize;
|
|
||||||
int zstart;
|
|
||||||
int zend;
|
|
||||||
int zsize;
|
|
||||||
} IntegerRect;
|
|
||||||
|
|
||||||
TerrainHeightMap* terrainHeightMapCreate(TerrainDefinition* definition);
|
|
||||||
void terrainHeightmapDelete(TerrainHeightMap* heightmap);
|
|
||||||
void terrainHeightmapCopy(TerrainHeightMap* source, TerrainHeightMap* destination);
|
|
||||||
void terrainHeightmapSave(PackStream* stream, TerrainHeightMap* heightmap);
|
|
||||||
void terrainHeightmapLoad(PackStream* stream, TerrainHeightMap* heightmap);
|
|
||||||
int terrainHeightmapGetInterpolatedHeight(TerrainHeightMap* heightmap, double x, double z, double* result);
|
|
||||||
int terrainHeightmapGetGridHeight(TerrainHeightMap* heightmap, int x, int z, double* result);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,41 +2,10 @@
|
||||||
#define _PAYSAGES_TERRAIN_PUBLIC_H_
|
#define _PAYSAGES_TERRAIN_PUBLIC_H_
|
||||||
|
|
||||||
#include "../rendering_global.h"
|
#include "../rendering_global.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include "../shared/types.h"
|
#include "../shared/types.h"
|
||||||
#include "../tools/color.h"
|
#include "../tools/color.h"
|
||||||
#include "../tools/euclid.h"
|
#include "../tools/euclid.h"
|
||||||
|
|
||||||
namespace paysages {
|
|
||||||
namespace basics {
|
|
||||||
class NoiseGenerator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
TERRAIN_PRESET_STANDARD
|
|
||||||
} TerrainPreset;
|
|
||||||
|
|
||||||
typedef struct TerrainHeightMap TerrainHeightMap;
|
|
||||||
|
|
||||||
class TerrainDefinition
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
double height;
|
|
||||||
double scaling;
|
|
||||||
double shadow_smoothing;
|
|
||||||
|
|
||||||
TerrainHeightMap* height_map;
|
|
||||||
|
|
||||||
double water_height;
|
|
||||||
|
|
||||||
double _detail;
|
|
||||||
NoiseGenerator* _height_noise;
|
|
||||||
double _min_height;
|
|
||||||
double _max_height;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
|
@ -62,37 +31,9 @@ public:
|
||||||
void* _internal_data;
|
void* _internal_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT extern StandardDefinition TerrainDefinitionClass;
|
|
||||||
RENDERINGSHARED_EXPORT extern StandardRenderer TerrainRendererClass;
|
RENDERINGSHARED_EXPORT extern StandardRenderer TerrainRendererClass;
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset);
|
|
||||||
RENDERINGSHARED_EXPORT double terrainGetGridHeight(TerrainDefinition* definition, int x, int z, int with_painting);
|
|
||||||
RENDERINGSHARED_EXPORT double terrainGetInterpolatedHeight(TerrainDefinition* definition, double x, double z, int scaled, int with_painting);
|
|
||||||
RENDERINGSHARED_EXPORT size_t terrainGetMemoryStats(TerrainDefinition* definition);
|
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT void terrainAlterPreviewRenderer(Renderer* renderer);
|
RENDERINGSHARED_EXPORT void terrainAlterPreviewRenderer(Renderer* renderer);
|
||||||
RENDERINGSHARED_EXPORT Color terrainGetPreviewColor(Renderer* renderer, double x, double z, double detail);
|
RENDERINGSHARED_EXPORT Color terrainGetPreviewColor(Renderer* renderer, double x, double z, double detail);
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT HeightInfo terrainGetHeightInfo(TerrainDefinition* definition);
|
|
||||||
RENDERINGSHARED_EXPORT double terrainGetWaterHeight(TerrainDefinition* definition);
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
double relative_x;
|
|
||||||
double relative_z;
|
|
||||||
double hard_radius;
|
|
||||||
double smoothed_size;
|
|
||||||
double total_radius;
|
|
||||||
} TerrainBrush;
|
|
||||||
|
|
||||||
/* Heightmap manipulation */
|
|
||||||
RENDERINGSHARED_EXPORT int terrainIsPainted(TerrainHeightMap* heightmap, int x, int z);
|
|
||||||
RENDERINGSHARED_EXPORT void terrainClearPainting(TerrainHeightMap* heightmap);
|
|
||||||
RENDERINGSHARED_EXPORT void terrainBrushElevation(TerrainHeightMap* heightmap, TerrainBrush* brush, double value);
|
|
||||||
RENDERINGSHARED_EXPORT void terrainBrushSmooth(TerrainHeightMap* heightmap, TerrainBrush* brush, double value);
|
|
||||||
RENDERINGSHARED_EXPORT void terrainBrushAddNoise(TerrainHeightMap* heightmap, TerrainBrush* brush, NoiseGenerator* generator, double value);
|
|
||||||
RENDERINGSHARED_EXPORT void terrainBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double value);
|
|
||||||
RENDERINGSHARED_EXPORT void terrainBrushFlatten(TerrainHeightMap* heightmap, TerrainBrush* brush, double height, double force);
|
|
||||||
RENDERINGSHARED_EXPORT void terrainEndBrushStroke(TerrainHeightMap* heightmap);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
#include "private.h"
|
|
||||||
|
|
||||||
#include "../tools.h"
|
|
||||||
#include "../renderer.h"
|
|
||||||
#include "NoiseGenerator.h"
|
|
||||||
#include "PackStream.h"
|
|
||||||
|
|
||||||
/******************** Definition ********************/
|
|
||||||
static void _validateDefinition(TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
definition->_height_noise->validate();
|
|
||||||
|
|
||||||
if (definition->height < 1.0)
|
|
||||||
{
|
|
||||||
definition->height = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get minimal and maximal height */
|
|
||||||
definition->_height_noise->getRange(&definition->_min_height, &definition->_max_height);
|
|
||||||
definition->_min_height *= definition->height * definition->scaling;
|
|
||||||
definition->_max_height *= definition->height * definition->scaling;
|
|
||||||
|
|
||||||
/* TODO Alter with heightmap min/max */
|
|
||||||
}
|
|
||||||
|
|
||||||
static TerrainDefinition* _createDefinition()
|
|
||||||
{
|
|
||||||
TerrainDefinition* definition = new TerrainDefinition;
|
|
||||||
|
|
||||||
definition->height = 1.0;
|
|
||||||
definition->scaling = 1.0;
|
|
||||||
definition->shadow_smoothing = 0.0;
|
|
||||||
|
|
||||||
definition->height_map = terrainHeightMapCreate(definition);
|
|
||||||
|
|
||||||
definition->water_height = -0.3;
|
|
||||||
|
|
||||||
definition->_height_noise = new NoiseGenerator();
|
|
||||||
|
|
||||||
terrainAutoPreset(definition, TERRAIN_PRESET_STANDARD);
|
|
||||||
|
|
||||||
return definition;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _deleteDefinition(TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
terrainHeightmapDelete(definition->height_map);
|
|
||||||
delete definition->_height_noise;
|
|
||||||
delete definition;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _copyDefinition(TerrainDefinition* source, TerrainDefinition* destination)
|
|
||||||
{
|
|
||||||
destination->height = source->height;
|
|
||||||
destination->scaling = source->scaling;
|
|
||||||
destination->shadow_smoothing = source->shadow_smoothing;
|
|
||||||
|
|
||||||
terrainHeightmapCopy(source->height_map, destination->height_map);
|
|
||||||
|
|
||||||
destination->water_height = source->water_height;
|
|
||||||
|
|
||||||
source->_height_noise->copy(destination->_height_noise);
|
|
||||||
|
|
||||||
_validateDefinition(destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _saveDefinition(PackStream* stream, TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
stream->write(&definition->height);
|
|
||||||
stream->write(&definition->scaling);
|
|
||||||
stream->write(&definition->shadow_smoothing);
|
|
||||||
terrainHeightmapSave(stream, definition->height_map);
|
|
||||||
stream->write(&definition->water_height);
|
|
||||||
definition->_height_noise->save(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _loadDefinition(PackStream* stream, TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
stream->read(&definition->height);
|
|
||||||
stream->read(&definition->scaling);
|
|
||||||
stream->read(&definition->shadow_smoothing);
|
|
||||||
terrainHeightmapLoad(stream, definition->height_map);
|
|
||||||
stream->read(&definition->water_height);
|
|
||||||
definition->_height_noise->load(stream);
|
|
||||||
|
|
||||||
_validateDefinition(definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardDefinition TerrainDefinitionClass = {
|
|
||||||
(FuncObjectCreate)_createDefinition,
|
|
||||||
(FuncObjectDelete)_deleteDefinition,
|
|
||||||
(FuncObjectCopy)_copyDefinition,
|
|
||||||
(FuncObjectValidate)_validateDefinition,
|
|
||||||
(FuncObjectSave)_saveDefinition,
|
|
||||||
(FuncObjectLoad)_loadDefinition
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************** Public tools ********************/
|
|
||||||
double terrainGetGridHeight(TerrainDefinition* definition, int x, int z, int with_painting)
|
|
||||||
{
|
|
||||||
double height;
|
|
||||||
|
|
||||||
if (!with_painting || !terrainHeightmapGetGridHeight(definition->height_map, x, z, &height))
|
|
||||||
{
|
|
||||||
height = definition->_height_noise->get2DTotal((double)x, (double)z);
|
|
||||||
}
|
|
||||||
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
double terrainGetInterpolatedHeight(TerrainDefinition* definition, double x, double z, int scaled, int with_painting)
|
|
||||||
{
|
|
||||||
double height;
|
|
||||||
x /= definition->scaling;
|
|
||||||
z /= definition->scaling;
|
|
||||||
|
|
||||||
if (!with_painting || !terrainHeightmapGetInterpolatedHeight(definition->height_map, x, z, &height))
|
|
||||||
{
|
|
||||||
height = definition->_height_noise->get2DTotal(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scaled)
|
|
||||||
{
|
|
||||||
return height * definition->height * definition->scaling;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HeightInfo terrainGetHeightInfo(TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
HeightInfo result;
|
|
||||||
|
|
||||||
result.min_height = definition->_min_height;
|
|
||||||
result.max_height = definition->_max_height;
|
|
||||||
/* TODO This is duplicated in ter_render.c (_realGetWaterHeight) */
|
|
||||||
result.base_height = definition->water_height * definition->height * definition->scaling;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
double terrainGetWaterHeight(TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
return definition->water_height * definition->height * definition->scaling;
|
|
||||||
}
|
|
|
@ -1,603 +0,0 @@
|
||||||
#include "private.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Terrain height map painting.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include "../tools/memory.h"
|
|
||||||
#include "../tools.h"
|
|
||||||
#include "PackStream.h"
|
|
||||||
#include "NoiseGenerator.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int xstart;
|
|
||||||
int xend;
|
|
||||||
double* height;
|
|
||||||
} HeightMapPixelGroup;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int z;
|
|
||||||
int pixel_groups_count;
|
|
||||||
HeightMapPixelGroup* pixel_groups;
|
|
||||||
} HeightMapRow;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int memsize;
|
|
||||||
int rows_count;
|
|
||||||
HeightMapRow* rows;
|
|
||||||
} HeightMapData;
|
|
||||||
|
|
||||||
struct TerrainHeightMap
|
|
||||||
{
|
|
||||||
TerrainDefinition* terrain;
|
|
||||||
HeightMapData merged_data;
|
|
||||||
HeightMapData brush_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void _initData(HeightMapData* data)
|
|
||||||
{
|
|
||||||
data->rows_count = 0;
|
|
||||||
data->rows = new HeightMapRow[1];
|
|
||||||
data->memsize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _clearData(HeightMapData* data)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
for (i = 0; i < data->rows_count; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
|
||||||
{
|
|
||||||
free(data->rows[i].pixel_groups[j].height);
|
|
||||||
}
|
|
||||||
free(data->rows[i].pixel_groups);
|
|
||||||
}
|
|
||||||
data->rows_count = 0;
|
|
||||||
delete[] data->rows;
|
|
||||||
data->rows = new HeightMapRow[1];
|
|
||||||
data->memsize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _deleteData(HeightMapData* data)
|
|
||||||
{
|
|
||||||
_clearData(data);
|
|
||||||
delete[] data->rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _copyData(HeightMapData* source, HeightMapData* destination)
|
|
||||||
{
|
|
||||||
int i, j, n;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
_clearData(destination);
|
|
||||||
|
|
||||||
destination->rows_count = source->rows_count;
|
|
||||||
if (destination->rows_count > 0)
|
|
||||||
{
|
|
||||||
size = sizeof(HeightMapRow) * destination->rows_count;
|
|
||||||
destination->rows = (HeightMapRow*)realloc(destination->rows, size);
|
|
||||||
destination->memsize += size;
|
|
||||||
for (i = 0; i < destination->rows_count; i++)
|
|
||||||
{
|
|
||||||
destination->rows[i].z = source->rows[i].z;
|
|
||||||
destination->rows[i].pixel_groups_count = source->rows[i].pixel_groups_count;
|
|
||||||
size = sizeof(HeightMapPixelGroup) * destination->rows[i].pixel_groups_count;
|
|
||||||
destination->rows[i].pixel_groups = (HeightMapPixelGroup*)malloc(size);
|
|
||||||
destination->memsize += size;
|
|
||||||
for (j = 0; j < destination->rows[i].pixel_groups_count; j++)
|
|
||||||
{
|
|
||||||
destination->rows[i].pixel_groups[j].xstart = source->rows[i].pixel_groups[j].xstart;
|
|
||||||
destination->rows[i].pixel_groups[j].xend = source->rows[i].pixel_groups[j].xend;
|
|
||||||
n = destination->rows[i].pixel_groups[j].xend - destination->rows[i].pixel_groups[j].xstart + 1;
|
|
||||||
size = sizeof(double) * n;
|
|
||||||
destination->rows[i].pixel_groups[j].height = (double*)malloc(size);
|
|
||||||
destination->memsize += size;
|
|
||||||
memcpy(destination->rows[i].pixel_groups[j].height, source->rows[i].pixel_groups[j].height, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _saveData(PackStream* stream, HeightMapData* data)
|
|
||||||
{
|
|
||||||
int i, j, k;
|
|
||||||
stream->write(&data->rows_count);
|
|
||||||
for (i = 0; i < data->rows_count; i++)
|
|
||||||
{
|
|
||||||
stream->write(&data->rows[i].z);
|
|
||||||
stream->write(&data->rows[i].pixel_groups_count);
|
|
||||||
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
|
||||||
{
|
|
||||||
stream->write(&data->rows[i].pixel_groups[j].xstart);
|
|
||||||
stream->write(&data->rows[i].pixel_groups[j].xend);
|
|
||||||
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart; k++)
|
|
||||||
{
|
|
||||||
stream->write(&data->rows[i].pixel_groups[j].height[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _loadData(PackStream* stream, HeightMapData* data)
|
|
||||||
{
|
|
||||||
int i, j, k, n;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
_clearData(data);
|
|
||||||
|
|
||||||
stream->read(&data->rows_count);
|
|
||||||
if (data->rows_count > 0)
|
|
||||||
{
|
|
||||||
size = sizeof(HeightMapRow) * data->rows_count;
|
|
||||||
data->rows = (HeightMapRow*)realloc(data->rows, size);
|
|
||||||
data->memsize += size;
|
|
||||||
for (i = 0; i < data->rows_count; i++)
|
|
||||||
{
|
|
||||||
stream->read(&data->rows[i].z);
|
|
||||||
stream->read(&data->rows[i].pixel_groups_count);
|
|
||||||
size = sizeof(HeightMapPixelGroup) * data->rows[i].pixel_groups_count;
|
|
||||||
data->rows[i].pixel_groups = (HeightMapPixelGroup*)malloc(size);
|
|
||||||
data->memsize += size;
|
|
||||||
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
|
||||||
{
|
|
||||||
stream->read(&data->rows[i].pixel_groups[j].xstart);
|
|
||||||
stream->read(&data->rows[i].pixel_groups[j].xend);
|
|
||||||
n = data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart;
|
|
||||||
size = sizeof(double) * n;
|
|
||||||
data->rows[i].pixel_groups[j].height = (double*)malloc(size);
|
|
||||||
data->memsize += size;
|
|
||||||
for (k = 0; k < n; k++)
|
|
||||||
{
|
|
||||||
stream->read(&data->rows[i].pixel_groups[j].height[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get a pointer to the data in a heightmap, to a certain location.
|
|
||||||
* If the location is not already in the heightmap, it is initialized with the terrain height.
|
|
||||||
* This method will grow the heightmap as necessary (if 'grow' is set to false, NULL will be returned on missing pixels).
|
|
||||||
*/
|
|
||||||
static double* _getDataPointer(HeightMapData* data, int x, int z, HeightMapData* fallback, TerrainDefinition* terrain, int grow)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Find row */
|
|
||||||
/* TODO Dichotomic search */
|
|
||||||
HeightMapRow* row;
|
|
||||||
i = 0;
|
|
||||||
while (i < data->rows_count && data->rows[i].z < z)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (i < data->rows_count && data->rows[i].z == z)
|
|
||||||
{
|
|
||||||
row = data->rows + i;
|
|
||||||
}
|
|
||||||
else if (grow)
|
|
||||||
{
|
|
||||||
row = (HeightMapRow*)naiveArrayInsert((void**)&data->rows, sizeof(HeightMapRow), data->rows_count, i);
|
|
||||||
|
|
||||||
row->z = z;
|
|
||||||
row->pixel_groups_count = 0;
|
|
||||||
row->pixel_groups = (HeightMapPixelGroup*)malloc(1);
|
|
||||||
|
|
||||||
data->rows_count++;
|
|
||||||
data->memsize += sizeof(HeightMapRow);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/* Check rows */
|
|
||||||
for (i = 1; i < data->rows_count; i++)
|
|
||||||
{
|
|
||||||
assert(data->rows[i].z > data->rows[i - 1].z);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Find pixel group */
|
|
||||||
HeightMapPixelGroup* pixel_group = NULL;
|
|
||||||
for (i = 0; i < row->pixel_groups_count; i++)
|
|
||||||
{
|
|
||||||
if (x < row->pixel_groups[i].xstart - 1)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (x <= row->pixel_groups[i].xend + 1)
|
|
||||||
{
|
|
||||||
if (x == row->pixel_groups[i].xend + 1 && i < row->pixel_groups_count - 1 && x == row->pixel_groups[i + 1].xstart)
|
|
||||||
{
|
|
||||||
/* Choose next group if it already includes the pixel */
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
pixel_group = row->pixel_groups + i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Alter pixel group */
|
|
||||||
double* pixel;
|
|
||||||
int added = 1;
|
|
||||||
if (!pixel_group)
|
|
||||||
{
|
|
||||||
if (!grow)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the pixel group with one pixel */
|
|
||||||
pixel_group = (HeightMapPixelGroup*)naiveArrayInsert((void**)&row->pixel_groups, sizeof(HeightMapPixelGroup), row->pixel_groups_count, i);
|
|
||||||
|
|
||||||
pixel_group->xstart = x;
|
|
||||||
pixel_group->xend = x;
|
|
||||||
pixel_group->height = (double*)malloc(sizeof(double));
|
|
||||||
|
|
||||||
pixel = pixel_group->height;
|
|
||||||
|
|
||||||
row->pixel_groups_count++;
|
|
||||||
data->memsize += sizeof(HeightMapPixelGroup) + sizeof(double);
|
|
||||||
}
|
|
||||||
else if (x == pixel_group->xstart - 1)
|
|
||||||
{
|
|
||||||
if (!grow)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extend the rowgroup at start */
|
|
||||||
pixel_group->xstart--;
|
|
||||||
pixel = (double*)naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, 0);
|
|
||||||
data->memsize += sizeof(double);
|
|
||||||
}
|
|
||||||
else if (x == pixel_group->xend + 1)
|
|
||||||
{
|
|
||||||
if (!grow)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extend the rowgroup at end */
|
|
||||||
pixel_group->xend++;
|
|
||||||
pixel = (double*)naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, pixel_group->xend - pixel_group->xstart);
|
|
||||||
data->memsize += sizeof(double);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(x >= pixel_group->xstart);
|
|
||||||
assert(x <= pixel_group->xend);
|
|
||||||
pixel = pixel_group->height + x - pixel_group->xstart;
|
|
||||||
added = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/* Check pixel groups */
|
|
||||||
for (i = 0; i < row->pixel_groups_count; i++)
|
|
||||||
{
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
assert(row->pixel_groups[i].xstart > row->pixel_groups[i - 1].xend);
|
|
||||||
}
|
|
||||||
if (i < row->pixel_groups_count - 1)
|
|
||||||
{
|
|
||||||
assert(row->pixel_groups[i].xend < row->pixel_groups[i + 1].xstart);
|
|
||||||
}
|
|
||||||
assert(row->pixel_groups[i].xend >= row->pixel_groups[i].xstart);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Reset pixel if it had been added */
|
|
||||||
if (added && (terrain || fallback))
|
|
||||||
{
|
|
||||||
if (fallback)
|
|
||||||
{
|
|
||||||
double* dpointer = _getDataPointer(fallback, x, z, NULL, terrain, 0);
|
|
||||||
if (dpointer)
|
|
||||||
{
|
|
||||||
*pixel = *dpointer;
|
|
||||||
}
|
|
||||||
else if (terrain)
|
|
||||||
{
|
|
||||||
*pixel = terrainGetGridHeight(terrain, x, z, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (terrain)
|
|
||||||
{
|
|
||||||
*pixel = terrainGetGridHeight(terrain, x, z, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
TerrainHeightMap* terrainHeightMapCreate(TerrainDefinition* terrain)
|
|
||||||
{
|
|
||||||
TerrainHeightMap* result;
|
|
||||||
|
|
||||||
result = new TerrainHeightMap;
|
|
||||||
result->terrain = terrain;
|
|
||||||
_initData(&result->merged_data);
|
|
||||||
_initData(&result->brush_data);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainHeightmapDelete(TerrainHeightMap* heightmap)
|
|
||||||
{
|
|
||||||
_deleteData(&heightmap->merged_data);
|
|
||||||
_deleteData(&heightmap->brush_data);
|
|
||||||
delete heightmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainHeightmapCopy(TerrainHeightMap* source, TerrainHeightMap* destination)
|
|
||||||
{
|
|
||||||
destination->terrain = source->terrain;
|
|
||||||
|
|
||||||
_copyData(&source->merged_data, &destination->merged_data);
|
|
||||||
_clearData(&destination->brush_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainHeightmapSave(PackStream* stream, TerrainHeightMap* heightmap)
|
|
||||||
{
|
|
||||||
_saveData(stream, &heightmap->merged_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainHeightmapLoad(PackStream* stream, TerrainHeightMap* heightmap)
|
|
||||||
{
|
|
||||||
_loadData(stream, &heightmap->merged_data);
|
|
||||||
_clearData(&heightmap->brush_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
int terrainHeightmapGetGridHeight(TerrainHeightMap* heightmap, int x, int z, double* result)
|
|
||||||
{
|
|
||||||
double* dpointer;
|
|
||||||
dpointer = _getDataPointer(&heightmap->brush_data, x, z, NULL, NULL, 0);
|
|
||||||
if (dpointer)
|
|
||||||
{
|
|
||||||
*result = *dpointer;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dpointer = _getDataPointer(&heightmap->merged_data, x, z, NULL, NULL, 0);
|
|
||||||
if (dpointer)
|
|
||||||
{
|
|
||||||
*result = *dpointer;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int terrainHeightmapGetInterpolatedHeight(TerrainHeightMap* heightmap, double x, double z, double* result)
|
|
||||||
{
|
|
||||||
int ix, iz;
|
|
||||||
int xlow;
|
|
||||||
int zlow;
|
|
||||||
|
|
||||||
xlow = floor(x);
|
|
||||||
zlow = floor(z);
|
|
||||||
|
|
||||||
int hit = 0;
|
|
||||||
for (ix = xlow - 1; ix <= xlow + 2 && !hit; ix++)
|
|
||||||
{
|
|
||||||
for (iz = zlow - 1; iz <= zlow + 2 && !hit; iz++)
|
|
||||||
{
|
|
||||||
if (_getDataPointer(&heightmap->brush_data, x, z, NULL, NULL, 0) || _getDataPointer(&heightmap->merged_data, x, z, NULL, NULL, 0))
|
|
||||||
{
|
|
||||||
hit = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hit && result)
|
|
||||||
{
|
|
||||||
double stencil[16];
|
|
||||||
double value;
|
|
||||||
for (ix = xlow - 1; ix <= xlow + 2; ix++)
|
|
||||||
{
|
|
||||||
for (iz = zlow - 1; iz <= zlow + 2; iz++)
|
|
||||||
{
|
|
||||||
if (!terrainHeightmapGetGridHeight(heightmap, ix, iz, &value))
|
|
||||||
{
|
|
||||||
value = terrainGetGridHeight(heightmap->terrain, ix, iz, 0);
|
|
||||||
}
|
|
||||||
stencil[(iz - (zlow - 1)) * 4 + ix - (xlow - 1)] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*result = toolsBicubicInterpolate(stencil, x - (double)xlow, z - (double)zlow);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline IntegerRect _getBrushRect(TerrainBrush* brush)
|
|
||||||
{
|
|
||||||
IntegerRect result;
|
|
||||||
double s = brush->smoothed_size + brush->hard_radius;
|
|
||||||
|
|
||||||
result.xstart = (int)floor(brush->relative_x - s);
|
|
||||||
result.xend = (int)ceil(brush->relative_x + s);
|
|
||||||
result.zstart = (int)floor(brush->relative_z - s);
|
|
||||||
result.zend = (int)ceil(brush->relative_z + s);
|
|
||||||
|
|
||||||
result.xsize = result.xend - result.xstart + 1;
|
|
||||||
result.zsize = result.zend - result.zstart + 1;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int _isInRect(IntegerRect rect, int x, int z)
|
|
||||||
{
|
|
||||||
return (x >= rect.xstart && x <= rect.xend && z >= rect.zstart && z <= rect.zend);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t terrainGetMemoryStats(TerrainDefinition* definition)
|
|
||||||
{
|
|
||||||
return definition->height_map->merged_data.memsize + definition->height_map->brush_data.memsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
int terrainIsPainted(TerrainHeightMap* heightmap, int x, int z)
|
|
||||||
{
|
|
||||||
return _getDataPointer(&heightmap->brush_data, x, z, NULL, NULL, 0) || _getDataPointer(&heightmap->merged_data, x, z, NULL, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainClearPainting(TerrainHeightMap* heightmap)
|
|
||||||
{
|
|
||||||
_clearData(&heightmap->merged_data);
|
|
||||||
_clearData(&heightmap->brush_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef double (*BrushCallback)(TerrainHeightMap* heightmap, TerrainBrush* brush, double x, double z, double basevalue, double influence, double force, void* data);
|
|
||||||
|
|
||||||
static inline void _applyBrush(TerrainHeightMap* heightmap, TerrainBrush* brush, double force, void* data, BrushCallback callback)
|
|
||||||
{
|
|
||||||
IntegerRect brush_rect = _getBrushRect(brush);
|
|
||||||
int x, z;
|
|
||||||
double dx, dz, distance, influence;
|
|
||||||
|
|
||||||
force /= heightmap->terrain->height;
|
|
||||||
|
|
||||||
for (x = brush_rect.xstart; x <= brush_rect.xend; x++)
|
|
||||||
{
|
|
||||||
dx = (double)x;
|
|
||||||
for (z = brush_rect.zstart; z <= brush_rect.zend; z++)
|
|
||||||
{
|
|
||||||
dz = (double)z;
|
|
||||||
distance = sqrt((brush->relative_x - dx) * (brush->relative_x - dx) + (brush->relative_z - dz) * (brush->relative_z - dz));
|
|
||||||
|
|
||||||
if (distance > brush->hard_radius)
|
|
||||||
{
|
|
||||||
if (distance <= brush->hard_radius + brush->smoothed_size)
|
|
||||||
{
|
|
||||||
influence = (1.0 - (distance - brush->hard_radius) / brush->smoothed_size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
influence = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
double* dpointer = _getDataPointer(&heightmap->brush_data, x, z, &heightmap->merged_data, heightmap->terrain, 1);
|
|
||||||
*dpointer = callback(heightmap, brush, dx, dz, *dpointer, influence, force, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static double _applyBrushElevation(TerrainHeightMap* heightmap, TerrainBrush* brush, double x, double z, double basevalue, double influence, double force, void* data)
|
|
||||||
{
|
|
||||||
UNUSED(heightmap);
|
|
||||||
UNUSED(brush);
|
|
||||||
UNUSED(data);
|
|
||||||
UNUSED(x);
|
|
||||||
UNUSED(z);
|
|
||||||
|
|
||||||
return basevalue + influence * force;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainBrushElevation(TerrainHeightMap* heightmap, TerrainBrush* brush, double value)
|
|
||||||
{
|
|
||||||
_applyBrush(heightmap, brush, value, NULL, _applyBrushElevation);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double _applyBrushFlatten(TerrainHeightMap* heightmap, TerrainBrush* brush, double, double, double basevalue, double influence, double force, void* data)
|
|
||||||
{
|
|
||||||
UNUSED(heightmap);
|
|
||||||
UNUSED(brush);
|
|
||||||
UNUSED(data);
|
|
||||||
|
|
||||||
double ideal = *((double*)data);
|
|
||||||
return basevalue + (ideal - basevalue) * influence * force;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainBrushFlatten(TerrainHeightMap* heightmap, TerrainBrush* brush, double height, double force)
|
|
||||||
{
|
|
||||||
_applyBrush(heightmap, brush, force, &height, _applyBrushFlatten);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double _applyBrushSmooth(TerrainHeightMap* heightmap, TerrainBrush* brush, double x, double z, double basevalue, double influence, double force, void* data)
|
|
||||||
{
|
|
||||||
UNUSED(data);
|
|
||||||
|
|
||||||
double ideal, factor;
|
|
||||||
ideal = terrainGetInterpolatedHeight(heightmap->terrain, (x + brush->total_radius * 0.5) * heightmap->terrain->scaling, z * heightmap->terrain->scaling, 0, 1);
|
|
||||||
ideal += terrainGetInterpolatedHeight(heightmap->terrain, (x - brush->total_radius * 0.5) * heightmap->terrain->scaling, z * heightmap->terrain->scaling, 0, 1);
|
|
||||||
ideal += terrainGetInterpolatedHeight(heightmap->terrain, x * heightmap->terrain->scaling, (z - brush->total_radius * 0.5) * heightmap->terrain->scaling, 0, 1);
|
|
||||||
ideal += terrainGetInterpolatedHeight(heightmap->terrain, x * heightmap->terrain->scaling, (z + brush->total_radius * 0.5) * heightmap->terrain->scaling, 0, 1);
|
|
||||||
ideal /= 4.0;
|
|
||||||
factor = influence * force;
|
|
||||||
if (factor > 1.0)
|
|
||||||
{
|
|
||||||
factor = 0.0;
|
|
||||||
}
|
|
||||||
return basevalue + (ideal - basevalue) * factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainBrushSmooth(TerrainHeightMap* heightmap, TerrainBrush* brush, double value)
|
|
||||||
{
|
|
||||||
_applyBrush(heightmap, brush, value, NULL, _applyBrushSmooth);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double _applyBrushAddNoise(TerrainHeightMap*, TerrainBrush* brush, double x, double z, double basevalue, double influence, double force, void* data)
|
|
||||||
{
|
|
||||||
NoiseGenerator* noise = (NoiseGenerator*)data;
|
|
||||||
|
|
||||||
return basevalue + noise->get2DTotal(x / brush->total_radius, z / brush->total_radius) * influence * force * brush->total_radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainBrushAddNoise(TerrainHeightMap* heightmap, TerrainBrush* brush, NoiseGenerator* generator, double value)
|
|
||||||
{
|
|
||||||
_applyBrush(heightmap, brush, value, generator, _applyBrushAddNoise);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double _applyBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double x, double z, double basevalue, double influence, double force, void* data)
|
|
||||||
{
|
|
||||||
UNUSED(brush);
|
|
||||||
UNUSED(data);
|
|
||||||
|
|
||||||
double ideal = terrainGetInterpolatedHeight(heightmap->terrain, x * heightmap->terrain->scaling, z * heightmap->terrain->scaling, 0, 0);
|
|
||||||
return basevalue + (ideal - basevalue) * influence * force;
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainBrushReset(TerrainHeightMap* heightmap, TerrainBrush* brush, double value)
|
|
||||||
{
|
|
||||||
_applyBrush(heightmap, brush, value, NULL, _applyBrushReset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void terrainEndBrushStroke(TerrainHeightMap* heightmap)
|
|
||||||
{
|
|
||||||
int i, j, k;
|
|
||||||
HeightMapData* data = &heightmap->brush_data;
|
|
||||||
|
|
||||||
for (i = 0; i < data->rows_count; i++)
|
|
||||||
{
|
|
||||||
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
|
||||||
{
|
|
||||||
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart + 1; k++)
|
|
||||||
{
|
|
||||||
double* dpointer = _getDataPointer(&heightmap->merged_data, data->rows[i].pixel_groups[j].xstart + k, data->rows[i].z, NULL, NULL, 1);
|
|
||||||
*dpointer = data->rows[i].pixel_groups[j].height[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_clearData(&heightmap->brush_data);
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
#include "private.h"
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include "NoiseGenerator.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Terrain presets.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void terrainAutoPreset(TerrainDefinition* definition, TerrainPreset preset)
|
|
||||||
{
|
|
||||||
int resolution = 8;
|
|
||||||
switch (preset)
|
|
||||||
{
|
|
||||||
case TERRAIN_PRESET_STANDARD:
|
|
||||||
definition->_height_noise->randomizeOffsets();
|
|
||||||
definition->_height_noise->clearLevels();
|
|
||||||
definition->_height_noise->addLevelSimple(pow(2.0, resolution + 1), -1.0, 1.0);
|
|
||||||
definition->_height_noise->addLevelsSimple(resolution - 2, pow(2.0, resolution - 1), -0.7, 0.7, 0.5);
|
|
||||||
definition->_height_noise->normalizeAmplitude(-1.0, 1.0, 0);
|
|
||||||
definition->_height_noise->setFunctionParams(NOISE_FUNCTION_SIMPLEX, 0.0, 0.0);
|
|
||||||
definition->scaling = 1.0;
|
|
||||||
definition->height = 30.0;
|
|
||||||
definition->shadow_smoothing = 0.03;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
terrainClearPainting(definition->height_map);
|
|
||||||
|
|
||||||
TerrainDefinitionClass.validate(definition);
|
|
||||||
}
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#include "../tools.h"
|
#include "../tools.h"
|
||||||
#include "../renderer.h"
|
#include "../renderer.h"
|
||||||
#include "textures/public.h"
|
#include "textures/public.h"
|
||||||
|
#include "TerrainDefinition.h"
|
||||||
|
|
||||||
/******************** Binding ********************/
|
/******************** Binding ********************/
|
||||||
static double _fakeGetHeight(Renderer* renderer, double x, double z, int with_painting)
|
static double _fakeGetHeight(Renderer* renderer, double x, double z, int with_painting)
|
||||||
|
@ -19,7 +20,7 @@ static double _fakeGetHeight(Renderer* renderer, double x, double z, int with_pa
|
||||||
|
|
||||||
static double _realGetHeight(Renderer* renderer, double x, double z, int with_painting)
|
static double _realGetHeight(Renderer* renderer, double x, double z, int with_painting)
|
||||||
{
|
{
|
||||||
return terrainGetInterpolatedHeight(renderer->terrain->definition, x, z, 1, with_painting);
|
return renderer->terrain->definition->getInterpolatedHeight(x, z, 1, with_painting);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TerrainResult _fakeGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures)
|
static TerrainResult _fakeGetResult(Renderer* renderer, double x, double z, int with_painting, int with_textures)
|
||||||
|
@ -313,7 +314,7 @@ static TerrainRenderer* _createRenderer()
|
||||||
TerrainRenderer* result;
|
TerrainRenderer* result;
|
||||||
|
|
||||||
result = new TerrainRenderer;
|
result = new TerrainRenderer;
|
||||||
result->definition = (TerrainDefinition*)TerrainDefinitionClass.create();
|
result->definition = new TerrainDefinition(NULL);
|
||||||
|
|
||||||
result->castRay = _fakeCastRay;
|
result->castRay = _fakeCastRay;
|
||||||
result->getHeight = _fakeGetHeight;
|
result->getHeight = _fakeGetHeight;
|
||||||
|
@ -326,13 +327,13 @@ static TerrainRenderer* _createRenderer()
|
||||||
|
|
||||||
static void _deleteRenderer(TerrainRenderer* renderer)
|
static void _deleteRenderer(TerrainRenderer* renderer)
|
||||||
{
|
{
|
||||||
TerrainDefinitionClass.destroy(renderer->definition);
|
delete renderer->definition;
|
||||||
delete renderer;
|
delete renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _bindRenderer(Renderer* renderer, TerrainDefinition* definition)
|
static void _bindRenderer(Renderer* renderer, TerrainDefinition* definition)
|
||||||
{
|
{
|
||||||
TerrainDefinitionClass.copy(definition, renderer->terrain->definition);
|
definition->copy(renderer->terrain->definition);
|
||||||
|
|
||||||
renderer->terrain->castRay = _realCastRay;
|
renderer->terrain->castRay = _realCastRay;
|
||||||
renderer->terrain->getHeight = _realGetHeight;
|
renderer->terrain->getHeight = _realGetHeight;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "tex_preview.h"
|
#include "tex_preview.h"
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "TexturesDefinition.h"
|
#include "TexturesDefinition.h"
|
||||||
|
|
||||||
void TexturesPreviewLayerCoverage_bind(Renderer* renderer, TexturesDefinition* definition)
|
void TexturesPreviewLayerCoverage_bind(Renderer* renderer, TexturesDefinition* definition)
|
||||||
{
|
{
|
||||||
TerrainRendererClass.bind(renderer, Scenery::getCurrent()->getTerrain());
|
TerrainRendererClass.bind(renderer, RenderingScenery::getCurrent()->getTerrain());
|
||||||
TexturesRendererClass.bind(renderer, definition);
|
TexturesRendererClass.bind(renderer, definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ Color TexturesPreviewLayerLook_getColor(Renderer* renderer, double x, double y,
|
||||||
|
|
||||||
void TexturesPreviewCumul_bind(Renderer* renderer, TexturesDefinition* definition)
|
void TexturesPreviewCumul_bind(Renderer* renderer, TexturesDefinition* definition)
|
||||||
{
|
{
|
||||||
TerrainRendererClass.bind(renderer, Scenery::getCurrent()->getTerrain());
|
TerrainRendererClass.bind(renderer, RenderingScenery::getCurrent()->getTerrain());
|
||||||
TexturesRendererClass.bind(renderer, definition);
|
TexturesRendererClass.bind(renderer, definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,18 +20,6 @@ double toolsCubicInterpolate(double stencil[4], double x)
|
||||||
return _cubicInterpolate(stencil, x);
|
return _cubicInterpolate(stencil, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
double toolsBicubicInterpolate(double stencil[16], double x, double y)
|
|
||||||
{
|
|
||||||
double buf_cubic_y[4];
|
|
||||||
|
|
||||||
buf_cubic_y[0] = _cubicInterpolate(stencil, x);
|
|
||||||
buf_cubic_y[1] = _cubicInterpolate(stencil + 4, x);
|
|
||||||
buf_cubic_y[2] = _cubicInterpolate(stencil + 8, x);
|
|
||||||
buf_cubic_y[3] = _cubicInterpolate(stencil + 12, x);
|
|
||||||
|
|
||||||
return _cubicInterpolate(buf_cubic_y, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void toolsFloat2DMapCopy(double* src, double* dest, int src_xstart, int src_ystart, int dest_xstart, int dest_ystart, int xsize, int ysize, int src_xstep, int src_ystep, int dest_xstep, int dest_ystep)
|
void toolsFloat2DMapCopy(double* src, double* dest, int src_xstart, int src_ystart, int dest_xstart, int dest_ystart, int xsize, int ysize, int src_xstep, int src_ystep, int dest_xstep, int dest_ystep)
|
||||||
{
|
{
|
||||||
/* TODO Optimize with memcpy if src_xstep == dest_xstep == 1 */
|
/* TODO Optimize with memcpy if src_xstep == dest_xstep == 1 */
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#define UNUSED(_x_) ((void)(_x_))
|
#define UNUSED(_x_) ((void)(_x_))
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT double toolsRandom();
|
RENDERINGSHARED_EXPORT double toolsRandom();
|
||||||
RENDERINGSHARED_EXPORT double toolsCubicInterpolate(double stencil[4], double x);
|
|
||||||
RENDERINGSHARED_EXPORT double toolsBicubicInterpolate(double stencil[16], double x, double y);
|
|
||||||
RENDERINGSHARED_EXPORT void toolsFloat2DMapCopy(double* src, double* dest, int src_xstart, int src_ystart, int dest_xstart, int dest_ystart, int xsize, int ysize, int src_xstep, int src_ystep, int dest_xstep, int dest_ystep);
|
RENDERINGSHARED_EXPORT void toolsFloat2DMapCopy(double* src, double* dest, int src_xstart, int src_ystart, int dest_xstart, int dest_ystart, int xsize, int ysize, int src_xstep, int src_ystep, int dest_xstep, int dest_ystep);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,22 +4,6 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
void* naiveArrayInsert(void** array, size_t item_size, int item_count, int location)
|
|
||||||
{
|
|
||||||
char** barray = (char**)array;
|
|
||||||
|
|
||||||
assert(location >= 0);
|
|
||||||
assert(location <= item_count);
|
|
||||||
|
|
||||||
*barray = (char*)realloc(*barray, item_size * (item_count + 1));
|
|
||||||
if (location < item_count)
|
|
||||||
{
|
|
||||||
memmove(*barray + item_size * (location + 1), *barray + item_size * location, item_size * (item_count - location));
|
|
||||||
}
|
|
||||||
|
|
||||||
return *barray + item_size * location;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* memory2dRealloc(char* data, int datasize, int oldxsize, int oldysize, int newxsize, int newysize, int xoffset, int yoffset)
|
char* memory2dRealloc(char* data, int datasize, int oldxsize, int oldysize, int newxsize, int newysize, int xoffset, int yoffset)
|
||||||
{
|
{
|
||||||
int xstart, xend, xlen;
|
int xstart, xend, xlen;
|
||||||
|
|
|
@ -8,6 +8,5 @@
|
||||||
#include "../rendering_global.h"
|
#include "../rendering_global.h"
|
||||||
|
|
||||||
RENDERINGSHARED_EXPORT char* memory2dRealloc(char* data, int datasize, int oldxsize, int oldysize, int newxsize, int newysize, int xoffset, int yoffset);
|
RENDERINGSHARED_EXPORT char* memory2dRealloc(char* data, int datasize, int oldxsize, int oldysize, int newxsize, int newysize, int xoffset, int yoffset);
|
||||||
RENDERINGSHARED_EXPORT void* naiveArrayInsert(void** array, size_t item_size, int item_count, int location);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
20
src/system/Memory.cpp
Normal file
20
src/system/Memory.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "Memory.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
void* Memory::naiveArrayInsert(void** array, unsigned long item_size, int item_count, int location)
|
||||||
|
{
|
||||||
|
char** barray = (char**)array;
|
||||||
|
|
||||||
|
assert(location >= 0);
|
||||||
|
assert(location <= item_count);
|
||||||
|
|
||||||
|
*barray = (char*)realloc(*barray, item_size * (item_count + 1));
|
||||||
|
if (location < item_count)
|
||||||
|
{
|
||||||
|
memmove(*barray + item_size * (location + 1), *barray + item_size * location, item_size * (item_count - location));
|
||||||
|
}
|
||||||
|
|
||||||
|
return *barray + item_size * location;
|
||||||
|
}
|
18
src/system/Memory.h
Normal file
18
src/system/Memory.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef MEMORY_H
|
||||||
|
#define MEMORY_H
|
||||||
|
|
||||||
|
#include "system_global.h"
|
||||||
|
|
||||||
|
namespace paysages {
|
||||||
|
namespace system {
|
||||||
|
|
||||||
|
class SYSTEMSHARED_EXPORT Memory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void* naiveArrayInsert(void** array, unsigned long item_size, int item_count, int location);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MEMORY_H
|
|
@ -19,7 +19,8 @@ SOURCES += \
|
||||||
Mutex.cpp \
|
Mutex.cpp \
|
||||||
System.cpp \
|
System.cpp \
|
||||||
PackStream.cpp \
|
PackStream.cpp \
|
||||||
RandomGenerator.cpp
|
RandomGenerator.cpp \
|
||||||
|
Memory.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
system_global.h \
|
system_global.h \
|
||||||
|
@ -28,7 +29,8 @@ HEADERS += \
|
||||||
Mutex.h \
|
Mutex.h \
|
||||||
System.h \
|
System.h \
|
||||||
PackStream.h \
|
PackStream.h \
|
||||||
RandomGenerator.h
|
RandomGenerator.h \
|
||||||
|
Memory.h
|
||||||
|
|
||||||
unix:!symbian {
|
unix:!symbian {
|
||||||
maemo5 {
|
maemo5 {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "SoftwareRenderer.h"
|
#include "SoftwareRenderer.h"
|
||||||
#include "AtmosphereDefinition.h"
|
#include "AtmosphereDefinition.h"
|
||||||
#include "AtmosphereRenderer.h"
|
#include "AtmosphereRenderer.h"
|
||||||
#include "Scenery.h"
|
#include "RenderingScenery.h"
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
|
|
||||||
#define OUTPUT_WIDTH 400
|
#define OUTPUT_WIDTH 400
|
||||||
|
@ -44,7 +44,7 @@ TEST(Bruneton, AerialPerspective1)
|
||||||
|
|
||||||
TEST(Bruneton, AerialPerspective2)
|
TEST(Bruneton, AerialPerspective2)
|
||||||
{
|
{
|
||||||
AtmosphereDefinition* atmo = Scenery::getCurrent()->getAtmosphere();
|
AtmosphereDefinition* atmo = RenderingScenery::getCurrent()->getAtmosphere();
|
||||||
atmo->hour = 6;
|
atmo->hour = 6;
|
||||||
atmo->minute = 30;
|
atmo->minute = 30;
|
||||||
atmo->validate();
|
atmo->validate();
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "NoiseGenerator.h"
|
#include "NoiseGenerator.h"
|
||||||
#include "terrain/public.h"
|
#include "TerrainDefinition.h"
|
||||||
|
#include "TerrainHeightMap.h"
|
||||||
|
#include "TerrainHeightMapBrush.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)
|
||||||
|
@ -25,7 +27,7 @@ static double _noise3dMock(double x, double, double)
|
||||||
class TerrainPainting_Test : public BaseTestCase {
|
class TerrainPainting_Test : public BaseTestCase {
|
||||||
protected:
|
protected:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
|
terrain = new TerrainDefinition(NULL);
|
||||||
terrain->height = 3.0;
|
terrain->height = 3.0;
|
||||||
terrain->scaling = 1.0;
|
terrain->scaling = 1.0;
|
||||||
terrain->_height_noise->clearLevels();
|
terrain->_height_noise->clearLevels();
|
||||||
|
@ -36,7 +38,7 @@ protected:
|
||||||
|
|
||||||
virtual void TearDown()
|
virtual void TearDown()
|
||||||
{
|
{
|
||||||
TerrainDefinitionClass.destroy(terrain);
|
delete terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerrainDefinition* terrain;
|
TerrainDefinition* terrain;
|
||||||
|
@ -45,63 +47,63 @@ protected:
|
||||||
TEST_F(TerrainPainting_Test, grid)
|
TEST_F(TerrainPainting_Test, grid)
|
||||||
{
|
{
|
||||||
/* Test base grid */
|
/* Test base grid */
|
||||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 0, 0));
|
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(0, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 1, 0));
|
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(0, 1, 0));
|
||||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 0, 1));
|
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(0, 0, 1));
|
||||||
EXPECT_DOUBLE_EQ(sin(1.0 * X_FACTOR), terrainGetGridHeight(terrain, 1, 0, 0));
|
EXPECT_DOUBLE_EQ(sin(1.0 * X_FACTOR), terrain->getGridHeight(1, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(sin(2.0 * X_FACTOR), terrainGetGridHeight(terrain, 2, 0, 0));
|
EXPECT_DOUBLE_EQ(sin(2.0 * X_FACTOR), terrain->getGridHeight(2, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(sin(3.0 * X_FACTOR), terrainGetGridHeight(terrain, 3, 0, 0));
|
EXPECT_DOUBLE_EQ(sin(3.0 * X_FACTOR), terrain->getGridHeight(3, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrainGetGridHeight(terrain, 4, 0, 0));
|
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrain->getGridHeight(4, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(1.0, terrainGetGridHeight(terrain, 5, 0, 0));
|
EXPECT_DOUBLE_EQ(1.0, terrain->getGridHeight(5, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrainGetGridHeight(terrain, 6, 0, 0));
|
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrain->getGridHeight(6, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(-sin(1.0 * X_FACTOR), terrainGetGridHeight(terrain, -1, 0, 0));
|
EXPECT_DOUBLE_EQ(-sin(1.0 * X_FACTOR), terrain->getGridHeight(-1, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 10, 0, 0));
|
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(10, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(-1.0, terrainGetGridHeight(terrain, 15, 0, 0));
|
EXPECT_DOUBLE_EQ(-1.0, terrain->getGridHeight(15, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 20, 0, 0));
|
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(20, 0, 0));
|
||||||
EXPECT_DOUBLE_EQ(-1.0, terrainGetGridHeight(terrain, -5, 0, 0));
|
EXPECT_DOUBLE_EQ(-1.0, terrain->getGridHeight(-5, 0, 0));
|
||||||
|
|
||||||
/* Test interpolated result */
|
/* Test interpolated result */
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0.0, 0.0, 0, 0), 0.0);
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(0.0, 0.0, 0, 0), 0.0);
|
||||||
EXPECT_DOUBLE_IN_RANGE(terrainGetInterpolatedHeight(terrain, 0.5, 0.0, 0, 0), 0.1564, 0.1566);
|
EXPECT_DOUBLE_IN_RANGE(terrain->getInterpolatedHeight(0.5, 0.0, 0, 0), 0.1564, 0.1566);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 1.0, 0.0, 0, 0), sin(1.0 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(1.0, 0.0, 0, 0), sin(1.0 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0.0, 0.0, 1, 0), 0.0);
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(0.0, 0.0, 1, 0), 0.0);
|
||||||
EXPECT_DOUBLE_IN_RANGE(terrainGetInterpolatedHeight(terrain, 0.5, 0.0, 1, 0), 3.0 * 0.1564, 3.0 * 0.1566);
|
EXPECT_DOUBLE_IN_RANGE(terrain->getInterpolatedHeight(0.5, 0.0, 1, 0), 3.0 * 0.1564, 3.0 * 0.1566);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 1.0, 0.0, 1, 0), 3.0 * sin(1.0 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(1.0, 0.0, 1, 0), 3.0 * sin(1.0 * X_FACTOR));
|
||||||
|
|
||||||
/* Test scaling */
|
/* Test scaling */
|
||||||
terrain->scaling = 2.0;
|
terrain->scaling = 2.0;
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 0, 0, 0), 0.0);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(0, 0, 0), 0.0);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 1, 0, 0), sin(1.0 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(1, 0, 0), sin(1.0 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 2, 0, 0), sin(2.0 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(2, 0, 0), sin(2.0 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 3, 0, 0), sin(3.0 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(3, 0, 0), sin(3.0 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0, 0, 0, 0), 0.0);
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(0, 0, 0, 0), 0.0);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 1, 0, 0, 0), sin(0.5 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(1, 0, 0, 0), sin(0.5 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 2, 0, 0, 0), sin(1.0 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(2, 0, 0, 0), sin(1.0 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 3, 0, 0, 0), sin(1.5 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(3, 0, 0, 0), sin(1.5 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0, 0, 1, 0), 0.0);
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(0, 0, 1, 0), 0.0);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 1, 0, 1, 0), 6.0 * sin(0.5 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(1, 0, 1, 0), 6.0 * sin(0.5 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 2, 0, 1, 0), 6.0 * sin(1.0 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(2, 0, 1, 0), 6.0 * sin(1.0 * X_FACTOR));
|
||||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 3, 0, 1, 0), 6.0 * sin(1.5 * X_FACTOR));
|
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(3, 0, 1, 0), 6.0 * sin(1.5 * X_FACTOR));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _checkBrushResultSides(TerrainDefinition* terrain, TerrainBrush*, double center, double midhard, double hard, double midsoft, double soft, double exter, double neg_midhard, double neg_hard, double neg_midsoft, double neg_soft, double neg_exter)
|
static void _checkBrushResultSides(TerrainDefinition* terrain, TerrainHeightMapBrush*, double center, double midhard, double hard, double midsoft, double soft, double exter, double neg_midhard, double neg_hard, double neg_midsoft, double neg_soft, double neg_exter)
|
||||||
{
|
{
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 0, 0, 1), center);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(0, 0, 1), center);
|
||||||
|
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 1, 0, 1), midhard);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(1, 0, 1), midhard);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 2, 0, 1), hard);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(2, 0, 1), hard);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 3, 0, 1), midsoft);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(3, 0, 1), midsoft);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 4, 0, 1), soft);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(4, 0, 1), soft);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 5, 0, 1), exter);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(5, 0, 1), exter);
|
||||||
|
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -1, 0, 1), neg_midhard);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-1, 0, 1), neg_midhard);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -2, 0, 1), neg_hard);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-2, 0, 1), neg_hard);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -3, 0, 1), neg_midsoft);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-3, 0, 1), neg_midsoft);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -4, 0, 1), neg_soft);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-4, 0, 1), neg_soft);
|
||||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -5, 0, 1), neg_exter);
|
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-5, 0, 1), neg_exter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _checkBrushResult(TerrainDefinition* terrain, TerrainBrush* brush, double center, double midhard, double hard, double midsoft, double soft, double exter, int mirror)
|
static void _checkBrushResult(TerrainDefinition* terrain, TerrainHeightMapBrush* brush, double center, double midhard, double hard, double midsoft, double soft, double exter, int mirror)
|
||||||
{
|
{
|
||||||
if (mirror)
|
if (mirror)
|
||||||
{
|
{
|
||||||
|
@ -116,95 +118,95 @@ static void _checkBrushResult(TerrainDefinition* terrain, TerrainBrush* brush, d
|
||||||
TEST_F(TerrainPainting_Test, brush_flatten)
|
TEST_F(TerrainPainting_Test, brush_flatten)
|
||||||
{
|
{
|
||||||
/* Set up */
|
/* Set up */
|
||||||
TerrainBrush brush = {0.0, 0.0, 2.0, 2.0, 4.0};
|
TerrainHeightMapBrush brush(0.0, 0.0, 2.0, 2.0, 4.0);
|
||||||
terrain->height = 1.0;
|
terrain->height = 1.0;
|
||||||
terrain->scaling = 1.0;
|
terrain->scaling = 1.0;
|
||||||
terrain->_height_noise->forceValue(0.0);
|
terrain->_height_noise->forceValue(0.0);
|
||||||
|
|
||||||
/* Test flattening center at 0.5 */
|
/* Test flattening center at 0.5 */
|
||||||
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 1.0);
|
terrain->height_map->brushFlatten(brush, 0.5, 1.0);
|
||||||
_checkBrushResult(terrain, &brush, 0.5, 0.5, 0.5, 0.25, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.5, 0.5, 0.5, 0.25, 0.0, 0.0, 0);
|
||||||
|
|
||||||
/* Test brush strength */
|
/* Test brush strength */
|
||||||
terrainClearPainting(terrain->height_map);
|
terrain->height_map->clearPainting();
|
||||||
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 0.01);
|
terrain->height_map->brushFlatten(brush, 0.5, 0.01);
|
||||||
_checkBrushResult(terrain, &brush, 0.005, 0.005, 0.005, 0.0025, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.005, 0.005, 0.005, 0.0025, 0.0, 0.0, 0);
|
||||||
|
|
||||||
/* Test cumulative effect */
|
/* Test cumulative effect */
|
||||||
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 0.01);
|
terrain->height_map->brushFlatten(brush, 0.5, 0.01);
|
||||||
_checkBrushResult(terrain, &brush, 0.00995, 0.00995, 0.00995, 0.0049875, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.00995, 0.00995, 0.00995, 0.0049875, 0.0, 0.0, 0);
|
||||||
|
|
||||||
/* Test with height modifier */
|
/* Test with height modifier */
|
||||||
terrain->height = 10.0;
|
terrain->height = 10.0;
|
||||||
terrainClearPainting(terrain->height_map);
|
terrain->height_map->clearPainting();
|
||||||
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 1.0);
|
terrain->height_map->brushFlatten(brush, 0.5, 1.0);
|
||||||
_checkBrushResult(terrain, &brush, 0.05, 0.05, 0.05, 0.025, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.05, 0.05, 0.05, 0.025, 0.0, 0.0, 0);
|
||||||
|
|
||||||
/* Test with scaling modifier */
|
/* Test with scaling modifier */
|
||||||
terrain->height = 10.0;
|
terrain->height = 10.0;
|
||||||
terrain->scaling = 2.0;
|
terrain->scaling = 2.0;
|
||||||
terrainClearPainting(terrain->height_map);
|
terrain->height_map->clearPainting();
|
||||||
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 1.0);
|
terrain->height_map->brushFlatten(brush, 0.5, 1.0);
|
||||||
_checkBrushResult(terrain, &brush, 0.05, 0.05, 0.05, 0.025, 0.0, 0.0, 0);
|
_checkBrushResult(terrain, &brush, 0.05, 0.05, 0.05, 0.025, 0.0, 0.0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TerrainPainting_Test, brush_reset)
|
TEST_F(TerrainPainting_Test, brush_reset)
|
||||||
{
|
{
|
||||||
/* Set up */
|
/* Set up */
|
||||||
TerrainBrush brush = {0.0, 0.0, 2.0, 2.0, 4.0};
|
TerrainHeightMapBrush brush(0.0, 0.0, 2.0, 2.0, 4.0);
|
||||||
TerrainBrush brush_full = {0.0, 0.0, 4.0, 0.0, 4.0};
|
TerrainHeightMapBrush brush_full(0.0, 0.0, 4.0, 0.0, 4.0);
|
||||||
terrain->height = 1.0;
|
terrain->height = 1.0;
|
||||||
terrain->scaling = 1.0;
|
terrain->scaling = 1.0;
|
||||||
terrain->_height_noise->forceValue(1.0);
|
terrain->_height_noise->forceValue(1.0);
|
||||||
|
|
||||||
/* Test resetting at center */
|
/* Test resetting at center */
|
||||||
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
|
terrain->height_map->brushFlatten(brush_full, 2.0, 1.0);
|
||||||
_checkBrushResult(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 0);
|
||||||
terrainBrushReset(terrain->height_map, &brush, 1.0);
|
terrain->height_map->brushReset(brush, 1.0);
|
||||||
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.5, 2.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.5, 2.0, 1.0, 0);
|
||||||
|
|
||||||
/* Test brush strength */
|
/* Test brush strength */
|
||||||
terrainClearPainting(terrain->height_map);
|
terrain->height_map->clearPainting();
|
||||||
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
|
terrain->height_map->brushFlatten(brush_full, 2.0, 1.0);
|
||||||
_checkBrushResult(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 0);
|
||||||
terrainBrushReset(terrain->height_map, &brush, 0.1);
|
terrain->height_map->brushReset(brush, 0.1);
|
||||||
_checkBrushResult(terrain, &brush, 1.9, 1.9, 1.9, 1.95, 2.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.9, 1.9, 1.9, 1.95, 2.0, 1.0, 0);
|
||||||
|
|
||||||
/* Test cumulative effect */
|
/* Test cumulative effect */
|
||||||
terrainBrushReset(terrain->height_map, &brush, 0.1);
|
terrain->height_map->brushReset(brush, 0.1);
|
||||||
_checkBrushResult(terrain, &brush, 1.81, 1.81, 1.81, 1.9025, 2.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.81, 1.81, 1.81, 1.9025, 2.0, 1.0, 0);
|
||||||
|
|
||||||
/* Test with height modifier */
|
/* Test with height modifier */
|
||||||
terrain->height = 10.0;
|
terrain->height = 10.0;
|
||||||
terrainClearPainting(terrain->height_map);
|
terrain->height_map->clearPainting();
|
||||||
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
|
terrain->height_map->brushFlatten(brush_full, 2.0, 1.0);
|
||||||
_checkBrushResult(terrain, &brush, 1.1, 1.1, 1.1, 1.1, 1.1, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.1, 1.1, 1.1, 1.1, 1.1, 1.0, 0);
|
||||||
terrainBrushReset(terrain->height_map, &brush, 0.1);
|
terrain->height_map->brushReset(brush, 0.1);
|
||||||
_checkBrushResult(terrain, &brush, 1.099, 1.099, 1.099, 1.0995, 1.1, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.099, 1.099, 1.099, 1.0995, 1.1, 1.0, 0);
|
||||||
|
|
||||||
/* Test with scaling modifier */
|
/* Test with scaling modifier */
|
||||||
terrain->height = 10.0;
|
terrain->height = 10.0;
|
||||||
terrain->scaling = 2.0;
|
terrain->scaling = 2.0;
|
||||||
terrainClearPainting(terrain->height_map);
|
terrain->height_map->clearPainting();
|
||||||
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
|
terrain->height_map->brushFlatten(brush_full, 2.0, 1.0);
|
||||||
_checkBrushResult(terrain, &brush, 1.1, 1.1, 1.1, 1.1, 1.1, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.1, 1.1, 1.1, 1.1, 1.1, 1.0, 0);
|
||||||
terrainBrushReset(terrain->height_map, &brush, 0.1);
|
terrain->height_map->brushReset(brush, 0.1);
|
||||||
_checkBrushResult(terrain, &brush, 1.099, 1.099, 1.099, 1.0995, 1.1, 1.0, 0);
|
_checkBrushResult(terrain, &brush, 1.099, 1.099, 1.099, 1.0995, 1.1, 1.0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TerrainPainting_Test, brush_reset_basevalue)
|
TEST_F(TerrainPainting_Test, brush_reset_basevalue)
|
||||||
{
|
{
|
||||||
/* Set up */
|
/* Set up */
|
||||||
TerrainBrush brush = {0.0, 0.0, 2.0, 2.0, 4.0};
|
TerrainHeightMapBrush brush(0.0, 0.0, 2.0, 2.0, 4.0);
|
||||||
TerrainBrush brush_full = {0.0, 0.0, 4.0, 0.0, 4.0};
|
TerrainHeightMapBrush brush_full(0.0, 0.0, 4.0, 0.0, 4.0);
|
||||||
terrain->height = 1.0;
|
terrain->height = 1.0;
|
||||||
terrain->scaling = 1.0;
|
terrain->scaling = 1.0;
|
||||||
|
|
||||||
|
@ -212,8 +214,8 @@ TEST_F(TerrainPainting_Test, brush_reset_basevalue)
|
||||||
terrain->height = 1.0;
|
terrain->height = 1.0;
|
||||||
terrain->scaling = 2.0;
|
terrain->scaling = 2.0;
|
||||||
_checkBrushResult(terrain, &brush, 0.0, 0.309016994375, 0.587785252292, 0.809016994375, 0.951056516295, 1.0, 1);
|
_checkBrushResult(terrain, &brush, 0.0, 0.309016994375, 0.587785252292, 0.809016994375, 0.951056516295, 1.0, 1);
|
||||||
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
|
terrain->height_map->brushFlatten(brush_full, 2.0, 1.0);
|
||||||
_checkBrushResultSides(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 2.0, 2.0, 2.0, 2.0, -1.0);
|
_checkBrushResultSides(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 2.0, 2.0, 2.0, 2.0, -1.0);
|
||||||
terrainBrushReset(terrain->height_map, &brush, 1.0);
|
terrain->height_map->brushReset(brush, 1.0);
|
||||||
_checkBrushResultSides(terrain, &brush, 0.0, 0.309016994375, 0.587785252292, 2.0 - (2.0 - 0.809016994375) * 0.5, 2.0, 1.0, -0.309016994375, -0.587785252292, 2.0 - (2.0 + 0.809016994375) * 0.5, 2.0, -1.0);
|
_checkBrushResultSides(terrain, &brush, 0.0, 0.309016994375, 0.587785252292, 2.0 - (2.0 - 0.809016994375) * 0.5, 2.0, 1.0, -0.309016994375, -0.587785252292, 2.0 - (2.0 + 0.809016994375) * 0.5, 2.0, -1.0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue