save (works)
This commit is contained in:
parent
549bd261b8
commit
97f4581224
45
.vscode/launch.json
vendored
Normal file
45
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
|
||||||
|
// Pointez pour afficher la description des attributs existants.
|
||||||
|
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'forestiles'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=forestiles",
|
||||||
|
"--package=forestiles"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "forestiles",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'forestiles'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=forestiles",
|
||||||
|
"--package=forestiles"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "forestiles",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
46
Cargo.lock
generated
46
Cargo.lock
generated
@ -473,6 +473,15 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "delaunator"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ab46e386c7a38300a0d93b0f3e484bc2ee0aded66c47b14762ec9ab383934fa"
|
||||||
|
dependencies = [
|
||||||
|
"robust",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dispatch"
|
name = "dispatch"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -580,8 +589,10 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
|
"noise",
|
||||||
"pollster",
|
"pollster",
|
||||||
"rand",
|
"rand",
|
||||||
|
"voronoice",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
@ -1004,6 +1015,17 @@ dependencies = [
|
|||||||
"jni-sys",
|
"jni-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "noise"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6da45c8333f2e152fc665d78a380be060eb84fad8ca4c9f7ac8ca29216cff0cc"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
"rand",
|
||||||
|
"rand_xorshift",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@ -1283,6 +1305,15 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_xorshift"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "range-alloc"
|
name = "range-alloc"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@ -1369,6 +1400,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
|
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "robust"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5864e7ef1a6b7bcf1d6ca3f655e65e724ed3b52546a0d0a663c991522f552ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-hash"
|
name = "rustc-hash"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@ -1706,6 +1743,15 @@ version = "0.9.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "voronoice"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23acc5e2a7645f62ff9d7d11b46c15819fb1132fc87352a35bb4a9dee3b27d80"
|
||||||
|
dependencies = [
|
||||||
|
"delaunator",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
|
@ -11,8 +11,10 @@ wgpu = "22.1"
|
|||||||
cfg-if = "1"
|
cfg-if = "1"
|
||||||
pollster = "0.3"
|
pollster = "0.3"
|
||||||
bytemuck = { version = "1.17", features = [ "derive" ] }
|
bytemuck = { version = "1.17", features = [ "derive" ] }
|
||||||
rand = "0.8"
|
rand = { version = "0.8", features = ["small_rng"] }
|
||||||
nalgebra = "0.33"
|
nalgebra = "0.33"
|
||||||
|
voronoice = "0.2"
|
||||||
|
noise = "0.9"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
console_error_panic_hook = "0.1.6"
|
console_error_panic_hook = "0.1.6"
|
||||||
|
@ -93,13 +93,13 @@ impl<'a> Graphics<'a> {
|
|||||||
|
|
||||||
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Vertex Buffer"),
|
label: Some("Vertex Buffer"),
|
||||||
contents: bytemuck::cast_slice(&state.vertices),
|
contents: &[bytemuck::cast_slice::<Vertex, _>(&state.vertices), &[0; 1024]].concat(),
|
||||||
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Index Buffer"),
|
label: Some("Index Buffer"),
|
||||||
contents: bytemuck::cast_slice(&state.indices),
|
contents: &[bytemuck::cast_slice::<u32, _>(&state.indices), &[0; 1024]].concat(),
|
||||||
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -265,6 +265,7 @@ impl<'a> Graphics<'a> {
|
|||||||
rpass.set_vertex_buffer(0, self.vertex_buf.slice(..));
|
rpass.set_vertex_buffer(0, self.vertex_buf.slice(..));
|
||||||
rpass.set_index_buffer(self.index_buf.slice(..), wgpu::IndexFormat::Uint32);
|
rpass.set_index_buffer(self.index_buf.slice(..), wgpu::IndexFormat::Uint32);
|
||||||
rpass.draw_indexed(0..self.state.indices.len() as u32, 0, 0..1);
|
rpass.draw_indexed(0..self.state.indices.len() as u32, 0, 0..1);
|
||||||
|
// rpass.draw(0..self.state.vertices.len() as u32, 0..1);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.queue.submit(Some(encoder.finish()));
|
self.queue.submit(Some(encoder.finish()));
|
||||||
|
@ -20,7 +20,8 @@ pub fn main() {
|
|||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
{
|
{
|
||||||
pollster::block_on(Graphics::init(&window, State::new())).run(event_loop);
|
let state = State::new();
|
||||||
|
pollster::block_on(Graphics::init(&window, state)).run(event_loop);
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
|
148
src/state.rs
148
src/state.rs
@ -1,6 +1,7 @@
|
|||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use nalgebra::Point2;
|
use noise::{Fbm, NoiseFn, Perlin};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
use voronoice::{BoundingBox, Point, Voronoi, VoronoiBuilder, VoronoiCell};
|
||||||
use winit::event::{DeviceEvent, ElementState, Event, MouseButton, MouseScrollDelta, WindowEvent};
|
use winit::event::{DeviceEvent, ElementState, Event, MouseButton, MouseScrollDelta, WindowEvent};
|
||||||
|
|
||||||
use crate::graphics::{Uniforms, Vertex};
|
use crate::graphics::{Uniforms, Vertex};
|
||||||
@ -17,6 +18,8 @@ enum CellKind {
|
|||||||
impl CellKind {
|
impl CellKind {
|
||||||
const VARIANTS: u8 = 3;
|
const VARIANTS: u8 = 3;
|
||||||
fn color(&self) -> [f32; 4] {
|
fn color(&self) -> [f32; 4] {
|
||||||
|
// let mut rng = thread_rng();
|
||||||
|
// [rng.gen(), rng.gen(), rng.gen(), 1.]
|
||||||
match self {
|
match self {
|
||||||
Self::Void => [0.; 4],
|
Self::Void => [0.; 4],
|
||||||
Self::Sea => [0., 0., 1., 1.],
|
Self::Sea => [0., 0., 1., 1.],
|
||||||
@ -35,43 +38,64 @@ impl From<u8> for CellKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Cell {
|
struct CellData {
|
||||||
pos: Point2<f32>,
|
kind: CellKind,
|
||||||
kind: CellKind
|
cell: usize,
|
||||||
|
z: f32
|
||||||
}
|
}
|
||||||
impl Cell {
|
impl CellData {
|
||||||
const RADIUS: f32 = 1.;
|
fn new(kind: CellKind, cell: usize, z: f32) -> Self {
|
||||||
fn new(pos: Point2<f32>, kind: CellKind) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
pos,
|
kind,
|
||||||
kind
|
cell,
|
||||||
|
z
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Map {
|
struct Map {
|
||||||
cells: [Cell; Self::SIZE]
|
voronoi: Voronoi,
|
||||||
|
cells_data: Vec<CellData>,
|
||||||
|
seed: u32
|
||||||
}
|
}
|
||||||
impl Map {
|
impl Map {
|
||||||
const HEIGHT: usize = 10;
|
const HEIGHT: f32 = 2.;
|
||||||
const WIDTH: usize = 10;
|
const WIDTH: f32 = 2.;
|
||||||
const SIZE: usize = 10;
|
const SIZE: usize = 1_00;
|
||||||
fn new() -> Self {
|
fn new(seed: u32) -> Self {
|
||||||
Self {
|
let mut rng = rand::rngs::SmallRng::seed_from_u64(seed as u64);
|
||||||
cells: std::array::from_fn(|_| {
|
let mut sites = Vec::with_capacity(Self::SIZE);
|
||||||
let mut rng = thread_rng();
|
for _ in 0..Self::SIZE {
|
||||||
Cell::new(
|
sites.push(Point { x:rng.gen_range(-Self::WIDTH/2.0..Self::WIDTH/2.0) as f64, y:rng.gen_range(-Self::HEIGHT/2.0..Self::HEIGHT/2.0) as f64 })
|
||||||
Point2::new(rng.gen_range(-1.0..1.), rng.gen_range(-1.0..1.)),
|
}
|
||||||
rng.gen_range(0..CellKind::VARIANTS).into()
|
let voronoi = VoronoiBuilder::default()
|
||||||
)
|
.set_sites(sites)
|
||||||
})
|
.set_bounding_box(BoundingBox::new_centered(Self::WIDTH as f64, Self::HEIGHT as f64))
|
||||||
|
.set_lloyd_relaxation_iterations(5)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
let mut cells_data = Vec::with_capacity(Self::SIZE);
|
||||||
|
let z_noise = Fbm::<Perlin>::new(seed);
|
||||||
|
for i in 0..Self::SIZE {
|
||||||
|
let c = voronoi.cell(i);
|
||||||
|
let site = c.site_position();
|
||||||
|
let z = (
|
||||||
|
0.3 // Arbitrary value
|
||||||
|
+ ((z_noise.get([site.x, site.y])+1.)/2.) // Noise + [0; 1]
|
||||||
|
- ((site.x.powi(2)+site.y.powi(2)).sqrt()*0.5) // Distance - [0; sqrt(2)] * 0.5
|
||||||
|
).clamp(0., 1.);
|
||||||
|
let k = if z <= 0.5 {
|
||||||
|
CellKind::Sea
|
||||||
|
} else {
|
||||||
|
CellKind::Grass
|
||||||
|
};
|
||||||
|
cells_data.push(CellData::new(k, i, z as f32));
|
||||||
|
}
|
||||||
|
Self {
|
||||||
|
voronoi,
|
||||||
|
cells_data,
|
||||||
|
seed
|
||||||
}
|
}
|
||||||
|
|
||||||
// "sgssv
|
|
||||||
// ggsvg
|
|
||||||
// gsvvs
|
|
||||||
// vgsgs
|
|
||||||
// ssggs".into()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +113,7 @@ impl State {
|
|||||||
indices: vec![],
|
indices: vec![],
|
||||||
uniforms: Uniforms::default(),
|
uniforms: Uniforms::default(),
|
||||||
start: Instant::now(),
|
start: Instant::now(),
|
||||||
map: Map::new()
|
map: Map::new(0)
|
||||||
};
|
};
|
||||||
s.update();
|
s.update();
|
||||||
s
|
s
|
||||||
@ -98,21 +122,15 @@ impl State {
|
|||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event: WindowEvent::MouseInput { state, button, ..}, ..} => {
|
Event::WindowEvent { event: WindowEvent::MouseInput { state, button, ..}, ..} => {
|
||||||
if let state = ElementState::Pressed {
|
if let state = ElementState::Pressed {
|
||||||
self.uniforms.camera[2] += match button {
|
match button {
|
||||||
MouseButton::Left => 0.1,
|
MouseButton::Left => self.map = Map::new(self.map.seed + 1),
|
||||||
MouseButton::Right => -0.1,
|
MouseButton::Right => self.map = Map::new(self.map.seed - 1),
|
||||||
_ => 0.
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Event::WindowEvent { event: WindowEvent::MouseWheel { delta, ..}, ..} => {
|
|
||||||
// self.uniforms.camera[2] -= match delta {
|
|
||||||
// MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
|
|
||||||
// MouseScrollDelta::LineDelta(_, y) => y
|
|
||||||
// };
|
|
||||||
// },
|
|
||||||
Event::DeviceEvent { event: DeviceEvent::MouseWheel { delta }, ..} => {
|
Event::DeviceEvent { event: DeviceEvent::MouseWheel { delta }, ..} => {
|
||||||
self.uniforms.camera[2] += match delta {
|
self.uniforms.camera[2] -= match delta {
|
||||||
MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
|
MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
|
||||||
MouseScrollDelta::LineDelta(_, y) => y
|
MouseScrollDelta::LineDelta(_, y) => y
|
||||||
};
|
};
|
||||||
@ -121,43 +139,21 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self) {
|
||||||
self.vertices = Vec::with_capacity(self.map.cells.len()*6);
|
self.vertices = Vec::new();
|
||||||
self.indices = Vec::with_capacity(self.map.cells.len()*12);
|
self.indices = Vec::new();
|
||||||
|
|
||||||
for c in self.map.cells.iter() {
|
|
||||||
let x = x as f32;
|
|
||||||
let y = y as f32;
|
|
||||||
let i = self.vertices.len();
|
|
||||||
let color = c.kind.color();
|
|
||||||
let center = [(0.5+x+((y%2.)*0.5)) * (SQRT_3*Cell::RADIUS), -(0.5+y)*(1.5*Cell::RADIUS)];
|
|
||||||
// self.vertices.push(Vertex { pos: [center[0], center[1], 0.], color });
|
|
||||||
// self.vertices.push(Vertex { pos: [center[0]+0.1, center[1]+0.1, 0.], color });
|
|
||||||
// self.vertices.push(Vertex { pos: [center[0]-0.1, center[1]+0.1, 0.], color });
|
|
||||||
self.vertices.push(Vertex { pos: [center[0], center[1]+Cell::RADIUS, 0.], color: color.clone() });
|
|
||||||
self.vertices.push(Vertex { pos: [center[0]-(0.5*SQRT_3*Cell::RADIUS), center[1]+(0.5*Cell::RADIUS), 0.], color: color.clone() });
|
|
||||||
self.vertices.push(Vertex { pos: [center[0]+(0.5*SQRT_3*Cell::RADIUS), center[1]+(0.5*Cell::RADIUS), 0.], color: color.clone() });
|
|
||||||
self.vertices.push(Vertex { pos: [center[0]-(0.5*SQRT_3*Cell::RADIUS), center[1]-(0.5*Cell::RADIUS), 0.], color: color.clone() });
|
|
||||||
self.vertices.push(Vertex { pos: [center[0]+(0.5*SQRT_3*Cell::RADIUS), center[1]-(0.5*Cell::RADIUS), 0.], color: color.clone() });
|
|
||||||
self.vertices.push(Vertex { pos: [center[0], center[1]-Cell::RADIUS, 0.], color: color.clone() });
|
|
||||||
|
|
||||||
self.indices.push(i as u32);
|
for (c, data) in self.map.voronoi.iter_cells().zip(self.map.cells_data.iter()) {
|
||||||
self.indices.push((i+1) as u32);
|
let color = data.kind.color();
|
||||||
self.indices.push((i+2) as u32);
|
let vs = c.iter_vertices().collect::<Vec<_>>();
|
||||||
|
let i = self.vertices.len() as u32;
|
||||||
self.indices.push((i+1) as u32);
|
for v in vs.iter() {
|
||||||
self.indices.push((i+3) as u32);
|
self.vertices.push(Vertex { pos: [v.x as f32, v.y as f32, data.z], color });
|
||||||
self.indices.push((i+2) as u32);
|
}
|
||||||
|
for v in 1..(vs.len()-1) as u32 {
|
||||||
self.indices.push((i+3) as u32);
|
self.indices.push(i);
|
||||||
self.indices.push((i+4) as u32);
|
self.indices.push(i+v);
|
||||||
self.indices.push((i+2) as u32);
|
self.indices.push(i+v+1);
|
||||||
|
}
|
||||||
self.indices.push((i+3) as u32);
|
|
||||||
self.indices.push((i+5) as u32);
|
|
||||||
self.indices.push((i+4) as u32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dbg!(&self.vertices, &self.indices, &self.uniforms);
|
|
||||||
// dbg!(self.vertices.len(), self.indices.len(), &self.uniforms);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user