paysages3d/src/rendering/Scenery.cpp

324 lines
7.4 KiB
C++

#include "Scenery.h"
#include <ctime>
#include "rendering/noise.h"
#include "rendering/terrain/ter_raster.h"
static Scenery* _main_scenery;
static SceneryCustomDataCallback _custom_save = NULL;
static SceneryCustomDataCallback _custom_load = NULL;
static void* _custom_data = NULL;
Scenery::Scenery():
BaseDefinition(NULL)
{
atmosphere = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
camera = cameraCreateDefinition();
clouds = (CloudsDefinition*)CloudsDefinitionClass.create();
terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
textures = (TexturesDefinition*)TexturesDefinitionClass.create();
water = (WaterDefinition*)WaterDefinitionClass.create();
}
Scenery::~Scenery()
{
AtmosphereDefinitionClass.destroy(atmosphere);
cameraDeleteDefinition(camera);
CloudsDefinitionClass.destroy(clouds);
TerrainDefinitionClass.destroy(terrain);
TexturesDefinitionClass.destroy(textures);
WaterDefinitionClass.destroy(water);
}
void Scenery::save(PackStream* stream)
{
BaseDefinition::save(stream);
AtmosphereDefinitionClass.save(stream, atmosphere);
cameraSave(stream, camera);
CloudsDefinitionClass.save(stream, clouds);
TerrainDefinitionClass.save(stream, terrain);
TexturesDefinitionClass.save(stream, textures);
WaterDefinitionClass.save(stream, water);
}
void Scenery::load(PackStream* stream)
{
BaseDefinition::load(stream);
AtmosphereDefinitionClass.load(stream, atmosphere);
cameraLoad(stream, camera);
CloudsDefinitionClass.load(stream, clouds);
TerrainDefinitionClass.load(stream, terrain);
TexturesDefinitionClass.load(stream, textures);
WaterDefinitionClass.load(stream, water);
}
void Scenery::autoPreset(int seed)
{
if (!seed)
{
seed = time(NULL);
}
srand(seed);
terrainAutoPreset(terrain, TERRAIN_PRESET_STANDARD);
texturesAutoPreset(textures, TEXTURES_PRESET_FULL);
atmosphereAutoPreset(atmosphere, ATMOSPHERE_PRESET_CLEAR_DAY);
waterAutoPreset(water, WATER_PRESET_LAKE);
cloudsAutoPreset(clouds, CLOUDS_PRESET_PARTLY_CLOUDY);
cameraSetLocation(camera, VECTOR_ZERO);
cameraSetTarget(camera, VECTOR_NORTH);
cameraValidateDefinition(camera, 1);
}
void Scenery::setAtmosphere(AtmosphereDefinition* atmosphere)
{
AtmosphereDefinitionClass.copy(atmosphere, this->atmosphere);
}
void Scenery::getAtmosphere(AtmosphereDefinition* atmosphere)
{
AtmosphereDefinitionClass.copy(this->atmosphere, atmosphere);
}
void Scenery::setCamera(CameraDefinition* camera)
{
cameraCopyDefinition(camera, this->camera);
}
void Scenery::getCamera(CameraDefinition* camera)
{
cameraCopyDefinition(this->camera, camera);
}
void Scenery::setClouds(CloudsDefinition* clouds)
{
CloudsDefinitionClass.copy(clouds, this->clouds);
}
void Scenery::getClouds(CloudsDefinition* clouds)
{
CloudsDefinitionClass.copy(this->clouds, 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)
{
TexturesDefinitionClass.copy(textures, this->textures);
}
void Scenery::getTextures(TexturesDefinition* textures)
{
TexturesDefinitionClass.copy(this->textures, textures);
}
void Scenery::setWater(WaterDefinition* water)
{
WaterDefinitionClass.copy(water, this->water);
}
void Scenery::getWater(WaterDefinition* water)
{
WaterDefinitionClass.copy(this->water, water);
}
void Scenery::bindToRenderer(Renderer* renderer)
{
cameraCopyDefinition(camera, renderer->render_camera);
AtmosphereRendererClass.bind(renderer, atmosphere);
TerrainRendererClass.bind(renderer, terrain);
TexturesRendererClass.bind(renderer, textures);
CloudsRendererClass.bind(renderer, clouds);
WaterRendererClass.bind(renderer, water);
}
// Transitional C-API
void sceneryInit()
{
noiseInit();
_main_scenery = new Scenery();
}
void sceneryQuit()
{
delete _main_scenery;
noiseQuit();
}
void sceneryAutoPreset(int seed)
{
_main_scenery->autoPreset(seed);
}
void scenerySetCustomDataCallback(SceneryCustomDataCallback callback_save, SceneryCustomDataCallback callback_load, void* data)
{
_custom_save = callback_save;
_custom_load = callback_load;
_custom_data = data;
}
void scenerySave(PackStream* stream)
{
noiseSave(stream);
_main_scenery->save(stream);
if (_custom_save)
{
_custom_save(stream, _custom_data);
}
}
void sceneryLoad(PackStream* stream)
{
/* TODO Use intermediary definitions ? */
noiseLoad(stream);
_main_scenery->load(stream);
if (_custom_load)
{
_custom_load(stream, _custom_data);
}
}
void scenerySetAtmosphere(AtmosphereDefinition* atmosphere)
{
_main_scenery->setAtmosphere(atmosphere);
}
void sceneryGetAtmosphere(AtmosphereDefinition* atmosphere)
{
_main_scenery->getAtmosphere(atmosphere);
}
void scenerySetCamera(CameraDefinition* camera)
{
_main_scenery->setCamera(camera);
}
void sceneryGetCamera(CameraDefinition* camera)
{
_main_scenery->getCamera(camera);
}
void scenerySetClouds(CloudsDefinition* clouds)
{
_main_scenery->setClouds(clouds);
}
void sceneryGetClouds(CloudsDefinition* clouds)
{
_main_scenery->getClouds(clouds);
}
void scenerySetTerrain(TerrainDefinition* terrain)
{
_main_scenery->setTerrain(terrain);
}
void sceneryGetTerrain(TerrainDefinition* terrain)
{
_main_scenery->getTerrain(terrain);
}
TerrainDefinition* sceneryGetTerrainDirect()
{
if (_main_scenery)
{
return _main_scenery->getTerrain();
}
else
{
return NULL;
}
}
void scenerySetTextures(TexturesDefinition* textures)
{
_main_scenery->setTextures(textures);
}
void sceneryGetTextures(TexturesDefinition* textures)
{
_main_scenery->getTextures(textures);
}
void scenerySetWater(WaterDefinition* water)
{
_main_scenery->setWater(water);
}
void sceneryGetWater(WaterDefinition* water)
{
_main_scenery->getWater(water);
}
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 = cameraProject(renderer->render_camera, location);
projected.x += 1.0;
//projected.y += 1.0;
return v3Norm(v3Sub(cameraUnproject(renderer->render_camera, projected), location)); // / (double)render_quality;
}
Renderer* sceneryCreateStandardRenderer()
{
Renderer* result;
result = rendererCreate();
result->rayWalking = _rayWalking;
result->getPrecision = _getPrecision;
sceneryBindRenderer(result);
return result;
}
void sceneryBindRenderer(Renderer* renderer)
{
_main_scenery->bindToRenderer(renderer);
}
void sceneryRenderFirstPass(Renderer* renderer)
{
terrainRenderSurface(renderer);
waterRenderSurface(renderer);
atmosphereRenderSkydome(renderer);
}