2013-11-17 21:36:18 +00:00
|
|
|
#include "Scenery.h"
|
|
|
|
|
2013-12-10 21:32:58 +00:00
|
|
|
#include <map>
|
2013-11-17 21:36:18 +00:00
|
|
|
|
|
|
|
#include "PackStream.h"
|
|
|
|
#include "AtmosphereDefinition.h"
|
|
|
|
#include "CameraDefinition.h"
|
|
|
|
#include "CloudsDefinition.h"
|
|
|
|
#include "TerrainDefinition.h"
|
|
|
|
#include "TexturesDefinition.h"
|
2015-10-18 15:26:19 +00:00
|
|
|
#include "VegetationDefinition.h"
|
2013-11-17 21:36:18 +00:00
|
|
|
#include "WaterDefinition.h"
|
2015-12-13 18:56:00 +00:00
|
|
|
#include "DiffManager.h"
|
2015-08-19 18:06:47 +00:00
|
|
|
#include "Logs.h"
|
2015-12-10 18:40:39 +00:00
|
|
|
#include "RandomGenerator.h"
|
2015-12-13 18:56:00 +00:00
|
|
|
#include "IntNode.h"
|
|
|
|
#include "FloatNode.h"
|
2013-11-17 21:36:18 +00:00
|
|
|
|
2013-12-10 21:32:58 +00:00
|
|
|
static const double APP_HEADER = 19866544632.125;
|
|
|
|
static const int DATA_VERSION = 1;
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Scenery::Scenery() : DefinitionNode(NULL, "scenery", "scenery") {
|
2015-08-23 23:23:05 +00:00
|
|
|
atmosphere = new AtmosphereDefinition(this);
|
|
|
|
camera = new CameraDefinition(this);
|
|
|
|
clouds = new CloudsDefinition(this);
|
|
|
|
terrain = new TerrainDefinition(this);
|
|
|
|
textures = new TexturesDefinition(this);
|
|
|
|
water = new WaterDefinition(this);
|
2015-10-18 15:26:19 +00:00
|
|
|
vegetation = new VegetationDefinition(this);
|
2013-11-17 22:33:46 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::validate() {
|
2015-08-12 20:21:10 +00:00
|
|
|
DefinitionNode::validate();
|
2013-11-17 21:36:18 +00:00
|
|
|
|
2015-07-22 16:39:46 +00:00
|
|
|
keepCameraAboveGround(camera);
|
2013-11-17 21:36:18 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 23:36:50 +00:00
|
|
|
Scenery::FileOperationResult Scenery::saveGlobal(const string &filepath) const {
|
2013-12-10 21:32:58 +00:00
|
|
|
PackStream stream;
|
2015-12-17 00:13:20 +00:00
|
|
|
double app_header = to_double(APP_HEADER);
|
|
|
|
double version_header = to_double(DATA_VERSION);
|
2013-12-10 21:32:58 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (not stream.bindToFile(filepath, true)) {
|
2013-12-10 21:32:58 +00:00
|
|
|
return FILE_OPERATION_IOERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream.write(&app_header);
|
|
|
|
stream.write(&version_header);
|
|
|
|
|
|
|
|
save(&stream);
|
|
|
|
|
2015-08-03 22:00:56 +00:00
|
|
|
stream.write(&version_header);
|
|
|
|
stream.write(&app_header);
|
|
|
|
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::debug("Definition") << "Scenery saved to file: " << filepath << endl;
|
2013-12-10 21:32:58 +00:00
|
|
|
return FILE_OPERATION_OK;
|
|
|
|
}
|
|
|
|
|
2015-12-10 23:36:50 +00:00
|
|
|
Scenery::FileOperationResult Scenery::loadGlobal(const string &filepath) {
|
2013-12-10 21:32:58 +00:00
|
|
|
PackStream stream;
|
|
|
|
double app_header, version_header;
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (not stream.bindToFile(filepath, false)) {
|
2013-12-10 21:32:58 +00:00
|
|
|
return FILE_OPERATION_IOERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream.read(&app_header);
|
2015-11-09 21:30:46 +00:00
|
|
|
if (app_header != APP_HEADER) {
|
2013-12-10 21:32:58 +00:00
|
|
|
return FILE_OPERATION_APP_MISMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream.read(&version_header);
|
2015-11-09 21:30:46 +00:00
|
|
|
if ((int)version_header != DATA_VERSION) {
|
2013-12-10 21:32:58 +00:00
|
|
|
return FILE_OPERATION_VERSION_MISMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
load(&stream);
|
|
|
|
|
2015-08-13 17:49:16 +00:00
|
|
|
// Reset read headers, to test them again
|
|
|
|
app_header = -1;
|
|
|
|
version_header = -1;
|
|
|
|
|
2015-08-03 22:00:56 +00:00
|
|
|
stream.read(&version_header);
|
2015-11-09 21:30:46 +00:00
|
|
|
if ((int)version_header != DATA_VERSION) {
|
2015-08-03 22:00:56 +00:00
|
|
|
return FILE_OPERATION_VERSION_MISMATCH;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream.read(&app_header);
|
2015-11-09 21:30:46 +00:00
|
|
|
if (app_header != APP_HEADER) {
|
2015-08-03 22:00:56 +00:00
|
|
|
return FILE_OPERATION_APP_MISMATCH;
|
|
|
|
}
|
|
|
|
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::debug("Definition") << "Scenery loaded from file: " << filepath << endl;
|
2013-12-10 21:32:58 +00:00
|
|
|
return FILE_OPERATION_OK;
|
|
|
|
}
|
|
|
|
|
2015-12-13 18:56:00 +00:00
|
|
|
void Scenery::undo() {
|
|
|
|
DiffManager *diffs = getDiffManager();
|
|
|
|
if (diffs) {
|
|
|
|
diffs->undo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scenery::redo() {
|
|
|
|
DiffManager *diffs = getDiffManager();
|
|
|
|
if (diffs) {
|
|
|
|
diffs->redo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NODE_SETTER(_path_, _nodetype_, _nodeclass_, _value_) \
|
|
|
|
DefinitionNode *node = findByPath(_path_); \
|
|
|
|
if (node) { \
|
|
|
|
if (node->getTypeName() == _nodetype_) { \
|
|
|
|
_nodeclass_ *tnode = (_nodeclass_ *)node; \
|
|
|
|
tnode->setValue(_value_); \
|
|
|
|
} else { \
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::warning("Definition") << "Node " << path << " of wrong type for value " << value << endl; \
|
2015-12-13 18:56:00 +00:00
|
|
|
} \
|
|
|
|
} else { \
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::warning("Definition") << "Can't find node " << path << " to set to " << value << endl; \
|
2015-12-13 18:56:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scenery::set(const string &path, const int &value) {
|
|
|
|
NODE_SETTER(path, "int", IntNode, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scenery::set(const string &path, const double &value) {
|
|
|
|
NODE_SETTER(path, "float", FloatNode, value)
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:38:00 +00:00
|
|
|
const Scenery *Scenery::getScenery() const {
|
2013-11-17 21:36:18 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2015-12-10 18:40:39 +00:00
|
|
|
void Scenery::autoPreset(RandomGenerator &random) {
|
|
|
|
terrain->applyPreset(TerrainDefinition::TERRAIN_PRESET_STANDARD, random);
|
|
|
|
textures->applyPreset(TexturesDefinition::TEXTURES_PRESET_FULL, random);
|
|
|
|
atmosphere->applyPreset(AtmosphereDefinition::ATMOSPHERE_PRESET_CLEAR_DAY, random);
|
|
|
|
water->applyPreset(WaterDefinition::WATER_PRESET_LAKE, random);
|
|
|
|
clouds->applyPreset(CloudsDefinition::CLOUDS_PRESET_PARTLY_CLOUDY, random);
|
2015-12-10 18:48:42 +00:00
|
|
|
vegetation->applyPreset(VegetationDefinition::VEGETATION_PRESET_TEMPERATE, random);
|
2013-11-17 21:36:18 +00:00
|
|
|
|
|
|
|
camera->setLocation(VECTOR_ZERO);
|
|
|
|
camera->setTarget(VECTOR_NORTH);
|
|
|
|
|
|
|
|
validate();
|
2015-08-19 18:06:47 +00:00
|
|
|
|
2015-12-13 19:08:38 +00:00
|
|
|
Logs::debug("Definition") << "New scenery generated from seed " << random.getSeed() << endl;
|
2015-12-10 18:40:39 +00:00
|
|
|
}
|
|
|
|
|
2015-12-10 22:41:42 +00:00
|
|
|
void Scenery::autoPreset(unsigned int seed) {
|
2015-12-10 18:40:39 +00:00
|
|
|
RandomGenerator random(seed);
|
|
|
|
autoPreset(random);
|
2013-11-17 21:36:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::setAtmosphere(AtmosphereDefinition *atmosphere) {
|
2013-11-17 21:36:18 +00:00
|
|
|
atmosphere->copy(this->atmosphere);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::getAtmosphere(AtmosphereDefinition *atmosphere) {
|
2013-11-17 21:36:18 +00:00
|
|
|
this->atmosphere->copy(atmosphere);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::setCamera(CameraDefinition *camera) {
|
2013-11-17 21:36:18 +00:00
|
|
|
camera->copy(this->camera);
|
2015-07-22 16:39:46 +00:00
|
|
|
keepCameraAboveGround(this->camera);
|
2013-11-17 21:36:18 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::getCamera(CameraDefinition *camera) {
|
2013-11-17 21:36:18 +00:00
|
|
|
this->camera->copy(camera);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::setClouds(CloudsDefinition *clouds) {
|
2013-11-17 21:36:18 +00:00
|
|
|
clouds->copy(this->clouds);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::getClouds(CloudsDefinition *clouds) {
|
2013-11-17 21:36:18 +00:00
|
|
|
this->clouds->copy(clouds);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::setTerrain(TerrainDefinition *terrain) {
|
2013-11-17 21:36:18 +00:00
|
|
|
terrain->copy(this->terrain);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::getTerrain(TerrainDefinition *terrain) {
|
2013-11-17 21:36:18 +00:00
|
|
|
this->terrain->copy(terrain);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::setTextures(TexturesDefinition *textures) {
|
2013-11-17 21:36:18 +00:00
|
|
|
textures->copy(this->textures);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::getTextures(TexturesDefinition *textures) {
|
2013-11-17 21:36:18 +00:00
|
|
|
this->textures->copy(textures);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:38:00 +00:00
|
|
|
void Scenery::setVegetation(VegetationDefinition *vegetation) {
|
2015-10-18 15:26:19 +00:00
|
|
|
vegetation->copy(this->vegetation);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:38:00 +00:00
|
|
|
void Scenery::getVegetation(VegetationDefinition *vegetation) {
|
2015-10-18 15:26:19 +00:00
|
|
|
this->vegetation->copy(vegetation);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::setWater(WaterDefinition *water) {
|
2013-11-17 21:36:18 +00:00
|
|
|
water->copy(this->water);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::getWater(WaterDefinition *water) {
|
2013-11-17 21:36:18 +00:00
|
|
|
this->water->copy(water);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Scenery::keepCameraAboveGround(CameraDefinition *camera) {
|
2013-11-17 21:36:18 +00:00
|
|
|
Vector3 camera_location = camera->getLocation();
|
2015-10-08 17:20:44 +00:00
|
|
|
double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, true, true) + 1.0;
|
|
|
|
double water_height = 0.5;
|
2015-11-09 21:30:46 +00:00
|
|
|
if (camera_location.y < water_height || camera_location.y < terrain_height) {
|
2013-11-17 21:36:18 +00:00
|
|
|
double diff = ((water_height > terrain_height) ? water_height : terrain_height) - camera_location.y;
|
|
|
|
camera->setLocation(camera_location.add(Vector3(0.0, diff, 0.0)));
|
|
|
|
}
|
|
|
|
}
|