17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-26 20:34:54 +01:00

Draw volumetric clouds, their shadows, a volumetric fog and catalogue stars from a new weather system in the GL 4.6 renderer

This commit is contained in:
2026-10-16 21:44:47 +02:00
parent d509775269
commit 2be85410ce
47 changed files with 5092 additions and 74 deletions

View File

@@ -108,6 +108,16 @@ state_manager::init_scripting_interface() {
simulation::Memory.insert( memorycell );
simulation::Region->insert( memorycell );
}
{
// the weather as a report: text a weather report (METAR) or entries of the weather section, value1 the time of the
// change in seconds. holds the report of the weather it goes to
auto *memorycell = new TMemCell( {
0, -1,
"__simulation.metar",
"memcell" } );
simulation::Memory.insert( memorycell );
simulation::Region->insert( memorycell );
}
}
// legacy method, calculates changes in simulation state over specified time
@@ -147,6 +157,7 @@ state_manager::update_scripting_interface() {
auto *weather{ Memory.find( "__simulation.weather" ) };
auto *time{ Memory.find( "__simulation.time" ) };
auto *date{ Memory.find( "__simulation.date" ) };
auto *metar{ Memory.find( "__simulation.metar" ) };
if( weather == nullptr || time == nullptr || date == nullptr ) {
// scripting interface cells weren't created, nothing to synchronize
@@ -167,6 +178,20 @@ state_manager::update_scripting_interface() {
m_scriptinginterface.weather = std::make_shared<TMemCell>( scene::node_data() );
m_scriptinginterface.date = std::make_shared<TMemCell>( scene::node_data() );
m_scriptinginterface.time = std::make_shared<TMemCell>( scene::node_data() );
m_scriptinginterface.metar.clear();
}
if( metar != nullptr ) {
if( ( true == simulation::is_ready )
&& ( metar->Text() != m_scriptinginterface.metar ) ) {
// a script or an event put a report or weather entries in, the change takes value1 seconds
simulation::Environment.weather().apply_text( metar->Text(), static_cast<float>( metar->Value1() ) );
}
auto const report { to_metar( simulation::Environment.weather().target() ) };
if( report != metar->Text() ) {
metar->UpdateValues( report, 0, 0, basic_event::flags::text );
}
m_scriptinginterface.metar = report;
}
// update scripting interface

View File

@@ -78,6 +78,8 @@ private:
state_serializer m_serializer;
struct {
std::shared_ptr<TMemCell> weather, time, date;
// the weather report last written to __simulation.metar, to tell when something else changed it
std::string metar;
} m_scriptinginterface;
};

View File

@@ -67,6 +67,12 @@ world_environment::compute_weather() const {
Global.AirTemperature > 1 ? "rain:" :
"snow:";
if( Global.Overcast > 1.f ) {
// a described weather may say what falls, whatever the temperature
if( auto const kind { m_weather.precipitation_override() } ) {
Global.Weather = ( *kind == precipitation_type::snow ? "snow:" : "rain:" );
}
}
Global.fTurbidity = Global.Overcast <= 0.10 ? 3 :
Global.Overcast <= 0.20 ? 4 :
@@ -87,6 +93,8 @@ world_environment::init() {
m_moon.init();
m_stars.init();
m_clouds.Init();
// the weather of the scenery, or the one made from its overcast and fog range, before anything reads them
m_weather.init();
m_precipitation.init();
{
auto const rainsoundoverride { simulation::Sound_overrides.find( "weather.rainsound:" ) };
@@ -105,6 +113,8 @@ world_environment::init() {
void
world_environment::update() {
// the clouds move with the wind, a change of the weather goes on; the overcast and fog range follow a described weather
m_weather.update( Timer::GetDeltaTime(), Global.pCamera.Pos );
// move celestial bodies...
m_sun.update();
m_moon.update();

View File

@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
#include "environment/moon.h"
#include "environment/stars.h"
#include "environment/skydome.h"
#include "environment/weather.h"
#include "rendering/precipitation.h"
#include "audio/sound.h"
@@ -62,6 +63,13 @@ public:
inline auto const &
wind_azimuth() const {
return m_wind.azimuth; }
// clouds, fog and precipitation of the scenery, see environment/weather.h
inline auto const &
weather() const {
return m_weather; }
inline auto &
weather() {
return m_weather; }
private:
// types
@@ -87,6 +95,7 @@ private:
basic_precipitation m_precipitation;
sound_source m_rainsound { sound_placement::external, -1 };
basic_wind m_wind;
world_weather m_weather;
};
namespace simulation {

View File

@@ -64,6 +64,8 @@ state_serializer::deserialize_begin( std::string const &Scenariofile ) {
Region = new scene::basic_region();
simulation::State.init_scripting_interface();
// the weather section of the previous scenery doesn't carry over
simulation::Environment.weather().reset();
// NOTE: for the time being import from text format is a given, since we don't have full binary serialization
std::shared_ptr<deserializer_state> state =
@@ -134,6 +136,7 @@ state_serializer::deserialize_begin( std::string const &Scenariofile ) {
{ "test", &state_serializer::deserialize_test },
{ "time", &state_serializer::deserialize_time },
{ "trainset", &state_serializer::deserialize_trainset },
{ "weather", &state_serializer::deserialize_weather },
{ "terrain", &state_serializer::deserialize_terrain },
{ "heightmap_terrain", &state_serializer::deserialize_heightmapterrain },
{ "editorterrain", &state_serializer::deserialize_editorterrain },
@@ -1041,6 +1044,13 @@ state_serializer::deserialize_sky( cParser &Input, scene::scratch_data &Scratchp
skip_until( Input, "endsky" );
}
void
state_serializer::deserialize_weather( cParser &Input, scene::scratch_data &Scratchpad ) {
// clouds, fog and precipitation, see environment/weather.h. wins over the atmo section
simulation::Environment.weather().deserialize( Input );
}
void
state_serializer::deserialize_test( cParser &Input, scene::scratch_data &Scratchpad ) {
@@ -1925,7 +1935,7 @@ std::pair<int, int> state_serializer::preview_include(std::string const &Directi
static std::unordered_map<std::string, std::string> const statementends {
{ "event", "endevent" }, { "trainset", "endtrainset" }, { "isolated", "endisolated" }, { "area", "endarea" }, { "assignment", "endassignment" },
{ "atmo", "endatmo" }, { "camera", "endcamera" }, { "config", "endconfig" }, { "description", "enddescription" }, { "light", "endlight" },
{ "sky", "endsky" }, { "test", "endtest" }, { "time", "endtime" }, { "terrain", "endterrain" }, { "heightmap_terrain", "endheightmap_terrain" }, { "editorterrain", "endeditorterrain" } };
{ "sky", "endsky" }, { "weather", "endweather" }, { "test", "endtest" }, { "time", "endtime" }, { "terrain", "endterrain" }, { "heightmap_terrain", "endheightmap_terrain" }, { "editorterrain", "endeditorterrain" } };
cParser parser(Directive, cParser::buffer_TEXT, Global.asCurrentSceneryPath, Global.bLoadTraction);
// the template is processed with the placement its directive is going to be loaded with

View File

@@ -76,6 +76,7 @@ private:
void deserialize_endscale( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_rotate( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_sky( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_weather( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_test( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_time( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_trainset( cParser &Input, scene::scratch_data &Scratchpad );