89 lines
2.7 KiB
Rust
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;
|
|
}
|