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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "delaunator"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab46e386c7a38300a0d93b0f3e484bc2ee0aded66c47b14762ec9ab383934fa"
|
||||
dependencies = [
|
||||
"robust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
@ -580,8 +589,10 @@ dependencies = [
|
||||
"env_logger",
|
||||
"log",
|
||||
"nalgebra",
|
||||
"noise",
|
||||
"pollster",
|
||||
"rand",
|
||||
"voronoice",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
@ -1004,6 +1015,17 @@ dependencies = [
|
||||
"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]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
@ -1283,6 +1305,15 @@ dependencies = [
|
||||
"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]]
|
||||
name = "range-alloc"
|
||||
version = "0.1.3"
|
||||
@ -1369,6 +1400,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
|
||||
|
||||
[[package]]
|
||||
name = "robust"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5864e7ef1a6b7bcf1d6ca3f655e65e724ed3b52546a0d0a663c991522f552ea"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
@ -1706,6 +1743,15 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "voronoice"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23acc5e2a7645f62ff9d7d11b46c15819fb1132fc87352a35bb4a9dee3b27d80"
|
||||
dependencies = [
|
||||
"delaunator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
|
@ -11,8 +11,10 @@ wgpu = "22.1"
|
||||
cfg-if = "1"
|
||||
pollster = "0.3"
|
||||
bytemuck = { version = "1.17", features = [ "derive" ] }
|
||||
rand = "0.8"
|
||||
rand = { version = "0.8", features = ["small_rng"] }
|
||||
nalgebra = "0.33"
|
||||
voronoice = "0.2"
|
||||
noise = "0.9"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
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 {
|
||||
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,
|
||||
});
|
||||
|
||||
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
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,
|
||||
});
|
||||
|
||||
@ -265,6 +265,7 @@ impl<'a> Graphics<'a> {
|
||||
rpass.set_vertex_buffer(0, self.vertex_buf.slice(..));
|
||||
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(0..self.state.vertices.len() as u32, 0..1);
|
||||
}
|
||||
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
|
@ -20,7 +20,8 @@ pub fn main() {
|
||||
|
||||
#[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")]
|
||||
{
|
||||
|
148
src/state.rs
148
src/state.rs
@ -1,6 +1,7 @@
|
||||
use std::time::Instant;
|
||||
use nalgebra::Point2;
|
||||
use noise::{Fbm, NoiseFn, Perlin};
|
||||
use rand::prelude::*;
|
||||
use voronoice::{BoundingBox, Point, Voronoi, VoronoiBuilder, VoronoiCell};
|
||||
use winit::event::{DeviceEvent, ElementState, Event, MouseButton, MouseScrollDelta, WindowEvent};
|
||||
|
||||
use crate::graphics::{Uniforms, Vertex};
|
||||
@ -17,6 +18,8 @@ enum CellKind {
|
||||
impl CellKind {
|
||||
const VARIANTS: u8 = 3;
|
||||
fn color(&self) -> [f32; 4] {
|
||||
// let mut rng = thread_rng();
|
||||
// [rng.gen(), rng.gen(), rng.gen(), 1.]
|
||||
match self {
|
||||
Self::Void => [0.; 4],
|
||||
Self::Sea => [0., 0., 1., 1.],
|
||||
@ -35,43 +38,64 @@ impl From<u8> for CellKind {
|
||||
}
|
||||
}
|
||||
|
||||
struct Cell {
|
||||
pos: Point2<f32>,
|
||||
kind: CellKind
|
||||
struct CellData {
|
||||
kind: CellKind,
|
||||
cell: usize,
|
||||
z: f32
|
||||
}
|
||||
impl Cell {
|
||||
const RADIUS: f32 = 1.;
|
||||
fn new(pos: Point2<f32>, kind: CellKind) -> Self {
|
||||
impl CellData {
|
||||
fn new(kind: CellKind, cell: usize, z: f32) -> Self {
|
||||
Self {
|
||||
pos,
|
||||
kind
|
||||
kind,
|
||||
cell,
|
||||
z
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Map {
|
||||
cells: [Cell; Self::SIZE]
|
||||
voronoi: Voronoi,
|
||||
cells_data: Vec<CellData>,
|
||||
seed: u32
|
||||
}
|
||||
impl Map {
|
||||
const HEIGHT: usize = 10;
|
||||
const WIDTH: usize = 10;
|
||||
const SIZE: usize = 10;
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
cells: std::array::from_fn(|_| {
|
||||
let mut rng = thread_rng();
|
||||
Cell::new(
|
||||
Point2::new(rng.gen_range(-1.0..1.), rng.gen_range(-1.0..1.)),
|
||||
rng.gen_range(0..CellKind::VARIANTS).into()
|
||||
)
|
||||
})
|
||||
const HEIGHT: f32 = 2.;
|
||||
const WIDTH: f32 = 2.;
|
||||
const SIZE: usize = 1_00;
|
||||
fn new(seed: u32) -> Self {
|
||||
let mut rng = rand::rngs::SmallRng::seed_from_u64(seed as u64);
|
||||
let mut sites = Vec::with_capacity(Self::SIZE);
|
||||
for _ in 0..Self::SIZE {
|
||||
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 })
|
||||
}
|
||||
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![],
|
||||
uniforms: Uniforms::default(),
|
||||
start: Instant::now(),
|
||||
map: Map::new()
|
||||
map: Map::new(0)
|
||||
};
|
||||
s.update();
|
||||
s
|
||||
@ -98,21 +122,15 @@ impl State {
|
||||
match event {
|
||||
Event::WindowEvent { event: WindowEvent::MouseInput { state, button, ..}, ..} => {
|
||||
if let state = ElementState::Pressed {
|
||||
self.uniforms.camera[2] += match button {
|
||||
MouseButton::Left => 0.1,
|
||||
MouseButton::Right => -0.1,
|
||||
_ => 0.
|
||||
match button {
|
||||
MouseButton::Left => self.map = Map::new(self.map.seed + 1),
|
||||
MouseButton::Right => self.map = Map::new(self.map.seed - 1),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
},
|
||||
// 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 }, ..} => {
|
||||
self.uniforms.camera[2] += match delta {
|
||||
self.uniforms.camera[2] -= match delta {
|
||||
MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
|
||||
MouseScrollDelta::LineDelta(_, y) => y
|
||||
};
|
||||
@ -121,43 +139,21 @@ impl State {
|
||||
}
|
||||
}
|
||||
pub fn update(&mut self) {
|
||||
self.vertices = Vec::with_capacity(self.map.cells.len()*6);
|
||||
self.indices = Vec::with_capacity(self.map.cells.len()*12);
|
||||
|
||||
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.vertices = Vec::new();
|
||||
self.indices = Vec::new();
|
||||
|
||||
self.indices.push(i as u32);
|
||||
self.indices.push((i+1) as u32);
|
||||
self.indices.push((i+2) as u32);
|
||||
|
||||
self.indices.push((i+1) as u32);
|
||||
self.indices.push((i+3) as u32);
|
||||
self.indices.push((i+2) as u32);
|
||||
|
||||
self.indices.push((i+3) as u32);
|
||||
self.indices.push((i+4) as u32);
|
||||
self.indices.push((i+2) as u32);
|
||||
|
||||
self.indices.push((i+3) as u32);
|
||||
self.indices.push((i+5) as u32);
|
||||
self.indices.push((i+4) as u32);
|
||||
for (c, data) in self.map.voronoi.iter_cells().zip(self.map.cells_data.iter()) {
|
||||
let color = data.kind.color();
|
||||
let vs = c.iter_vertices().collect::<Vec<_>>();
|
||||
let i = self.vertices.len() as u32;
|
||||
for v in vs.iter() {
|
||||
self.vertices.push(Vertex { pos: [v.x as f32, v.y as f32, data.z], color });
|
||||
}
|
||||
for v in 1..(vs.len()-1) as u32 {
|
||||
self.indices.push(i);
|
||||
self.indices.push(i+v);
|
||||
self.indices.push(i+v+1);
|
||||
}
|
||||
}
|
||||
|
||||
// dbg!(&self.vertices, &self.indices, &self.uniforms);
|
||||
// dbg!(self.vertices.len(), self.indices.len(), &self.uniforms);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user