Move cube::to_vertices to quad::to_vertices

This commit is contained in:
Sijmen 2021-06-02 12:19:56 +02:00
parent 107c7c5cab
commit cfe4304f7c
Signed by: vijfhoek
GPG key ID: 82D05C89B28B0DAE
6 changed files with 163 additions and 181 deletions

View file

@ -1,8 +1,8 @@
use std::{collections::VecDeque, usize};
use crate::{cube, geometry::Geometry, quad::Quad, vertex::BlockVertex};
use crate::{geometry::Geometry, quad::Quad, vertex::BlockVertex};
use ahash::{AHashMap, AHashSet};
use cgmath::{Vector3, Zero};
use cgmath::Vector3;
use noise::utils::{NoiseMapBuilder, PlaneMapBuilder};
#[allow(dead_code)]
@ -218,9 +218,8 @@ impl Chunk {
culled: AHashMap<(usize, usize), (BlockType, FaceFlags)>,
queue: &mut VecDeque<(usize, usize)>,
highlighted: Option<&(Vector3<usize>, Vector3<i32>)>,
) -> Vec<(BlockType, i32, Vector3<i32>, Quad, Vector3<i32>, FaceFlags)> {
let mut quads: Vec<(BlockType, i32, Vector3<i32>, Quad, Vector3<i32>, FaceFlags)> =
Vec::new();
) -> Vec<(BlockType, i32, Vector3<i32>, Quad, FaceFlags)> {
let mut quads: Vec<(BlockType, i32, Vector3<i32>, Quad, FaceFlags)> = Vec::new();
let mut visited = AHashSet::new();
let hl = highlighted.map(|h| h.0);
while let Some((x, z)) = queue.pop_front() {
@ -233,28 +232,15 @@ impl Chunk {
let mut quad_faces = visible_faces;
if hl == Some(Vector3::new(x, y, z)) {
let quad = Quad::new(x as i32, z as i32, 1, 1);
quads.push((
block_type,
y as i32,
offset,
quad,
highlighted.unwrap().1,
quad_faces,
));
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));
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,
Vector3::zero(),
quad_faces,
));
quads.push((block_type, y as i32, offset, quad, quad_faces));
continue;
}
@ -305,14 +291,7 @@ 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,
Vector3::zero(),
quad_faces,
));
quads.push((block_type, y as i32, offset, quad, quad_faces));
}
}
@ -320,20 +299,15 @@ impl Chunk {
}
fn quads_to_geometry(
quads: Vec<(BlockType, i32, Vector3<i32>, Quad, Vector3<i32>, FaceFlags)>,
quads: Vec<(BlockType, i32, Vector3<i32>, Quad, FaceFlags)>,
) -> Geometry<BlockVertex> {
let mut geometry: Geometry<BlockVertex> = Default::default();
for (block_type, y, offset, quad, highlighted, visible_faces) in quads {
let texture_indices = block_type.texture_indices();
geometry.append(&mut cube::vertices(
&quad,
for (block_type, y, offset, quad, visible_faces) in quads {
geometry.append(&mut quad.to_geometry(
y,
1.0,
offset,
texture_indices,
highlighted,
block_type,
visible_faces,
geometry.vertices.len() as u16,
));
@ -347,8 +321,7 @@ impl Chunk {
offset: Vector3<i32>,
highlighted: Option<&(Vector3<usize>, Vector3<i32>)>,
) -> Geometry<BlockVertex> {
let mut quads: Vec<(BlockType, i32, Vector3<i32>, Quad, Vector3<i32>, FaceFlags)> =
Vec::new();
let mut quads: Vec<(BlockType, i32, Vector3<i32>, Quad, FaceFlags)> = Vec::new();
for y in 0..CHUNK_SIZE {
let (culled, mut queue) = self.cull_layer(y);

View file

@ -1,133 +0,0 @@
use crate::geometry::Geometry;
use cgmath::Vector3;
use crate::{
chunk::{FaceFlags, FACE_BACK, FACE_BOTTOM, FACE_FRONT, FACE_LEFT, FACE_RIGHT, FACE_TOP},
quad::Quad,
vertex::BlockVertex,
};
#[allow(clippy::many_single_char_names)]
#[rustfmt::skip]
pub fn vertices(
quad: &Quad,
y: i32,
z_height: f32,
offset: Vector3<i32>,
texture_indices: (usize, usize, usize, usize, usize, usize),
highlighted: Vector3<i32>,
visible_faces: FaceFlags,
start_index: u16,
) -> Geometry<BlockVertex> {
let w = quad.w as f32;
let h = quad.h as f32;
let zh = z_height;
let x = (quad.x + offset.x) as f32;
let y = (y + offset.y) as f32;
let z = (quad.y + offset.z) as f32;
let t = texture_indices;
let mut current_index = start_index;
let mut vertices = Vec::new();
let mut indices = Vec::new();
let highlighted: [f32; 3] = (-highlighted).cast().unwrap().into();
if 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: [h, 1.0], texture_id: t.0 as i32, normal, highlighted },
BlockVertex { position: [x, y, z + h], texture_coordinates: [0.0, 1.0], texture_id: t.0 as i32, normal, highlighted },
BlockVertex { position: [x, y + zh, z + h], texture_coordinates: [0.0, 0.0], texture_id: t.0 as i32, normal, highlighted },
BlockVertex { position: [x, y + zh, z ], texture_coordinates: [h, 0.0], texture_id: t.0 as i32, normal, highlighted },
]);
indices.extend(&[
2 + current_index, current_index, 1 + current_index,
3 + current_index, current_index, 2 + current_index,
]);
current_index += 4;
}
if 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 + h], texture_coordinates: [h, 1.0], texture_id: t.1 as i32, normal, highlighted },
BlockVertex { position: [x + w, y + zh, z + h], texture_coordinates: [h, 0.0], texture_id: t.1 as i32, normal, highlighted },
BlockVertex { position: [x + w, y + zh, 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,
2 + current_index, current_index, 3 + current_index,
]);
current_index += 4;
}
if 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 + zh, z], texture_coordinates: [w, 0.0], texture_id: t.2 as i32, normal, highlighted },
BlockVertex { position: [x + w, y + zh, 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 },
]);
indices.extend(&[
2 + current_index, current_index, 1 + current_index,
3 + current_index, current_index, 2 + current_index,
]);
current_index += 4;
}
if 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 + h], texture_coordinates: [0.0, 1.0], texture_id: t.3 as i32, normal, highlighted },
BlockVertex { position: [x, y + zh, z + h], texture_coordinates: [0.0, 0.0], texture_id: t.3 as i32, normal, highlighted },
BlockVertex { position: [x + w, y + zh, z + h], texture_coordinates: [w, 0.0], texture_id: t.3 as i32, normal, highlighted },
BlockVertex { position: [x + w, y, z + h], texture_coordinates: [w, 1.0], texture_id: t.3 as i32, normal, highlighted },
]);
indices.extend(&[
1 + current_index, current_index, 2 + current_index,
2 + current_index, current_index, 3 + current_index,
]);
current_index += 4;
}
if 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 + h], texture_coordinates: [w, h ], texture_id: t.4 as i32, normal, highlighted },
BlockVertex { position: [x + w, y, z + h], texture_coordinates: [0.0, h ], 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 },
]);
indices.extend(&[
current_index, 2 + current_index, 1 + current_index,
current_index, 3 + current_index, 2 + current_index,
]);
current_index += 4;
}
if 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 + zh, z ], texture_coordinates: [0.0, 0.0], texture_id: t.5 as i32, normal, highlighted },
BlockVertex { position: [x, y + zh, z + h], texture_coordinates: [0.0, h ], texture_id: t.5 as i32, normal, highlighted },
BlockVertex { position: [x + w, y + zh, z + h], texture_coordinates: [w, h ], texture_id: t.5 as i32, normal, highlighted },
BlockVertex { position: [x + w, y + zh, z ], texture_coordinates: [w, 0.0], texture_id: t.5 as i32, normal, highlighted },
]);
indices.extend(&[
current_index, 1 + current_index, 2 + current_index,
current_index, 2 + current_index, 3 + current_index,
]);
}
Geometry::new(vertices, indices)
}

View file

@ -1,7 +1,6 @@
mod aabb;
mod camera;
mod chunk;
mod cube;
mod geometry;
mod quad;
mod render_context;

View file

@ -1,13 +1,154 @@
use cgmath::{Vector3, Zero};
use crate::{
chunk::{
BlockType, FaceFlags, FACE_BACK, FACE_BOTTOM, FACE_FRONT, FACE_LEFT, FACE_RIGHT, FACE_TOP,
},
geometry::Geometry,
vertex::BlockVertex,
};
#[derive(Debug)]
pub struct Quad {
pub x: i32,
pub y: i32,
pub w: i32,
pub h: i32,
pub highlighted_normal: Vector3<i32>,
}
impl Quad {
pub fn new(x: i32, y: i32, w: i32, h: i32) -> Self {
Quad { x, y, w, h }
Quad {
x,
y,
w,
h,
highlighted_normal: Vector3::zero(),
}
}
#[allow(clippy::many_single_char_names)]
#[rustfmt::skip]
pub fn to_geometry(
&self,
y: i32,
offset: Vector3<i32>,
block_type: BlockType,
visible_faces: FaceFlags,
start_index: u16,
) -> Geometry<BlockVertex> {
let w = self.w as f32;
let d = self.h as f32;
let h = 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 t = block_type.texture_indices();
let mut current_index = start_index;
let mut vertices = Vec::new();
let mut indices = Vec::new();
let highlighted: [f32; 3] = self.highlighted_normal.cast().unwrap().into();
if 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 },
]);
indices.extend(&[
2 + current_index, current_index, 1 + current_index,
3 + current_index, current_index, 2 + current_index,
]);
current_index += 4;
}
if 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 },
]);
indices.extend(&[
1 + current_index, current_index, 2 + current_index,
2 + current_index, current_index, 3 + current_index,
]);
current_index += 4;
}
if 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 },
]);
indices.extend(&[
2 + current_index, current_index, 1 + current_index,
3 + current_index, current_index, 2 + current_index,
]);
current_index += 4;
}
if 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 },
]);
indices.extend(&[
1 + current_index, current_index, 2 + current_index,
2 + current_index, current_index, 3 + current_index,
]);
current_index += 4;
}
if 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 },
]);
indices.extend(&[
current_index, 2 + current_index, 1 + current_index,
current_index, 3 + current_index, 2 + current_index,
]);
current_index += 4;
}
if 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 },
]);
indices.extend(&[
current_index, 1 + current_index, 2 + current_index,
current_index, 2 + current_index, 3 + current_index,
]);
}
Geometry::new(vertices, indices)
}
}

View file

@ -429,12 +429,14 @@ impl WorldState {
let camera = &self.camera;
let world = &mut self.world;
if let Some((pos, axis)) = world.raycast(camera.position.to_vec(), camera.direction()) {
if let Some((pos, face_normal)) =
world.raycast(camera.position.to_vec(), camera.direction())
{
if button == &MouseButton::Left {
world.set_block(pos.x as isize, pos.y as isize, pos.z as isize, None);
self.update_chunk_geometry(render_context, pos / CHUNK_SIZE);
} else if button == &MouseButton::Right {
let new_pos = pos.cast().unwrap() - axis;
let new_pos = pos.cast().unwrap() + face_normal;
world.set_block(
new_pos.x as isize,

View file

@ -179,15 +179,15 @@ impl World {
if lengths.x < lengths.y && lengths.x < lengths.z {
lengths.x += scale.x;
position.x += step.x;
face = Vector3::unit_x() * step.x;
face = Vector3::unit_x() * -step.x;
} else if lengths.y < lengths.x && lengths.y < lengths.z {
lengths.y += scale.y;
position.y += step.y;
face = Vector3::unit_y() * step.y;
face = Vector3::unit_y() * -step.y;
} else if lengths.z < lengths.x && lengths.z < lengths.y {
lengths.z += scale.z;
position.z += step.z;
face = Vector3::unit_z() * step.z;
face = Vector3::unit_z() * -step.z;
} else {
return None;
}