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"
|
||||
|
||||
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 basics {
|
||||
|
||||
class Interpolation
|
||||
class BASICSSHARED_EXPORT Interpolation
|
||||
{
|
||||
public:
|
||||
Interpolation();
|
||||
|
||||
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])));
|
||||
}
|
||||
static double bicubic(double stencil[16], double x, double y);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,18 @@ void BaseDefinition::setName(QString name)
|
|||
this->name = name;
|
||||
}
|
||||
|
||||
Scenery* BaseDefinition::getScenery()
|
||||
{
|
||||
if (parent)
|
||||
{
|
||||
return parent->getScenery();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void BaseDefinition::save(PackStream* stream) const
|
||||
{
|
||||
stream->write(name);
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
inline const QString& getName() const {return name;}
|
||||
virtual void setName(QString name);
|
||||
|
||||
virtual Scenery* getScenery();
|
||||
|
||||
inline const BaseDefinition* getParent() const {return parent;}
|
||||
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
|
||||
#define SCENERY_H
|
||||
|
||||
#include "rendering_global.h"
|
||||
#include "definition_global.h"
|
||||
|
||||
#include "BaseDefinition.h"
|
||||
|
||||
class TerrainDefinition;
|
||||
class Renderer;
|
||||
|
||||
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
|
||||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
/**
|
||||
* @brief Global scenery management
|
||||
*
|
||||
* This class contains the whole scenery definition.
|
||||
*/
|
||||
class RENDERINGSHARED_EXPORT Scenery: private BaseDefinition
|
||||
class DEFINITIONSHARED_EXPORT Scenery: public BaseDefinition
|
||||
{
|
||||
public:
|
||||
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 load(PackStream* stream) override;
|
||||
|
||||
virtual void validate() override;
|
||||
virtual Scenery* getScenery() override;
|
||||
|
||||
void autoPreset(int seed);
|
||||
|
||||
|
@ -56,8 +50,6 @@ public:
|
|||
inline WaterDefinition* getWater() const {return water;}
|
||||
void getWater(WaterDefinition* water);
|
||||
|
||||
void bindToRenderer(Renderer* renderer);
|
||||
|
||||
void checkCameraAboveGround();
|
||||
|
||||
private:
|
||||
|
@ -67,14 +59,9 @@ private:
|
|||
TerrainDefinition* terrain;
|
||||
TexturesDefinition* textures;
|
||||
WaterDefinition* water;
|
||||
|
||||
SceneryCustomDataCallback _custom_save;
|
||||
SceneryCustomDataCallback _custom_load;
|
||||
void* _custom_data;
|
||||
};
|
||||
|
||||
// Transitional C-API
|
||||
|
||||
RENDERINGSHARED_EXPORT void sceneryRenderFirstPass(Renderer* renderer);
|
||||
}
|
||||
}
|
||||
|
||||
#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 "SurfaceMaterial.h"
|
||||
#include "PackStream.h"
|
||||
#include "Scenery.h"
|
||||
#include "TerrainDefinition.h"
|
||||
|
||||
TextureLayerDefinition::TextureLayerDefinition(BaseDefinition* parent):
|
||||
BaseDefinition(parent)
|
||||
|
@ -42,13 +44,13 @@ void TextureLayerDefinition::validate()
|
|||
materialValidate(material);
|
||||
|
||||
/* Update zone height range */
|
||||
// TODO
|
||||
/*TerrainDefinition* terrain = Scenery::getCurrent()->getTerrain();
|
||||
if (terrain)
|
||||
Scenery* scenery = getScenery();
|
||||
if (scenery)
|
||||
{
|
||||
HeightInfo height_info = terrainGetHeightInfo(terrain);
|
||||
zoneSetRelativeHeight(terrain_zone, height_info.min_height, height_info.base_height, height_info.max_height);
|
||||
}*/
|
||||
TerrainDefinition* terrain = scenery->getTerrain();
|
||||
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
|
||||
|
|
|
@ -8,12 +8,6 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WATER_PRESET_LAKE,
|
||||
WATER_PRESET_SEA
|
||||
} WaterPreset;
|
||||
|
||||
class WaterDefinition: public BaseDefinition
|
||||
{
|
||||
public:
|
||||
|
@ -26,6 +20,12 @@ public:
|
|||
virtual void copy(BaseDefinition* destination) const override;
|
||||
virtual void validate() override;
|
||||
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
WATER_PRESET_LAKE,
|
||||
WATER_PRESET_SEA
|
||||
} WaterPreset;
|
||||
void applyPreset(WaterPreset preset);
|
||||
|
||||
public:
|
||||
|
|
|
@ -24,7 +24,11 @@ SOURCES += \
|
|||
AtmosphereDefinition.cpp \
|
||||
TexturesDefinition.cpp \
|
||||
TextureLayerDefinition.cpp \
|
||||
Zone.cpp
|
||||
Zone.cpp \
|
||||
TerrainDefinition.cpp \
|
||||
TerrainHeightMap.cpp \
|
||||
TerrainHeightMapBrush.cpp \
|
||||
Scenery.cpp
|
||||
|
||||
HEADERS +=\
|
||||
definition_global.h \
|
||||
|
@ -38,7 +42,11 @@ HEADERS +=\
|
|||
AtmosphereDefinition.h \
|
||||
TexturesDefinition.h \
|
||||
TextureLayerDefinition.h \
|
||||
Zone.h
|
||||
Zone.h \
|
||||
TerrainDefinition.h \
|
||||
TerrainHeightMap.h \
|
||||
TerrainHeightMapBrush.h \
|
||||
Scenery.h
|
||||
|
||||
unix:!symbian {
|
||||
maemo5 {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
class BaseDefinition;
|
||||
class Scenery;
|
||||
class CameraDefinition;
|
||||
class SurfaceMaterial;
|
||||
class Zone;
|
||||
|
@ -23,6 +24,14 @@ namespace definition {
|
|||
class AtmosphereDefinition;
|
||||
class TexturesDefinition;
|
||||
class TextureLayerDefinition;
|
||||
class TerrainDefinition;
|
||||
class TerrainHeightMap;
|
||||
class TerrainHeightMapBrush;
|
||||
class TerrainHeightMapBrushElevation;
|
||||
class TerrainHeightMapBrushSmooth;
|
||||
class TerrainHeightMapBrushAddNoise;
|
||||
class TerrainHeightMapBrushReset;
|
||||
class TerrainHeightMapBrushFlatten;
|
||||
}
|
||||
}
|
||||
using namespace paysages::definition;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "CameraDefinition.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
|
||||
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++)
|
||||
{
|
||||
AtmosphereDefinition* atmo = Scenery::getCurrent()->getAtmosphere();
|
||||
AtmosphereDefinition* atmo = RenderingScenery::getCurrent()->getAtmosphere();
|
||||
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->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};
|
||||
camera->setLocation(camera->getLocation().add(step));
|
||||
|
||||
renderer = new SoftwareRenderer(Scenery::getCurrent());
|
||||
renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||
rendererSetPreviewCallbacks(renderer, NULL, NULL, _previewUpdate);
|
||||
|
||||
if (outputcount >= conf_first_picture)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "mainwindow.h"
|
||||
#include "dialogrender.h"
|
||||
#include "dialogexplorer.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "BasePreview.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "CameraDefinition.h"
|
||||
|
@ -232,12 +232,12 @@ void FreeFormHelper::processApplyClicked()
|
|||
|
||||
void FreeFormHelper::processExploreClicked()
|
||||
{
|
||||
SoftwareRenderer renderer(Scenery::getCurrent());
|
||||
SoftwareRenderer renderer(RenderingScenery::getCurrent());
|
||||
|
||||
emit needAlterRenderer(&renderer);
|
||||
|
||||
CameraDefinition camera;
|
||||
Scenery::getCurrent()->getCamera(&camera);
|
||||
RenderingScenery::getCurrent()->getCamera(&camera);
|
||||
|
||||
DialogExplorer* dialog = new DialogExplorer(_form_widget, &camera, false, &renderer);
|
||||
dialog->exec();
|
||||
|
@ -246,7 +246,7 @@ void FreeFormHelper::processExploreClicked()
|
|||
|
||||
void FreeFormHelper::processRenderClicked()
|
||||
{
|
||||
SoftwareRenderer renderer(Scenery::getCurrent());
|
||||
SoftwareRenderer renderer(RenderingScenery::getCurrent());
|
||||
|
||||
emit needAlterRenderer(&renderer);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "dialogexplorer.h"
|
||||
|
||||
#include "main.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "PackStream.h"
|
||||
#include "tools.h"
|
||||
|
||||
|
@ -127,11 +127,11 @@ MainWindow::MainWindow() :
|
|||
ui->tool_panel->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
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ void MainWindow::refreshAll()
|
|||
PreviewOsd* osd = PreviewOsd::getInstance(QString("geolocation"));
|
||||
osd->clearItems();
|
||||
PreviewOsdItem* item = osd->newItem(50, 50);
|
||||
item->drawCamera(Scenery::getCurrent()->getCamera());
|
||||
item->drawCamera(RenderingScenery::getCurrent()->getCamera());
|
||||
item->setToolTip(QString(tr("Camera")));
|
||||
|
||||
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)
|
||||
{
|
||||
Scenery::getCurrent()->autoPreset(0);
|
||||
RenderingScenery::getCurrent()->autoPreset(0);
|
||||
refreshAll();
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ void MainWindow::explore3D()
|
|||
CameraDefinition* camera = new CameraDefinition;
|
||||
int result;
|
||||
|
||||
Scenery::getCurrent()->getCamera(camera);
|
||||
RenderingScenery::getCurrent()->getCamera(camera);
|
||||
|
||||
DialogExplorer* dialog = new DialogExplorer(this, camera, true);
|
||||
result = dialog->exec();
|
||||
|
@ -271,7 +271,7 @@ void MainWindow::explore3D()
|
|||
|
||||
if (result == QDialog::Accepted)
|
||||
{
|
||||
Scenery::getCurrent()->setCamera(camera);
|
||||
RenderingScenery::getCurrent()->setCamera(camera);
|
||||
refreshAll();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <cmath>
|
||||
|
||||
#include "AtmosphereColorPreviewRenderer.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "BasePreview.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "renderer.h"
|
||||
|
@ -78,13 +78,13 @@ FormAtmosphere::~FormAtmosphere()
|
|||
|
||||
void FormAtmosphere::revertConfig()
|
||||
{
|
||||
Scenery::getCurrent()->getAtmosphere(_definition);
|
||||
RenderingScenery::getCurrent()->getAtmosphere(_definition);
|
||||
BaseForm::revertConfig();
|
||||
}
|
||||
|
||||
void FormAtmosphere::applyConfig()
|
||||
{
|
||||
Scenery::getCurrent()->setAtmosphere(_definition);
|
||||
RenderingScenery::getCurrent()->setAtmosphere(_definition);
|
||||
BaseForm::applyConfig();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "clouds/clo_preview.h"
|
||||
#include "tools/color.h"
|
||||
#include "tools/euclid.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "BasePreview.h"
|
||||
#include "renderer.h"
|
||||
#include "CloudsDefinition.h"
|
||||
|
@ -127,14 +127,14 @@ FormClouds::~FormClouds()
|
|||
|
||||
void FormClouds::revertConfig()
|
||||
{
|
||||
Scenery::getCurrent()->getClouds(_definition);
|
||||
RenderingScenery::getCurrent()->getClouds(_definition);
|
||||
BaseFormLayer::revertConfig();
|
||||
}
|
||||
|
||||
void FormClouds::applyConfig()
|
||||
{
|
||||
BaseFormLayer::applyConfig();
|
||||
Scenery::getCurrent()->setClouds(_definition);
|
||||
RenderingScenery::getCurrent()->setClouds(_definition);
|
||||
}
|
||||
|
||||
void FormClouds::layerReadCurrentFrom(void* layer_definition)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "clouds/public.h"
|
||||
#include "terrain/public.h"
|
||||
#include "water/public.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "PackStream.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "BasePreview.h"
|
||||
|
@ -64,7 +64,7 @@ protected:
|
|||
|
||||
void updateData()
|
||||
{
|
||||
Scenery::getCurrent()->bindToRenderer(_renderer);
|
||||
RenderingScenery::getCurrent()->bindToRenderer(_renderer);
|
||||
if (!_clouds_enabled)
|
||||
{
|
||||
CloudsRendererClass.bind(_renderer, _no_clouds);
|
||||
|
@ -171,13 +171,13 @@ void FormRender::loadPack(PackStream* stream)
|
|||
|
||||
void FormRender::revertConfig()
|
||||
{
|
||||
Scenery::getCurrent()->getCamera(_camera);
|
||||
RenderingScenery::getCurrent()->getCamera(_camera);
|
||||
BaseForm::revertConfig();
|
||||
}
|
||||
|
||||
void FormRender::applyConfig()
|
||||
{
|
||||
Scenery::getCurrent()->setCamera(_camera);
|
||||
RenderingScenery::getCurrent()->setCamera(_camera);
|
||||
BaseForm::applyConfig();
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ void FormRender::startQuickRender()
|
|||
{
|
||||
rendererDelete(_renderer);
|
||||
}
|
||||
_renderer = new SoftwareRenderer(Scenery::getCurrent());
|
||||
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||
_renderer_inited = true;
|
||||
|
||||
DialogRender* dialog = new DialogRender(this, _renderer);
|
||||
|
@ -209,7 +209,7 @@ void FormRender::startRender()
|
|||
{
|
||||
rendererDelete(_renderer);
|
||||
}
|
||||
_renderer = new SoftwareRenderer(Scenery::getCurrent());
|
||||
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||
_renderer_inited = true;
|
||||
|
||||
DialogRender* dialog = new DialogRender(this, _renderer);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "formtextures.h"
|
||||
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "BasePreview.h"
|
||||
#include "renderer.h"
|
||||
#include "tools.h"
|
||||
|
@ -47,7 +47,7 @@ protected:
|
|||
|
||||
void updateData()
|
||||
{
|
||||
TerrainRendererClass.bind(_renderer, Scenery::getCurrent()->getTerrain());
|
||||
TerrainRendererClass.bind(_renderer, RenderingScenery::getCurrent()->getTerrain());
|
||||
|
||||
//TexturesDefinitionClass.copy(_original_layer, _preview_layer);
|
||||
}
|
||||
|
@ -140,14 +140,14 @@ FormTextures::~FormTextures()
|
|||
|
||||
void FormTextures::revertConfig()
|
||||
{
|
||||
Scenery::getCurrent()->getTextures(_definition);
|
||||
RenderingScenery::getCurrent()->getTextures(_definition);
|
||||
BaseFormLayer::revertConfig();
|
||||
}
|
||||
|
||||
void FormTextures::applyConfig()
|
||||
{
|
||||
BaseFormLayer::applyConfig();
|
||||
Scenery::getCurrent()->setTextures(_definition);
|
||||
RenderingScenery::getCurrent()->setTextures(_definition);
|
||||
}
|
||||
|
||||
void FormTextures::layerReadCurrentFrom(void* layer_definition)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "terrain/public.h"
|
||||
#include "atmosphere/public.h"
|
||||
#include "tools.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "BasePreview.h"
|
||||
#include "CameraDefinition.h"
|
||||
#include "WaterDefinition.h"
|
||||
|
@ -45,7 +45,7 @@ protected:
|
|||
void updateData()
|
||||
{
|
||||
WaterRendererClass.bind(_renderer, _definition);
|
||||
TerrainRendererClass.bind(_renderer, Scenery::getCurrent()->getTerrain());
|
||||
TerrainRendererClass.bind(_renderer, RenderingScenery::getCurrent()->getTerrain());
|
||||
}
|
||||
|
||||
void toggleChangeEvent(QString key, bool value)
|
||||
|
@ -257,13 +257,13 @@ BaseForm(parent)
|
|||
|
||||
void FormWater::revertConfig()
|
||||
{
|
||||
Scenery::getCurrent()->getWater(_definition);
|
||||
RenderingScenery::getCurrent()->getWater(_definition);
|
||||
BaseForm::revertConfig();
|
||||
}
|
||||
|
||||
void FormWater::applyConfig()
|
||||
{
|
||||
Scenery::getCurrent()->setWater(_definition);
|
||||
RenderingScenery::getCurrent()->setWater(_definition);
|
||||
BaseForm::applyConfig();
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ void FormWater::configChangeEvent()
|
|||
|
||||
void FormWater::autoPresetSelected(int preset)
|
||||
{
|
||||
_definition->applyPreset((WaterPreset)preset);
|
||||
_definition->applyPreset((WaterDefinition::WaterPreset)preset);
|
||||
BaseForm::autoPresetSelected(preset);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#include "dialogterrainpainting.h"
|
||||
#include "ui_dialogterrainpainting.h"
|
||||
|
||||
#include "tools.h"
|
||||
#include <QKeyEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QMessageBox>
|
||||
#include "tools.h"
|
||||
#include "TerrainDefinition.h"
|
||||
|
||||
DialogTerrainPainting::DialogTerrainPainting(QWidget*parent, TerrainDefinition* terrain) :
|
||||
QDialog(parent),
|
||||
|
@ -16,7 +17,7 @@ DialogTerrainPainting::DialogTerrainPainting(QWidget*parent, TerrainDefinition*
|
|||
ui->brush_preview->hide();
|
||||
|
||||
_terrain_original = terrain;
|
||||
_terrain_modified = (TerrainDefinition*)TerrainDefinitionClass.create();
|
||||
_terrain_modified = new TerrainDefinition(NULL);
|
||||
|
||||
ui->widget_commands->hide();
|
||||
|
||||
|
@ -80,13 +81,13 @@ void DialogTerrainPainting::wheelEvent(QWheelEvent* event)
|
|||
|
||||
void DialogTerrainPainting::accept()
|
||||
{
|
||||
TerrainDefinitionClass.copy(_terrain_modified, _terrain_original);
|
||||
_terrain_modified->copy(_terrain_original);
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void DialogTerrainPainting::revert()
|
||||
{
|
||||
TerrainDefinitionClass.copy(_terrain_original, _terrain_modified);
|
||||
_terrain_original->copy(_terrain_modified);
|
||||
|
||||
ui->widget_heightmap->setTerrain(_terrain_modified);
|
||||
ui->widget_heightmap->setBrush(&_brush);
|
||||
|
@ -112,7 +113,7 @@ void DialogTerrainPainting::brushConfigChanged()
|
|||
|
||||
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->progress_memory_consumption->setMaximum(1024);
|
||||
ui->progress_memory_consumption->setValue(memused / 1024);
|
||||
|
|
|
@ -7,14 +7,16 @@
|
|||
#include "previewterrainshape.h"
|
||||
#include "common/freeformhelper.h"
|
||||
#include "tools.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "TerrainDefinition.h"
|
||||
#include "TerrainHeightMap.h"
|
||||
#include "textures/public.h"
|
||||
|
||||
MainTerrainForm::MainTerrainForm(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
ui(new Ui::MainTerrainForm)
|
||||
{
|
||||
_terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
|
||||
_terrain = new TerrainDefinition(NULL);
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -49,12 +51,12 @@ MainTerrainForm::~MainTerrainForm()
|
|||
delete ui;
|
||||
delete _renderer_shape;
|
||||
|
||||
TerrainDefinitionClass.destroy(_terrain);
|
||||
delete _terrain;
|
||||
}
|
||||
|
||||
void MainTerrainForm::refreshFromLocalData()
|
||||
{
|
||||
qint64 memused = terrainGetMemoryStats(_terrain);
|
||||
unsigned long memused = _terrain->getMemoryStats();
|
||||
if (memused > 0)
|
||||
{
|
||||
_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()
|
||||
{
|
||||
double disp = texturesGetMaximalDisplacement(Scenery::getCurrent()->getTextures());
|
||||
double disp = texturesGetMaximalDisplacement(RenderingScenery::getCurrent()->getTextures());
|
||||
|
||||
if (disp == 0.0)
|
||||
{
|
||||
|
@ -83,12 +85,12 @@ void MainTerrainForm::refreshFromFellowData()
|
|||
|
||||
void MainTerrainForm::updateLocalDataFromScenery()
|
||||
{
|
||||
Scenery::getCurrent()->getTerrain(_terrain);
|
||||
RenderingScenery::getCurrent()->getTerrain(_terrain);
|
||||
}
|
||||
|
||||
void MainTerrainForm::commitLocalDataToScenery()
|
||||
{
|
||||
Scenery::getCurrent()->setTerrain(_terrain);
|
||||
RenderingScenery::getCurrent()->setTerrain(_terrain);
|
||||
}
|
||||
|
||||
void MainTerrainForm::alterRenderer(Renderer* renderer)
|
||||
|
@ -99,7 +101,7 @@ void MainTerrainForm::alterRenderer(Renderer* renderer)
|
|||
void MainTerrainForm::buttonBaseNoisePressed()
|
||||
{
|
||||
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"));
|
||||
}
|
||||
|
@ -112,7 +114,7 @@ void MainTerrainForm::buttonBaseNoisePressed()
|
|||
{
|
||||
if (erase)
|
||||
{
|
||||
terrainClearPainting(_terrain->height_map);
|
||||
_terrain->height_map->clearPainting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include <cmath>
|
||||
#include <QAbstractSlider>
|
||||
#include "NoiseGenerator.h"
|
||||
#include "TerrainDefinition.h"
|
||||
#include "TerrainHeightMap.h"
|
||||
#include "TerrainHeightMapBrush.h"
|
||||
|
||||
PaintingBrush::PaintingBrush()
|
||||
{
|
||||
|
@ -101,7 +104,7 @@ QString PaintingBrush::getHelpText()
|
|||
void PaintingBrush::applyToTerrain(TerrainDefinition* terrain, double x, double z, double duration, bool reverse)
|
||||
{
|
||||
double brush_strength;
|
||||
TerrainBrush brush;
|
||||
TerrainHeightMapBrush brush;
|
||||
|
||||
brush.relative_x = x;
|
||||
brush.relative_z = z;
|
||||
|
@ -118,30 +121,30 @@ void PaintingBrush::applyToTerrain(TerrainDefinition* terrain, double x, double
|
|||
{
|
||||
brush_strength = -brush_strength;
|
||||
}
|
||||
terrainBrushElevation(terrain->height_map, &brush, brush_strength * 2.0);
|
||||
terrain->height_map->brushElevation(brush, brush_strength * 2.0);
|
||||
break;
|
||||
case PAINTING_BRUSH_SMOOTH:
|
||||
if (reverse)
|
||||
{
|
||||
terrainBrushSmooth(terrain->height_map, &brush, brush_strength * 30.0);
|
||||
terrain->height_map->brushSmooth(brush, brush_strength * 30.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
terrainBrushAddNoise(terrain->height_map, &brush, _noise, brush_strength * 0.3);
|
||||
terrain->height_map->brushAddNoise(brush, _noise, brush_strength * 0.3);
|
||||
}
|
||||
break;
|
||||
case PAINTING_BRUSH_FLATTEN:
|
||||
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
|
||||
{
|
||||
terrainBrushFlatten(terrain->height_map, &brush, _height, brush_strength * 30.0);
|
||||
terrain->height_map->brushFlatten(brush, _height, brush_strength * 30.0);
|
||||
}
|
||||
break;
|
||||
case PAINTING_BRUSH_RESTORE:
|
||||
terrainBrushReset(terrain->height_map, &brush, brush_strength * 30.0);
|
||||
terrain->height_map->brushReset(brush, brush_strength * 30.0);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <GL/glu.h>
|
||||
#include "tools.h"
|
||||
#include "Scenery.h"
|
||||
#include "TerrainDefinition.h"
|
||||
#include "TerrainHeightMap.h"
|
||||
#include "WaterDefinition.h"
|
||||
|
||||
#define HEIGHTMAP_RESOLUTION 256
|
||||
|
@ -174,7 +176,7 @@ void WidgetHeightMap::mouseReleaseEvent(QMouseEvent*)
|
|||
_last_brush_action = 0;
|
||||
if (_terrain)
|
||||
{
|
||||
terrainEndBrushStroke(_terrain->height_map);
|
||||
_terrain->height_map->endBrushStroke();
|
||||
}
|
||||
if (_brush)
|
||||
{
|
||||
|
@ -214,7 +216,7 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
|||
_last_time = new_time;
|
||||
|
||||
// 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->setTarget(target);
|
||||
_top_camera->setZoomToTarget(_zoom);
|
||||
|
@ -533,9 +535,9 @@ void WidgetHeightMap::updateVertexInfo()
|
|||
vertex->point.x = (double) dx;
|
||||
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/freelayerhelper.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "TexturesDefinition.h"
|
||||
#include "TextureLayerDefinition.h"
|
||||
#include "previewmaterial.h"
|
||||
|
@ -133,12 +133,12 @@ void MainTexturesForm::selectPreset(int preset)
|
|||
|
||||
void MainTexturesForm::updateLocalDataFromScenery()
|
||||
{
|
||||
Scenery::getCurrent()->getTextures(textures);
|
||||
RenderingScenery::getCurrent()->getTextures(textures);
|
||||
}
|
||||
|
||||
void MainTexturesForm::commitLocalDataToScenery()
|
||||
{
|
||||
Scenery::getCurrent()->setTextures(textures);
|
||||
RenderingScenery::getCurrent()->setTextures(textures);
|
||||
}
|
||||
|
||||
void MainTexturesForm::refreshFromLocalData()
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <cmath>
|
||||
#include <GL/glu.h>
|
||||
#include <QThread>
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "SoftwareRenderer.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "WaterDefinition.h"
|
||||
|
@ -90,7 +90,7 @@ QGLWidget(parent)
|
|||
}
|
||||
else
|
||||
{
|
||||
_renderer = new SoftwareRenderer(Scenery::getCurrent());
|
||||
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
|
||||
_renderer_created = true;
|
||||
}
|
||||
_opengl_renderer = new OpenGLRenderer(NULL);
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
#include "SoftwareRenderer.h"
|
||||
#include "tools/color.h"
|
||||
|
||||
class Scenery;
|
||||
|
||||
namespace paysages {
|
||||
namespace preview {
|
||||
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
|
||||
#include "software_global.h"
|
||||
|
||||
// TEMP
|
||||
class Scenery;
|
||||
|
||||
namespace paysages {
|
||||
namespace preview {
|
||||
class PreviewOsd;
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
|
||||
|
||||
// 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)
|
||||
{
|
||||
return ((SoftwareRenderer*)renderer)->getAtmosphereRenderer()->applyAerialPerspective(location, base);
|
||||
|
@ -24,7 +29,33 @@ static Vector3 _legacyGetSunDirection(Renderer* renderer)
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -42,7 +73,6 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery)
|
|||
this->scenery = new Scenery;
|
||||
own_scenery = true;
|
||||
}
|
||||
this->scenery->bindToRenderer(this);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
// Prepare sub renderers
|
||||
|
@ -64,12 +104,21 @@ void SoftwareRenderer::prepare()
|
|||
atmosphere_renderer = new SoftwareBrunetonAtmosphereRenderer(this);
|
||||
|
||||
// Setup transitional renderers (for C-legacy subsystems)
|
||||
rayWalking = _rayWalking;
|
||||
getPrecision = _getPrecision;
|
||||
|
||||
scenery->getAtmosphere()->copy(atmosphere->definition);
|
||||
atmosphere->applyAerialPerspective = _legacyApplyAerialPerspective;
|
||||
atmosphere->getSkyColor = _legacyGetSkyColor;
|
||||
atmosphere->getLightingStatus = _legacyGetLightingStatus;
|
||||
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
|
||||
fluid_medium->clearMedia();
|
||||
//fluid_medium->registerMedium(water_renderer);
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include "renderer.h"
|
||||
|
||||
class Scenery;
|
||||
|
||||
namespace paysages {
|
||||
namespace software {
|
||||
|
||||
|
@ -20,13 +18,20 @@ public:
|
|||
SoftwareRenderer(Scenery* scenery=0);
|
||||
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.
|
||||
*
|
||||
* This will clear the caches and connect elements together.
|
||||
* 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 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 "tools/data.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "Scenery.h"
|
||||
#include "PackStream.h"
|
||||
#include "render.h"
|
||||
|
@ -45,7 +46,7 @@ FileOperationResult paysagesSave(char* filepath)
|
|||
version_header = (double)PAYSAGES_CURRENT_DATA_VERSION;
|
||||
stream.write(&version_header);
|
||||
|
||||
Scenery::getCurrent()->save(&stream);
|
||||
RenderingScenery::getCurrent()->save(&stream);
|
||||
|
||||
return FILE_OPERATION_OK;
|
||||
}
|
||||
|
@ -72,7 +73,7 @@ FileOperationResult paysagesLoad(char* filepath)
|
|||
return FILE_OPERATION_VERSION_MISMATCH;
|
||||
}
|
||||
|
||||
Scenery::getCurrent()->load(&stream);
|
||||
RenderingScenery::getCurrent()->load(&stream);
|
||||
|
||||
return FILE_OPERATION_OK;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "System.h"
|
||||
#include "Thread.h"
|
||||
#include "render.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "tools.h"
|
||||
#include "CameraDefinition.h"
|
||||
#include "atmosphere/public.h"
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
virtual ~Renderer();
|
||||
|
||||
virtual void prepare() {}
|
||||
virtual void setScenery(Scenery*) {}
|
||||
|
||||
/* Render base configuration */
|
||||
int render_quality;
|
||||
|
|
|
@ -24,9 +24,7 @@ SOURCES += main.cpp \
|
|||
terrain/ter_render.cpp \
|
||||
terrain/ter_raster.cpp \
|
||||
terrain/ter_preview.cpp \
|
||||
terrain/ter_presets.cpp \
|
||||
terrain/ter_painting.cpp \
|
||||
terrain/ter_definition.cpp \
|
||||
textures/tex_tools.cpp \
|
||||
textures/tex_rendering.cpp \
|
||||
textures/tex_preview.cpp \
|
||||
|
@ -42,7 +40,7 @@ SOURCES += main.cpp \
|
|||
water/wat_raster.cpp \
|
||||
water/wat_preview.cpp \
|
||||
water/wat_definition.cpp \
|
||||
Scenery.cpp
|
||||
RenderingScenery.cpp
|
||||
|
||||
HEADERS += \
|
||||
tools.h \
|
||||
|
@ -76,7 +74,7 @@ HEADERS += \
|
|||
water/public.h \
|
||||
water/private.h \
|
||||
rendering_global.h \
|
||||
Scenery.h
|
||||
RenderingScenery.h
|
||||
|
||||
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
|
||||
|
|
|
@ -3,22 +3,6 @@
|
|||
|
||||
#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
|
||||
|
|
|
@ -2,41 +2,10 @@
|
|||
#define _PAYSAGES_TERRAIN_PUBLIC_H_
|
||||
|
||||
#include "../rendering_global.h"
|
||||
#include <stdlib.h>
|
||||
#include "../shared/types.h"
|
||||
#include "../tools/color.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
|
||||
{
|
||||
Vector3 location;
|
||||
|
@ -62,37 +31,9 @@ public:
|
|||
void* _internal_data;
|
||||
};
|
||||
|
||||
RENDERINGSHARED_EXPORT extern StandardDefinition TerrainDefinitionClass;
|
||||
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 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
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include "../tools.h"
|
||||
#include "../renderer.h"
|
||||
#include "textures/public.h"
|
||||
#include "TerrainDefinition.h"
|
||||
|
||||
/******************** Binding ********************/
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -313,7 +314,7 @@ static TerrainRenderer* _createRenderer()
|
|||
TerrainRenderer* result;
|
||||
|
||||
result = new TerrainRenderer;
|
||||
result->definition = (TerrainDefinition*)TerrainDefinitionClass.create();
|
||||
result->definition = new TerrainDefinition(NULL);
|
||||
|
||||
result->castRay = _fakeCastRay;
|
||||
result->getHeight = _fakeGetHeight;
|
||||
|
@ -326,13 +327,13 @@ static TerrainRenderer* _createRenderer()
|
|||
|
||||
static void _deleteRenderer(TerrainRenderer* renderer)
|
||||
{
|
||||
TerrainDefinitionClass.destroy(renderer->definition);
|
||||
delete renderer->definition;
|
||||
delete renderer;
|
||||
}
|
||||
|
||||
static void _bindRenderer(Renderer* renderer, TerrainDefinition* definition)
|
||||
{
|
||||
TerrainDefinitionClass.copy(definition, renderer->terrain->definition);
|
||||
definition->copy(renderer->terrain->definition);
|
||||
|
||||
renderer->terrain->castRay = _realCastRay;
|
||||
renderer->terrain->getHeight = _realGetHeight;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "tex_preview.h"
|
||||
#include "private.h"
|
||||
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "TexturesDefinition.h"
|
||||
|
||||
void TexturesPreviewLayerCoverage_bind(Renderer* renderer, TexturesDefinition* definition)
|
||||
{
|
||||
TerrainRendererClass.bind(renderer, Scenery::getCurrent()->getTerrain());
|
||||
TerrainRendererClass.bind(renderer, RenderingScenery::getCurrent()->getTerrain());
|
||||
TexturesRendererClass.bind(renderer, definition);
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ Color TexturesPreviewLayerLook_getColor(Renderer* renderer, double x, double y,
|
|||
|
||||
void TexturesPreviewCumul_bind(Renderer* renderer, TexturesDefinition* definition)
|
||||
{
|
||||
TerrainRendererClass.bind(renderer, Scenery::getCurrent()->getTerrain());
|
||||
TerrainRendererClass.bind(renderer, RenderingScenery::getCurrent()->getTerrain());
|
||||
TexturesRendererClass.bind(renderer, definition);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,18 +20,6 @@ double toolsCubicInterpolate(double stencil[4], double 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)
|
||||
{
|
||||
/* TODO Optimize with memcpy if src_xstep == dest_xstep == 1 */
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#define UNUSED(_x_) ((void)(_x_))
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,22 +4,6 @@
|
|||
#include <cstring>
|
||||
#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)
|
||||
{
|
||||
int xstart, xend, xlen;
|
||||
|
|
|
@ -8,6 +8,5 @@
|
|||
#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 void* naiveArrayInsert(void** array, size_t item_size, int item_count, int location);
|
||||
|
||||
#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 \
|
||||
System.cpp \
|
||||
PackStream.cpp \
|
||||
RandomGenerator.cpp
|
||||
RandomGenerator.cpp \
|
||||
Memory.cpp
|
||||
|
||||
HEADERS += \
|
||||
system_global.h \
|
||||
|
@ -28,7 +29,8 @@ HEADERS += \
|
|||
Mutex.h \
|
||||
System.h \
|
||||
PackStream.h \
|
||||
RandomGenerator.h
|
||||
RandomGenerator.h \
|
||||
Memory.h
|
||||
|
||||
unix:!symbian {
|
||||
maemo5 {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "SoftwareRenderer.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "AtmosphereRenderer.h"
|
||||
#include "Scenery.h"
|
||||
#include "RenderingScenery.h"
|
||||
#include "System.h"
|
||||
|
||||
#define OUTPUT_WIDTH 400
|
||||
|
@ -44,7 +44,7 @@ TEST(Bruneton, AerialPerspective1)
|
|||
|
||||
TEST(Bruneton, AerialPerspective2)
|
||||
{
|
||||
AtmosphereDefinition* atmo = Scenery::getCurrent()->getAtmosphere();
|
||||
AtmosphereDefinition* atmo = RenderingScenery::getCurrent()->getAtmosphere();
|
||||
atmo->hour = 6;
|
||||
atmo->minute = 30;
|
||||
atmo->validate();
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
#include <cmath>
|
||||
#include "NoiseGenerator.h"
|
||||
#include "terrain/public.h"
|
||||
#include "TerrainDefinition.h"
|
||||
#include "TerrainHeightMap.h"
|
||||
#include "TerrainHeightMapBrush.h"
|
||||
|
||||
/* Noise sin period is defined at 20.0 */
|
||||
#define X_FACTOR (M_PI / 10.0)
|
||||
|
@ -25,7 +27,7 @@ static double _noise3dMock(double x, double, double)
|
|||
class TerrainPainting_Test : public BaseTestCase {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
|
||||
terrain = new TerrainDefinition(NULL);
|
||||
terrain->height = 3.0;
|
||||
terrain->scaling = 1.0;
|
||||
terrain->_height_noise->clearLevels();
|
||||
|
@ -36,7 +38,7 @@ protected:
|
|||
|
||||
virtual void TearDown()
|
||||
{
|
||||
TerrainDefinitionClass.destroy(terrain);
|
||||
delete terrain;
|
||||
}
|
||||
|
||||
TerrainDefinition* terrain;
|
||||
|
@ -45,63 +47,63 @@ protected:
|
|||
TEST_F(TerrainPainting_Test, grid)
|
||||
{
|
||||
/* Test base grid */
|
||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 1, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 0, 1));
|
||||
EXPECT_DOUBLE_EQ(sin(1.0 * X_FACTOR), terrainGetGridHeight(terrain, 1, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(sin(2.0 * X_FACTOR), terrainGetGridHeight(terrain, 2, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(sin(3.0 * X_FACTOR), terrainGetGridHeight(terrain, 3, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrainGetGridHeight(terrain, 4, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(1.0, terrainGetGridHeight(terrain, 5, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrainGetGridHeight(terrain, 6, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(-sin(1.0 * X_FACTOR), terrainGetGridHeight(terrain, -1, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 10, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(-1.0, terrainGetGridHeight(terrain, 15, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 20, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(-1.0, terrainGetGridHeight(terrain, -5, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(0, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(0, 1, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(0, 0, 1));
|
||||
EXPECT_DOUBLE_EQ(sin(1.0 * X_FACTOR), terrain->getGridHeight(1, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(sin(2.0 * X_FACTOR), terrain->getGridHeight(2, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(sin(3.0 * X_FACTOR), terrain->getGridHeight(3, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrain->getGridHeight(4, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(1.0, terrain->getGridHeight(5, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrain->getGridHeight(6, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(-sin(1.0 * X_FACTOR), terrain->getGridHeight(-1, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(10, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(-1.0, terrain->getGridHeight(15, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(0.0, terrain->getGridHeight(20, 0, 0));
|
||||
EXPECT_DOUBLE_EQ(-1.0, terrain->getGridHeight(-5, 0, 0));
|
||||
|
||||
/* Test interpolated result */
|
||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 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_EQ(terrainGetInterpolatedHeight(terrain, 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_IN_RANGE(terrainGetInterpolatedHeight(terrain, 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(0.0, 0.0, 0, 0), 0.0);
|
||||
EXPECT_DOUBLE_IN_RANGE(terrain->getInterpolatedHeight(0.5, 0.0, 0, 0), 0.1564, 0.1566);
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(1.0, 0.0, 0, 0), sin(1.0 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(0.0, 0.0, 1, 0), 0.0);
|
||||
EXPECT_DOUBLE_IN_RANGE(terrain->getInterpolatedHeight(0.5, 0.0, 1, 0), 3.0 * 0.1564, 3.0 * 0.1566);
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(1.0, 0.0, 1, 0), 3.0 * sin(1.0 * X_FACTOR));
|
||||
|
||||
/* Test scaling */
|
||||
terrain->scaling = 2.0;
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 0, 0, 0), 0.0);
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 1, 0, 0), sin(1.0 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 2, 0, 0), sin(2.0 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 3, 0, 0), sin(3.0 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0, 0, 0, 0), 0.0);
|
||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 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(terrainGetInterpolatedHeight(terrain, 3, 0, 0, 0), sin(1.5 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 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(terrainGetInterpolatedHeight(terrain, 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->getGridHeight(0, 0, 0), 0.0);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(1, 0, 0), sin(1.0 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(2, 0, 0), sin(2.0 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(3, 0, 0), sin(3.0 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(0, 0, 0, 0), 0.0);
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(1, 0, 0, 0), sin(0.5 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(2, 0, 0, 0), sin(1.0 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(3, 0, 0, 0), sin(1.5 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(0, 0, 1, 0), 0.0);
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(1, 0, 1, 0), 6.0 * sin(0.5 * X_FACTOR));
|
||||
EXPECT_DOUBLE_EQ(terrain->getInterpolatedHeight(2, 0, 1, 0), 6.0 * sin(1.0 * 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(terrainGetGridHeight(terrain, 2, 0, 1), hard);
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 3, 0, 1), midsoft);
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 4, 0, 1), soft);
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 5, 0, 1), exter);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(1, 0, 1), midhard);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(2, 0, 1), hard);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(3, 0, 1), midsoft);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(4, 0, 1), soft);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(5, 0, 1), exter);
|
||||
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -1, 0, 1), neg_midhard);
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -2, 0, 1), neg_hard);
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -3, 0, 1), neg_midsoft);
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -4, 0, 1), neg_soft);
|
||||
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -5, 0, 1), neg_exter);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-1, 0, 1), neg_midhard);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-2, 0, 1), neg_hard);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-3, 0, 1), neg_midsoft);
|
||||
EXPECT_DOUBLE_EQ(terrain->getGridHeight(-4, 0, 1), neg_soft);
|
||||
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)
|
||||
{
|
||||
|
@ -116,95 +118,95 @@ static void _checkBrushResult(TerrainDefinition* terrain, TerrainBrush* brush, d
|
|||
TEST_F(TerrainPainting_Test, brush_flatten)
|
||||
{
|
||||
/* 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->scaling = 1.0;
|
||||
terrain->_height_noise->forceValue(0.0);
|
||||
|
||||
/* Test flattening center at 0.5 */
|
||||
_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);
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Test with height modifier */
|
||||
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);
|
||||
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);
|
||||
|
||||
/* Test with scaling modifier */
|
||||
terrain->height = 10.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);
|
||||
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);
|
||||
}
|
||||
|
||||
TEST_F(TerrainPainting_Test, brush_reset)
|
||||
{
|
||||
/* Set up */
|
||||
TerrainBrush 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(0.0, 0.0, 2.0, 2.0, 4.0);
|
||||
TerrainHeightMapBrush brush_full(0.0, 0.0, 4.0, 0.0, 4.0);
|
||||
terrain->height = 1.0;
|
||||
terrain->scaling = 1.0;
|
||||
terrain->_height_noise->forceValue(1.0);
|
||||
|
||||
/* Test resetting at center */
|
||||
_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);
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Test with height modifier */
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
/* Test with scaling modifier */
|
||||
terrain->height = 10.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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
TEST_F(TerrainPainting_Test, brush_reset_basevalue)
|
||||
{
|
||||
/* Set up */
|
||||
TerrainBrush 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(0.0, 0.0, 2.0, 2.0, 4.0);
|
||||
TerrainHeightMapBrush brush_full(0.0, 0.0, 4.0, 0.0, 4.0);
|
||||
terrain->height = 1.0;
|
||||
terrain->scaling = 1.0;
|
||||
|
||||
|
@ -212,8 +214,8 @@ TEST_F(TerrainPainting_Test, brush_reset_basevalue)
|
|||
terrain->height = 1.0;
|
||||
terrain->scaling = 2.0;
|
||||
_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);
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue