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));
|
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_1 = make_perlin(rng, min_octave, max_octave, 2.f);
|
||||||
auto noise_2 = 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)
|
for (int x = 0; x < result.width(); ++x)
|
||||||
{
|
{
|
||||||
math::point p{(x + 0.5f) / result.height(), (y + 0.5f) / result.width()};
|
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;
|
int stage = 0;
|
||||||
bool finished = false;
|
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)
|
: terrain(terrain)
|
||||||
, rng(rng)
|
, rng(rng)
|
||||||
, season(season)
|
, season(season)
|
||||||
|
|
@ -191,7 +192,8 @@ struct solver
|
||||||
snapshot.humidity.resize({N, N}, 0.f);
|
snapshot.humidity.resize({N, N}, 0.f);
|
||||||
new_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 y = 0; y < N; ++y)
|
||||||
for (int x = 0; x < N; ++x)
|
for (int x = 0; x < N; ++x)
|
||||||
|
|
@ -398,6 +400,8 @@ struct weather_app
|
||||||
// 1 - Day
|
// 1 - Day
|
||||||
int day_night = 0;
|
int day_night = 0;
|
||||||
|
|
||||||
|
util::ndarray<math::vector<float, 2>, 2> base_wind_velocity;
|
||||||
|
|
||||||
climate_snapshot snapshots[4][2];
|
climate_snapshot snapshots[4][2];
|
||||||
climate_snapshot average;
|
climate_snapshot average;
|
||||||
climate_snapshot display_snapshot;
|
climate_snapshot display_snapshot;
|
||||||
|
|
@ -417,13 +421,17 @@ struct weather_app
|
||||||
simulation_box = {{{0.f, N}, {0.f, N}}};
|
simulation_box = {{{0.f, N}, {0.f, N}}};
|
||||||
|
|
||||||
terrain.resize({N, N}, 0.f);
|
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 y = 0; y < N; ++y)
|
||||||
for (int x = 0; x < N; ++x)
|
for (int x = 0; x < N; ++x)
|
||||||
terrain(x, y) = ((heightmap(x, y) / 255.f) * 2048.f - 512.f) / 1024.f;
|
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"});
|
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);
|
context.vsync(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -473,13 +481,13 @@ struct weather_app
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!solver && season < 4)
|
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 (!paused)
|
||||||
{
|
{
|
||||||
if (solver)
|
if (solver)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 64; ++i)
|
||||||
{
|
{
|
||||||
solver->step();
|
solver->step();
|
||||||
if (solver->finished)
|
if (solver->finished)
|
||||||
|
|
@ -488,7 +496,7 @@ struct weather_app
|
||||||
}
|
}
|
||||||
else if (season == 4 && !rivers.queue.empty())
|
else if (season == 4 && !rivers.queue.empty())
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 64; ++i)
|
||||||
{
|
{
|
||||||
propagate_rivers();
|
propagate_rivers();
|
||||||
if (rivers.queue.empty())
|
if (rivers.queue.empty())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue