Merge branch 'master' into vegetation
Conflicts: src/definition/Scenery.cpp src/interface/commandline/tests.cpp
This commit is contained in:
commit
c5950f810f
30 changed files with 146 additions and 91 deletions
|
@ -135,8 +135,8 @@ void NoiseGenerator::setState(const NoiseState &state) {
|
||||||
state.copy(&this->state);
|
state.copy(&this->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoiseGenerator::randomizeOffsets() {
|
void NoiseGenerator::randomizeOffsets(RandomGenerator &random) {
|
||||||
state.randomizeOffsets();
|
state.randomizeOffsets(random);
|
||||||
}
|
}
|
||||||
|
|
||||||
NoiseGenerator::NoiseFunction NoiseGenerator::getFunction() {
|
NoiseGenerator::NoiseFunction NoiseGenerator::getFunction() {
|
||||||
|
|
|
@ -39,7 +39,7 @@ class BASICSSHARED_EXPORT NoiseGenerator {
|
||||||
}
|
}
|
||||||
void setState(const NoiseState &state);
|
void setState(const NoiseState &state);
|
||||||
|
|
||||||
void randomizeOffsets();
|
void randomizeOffsets(RandomGenerator &random = RandomGeneratorDefault);
|
||||||
NoiseFunction getFunction();
|
NoiseFunction getFunction();
|
||||||
void setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y),
|
void setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y),
|
||||||
double (*func3d)(double x, double y, double z));
|
double (*func3d)(double x, double y, double z));
|
||||||
|
|
|
@ -42,11 +42,11 @@ void NoiseState::copy(NoiseState *destination) const {
|
||||||
destination->level_offsets = level_offsets;
|
destination->level_offsets = level_offsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoiseState::randomizeOffsets() {
|
void NoiseState::randomizeOffsets(RandomGenerator &random) {
|
||||||
for (auto &level_offset : level_offsets) {
|
for (auto &level_offset : level_offsets) {
|
||||||
level_offset.x = RandomGenerator::random();
|
level_offset.x = random.genDouble();
|
||||||
level_offset.y = RandomGenerator::random();
|
level_offset.y = random.genDouble();
|
||||||
level_offset.z = RandomGenerator::random();
|
level_offset.z = random.genDouble();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ class BASICSSHARED_EXPORT NoiseState {
|
||||||
void load(PackStream *stream);
|
void load(PackStream *stream);
|
||||||
void copy(NoiseState *destination) const;
|
void copy(NoiseState *destination) const;
|
||||||
|
|
||||||
void randomizeOffsets();
|
void randomizeOffsets(RandomGenerator &random = RandomGeneratorDefault);
|
||||||
void resetOffsets(double x = 0.0, double y = 0.0, double z = 0.0);
|
void resetOffsets(double x = 0.0, double y = 0.0, double z = 0.0);
|
||||||
|
|
||||||
void setLevel(int level, double x, double y, double z);
|
void setLevel(int level, double x, double y, double z);
|
||||||
|
|
|
@ -19,7 +19,6 @@ Vector3::Vector3(const VectorSpherical &v)
|
||||||
Vector3::Vector3(double x, double y, double z) : x(x), y(y), z(z) {
|
Vector3::Vector3(double x, double y, double z) : x(x), y(y), z(z) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Vector3::save(PackStream *stream) const {
|
void Vector3::save(PackStream *stream) const {
|
||||||
stream->write(&x);
|
stream->write(&x);
|
||||||
stream->write(&y);
|
stream->write(&y);
|
||||||
|
@ -115,10 +114,10 @@ Vector3 Vector3::midPointTo(const Vector3 &other) const {
|
||||||
return Vector3((other.x + x) * 0.5, (other.y + y) * 0.5, (other.z + z) * 0.5);
|
return Vector3((other.x + x) * 0.5, (other.y + y) * 0.5, (other.z + z) * 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3::randomInSphere(double radius, bool only_surface) {
|
Vector3 Vector3::randomInSphere(double radius, bool only_surface, RandomGenerator &random) {
|
||||||
// TODO More uniform spatial repartition
|
// TODO More uniform spatial repartition
|
||||||
// The current randomization clusters result near the center and at the poles
|
// The current randomization clusters result near the center and at the poles
|
||||||
VectorSpherical vec = {only_surface ? radius : RandomGenerator::random() * radius,
|
VectorSpherical vec = {only_surface ? radius : random.genDouble() * radius,
|
||||||
(RandomGenerator::random() - 0.5) * M_PI, RandomGenerator::random() * M_2PI};
|
(random.genDouble() - 0.5) * M_PI, random.genDouble() * M_2PI};
|
||||||
return Vector3(vec);
|
return Vector3(vec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ class BASICSSHARED_EXPORT Vector3 {
|
||||||
*
|
*
|
||||||
* If *only_surface* is true, produce a vector with *radius* as length.
|
* If *only_surface* is true, produce a vector with *radius* as length.
|
||||||
*/
|
*/
|
||||||
static Vector3 randomInSphere(double radius = 1.0, bool only_surface = false);
|
static Vector3 randomInSphere(double radius = 1.0, bool only_surface = false, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// TODO Make private
|
// TODO Make private
|
||||||
|
|
|
@ -100,7 +100,7 @@ void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const {
|
||||||
*second = value - *minute * 60.0;
|
*second = value - *minute * 60.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtmosphereDefinition::applyPreset(AtmospherePreset preset) {
|
void AtmosphereDefinition::applyPreset(AtmospherePreset preset, RandomGenerator &random) {
|
||||||
sun_color.r = 1.0;
|
sun_color.r = 1.0;
|
||||||
sun_color.g = 0.95;
|
sun_color.g = 0.95;
|
||||||
sun_color.b = 0.9;
|
sun_color.b = 0.9;
|
||||||
|
@ -142,28 +142,28 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
generateStars(2000);
|
generateStars(2000, random);
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtmosphereDefinition::generateStars(int count) {
|
void AtmosphereDefinition::generateStars(int count, RandomGenerator &random) {
|
||||||
stars.clear();
|
stars.clear();
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
Star star;
|
Star star;
|
||||||
|
|
||||||
star.location =
|
star.location =
|
||||||
Vector3((RandomGenerator::random() - 0.5) * 100000.0, (RandomGenerator::random() * 0.5) * 100000.0,
|
Vector3((random.genDouble() - 0.5) * 100000.0, (random.genDouble() * 0.5) * 100000.0,
|
||||||
(RandomGenerator::random() - 0.5) * 100000.0);
|
(random.genDouble() - 0.5) * 100000.0);
|
||||||
if (star.location.getNorm() < 30000.0) {
|
if (star.location.getNorm() < 30000.0) {
|
||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double brillance = RandomGenerator::random() * 0.05 + 0.1;
|
double brillance = random.genDouble() * 0.05 + 0.1;
|
||||||
star.col = Color(brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03,
|
star.col = Color(brillance + random.genDouble() * 0.03, brillance + random.genDouble() * 0.03,
|
||||||
brillance + RandomGenerator::random() * 0.03, 1.0);
|
brillance + random.genDouble() * 0.03, 1.0);
|
||||||
star.radius = 30.0 + RandomGenerator::random() * 20.0;
|
star.radius = 30.0 + random.genDouble() * 20.0;
|
||||||
|
|
||||||
stars.push_back(star);
|
stars.push_back(star);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,8 @@ class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode {
|
||||||
*/
|
*/
|
||||||
void getHMS(int *hour, int *minute, int *second) const;
|
void getHMS(int *hour, int *minute, int *second) const;
|
||||||
|
|
||||||
void applyPreset(AtmospherePreset preset);
|
void applyPreset(AtmospherePreset preset, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
void generateStars(int count);
|
void generateStars(int count, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AtmosphereModel model;
|
AtmosphereModel model;
|
||||||
|
|
|
@ -9,12 +9,13 @@ static DefinitionNode *_layerConstructor(Layers *parent, const std::string &name
|
||||||
CloudsDefinition::CloudsDefinition(DefinitionNode *parent) : Layers(parent, "clouds", _layerConstructor) {
|
CloudsDefinition::CloudsDefinition(DefinitionNode *parent) : Layers(parent, "clouds", _layerConstructor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloudsDefinition::applyPreset(CloudsPreset preset) {
|
void CloudsDefinition::applyPreset(CloudsPreset preset, RandomGenerator &random) {
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY) {
|
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY) {
|
||||||
CloudLayerDefinition layer(NULL, "Strato-cumulus");
|
CloudLayerDefinition layer(NULL, "Strato-cumulus");
|
||||||
layer.type = CloudLayerDefinition::STRATOCUMULUS;
|
layer.type = CloudLayerDefinition::STRATOCUMULUS;
|
||||||
|
layer.noise_state.randomizeOffsets(random);
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ class DEFINITIONSHARED_EXPORT CloudsDefinition : public Layers {
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum { CLOUDS_PRESET_PARTLY_CLOUDY } CloudsPreset;
|
typedef enum { CLOUDS_PRESET_PARTLY_CLOUDY } CloudsPreset;
|
||||||
void applyPreset(CloudsPreset preset);
|
void applyPreset(CloudsPreset preset, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "Scenery.h"
|
#include "Scenery.h"
|
||||||
|
|
||||||
#include <ctime>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "PackStream.h"
|
#include "PackStream.h"
|
||||||
|
@ -12,6 +11,7 @@
|
||||||
#include "VegetationDefinition.h"
|
#include "VegetationDefinition.h"
|
||||||
#include "WaterDefinition.h"
|
#include "WaterDefinition.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
|
#include "RandomGenerator.h"
|
||||||
|
|
||||||
static const double APP_HEADER = 19866544632.125;
|
static const double APP_HEADER = 19866544632.125;
|
||||||
static const int DATA_VERSION = 1;
|
static const int DATA_VERSION = 1;
|
||||||
|
@ -95,25 +95,26 @@ const Scenery *Scenery::getScenery() const {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scenery::autoPreset(int seed) {
|
void Scenery::autoPreset(RandomGenerator &random) {
|
||||||
if (!seed) {
|
terrain->applyPreset(TerrainDefinition::TERRAIN_PRESET_STANDARD, random);
|
||||||
seed = time(NULL);
|
textures->applyPreset(TexturesDefinition::TEXTURES_PRESET_FULL, random);
|
||||||
}
|
atmosphere->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_DAY, random);
|
||||||
srand(seed);
|
water->applyPreset(WaterDefinition::WATER_PRESET_LAKE, random);
|
||||||
|
clouds->applyPreset(CloudsDefinition::CLOUDS_PRESET_PARTLY_CLOUDY, random);
|
||||||
terrain->applyPreset(TerrainDefinition::TERRAIN_PRESET_STANDARD);
|
vegetation->applyPreset(VegetationDefinition::VEGETATION_PRESET_TEMPERATE, random);
|
||||||
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);
|
|
||||||
vegetation->applyPreset(VegetationDefinition::VEGETATION_PRESET_TEMPERATE);
|
|
||||||
|
|
||||||
camera->setLocation(VECTOR_ZERO);
|
camera->setLocation(VECTOR_ZERO);
|
||||||
camera->setTarget(VECTOR_NORTH);
|
camera->setTarget(VECTOR_NORTH);
|
||||||
|
|
||||||
validate();
|
validate();
|
||||||
|
|
||||||
Logs::debug() << "[Definition] New scenery generated from seed " << seed << std::endl;
|
Logs::debug() << "[Definition] New scenery generated from seed " << random.getSeed() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scenery::autoPreset(unsigned int seed)
|
||||||
|
{
|
||||||
|
RandomGenerator random(seed);
|
||||||
|
autoPreset(random);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scenery::setAtmosphere(AtmosphereDefinition *atmosphere) {
|
void Scenery::setAtmosphere(AtmosphereDefinition *atmosphere) {
|
||||||
|
|
|
@ -34,7 +34,8 @@ class DEFINITIONSHARED_EXPORT Scenery : public DefinitionNode {
|
||||||
|
|
||||||
virtual const Scenery *getScenery() const override;
|
virtual const Scenery *getScenery() const override;
|
||||||
|
|
||||||
void autoPreset(int seed = 0);
|
void autoPreset(RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
void autoPreset(unsigned int seed);
|
||||||
|
|
||||||
void setAtmosphere(AtmosphereDefinition *atmosphere);
|
void setAtmosphere(AtmosphereDefinition *atmosphere);
|
||||||
inline AtmosphereDefinition *getAtmosphere() const {
|
inline AtmosphereDefinition *getAtmosphere() const {
|
||||||
|
|
|
@ -113,11 +113,11 @@ unsigned long TerrainDefinition::getMemoryStats() {
|
||||||
return height_map->getMemoryStats();
|
return height_map->getMemoryStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerrainDefinition::applyPreset(TerrainPreset preset) {
|
void TerrainDefinition::applyPreset(TerrainPreset preset, RandomGenerator &random) {
|
||||||
int resolution = 8;
|
int resolution = 8;
|
||||||
switch (preset) {
|
switch (preset) {
|
||||||
case TERRAIN_PRESET_STANDARD:
|
case TERRAIN_PRESET_STANDARD:
|
||||||
_height_noise->randomizeOffsets();
|
_height_noise->randomizeOffsets(random);
|
||||||
_height_noise->clearLevels();
|
_height_noise->clearLevels();
|
||||||
_height_noise->addLevelSimple(pow(2.0, resolution + 1), -1.0, 1.0);
|
_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->addLevelsSimple(resolution - 2, pow(2.0, resolution - 1), -0.7, 0.7, 0.5);
|
||||||
|
|
|
@ -37,7 +37,7 @@ class DEFINITIONSHARED_EXPORT TerrainDefinition : public DefinitionNode {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef enum { TERRAIN_PRESET_STANDARD } TerrainPreset;
|
typedef enum { TERRAIN_PRESET_STANDARD } TerrainPreset;
|
||||||
void applyPreset(TerrainPreset preset);
|
void applyPreset(TerrainPreset preset, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
double height;
|
double height;
|
||||||
|
|
|
@ -96,9 +96,9 @@ void TextureLayerDefinition::load(PackStream *stream) {
|
||||||
_detail_noise->load(stream);
|
_detail_noise->load(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureLayerDefinition::applyPreset(TextureLayerPreset preset) {
|
void TextureLayerDefinition::applyPreset(TextureLayerPreset preset, RandomGenerator &random) {
|
||||||
_displacement_noise->randomizeOffsets();
|
_displacement_noise->randomizeOffsets(random);
|
||||||
_detail_noise->randomizeOffsets();
|
_detail_noise->randomizeOffsets(random);
|
||||||
|
|
||||||
terrain_zone->clear();
|
terrain_zone->clear();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class DEFINITIONSHARED_EXPORT TextureLayerDefinition : public DefinitionNode {
|
||||||
virtual void copy(DefinitionNode *destination) const override;
|
virtual void copy(DefinitionNode *destination) const override;
|
||||||
virtual void validate() override;
|
virtual void validate() override;
|
||||||
|
|
||||||
void applyPreset(TextureLayerPreset preset);
|
void applyPreset(TextureLayerPreset preset, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Zone *terrain_zone;
|
Zone *terrain_zone;
|
||||||
|
|
|
@ -9,44 +9,44 @@ static DefinitionNode *_layer_constructor(Layers *parent, const std::string &nam
|
||||||
TexturesDefinition::TexturesDefinition(DefinitionNode *parent) : Layers(parent, "textures", _layer_constructor) {
|
TexturesDefinition::TexturesDefinition(DefinitionNode *parent) : Layers(parent, "textures", _layer_constructor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexturesDefinition::applyPreset(TexturesPreset preset) {
|
void TexturesDefinition::applyPreset(TexturesPreset preset, RandomGenerator &random) {
|
||||||
TextureLayerDefinition layer(NULL, "temp");
|
TextureLayerDefinition layer(NULL, "temp");
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_MUD);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_MUD, random);
|
||||||
layer.setName("Mud");
|
layer.setName("Mud");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
|
|
||||||
if (preset == TEXTURES_PRESET_FULL) {
|
if (preset == TEXTURES_PRESET_FULL) {
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK, random);
|
||||||
layer.setName("Ground");
|
layer.setName("Ground");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
|
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_GRASS);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_GRASS, random);
|
||||||
layer.setName("Grass");
|
layer.setName("Grass");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
|
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SAND);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SAND, random);
|
||||||
layer.setName("Sand");
|
layer.setName("Sand");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
|
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SNOW);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SNOW, random);
|
||||||
layer.setName("Snow");
|
layer.setName("Snow");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
} else if (preset == TEXTURES_PRESET_IRELAND) {
|
} else if (preset == TEXTURES_PRESET_IRELAND) {
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK, random);
|
||||||
layer.setName("Ground");
|
layer.setName("Ground");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
|
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_GRASS);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_GRASS, random);
|
||||||
layer.setName("Grass");
|
layer.setName("Grass");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
} else if (preset == TEXTURES_PRESET_ALPS) {
|
} else if (preset == TEXTURES_PRESET_ALPS) {
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_ROCK, random);
|
||||||
layer.setName("Ground");
|
layer.setName("Ground");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
|
|
||||||
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SNOW);
|
layer.applyPreset(TextureLayerDefinition::TEXTURES_LAYER_PRESET_SNOW, random);
|
||||||
layer.setName("Snow");
|
layer.setName("Snow");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
} else if (preset == TEXTURES_PRESET_CANYON) {
|
} else if (preset == TEXTURES_PRESET_CANYON) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ class DEFINITIONSHARED_EXPORT TexturesDefinition : public Layers {
|
||||||
TEXTURES_PRESET_ALPS,
|
TEXTURES_PRESET_ALPS,
|
||||||
TEXTURES_PRESET_CANYON
|
TEXTURES_PRESET_CANYON
|
||||||
} TexturesPreset;
|
} TexturesPreset;
|
||||||
void applyPreset(TexturesPreset preset);
|
void applyPreset(TexturesPreset preset, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
double getMaximalDisplacement();
|
double getMaximalDisplacement();
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,13 +24,13 @@ double VegetationDefinition::getMaxHeight() const {
|
||||||
return max_height;
|
return max_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VegetationDefinition::applyPreset(VegetationPreset preset) {
|
void VegetationDefinition::applyPreset(VegetationPreset preset, RandomGenerator &random) {
|
||||||
VegetationLayerDefinition layer(this, "temp");
|
VegetationLayerDefinition layer(this, "temp");
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
if (preset == VEGETATION_PRESET_TEMPERATE) {
|
if (preset == VEGETATION_PRESET_TEMPERATE) {
|
||||||
layer.applyPreset(VegetationLayerDefinition::VEGETATION_BASIC_TREES);
|
layer.applyPreset(VegetationLayerDefinition::VEGETATION_BASIC_TREES, random);
|
||||||
layer.setName("Basic tree");
|
layer.setName("Basic tree");
|
||||||
addLayer(layer);
|
addLayer(layer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ class DEFINITIONSHARED_EXPORT VegetationDefinition : public Layers {
|
||||||
double getMaxHeight() const;
|
double getMaxHeight() const;
|
||||||
|
|
||||||
typedef enum { VEGETATION_PRESET_TEMPERATE } VegetationPreset;
|
typedef enum { VEGETATION_PRESET_TEMPERATE } VegetationPreset;
|
||||||
void applyPreset(VegetationPreset preset);
|
void applyPreset(VegetationPreset preset, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,6 @@ double VegetationLayerDefinition::getMaxHeight() const {
|
||||||
return presence->getMaxHeight();
|
return presence->getMaxHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VegetationLayerDefinition::applyPreset(VegetationLayerPreset) {
|
void VegetationLayerDefinition::applyPreset(VegetationLayerPreset, RandomGenerator &random) {
|
||||||
model->randomize();
|
model->randomize(random);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ class DEFINITIONSHARED_EXPORT VegetationLayerDefinition : public DefinitionNode
|
||||||
double getMaxHeight() const;
|
double getMaxHeight() const;
|
||||||
|
|
||||||
typedef enum { VEGETATION_BASIC_TREES } VegetationLayerPreset;
|
typedef enum { VEGETATION_BASIC_TREES } VegetationLayerPreset;
|
||||||
void applyPreset(VegetationLayerPreset preset);
|
void applyPreset(VegetationLayerPreset preset, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -101,41 +101,41 @@ void VegetationModelDefinition::copy(DefinitionNode *destination_) const {
|
||||||
void VegetationModelDefinition::validate() {
|
void VegetationModelDefinition::validate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double randomizeValue(double base, double min_factor, double max_factor) {
|
static inline double randomizeValue(RandomGenerator &random, double base, double min_factor, double max_factor) {
|
||||||
return base * (min_factor + RandomGenerator::random() * (max_factor - min_factor));
|
return base * (min_factor + random.genDouble() * (max_factor - min_factor));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addBranchRecurse(std::vector<CappedCylinder> &branches, const Vector3 &base, const Vector3 &direction,
|
static void addBranchRecurse(RandomGenerator &random, std::vector<CappedCylinder> &branches, const Vector3 &base,
|
||||||
double radius, double length) {
|
const Vector3 &direction, double radius, double length) {
|
||||||
branches.push_back(CappedCylinder(base, direction, radius, length));
|
branches.push_back(CappedCylinder(base, direction, radius, length));
|
||||||
|
|
||||||
if (length > 0.1) {
|
if (length > 0.1) {
|
||||||
int split_count = 3;
|
int split_count = 3;
|
||||||
Matrix4 pivot1 = Matrix4::newRotateAxis(randomizeValue(1.0 - 0.6 * length, 0.9, 1.1), VECTOR_EAST);
|
Matrix4 pivot1 = Matrix4::newRotateAxis(randomizeValue(random, 1.0 - 0.6 * length, 0.9, 1.1), VECTOR_EAST);
|
||||||
Vector3 new_direction = pivot1.multPoint(direction);
|
Vector3 new_direction = pivot1.multPoint(direction);
|
||||||
for (int i = 0; i < split_count; i++) {
|
for (int i = 0; i < split_count; i++) {
|
||||||
Matrix4 pivot2 =
|
Matrix4 pivot2 =
|
||||||
Matrix4::newRotateAxis(randomizeValue(M_PI * 2.0 / (double)split_count, 0.9, 1.1), direction);
|
Matrix4::newRotateAxis(randomizeValue(random, M_PI * 2.0 / (double)split_count, 0.9, 1.1), direction);
|
||||||
new_direction = pivot2.multPoint(new_direction);
|
new_direction = pivot2.multPoint(new_direction);
|
||||||
|
|
||||||
Vector3 new_base = base.add(direction.scale(randomizeValue(length, 0.4, 1.0)));
|
Vector3 new_base = base.add(direction.scale(randomizeValue(random, length, 0.4, 1.0)));
|
||||||
if (new_base.add(new_direction).y > 0.1) {
|
if (new_base.add(new_direction).y > 0.1) {
|
||||||
addBranchRecurse(branches, new_base, new_direction, randomizeValue(radius, 0.45, 0.6),
|
addBranchRecurse(random, branches, new_base, new_direction, randomizeValue(random, radius, 0.45, 0.6),
|
||||||
randomizeValue(length, 0.55, 0.85));
|
randomizeValue(random, length, 0.55, 0.85));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VegetationModelDefinition::randomize() {
|
void VegetationModelDefinition::randomize(RandomGenerator &random) {
|
||||||
// Clear structure
|
// Clear structure
|
||||||
solid_volumes.clear();
|
solid_volumes.clear();
|
||||||
foliage_groups.clear();
|
foliage_groups.clear();
|
||||||
foliage_items.clear();
|
foliage_items.clear();
|
||||||
|
|
||||||
// Add trunk and branches
|
// Add trunk and branches
|
||||||
addBranchRecurse(solid_volumes, VECTOR_ZERO, VECTOR_UP, randomizeValue(0.05, 0.6, 1.0),
|
addBranchRecurse(random, solid_volumes, VECTOR_ZERO, VECTOR_UP, randomizeValue(random, 0.05, 0.6, 1.0),
|
||||||
randomizeValue(0.5, 0.8, 1.0));
|
randomizeValue(random, 0.5, 0.8, 1.0));
|
||||||
|
|
||||||
// Add foliage groups
|
// Add foliage groups
|
||||||
for (const auto &branch : solid_volumes) {
|
for (const auto &branch : solid_volumes) {
|
||||||
|
@ -150,9 +150,9 @@ void VegetationModelDefinition::randomize() {
|
||||||
// Add foliage items
|
// Add foliage items
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
double radius = 0.15;
|
double radius = 0.15;
|
||||||
double scale = randomizeValue(radius, 0.5, 1.0);
|
double scale = randomizeValue(random, radius, 0.5, 1.0);
|
||||||
Vector3 dir = Vector3::randomInSphere(1.0 - radius);
|
Vector3 dir = Vector3::randomInSphere(1.0 - radius, false, random);
|
||||||
Vector3 normal = dir.add(Vector3::randomInSphere(0.4)).add(Vector3(0.0, 0.3, 0.0)).normalize();
|
Vector3 normal = dir.add(Vector3::randomInSphere(0.4, false, random)).add(Vector3(0.0, 0.3, 0.0)).normalize();
|
||||||
Disk leaf(dir, normal, scale);
|
Disk leaf(dir, normal, scale);
|
||||||
foliage_items.push_back(leaf);
|
foliage_items.push_back(leaf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ class DEFINITIONSHARED_EXPORT VegetationModelDefinition : public DefinitionNode
|
||||||
/**
|
/**
|
||||||
* Randomize the model geometry.
|
* Randomize the model geometry.
|
||||||
*/
|
*/
|
||||||
void randomize();
|
void randomize(RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SurfaceMaterial *solid_material;
|
SurfaceMaterial *solid_material;
|
||||||
|
|
|
@ -154,7 +154,7 @@ void WaterDefinition::nodeChanged(const DefinitionNode *node, const DefinitionDi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterDefinition::applyPreset(WaterPreset preset) {
|
void WaterDefinition::applyPreset(WaterPreset preset, RandomGenerator &random) {
|
||||||
if (preset == WATER_PRESET_LAKE) {
|
if (preset == WATER_PRESET_LAKE) {
|
||||||
model->setValue(0);
|
model->setValue(0);
|
||||||
} else if (preset == WATER_PRESET_SEA) {
|
} else if (preset == WATER_PRESET_SEA) {
|
||||||
|
|
|
@ -36,7 +36,7 @@ class DEFINITIONSHARED_EXPORT WaterDefinition : public DefinitionNode, public De
|
||||||
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff);
|
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff);
|
||||||
|
|
||||||
typedef enum { WATER_PRESET_LAKE, WATER_PRESET_SEA } WaterPreset;
|
typedef enum { WATER_PRESET_LAKE, WATER_PRESET_SEA } WaterPreset;
|
||||||
void applyPreset(WaterPreset preset);
|
void applyPreset(WaterPreset preset, RandomGenerator &random = RandomGeneratorDefault);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
double transparency;
|
double transparency;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "RayCastingResult.h"
|
#include "RayCastingResult.h"
|
||||||
#include "OpenGLVegetationImpostor.h"
|
#include "OpenGLVegetationImpostor.h"
|
||||||
#include "Texture2D.h"
|
#include "Texture2D.h"
|
||||||
|
#include "RandomGenerator.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -52,8 +53,8 @@ static void startTestRender(SoftwareCanvasRenderer *renderer, const std::string
|
||||||
|
|
||||||
static void testGroundShadowQuality() {
|
static void testGroundShadowQuality() {
|
||||||
Scenery scenery;
|
Scenery scenery;
|
||||||
srand(5);
|
RandomGenerator random(5);
|
||||||
scenery.getTerrain()->applyPreset(TerrainDefinition::TERRAIN_PRESET_STANDARD);
|
scenery.getTerrain()->applyPreset(TerrainDefinition::TERRAIN_PRESET_STANDARD, random);
|
||||||
scenery.getTerrain()->propWaterHeight()->setValue(-0.5);
|
scenery.getTerrain()->propWaterHeight()->setValue(-0.5);
|
||||||
scenery.getWater()->propReflection()->setValue(0.0);
|
scenery.getWater()->propReflection()->setValue(0.0);
|
||||||
scenery.getWater()->material->base->r = 0.0;
|
scenery.getWater()->material->base->r = 0.0;
|
||||||
|
@ -62,7 +63,7 @@ static void testGroundShadowQuality() {
|
||||||
scenery.getWater()->material->reflection = 0.0;
|
scenery.getWater()->material->reflection = 0.0;
|
||||||
scenery.getWater()->foam_coverage = 0.0;
|
scenery.getWater()->foam_coverage = 0.0;
|
||||||
scenery.getWater()->transparency = 0.0;
|
scenery.getWater()->transparency = 0.0;
|
||||||
scenery.getAtmosphere()->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_SUNSET);
|
scenery.getAtmosphere()->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_SUNSET, random);
|
||||||
scenery.getAtmosphere()->setDayTime(16, 45);
|
scenery.getAtmosphere()->setDayTime(16, 45);
|
||||||
scenery.getTextures()->clear();
|
scenery.getTextures()->clear();
|
||||||
TextureLayerDefinition texture(NULL, "test");
|
TextureLayerDefinition texture(NULL, "test");
|
||||||
|
|
|
@ -1 +1,38 @@
|
||||||
#include "RandomGenerator.h"
|
#include "RandomGenerator.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
static RandomGenerator _RandomGeneratorDefault;
|
||||||
|
RandomGenerator& paysages::system::RandomGeneratorDefault = _RandomGeneratorDefault;
|
||||||
|
|
||||||
|
class RandomGenerator::RandomGeneratorPrivate {
|
||||||
|
public:
|
||||||
|
RandomGeneratorPrivate(unsigned int seed): generator(seed) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::default_random_engine generator;
|
||||||
|
std::uniform_real_distribution<double> distribution_double;
|
||||||
|
};
|
||||||
|
|
||||||
|
RandomGenerator::RandomGenerator(RandomGenerator::Seed seed) {
|
||||||
|
if (not seed) {
|
||||||
|
std::random_device true_random;
|
||||||
|
if (true_random.entropy()) {
|
||||||
|
seed = true_random();
|
||||||
|
} else {
|
||||||
|
seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = new RandomGeneratorPrivate(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
RandomGenerator::~RandomGenerator()
|
||||||
|
{
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
double RandomGenerator::genDouble()
|
||||||
|
{
|
||||||
|
return data->distribution_double(data->generator);
|
||||||
|
}
|
||||||
|
|
|
@ -3,18 +3,30 @@
|
||||||
|
|
||||||
#include "system_global.h"
|
#include "system_global.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace paysages {
|
namespace paysages {
|
||||||
namespace system {
|
namespace system {
|
||||||
|
|
||||||
class SYSTEMSHARED_EXPORT RandomGenerator {
|
class SYSTEMSHARED_EXPORT RandomGenerator {
|
||||||
public:
|
public:
|
||||||
RandomGenerator();
|
typedef unsigned long Seed;
|
||||||
|
class RandomGeneratorPrivate;
|
||||||
|
|
||||||
static inline double random() {
|
public:
|
||||||
return ((double)rand()) / (double)RAND_MAX;
|
RandomGenerator(Seed seed = 0);
|
||||||
|
~RandomGenerator();
|
||||||
|
|
||||||
|
inline Seed getSeed() const {
|
||||||
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a 0.0-1.0 random double value.
|
||||||
|
*/
|
||||||
|
double genDouble();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Seed seed;
|
||||||
|
RandomGeneratorPrivate *data;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ class Mutex;
|
||||||
class Semaphore;
|
class Semaphore;
|
||||||
class PictureWriter;
|
class PictureWriter;
|
||||||
class Time;
|
class Time;
|
||||||
|
class RandomGenerator;
|
||||||
|
|
||||||
|
extern RandomGenerator& RandomGeneratorDefault;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
using namespace paysages::system;
|
using namespace paysages::system;
|
||||||
|
|
Loading…
Reference in a new issue