Weather sim v2: use a fixed initial wind field + a small noise for all 8 climate snapshots
This commit is contained in:
parent
c097420a50
commit
5b98171283
1 changed files with 16 additions and 8 deletions
|
|
@ -44,7 +44,7 @@ auto make_perlin(random::generator & rng, int min_octave, int max_octave, float
|
|||
return pcg::fractal<pcg::perlin<float, 2>>(std::move(octaves), std::move(weights));
|
||||
}
|
||||
|
||||
void make_random_vector_field(random::generator & rng, util::ndarray<math::vector<float, 2>, 2> & result, int min_octave, int max_octave, float scale)
|
||||
void add_random_vector_field(random::generator & rng, util::ndarray<math::vector<float, 2>, 2> & result, int min_octave, int max_octave, float scale)
|
||||
{
|
||||
auto noise_1 = make_perlin(rng, min_octave, max_octave, 2.f);
|
||||
auto noise_2 = make_perlin(rng, min_octave, max_octave, 2.f);
|
||||
|
|
@ -54,7 +54,7 @@ void make_random_vector_field(random::generator & rng, util::ndarray<math::vecto
|
|||
for (int x = 0; x < result.width(); ++x)
|
||||
{
|
||||
math::point p{(x + 0.5f) / result.height(), (y + 0.5f) / result.width()};
|
||||
result(x, y) = math::normalized(math::vector{2.f * noise_1(p) - 1.f, 2.f * noise_2(p) - 1.f}) * scale;
|
||||
result(x, y) += math::normalized(math::vector{2.f * noise_1(p) - 1.f, 2.f * noise_2(p) - 1.f}) * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -176,7 +176,8 @@ struct solver
|
|||
int stage = 0;
|
||||
bool finished = false;
|
||||
|
||||
solver(util::ndarray<float, 2> const & terrain, random::generator & rng, int season, int day_night, climate_snapshot & snapshot)
|
||||
solver(util::ndarray<float, 2> const & terrain, random::generator & rng, int season, int day_night, climate_snapshot & snapshot,
|
||||
util::ndarray<math::vector<float, 2>, 2> const & base_wind_velocity)
|
||||
: terrain(terrain)
|
||||
, rng(rng)
|
||||
, season(season)
|
||||
|
|
@ -191,7 +192,8 @@ struct solver
|
|||
snapshot.humidity.resize({N, N}, 0.f);
|
||||
new_humidity.resize({N, N}, 0.f);
|
||||
|
||||
make_random_vector_field(rng, initial_random_wind_velocity, 3, 6, 0.005f);
|
||||
initial_random_wind_velocity = base_wind_velocity.copy();
|
||||
add_random_vector_field(rng, initial_random_wind_velocity, 3, 6, 0.002f);
|
||||
|
||||
for (int y = 0; y < N; ++y)
|
||||
for (int x = 0; x < N; ++x)
|
||||
|
|
@ -398,6 +400,8 @@ struct weather_app
|
|||
// 1 - Day
|
||||
int day_night = 0;
|
||||
|
||||
util::ndarray<math::vector<float, 2>, 2> base_wind_velocity;
|
||||
|
||||
climate_snapshot snapshots[4][2];
|
||||
climate_snapshot average;
|
||||
climate_snapshot display_snapshot;
|
||||
|
|
@ -417,13 +421,17 @@ struct weather_app
|
|||
simulation_box = {{{0.f, N}, {0.f, N}}};
|
||||
|
||||
terrain.resize({N, N}, 0.f);
|
||||
auto heightmap = gfx::read_image<std::uint8_t>(io::file_istream{std::filesystem::path{PSEMEK_EXAMPLES_DIR} / "heightmap_seed_3.png"});
|
||||
auto heightmap = gfx::read_image<std::uint8_t>(io::file_istream{std::filesystem::path{PSEMEK_EXAMPLES_DIR} / "heightmap_seed_1.png"});
|
||||
for (int y = 0; y < N; ++y)
|
||||
for (int x = 0; x < N; ++x)
|
||||
terrain(x, y) = ((heightmap(x, y) / 255.f) * 2048.f - 512.f) / 1024.f;
|
||||
|
||||
biomes_map = gfx::read_image<gfx::color_rgba>(io::file_istream{std::filesystem::path{PSEMEK_EXAMPLES_DIR} / "biomes.png"});
|
||||
|
||||
base_wind_velocity.resize({N, N}, math::vector{0.f, 0.f});
|
||||
|
||||
add_random_vector_field(rng, base_wind_velocity, 3, 6, 0.003f);
|
||||
|
||||
context.vsync(false);
|
||||
}
|
||||
|
||||
|
|
@ -473,13 +481,13 @@ struct weather_app
|
|||
}
|
||||
|
||||
if (!solver && season < 4)
|
||||
solver.emplace(terrain, rng, season, day_night, snapshots[season][day_night]);
|
||||
solver.emplace(terrain, rng, season, day_night, snapshots[season][day_night], base_wind_velocity);
|
||||
|
||||
if (!paused)
|
||||
{
|
||||
if (solver)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
solver->step();
|
||||
if (solver->finished)
|
||||
|
|
@ -488,7 +496,7 @@ struct weather_app
|
|||
}
|
||||
else if (season == 4 && !rivers.queue.empty())
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (int i = 0; i < 64; ++i)
|
||||
{
|
||||
propagate_rivers();
|
||||
if (rivers.queue.empty())
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue