norenorn/src/main.rs

89 lines
2.7 KiB
Rust

use bevy::{prelude::*, winit::WinitSettings};
use bevy_vello::{
VelloPlugin,
prelude::*,
vello::kurbo::{PathEl, Point},
};
use fast_poisson::Poisson2D;
use noise::{NoiseFn, Simplex};
use std::{ops::DerefMut, time::SystemTime};
use voronator::CentroidDiagram;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(VelloPlugin::default())
.insert_resource(WinitSettings::desktop_app())
.add_systems(Startup, setup_vector_graphics)
.add_systems(PostStartup, draw_map)
.run();
}
fn setup_vector_graphics(mut commands: Commands) {
commands.spawn((Camera2d, VelloView));
commands.spawn(VelloScene::new());
}
fn draw_map(mut query_scene: Single<(&mut Transform, &mut VelloScene)>) {
let (transform, scene) = query_scene.deref_mut();
scene.reset();
let grid_size_x = 120.0;
let grid_size_y = 60.0;
let points: Vec<_> = Poisson2D::new()
.with_dimensions([grid_size_x, grid_size_y], 1.0)
.iter()
.map(|[x, y]| (x, y))
.collect();
// Barycentric dual mesh
let mesh = CentroidDiagram::<voronator::delaunator::Point>::from_tuple(&points).unwrap();
let seed = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs() as u32;
let noise = Simplex::new(seed);
for cell in &mesh.cells {
let mut first = true;
let mut path = Vec::new();
let mut center = Point::new(0.0, 0.0);
let points = cell.points().len() as f64;
for point in cell.points() {
let point = Point::new(point.x, point.y);
center.x += point.x / points;
center.y += point.y / points;
if first {
first = false;
path.push(PathEl::MoveTo(point));
} else {
path.push(PathEl::LineTo(point));
}
}
let nx = center.x / (grid_size_x as f64) - 0.5;
let ny = center.y / (grid_size_y as f64) - 0.5;
let elevation = (1.0 + noise.get([nx / 0.5, ny / 0.5])) / 2.0;
let d = 2.0 * nx.abs().max(ny.abs());
let elevation = (1.0 + elevation - d) / 2.0;
let color = if elevation < 0.5 {
peniko::Color::from_rgb8(89, 89, 166)
} else {
peniko::Color::from_rgb8(128, 153, 102)
};
scene.fill(
peniko::Fill::NonZero,
kurbo::Affine::default(),
color,
None,
&kurbo::BezPath::from_vec(path),
);
}
let scale = 10.0;
transform.scale = Vec3::ONE * scale;
transform.translation =
Vec3::new(-(grid_size_x as f32 / 2.0), grid_size_y as f32 / 2.0, 0.0) * scale;
}