tangled
alpha
login
or
join now
j0.lol
/
bl0ck
0
fork
atom
WebGPU Voxel Game
0
fork
atom
overview
issues
4
pulls
pipelines
Basic map chunking
j0.lol
1 year ago
23475d24
8bc7c8ce
+85
-10
3 changed files
expand all
collapse all
unified
split
src
gfx.rs
lib.rs
map.rs
+25
-10
src/gfx.rs
···
15
15
window::Window,
16
16
};
17
17
18
18
-
use crate::{app::WASM_WIN_SIZE, gfx::model::Vertex, Instance, InstanceRaw};
18
18
+
use crate::{app::WASM_WIN_SIZE, gfx::model::Vertex, map::{sl3get, Block, CHUNK_SIZE}, Instance, InstanceRaw};
19
19
20
20
#[repr(C)]
21
21
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
···
290
290
291
291
292
292
let camera = camera::Camera {
293
293
-
eye: vec3(0., 1., 2.),
293
293
+
eye: vec3(50., 20., 50.),
294
294
target: Vec3::ZERO,
295
295
up: Vec3::Y,
296
296
aspect: surface_config.width as f32 / surface_config.height as f32,
···
336
336
bind_group: camera_bind_group,
337
337
};
338
338
339
339
-
const NUM_INSTANCES_PER_ROW: u32 = 10;
339
339
+
// MAP LOAD
340
340
+
341
341
+
let map = crate::map::new_map();
342
342
+
343
343
+
let mut instances = vec![];
344
344
+
340
345
const SPACE_BETWEEN: f32 = 3.0;
341
341
-
let instances = itertools::iproduct!(0..NUM_INSTANCES_PER_ROW, 0..NUM_INSTANCES_PER_ROW)
342
342
-
.map(|(x, z)| {
343
343
-
let mapping = |n| SPACE_BETWEEN * (n as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
344
344
-
let position = vec3(mapping(x), 0.0, mapping(z));
346
346
+
for (_coords, chunk) in map.chunks {
347
347
+
let _3diter = itertools::iproduct!(0..CHUNK_SIZE.0, 0..CHUNK_SIZE.1, 0..CHUNK_SIZE.2);
348
348
+
349
349
+
let mut i = _3diter.filter_map(|(x,y,z)| {
350
350
+
351
351
+
if let Block::AIR = sl3get(&chunk.blocks, x, y, z) {
352
352
+
return None;
353
353
+
}
354
354
+
355
355
+
let mapping = |n| SPACE_BETWEEN * (n as f32 - CHUNK_SIZE.0 as f32 / 2.0);
356
356
+
let position = vec3(mapping(x), -mapping(y), mapping(z));
345
357
346
358
// this is needed so an object at (0, 0, 0) won't get scaled to zero
347
359
// as Quaternions can affect scale if they're not created correctly
···
350
362
_ => Quat::from_axis_angle(Vec3::Z, 0.0),
351
363
};
352
364
353
353
-
Instance { position, rotation }
354
354
-
})
355
355
-
.collect::<Vec<_>>();
365
365
+
Some(Instance { position, rotation })
366
366
+
367
367
+
}).collect::<Vec<_>>();
368
368
+
369
369
+
instances.append(&mut i);
370
370
+
}
356
371
357
372
let instance_data = instances.iter().map(Instance::to_raw).collect::<Vec<_>>();
358
373
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
+1
src/lib.rs
···
2
2
3
3
mod app;
4
4
mod gfx;
5
5
+
mod map;
5
6
6
7
use glam::{Mat3, Mat4, Quat, Vec3};
7
8
#[cfg(target_arch = "wasm32")]
+59
src/map.rs
···
1
1
+
use glam::IVec2;
2
2
+
use std::collections::HashMap;
3
3
+
4
4
+
// I have arbitrarily decided that this is (x,z,y) where +y is up.
5
5
+
6
6
+
pub(crate) const CHUNK_SIZE: (usize, usize, usize) = (16, 16, 16);
7
7
+
8
8
+
// A [Block; X*Y*Z] would be a much more efficient datatype, but, well...
9
9
+
pub type Slice3 = [[[Block; CHUNK_SIZE.0]; CHUNK_SIZE.1]; CHUNK_SIZE.2];
10
10
+
11
11
+
pub fn sl3get(sl3: &Slice3, x: usize, y: usize, z: usize) -> Block {
12
12
+
sl3[y][z][x]
13
13
+
}
14
14
+
pub fn sl3set(sl3: &mut Slice3, x: usize, y: usize, z: usize, new: Block) {
15
15
+
sl3[y][z][x] = new;
16
16
+
}
17
17
+
18
18
+
pub struct WorldMap {
19
19
+
pub chunks: HashMap<IVec2, Chunk>,
20
20
+
}
21
21
+
22
22
+
pub struct Chunk {
23
23
+
pub blocks: Slice3,
24
24
+
}
25
25
+
26
26
+
#[derive(Copy, Clone, Default)]
27
27
+
#[repr(u32)]
28
28
+
pub enum Block {
29
29
+
#[default]
30
30
+
AIR = 0,
31
31
+
BRICK,
32
32
+
}
33
33
+
34
34
+
35
35
+
fn new_chunk(world_x: i32, world_z: i32) -> Chunk {
36
36
+
let mut blocks = Slice3::default();
37
37
+
38
38
+
for (x, z, y) in itertools::iproduct!(0..CHUNK_SIZE.0, 0..CHUNK_SIZE.1, 0..CHUNK_SIZE.2) {
39
39
+
let (xf, zf) = (
40
40
+
(x as i32 + (world_x * CHUNK_SIZE.0 as i32)) as f32,
41
41
+
(z as i32 + (world_z * CHUNK_SIZE.0 as i32)) as f32,
42
42
+
);
43
43
+
44
44
+
let sines = f32::sin(xf * 0.1) + f32::sin(zf * 0.1);
45
45
+
46
46
+
let n = ((sines / 2. * CHUNK_SIZE.2 as f32).round() as i32) <= y as _;
47
47
+
sl3set(&mut blocks, x, y, z, {
48
48
+
if n { Block::BRICK } else { Block::AIR }
49
49
+
});
50
50
+
}
51
51
+
52
52
+
Chunk { blocks }
53
53
+
}
54
54
+
55
55
+
pub fn new_map() -> WorldMap {
56
56
+
WorldMap {
57
57
+
chunks: HashMap::from([((0, 0).into(), new_chunk(0, 0))]),
58
58
+
}
59
59
+
}