diff --git a/src/chunk.rs b/src/chunk.rs index 122dcd7..1454b9a 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -46,6 +46,8 @@ pub const FACE_BOTTOM: FaceFlags = 4; pub const FACE_TOP: FaceFlags = 8; pub const FACE_BACK: FaceFlags = 16; pub const FACE_FRONT: FaceFlags = 32; +pub const FACE_ALL: FaceFlags = + FACE_LEFT | FACE_RIGHT | FACE_BOTTOM | FACE_TOP | FACE_BACK | FACE_FRONT; #[derive(Debug, Clone, Copy)] pub struct Block { @@ -218,11 +220,13 @@ impl Chunk { culled: AHashMap<(usize, usize), (BlockType, FaceFlags)>, queue: &mut VecDeque<(usize, usize)>, highlighted: Option<&(Vector3, Vector3)>, - ) -> Vec<(BlockType, i32, Vector3, Quad, FaceFlags)> { - let mut quads: Vec<(BlockType, i32, Vector3, Quad, FaceFlags)> = Vec::new(); + ) -> Vec<(BlockType, Vector3, Quad)> { + let mut quads: Vec<(BlockType, Vector3, Quad)> = Vec::new(); let mut visited = AHashSet::new(); let hl = highlighted.map(|h| h.0); while let Some((x, z)) = queue.pop_front() { + let translation = offset + Vector3::unit_y() * y as i32; + if visited.contains(&(x, z)) { continue; } @@ -234,13 +238,15 @@ impl Chunk { if hl == Some(Vector3::new(x, y, z)) { let mut quad = Quad::new(x as i32, z as i32, 1, 1); quad.highlighted_normal = highlighted.unwrap().1; - quads.push((block_type, y as i32, offset, quad, quad_faces)); + quad.visible_faces = quad_faces; + quads.push((block_type, translation, quad)); continue; } if block_type == BlockType::Water { - let quad = Quad::new(x as i32, z as i32, 1, 1); - quads.push((block_type, y as i32, offset, quad, quad_faces)); + let mut quad = Quad::new(x as i32, z as i32, 1, 1); + quad.visible_faces = quad_faces; + quads.push((block_type, translation, quad)); continue; } @@ -290,25 +296,22 @@ impl Chunk { } } - let quad = Quad::new(x as i32, z as i32, (xmax - x) as i32, (zmax - z) as i32); - quads.push((block_type, y as i32, offset, quad, quad_faces)); + let mut quad = Quad::new(x as i32, z as i32, (xmax - x) as i32, (zmax - z) as i32); + quad.visible_faces = quad_faces; + quads.push((block_type, translation, quad)); } } quads } - fn quads_to_geometry( - quads: Vec<(BlockType, i32, Vector3, Quad, FaceFlags)>, - ) -> Geometry { + fn quads_to_geometry(quads: Vec<(BlockType, Vector3, Quad)>) -> Geometry { let mut geometry: Geometry = Default::default(); - for (block_type, y, offset, quad, visible_faces) in quads { + for (block_type, translation, quad) in quads { geometry.append(&mut quad.to_geometry( - y, - offset, + translation, block_type, - visible_faces, geometry.vertices.len() as u16, )); } @@ -321,7 +324,7 @@ impl Chunk { offset: Vector3, highlighted: Option<&(Vector3, Vector3)>, ) -> Geometry { - let mut quads: Vec<(BlockType, i32, Vector3, Quad, FaceFlags)> = Vec::new(); + let mut quads: Vec<(BlockType, Vector3, Quad)> = Vec::new(); for y in 0..CHUNK_SIZE { let (culled, mut queue) = self.cull_layer(y); diff --git a/src/quad.rs b/src/quad.rs index b922114..67a09d2 100644 --- a/src/quad.rs +++ b/src/quad.rs @@ -2,7 +2,8 @@ use cgmath::{Vector3, Zero}; use crate::{ chunk::{ - BlockType, FaceFlags, FACE_BACK, FACE_BOTTOM, FACE_FRONT, FACE_LEFT, FACE_RIGHT, FACE_TOP, + BlockType, FaceFlags, FACE_ALL, FACE_BACK, FACE_BOTTOM, FACE_FRONT, FACE_LEFT, FACE_RIGHT, + FACE_TOP, }, geometry::Geometry, vertex::BlockVertex, @@ -12,40 +13,53 @@ use crate::{ pub struct Quad { pub x: i32, pub y: i32, - pub w: i32, - pub h: i32, + pub dx: i32, + pub dy: i32, pub highlighted_normal: Vector3, + pub visible_faces: FaceFlags, } impl Quad { - pub fn new(x: i32, y: i32, w: i32, h: i32) -> Self { + pub fn new(x: i32, y: i32, dx: i32, dy: i32) -> Self { Quad { x, y, - w, - h, + dx, + dy, + + /// The normal of the face that was highlighted. + /// + /// Set to Vector3::zero if no faces are highlighted. highlighted_normal: Vector3::zero(), + + /// Bitmap of the visible faces. + visible_faces: FACE_ALL, } } + /// Converts the quad to `Geometry` (i.e. a list of vertices and indices) to be rendered. + /// + /// # Arguments + /// + /// * `translation` - How much to translate the quad for when rendering. + /// * `block_type` - The type of the block. Used for determining the texture indices. + /// * `start_index` - Which geometry index to start at. #[allow(clippy::many_single_char_names)] #[rustfmt::skip] pub fn to_geometry( &self, - y: i32, - offset: Vector3, + translation: Vector3, block_type: BlockType, - visible_faces: FaceFlags, start_index: u16, ) -> Geometry { - let w = self.w as f32; - let d = self.h as f32; - let h = 1.0; + let dx = self.dx as f32; + let dz = self.dy as f32; + let dy = 1.0; - let x = (self.x + offset.x) as f32; - let y = (y + offset.y) as f32; - let z = (self.y + offset.z) as f32; + let x = (self.x + translation.x) as f32; + let y = translation.y as f32; + let z = (self.y + translation.z) as f32; let t = block_type.texture_indices(); @@ -54,14 +68,14 @@ impl Quad { let mut indices = Vec::new(); let highlighted: [f32; 3] = self.highlighted_normal.cast().unwrap().into(); - if visible_faces & FACE_LEFT == FACE_LEFT { + if self.visible_faces & FACE_LEFT == FACE_LEFT { let normal = [-1.0, 0.0, 0.0]; let highlighted = (normal == highlighted) as i32; vertices.extend(&[ - BlockVertex { position: [x, y, z ], texture_coordinates: [d, 1.0], texture_id: t.0 as i32, normal, highlighted }, - BlockVertex { position: [x, y, z + d], texture_coordinates: [0.0, 1.0], texture_id: t.0 as i32, normal, highlighted }, - BlockVertex { position: [x, y + h, z + d], texture_coordinates: [0.0, 0.0], texture_id: t.0 as i32, normal, highlighted }, - BlockVertex { position: [x, y + h, z ], texture_coordinates: [d, 0.0], texture_id: t.0 as i32, normal, highlighted }, + BlockVertex { position: [x, y, z ], texture_coordinates: [dz, 1.0], texture_id: t.0 as i32, normal, highlighted }, + BlockVertex { position: [x, y, z + dz], texture_coordinates: [0.0, 1.0], texture_id: t.0 as i32, normal, highlighted }, + BlockVertex { position: [x, y + dy, z + dz], texture_coordinates: [0.0, 0.0], texture_id: t.0 as i32, normal, highlighted }, + BlockVertex { position: [x, y + dy, z ], texture_coordinates: [dz, 0.0], texture_id: t.0 as i32, normal, highlighted }, ]); indices.extend(&[ 2 + current_index, current_index, 1 + current_index, @@ -70,14 +84,14 @@ impl Quad { current_index += 4; } - if visible_faces & FACE_RIGHT == FACE_RIGHT { + if self.visible_faces & FACE_RIGHT == FACE_RIGHT { let normal = [1.0, 0.0, 0.0]; let highlighted = (normal == highlighted) as i32; vertices.extend(&[ - BlockVertex { position: [x + w, y, z ], texture_coordinates: [0.0, 1.0], texture_id: t.1 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y, z + d], texture_coordinates: [d, 1.0], texture_id: t.1 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y + h, z + d], texture_coordinates: [d, 0.0], texture_id: t.1 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y + h, z ], texture_coordinates: [0.0, 0.0], texture_id: t.1 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y, z ], texture_coordinates: [0.0, 1.0], texture_id: t.1 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y, z + dz], texture_coordinates: [dz, 1.0], texture_id: t.1 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y + dy, z + dz], texture_coordinates: [dz, 0.0], texture_id: t.1 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y + dy, z ], texture_coordinates: [0.0, 0.0], texture_id: t.1 as i32, normal, highlighted }, ]); indices.extend(&[ 1 + current_index, current_index, 2 + current_index, @@ -86,14 +100,14 @@ impl Quad { current_index += 4; } - if visible_faces & FACE_BACK == FACE_BACK { + if self.visible_faces & FACE_BACK == FACE_BACK { let normal = [0.0, 0.0, -1.0]; let highlighted = (normal == highlighted) as i32; vertices.extend(&[ - BlockVertex { position: [x, y, z], texture_coordinates: [w, 1.0], texture_id: t.2 as i32, normal, highlighted }, - BlockVertex { position: [x, y + h, z], texture_coordinates: [w, 0.0], texture_id: t.2 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y + h, z], texture_coordinates: [0.0, 0.0], texture_id: t.2 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y, z], texture_coordinates: [0.0, 1.0], texture_id: t.2 as i32, normal, highlighted }, + BlockVertex { position: [x, y, z], texture_coordinates: [dx, 1.0], texture_id: t.2 as i32, normal, highlighted }, + BlockVertex { position: [x, y + dy, z], texture_coordinates: [dx, 0.0], texture_id: t.2 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y + dy, z], texture_coordinates: [0.0, 0.0], texture_id: t.2 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y, z], texture_coordinates: [0.0, 1.0], texture_id: t.2 as i32, normal, highlighted }, ]); indices.extend(&[ 2 + current_index, current_index, 1 + current_index, @@ -102,14 +116,14 @@ impl Quad { current_index += 4; } - if visible_faces & FACE_FRONT == FACE_FRONT { + if self.visible_faces & FACE_FRONT == FACE_FRONT { let normal = [0.0, 0.0, 1.0]; let highlighted = (normal == highlighted) as i32; vertices.extend(&[ - BlockVertex { position: [x, y, z + d], texture_coordinates: [0.0, 1.0], texture_id: t.3 as i32, normal, highlighted }, - BlockVertex { position: [x, y + h, z + d], texture_coordinates: [0.0, 0.0], texture_id: t.3 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y + h, z + d], texture_coordinates: [w, 0.0], texture_id: t.3 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y, z + d], texture_coordinates: [w, 1.0], texture_id: t.3 as i32, normal, highlighted }, + BlockVertex { position: [x, y, z + dz], texture_coordinates: [0.0, 1.0], texture_id: t.3 as i32, normal, highlighted }, + BlockVertex { position: [x, y + dy, z + dz], texture_coordinates: [0.0, 0.0], texture_id: t.3 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y + dy, z + dz], texture_coordinates: [dx, 0.0], texture_id: t.3 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y, z + dz], texture_coordinates: [dx, 1.0], texture_id: t.3 as i32, normal, highlighted }, ]); indices.extend(&[ 1 + current_index, current_index, 2 + current_index, @@ -118,14 +132,14 @@ impl Quad { current_index += 4; } - if visible_faces & FACE_BOTTOM == FACE_BOTTOM { + if self.visible_faces & FACE_BOTTOM == FACE_BOTTOM { let normal = [0.0, -1.0, 0.0]; let highlighted = (normal == highlighted) as i32; vertices.extend(&[ - BlockVertex { position: [x, y, z ], texture_coordinates: [w, 0.0], texture_id: t.4 as i32, normal, highlighted }, - BlockVertex { position: [x, y, z + d], texture_coordinates: [w, d ], texture_id: t.4 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y, z + d], texture_coordinates: [0.0, d ], texture_id: t.4 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y, z ], texture_coordinates: [0.0, 0.0], texture_id: t.4 as i32, normal, highlighted }, + BlockVertex { position: [x, y, z ], texture_coordinates: [dx, 0.0], texture_id: t.4 as i32, normal, highlighted }, + BlockVertex { position: [x, y, z + dz], texture_coordinates: [dx, dz ], texture_id: t.4 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y, z + dz], texture_coordinates: [0.0, dz ], texture_id: t.4 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y, z ], texture_coordinates: [0.0, 0.0], texture_id: t.4 as i32, normal, highlighted }, ]); indices.extend(&[ current_index, 2 + current_index, 1 + current_index, @@ -134,14 +148,14 @@ impl Quad { current_index += 4; } - if visible_faces & FACE_TOP == FACE_TOP { + if self.visible_faces & FACE_TOP == FACE_TOP { let normal = [0.0, 1.0, 0.0]; let highlighted = (normal == highlighted) as i32; vertices.extend(&[ - BlockVertex { position: [x, y + h, z ], texture_coordinates: [0.0, 0.0], texture_id: t.5 as i32, normal, highlighted }, - BlockVertex { position: [x, y + h, z + d], texture_coordinates: [0.0, d ], texture_id: t.5 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y + h, z + d], texture_coordinates: [w, d ], texture_id: t.5 as i32, normal, highlighted }, - BlockVertex { position: [x + w, y + h, z ], texture_coordinates: [w, 0.0], texture_id: t.5 as i32, normal, highlighted }, + BlockVertex { position: [x, y + dy, z ], texture_coordinates: [0.0, 0.0], texture_id: t.5 as i32, normal, highlighted }, + BlockVertex { position: [x, y + dy, z + dz], texture_coordinates: [0.0, dz ], texture_id: t.5 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y + dy, z + dz], texture_coordinates: [dx, dz ], texture_id: t.5 as i32, normal, highlighted }, + BlockVertex { position: [x + dx, y + dy, z ], texture_coordinates: [dx, 0.0], texture_id: t.5 as i32, normal, highlighted }, ]); indices.extend(&[ current_index, 1 + current_index, 2 + current_index,