minor refactor

This commit is contained in:
griffi-gh 2023-02-15 23:32:06 +01:00
parent 00b3a90fd4
commit 2c374c6e23
4 changed files with 131 additions and 95 deletions

View file

@ -29,6 +29,7 @@ pub enum Block {
Grass,
Sand,
Cobblestone,
TallGrass,
}
impl Block {
@ -74,6 +75,12 @@ impl Block {
render: RenderType::SolidBlock(CubeTexture::all(BlockTexture::Cobblestone)),
collision: CollisionType::Solid,
raycast_collision: true,
},
Self::TallGrass => BlockDescriptor {
name: "tall grass",
render: RenderType::CrossShape(CrossTexture::all(BlockTexture::TallGrass)),
collision: CollisionType::None,
raycast_collision: true,
}
}
}
@ -123,12 +130,22 @@ impl CubeTexture {
#[derive(Clone, Copy, Debug)]
pub struct CrossTexture {
pub a_front: BlockTexture,
pub b_front: BlockTexture,
pub a_back: BlockTexture,
pub b_front: BlockTexture,
pub b_back: BlockTexture,
}
impl CrossTexture {
pub const fn same_front_back(a: BlockTexture, b: BlockTexture) -> Self {
Self {
a_front: a,
a_back: a,
b_front: b,
b_back: b,
}
}
pub const fn all(texture: BlockTexture) -> Self {
Self::same_front_back(texture, texture)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]

View file

@ -44,7 +44,6 @@ pub struct ChunkVertex {
}
implement_vertex!(ChunkVertex, position, normal, uv, tex_index);
pub fn draw_world(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
chunks: UniqueView<ChunkStorage>,

View file

@ -1,84 +1,14 @@
use strum::{EnumIter, IntoEnumIterator};
use glam::{Vec3A, vec3a, IVec3, ivec3};
use std::mem::discriminant;
use glam::{IVec3, ivec3};
use strum::IntoEnumIterator;
use kubi_shared::block::{Block, RenderType};
use super::{chunk::CHUNK_SIZE, };
use crate::world::chunk::CHUNK_SIZE;
use crate::rendering::world::ChunkVertex;
pub mod data;
mod builder;
use data::MeshGenData;
#[repr(usize)]
#[derive(Clone, Copy, Debug, EnumIter)]
pub enum CubeFace {
Top = 0,
Front = 1,
Left = 2,
Right = 3,
Back = 4,
Bottom = 5,
}
const CUBE_FACE_VERTICES: [[Vec3A; 4]; 6] = [
[vec3a(0., 1., 0.), vec3a(0., 1., 1.), vec3a(1., 1., 0.), vec3a(1., 1., 1.)],
[vec3a(0., 0., 0.), vec3a(0., 1., 0.), vec3a(1., 0., 0.), vec3a(1., 1., 0.)],
[vec3a(0., 0., 1.), vec3a(0., 1., 1.), vec3a(0., 0., 0.), vec3a(0., 1., 0.)],
[vec3a(1., 0., 0.), vec3a(1., 1., 0.), vec3a(1., 0., 1.), vec3a(1., 1., 1.)],
[vec3a(1., 0., 1.), vec3a(1., 1., 1.), vec3a(0., 0., 1.), vec3a(0., 1., 1.)],
[vec3a(0., 0., 1.), vec3a(0., 0., 0.), vec3a(1., 0., 1.), vec3a(1., 0., 0.)],
];
const CUBE_FACE_NORMALS: [Vec3A; 6] = [
vec3a(0., 1., 0.),
vec3a(0., 0., -1.),
vec3a(-1.,0., 0.),
vec3a(1., 0., 0.),
vec3a(0., 0., 1.),
vec3a(0., -1.,0.)
];
const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3];
const UV_COORDS: [[f32; 2]; 4] = [
[0., 0.],
[0., 1.],
[1., 0.],
[1., 1.],
];
#[derive(Default)]
struct MeshBuilder {
vertex_buffer: Vec<ChunkVertex>,
index_buffer: Vec<u32>,
idx_counter: u32,
}
impl MeshBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) {
let coord = coord.as_vec3a();
let face_index = face as usize;
//Push vertexes
let norm = CUBE_FACE_NORMALS[face_index];
let vert = CUBE_FACE_VERTICES[face_index];
self.vertex_buffer.reserve(4);
for i in 0..4 {
self.vertex_buffer.push(ChunkVertex {
position: (coord + vert[i]).to_array(),
normal: norm.to_array(),
uv: UV_COORDS[i],
tex_index: texture
});
}
//Push indices
self.index_buffer.extend_from_slice(&CUBE_FACE_INDICES.map(|x| x + self.idx_counter));
self.idx_counter += 4;
}
pub fn finish(self) -> (Vec<ChunkVertex>, Vec<u32>) {
(self.vertex_buffer, self.index_buffer)
}
}
use builder::{CubeFace, MeshBuilder};
pub fn generate_mesh(data: MeshGenData) -> (Vec<ChunkVertex>, Vec<u32>) {
let get_block = |pos: IVec3| -> Block {
@ -101,22 +31,21 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec<ChunkVertex>, Vec<u32>) {
let mut builder = MeshBuilder::new();
for x in 0..CHUNK_SIZE {
for y in 0..CHUNK_SIZE {
for z in 0..CHUNK_SIZE {
let coord = ivec3(x as i32, y as i32, z as i32);
for x in 0..CHUNK_SIZE as i32 {
for y in 0..CHUNK_SIZE as i32 {
for z in 0..CHUNK_SIZE as i32 {
let coord = ivec3(x, y, z);
let block = get_block(coord);
let descriptor = block.descriptor();
if matches!(descriptor.render, RenderType::None) {
continue
}
for face in CubeFace::iter() {
let facing = CUBE_FACE_NORMALS[face as usize].as_ivec3();
let facing_coord = coord + facing;
let show = discriminant(&get_block(facing_coord).descriptor().render) != discriminant(&descriptor.render);
if show {
match descriptor.render {
RenderType::None => continue,
RenderType::SolidBlock(textures) => {
for face in CubeFace::iter() {
let facing_direction = face.normal();
let facing_coord = coord + facing_direction;
let facing_descriptor = get_block(facing_coord).descriptor();
let face_obstructed = matches!(facing_descriptor.render, RenderType::SolidBlock(_));
if !face_obstructed {
let face_texture = match face {
CubeFace::Top => textures.top,
CubeFace::Front => textures.front,
@ -126,10 +55,12 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec<ChunkVertex>, Vec<u32>) {
CubeFace::Bottom => textures.bottom,
};
builder.add_face(face, coord, face_texture as u8);
},
_ => unimplemented!()
}
}
},
RenderType::CrossShape(_) => {
todo!()
}
}
}
}

View file

@ -0,0 +1,89 @@
use strum::EnumIter;
use glam::{Vec3, vec3, IVec3, ivec3};
use crate::rendering::world::ChunkVertex;
#[repr(usize)]
#[derive(Clone, Copy, Debug, EnumIter)]
pub enum CubeFace {
Top = 0,
Front = 1,
Left = 2,
Right = 3,
Back = 4,
Bottom = 5,
}
impl CubeFace {
pub const fn normal(self) -> IVec3 {
CUBE_FACE_NORMALS_IVEC3[self as usize]
}
}
const CUBE_FACE_VERTICES: [[Vec3; 4]; 6] = [
[vec3(0., 1., 0.), vec3(0., 1., 1.), vec3(1., 1., 0.), vec3(1., 1., 1.)],
[vec3(0., 0., 0.), vec3(0., 1., 0.), vec3(1., 0., 0.), vec3(1., 1., 0.)],
[vec3(0., 0., 1.), vec3(0., 1., 1.), vec3(0., 0., 0.), vec3(0., 1., 0.)],
[vec3(1., 0., 0.), vec3(1., 1., 0.), vec3(1., 0., 1.), vec3(1., 1., 1.)],
[vec3(1., 0., 1.), vec3(1., 1., 1.), vec3(0., 0., 1.), vec3(0., 1., 1.)],
[vec3(0., 0., 1.), vec3(0., 0., 0.), vec3(1., 0., 1.), vec3(1., 0., 0.)],
];
const CUBE_FACE_NORMALS_IVEC3: [IVec3; 6] = [
ivec3( 0, 1, 0),
ivec3( 0, 0, -1),
ivec3(-1, 0, 0),
ivec3( 1, 0, 0),
ivec3( 0, 0, 1),
ivec3( 0, -1, 0)
];
const CUBE_FACE_NORMALS: [Vec3; 6] = [
vec3(0., 1., 0.),
vec3(0., 0., -1.),
vec3(-1.,0., 0.),
vec3(1., 0., 0.),
vec3(0., 0., 1.),
vec3(0., -1.,0.)
];
const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3];
const UV_COORDS: [[f32; 2]; 4] = [
[0., 0.],
[0., 1.],
[1., 0.],
[1., 1.],
];
#[derive(Default)]
pub struct MeshBuilder {
vertex_buffer: Vec<ChunkVertex>,
index_buffer: Vec<u32>,
idx_counter: u32,
}
impl MeshBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) {
let coord = coord.as_vec3();
let face_index = face as usize;
//Push vertices
let norm = CUBE_FACE_NORMALS[face_index];
let vert = CUBE_FACE_VERTICES[face_index];
self.vertex_buffer.reserve(4);
for i in 0..4 {
self.vertex_buffer.push(ChunkVertex {
position: (coord + vert[i]).to_array(),
normal: norm.to_array(),
uv: UV_COORDS[i],
tex_index: texture
});
}
//Push indices
self.index_buffer.extend_from_slice(&CUBE_FACE_INDICES.map(|x| x + self.idx_counter));
self.idx_counter += 4;
}
pub fn finish(self) -> (Vec<ChunkVertex>, Vec<u32>) {
(self.vertex_buffer, self.index_buffer)
}
}