Separate chunk neighbor code, WIP tasks

This commit is contained in:
griffi-gh 2023-01-22 21:24:35 +01:00
parent 7b5120b1d4
commit f9a7953dd8
6 changed files with 172 additions and 79 deletions

View file

@ -3,9 +3,6 @@ name = "kubi"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[profile.dev.package.noise]
opt-level = 3
[dependencies] [dependencies]
glium = "0.32" glium = "0.32"
image = { version = "0.24", default_features = false, features = ["png"] } image = { version = "0.24", default_features = false, features = ["png"] }
@ -19,3 +16,4 @@ rayon = "1.6"
shipyard = { version = "0.6", features = ["thread_local"] } shipyard = { version = "0.6", features = ["thread_local"] }
nohash-hasher = "0.2.0" nohash-hasher = "0.2.0"
anyhow = "1.0" anyhow = "1.0"
flume = "0.10"

View file

@ -81,6 +81,8 @@ pub fn draw_world(
write: true, write: true,
..Default::default() ..Default::default()
}, },
polygon_mode: PolygonMode::Fill, //Change to Line for wireframe
backface_culling: BackfaceCullingMode::CullCounterClockwise,
..Default::default() ..Default::default()
}; };
let texture_sampler = Sampler(&texture.0, SamplerBehavior { let texture_sampler = Sampler(&texture.0, SamplerBehavior {

View file

@ -10,52 +10,14 @@ pub mod render;
pub mod tasks; pub mod tasks;
pub mod loading; pub mod loading;
pub mod mesh; pub mod mesh;
pub mod neighbors;
use chunk::{Chunk, ChunkMesh}; use chunk::{Chunk, ChunkMesh};
//TODO separate world struct for render data //TODO separate world struct for render data
// because this is not send-sync // because this is not send-sync
pub struct AllChunksNeighbors<'a> {
pub center: &'a Chunk,
pub top: &'a Chunk,
pub bottom: &'a Chunk,
pub left: &'a Chunk,
pub right: &'a Chunk,
pub front: &'a Chunk,
pub back: &'a Chunk,
}
pub struct AllChunksNeighborsMut<'a> {
pub center: &'a mut Chunk,
pub top: &'a mut Chunk,
pub bottom: &'a mut Chunk,
pub left: &'a mut Chunk,
pub right: &'a mut Chunk,
pub front: &'a mut Chunk,
pub back: &'a mut Chunk,
}
pub struct ChunksNeighbors<'a> {
pub center: Option<&'a Chunk>,
pub top: Option<&'a Chunk>,
pub bottom: Option<&'a Chunk>,
pub left: Option<&'a Chunk>,
pub right: Option<&'a Chunk>,
pub front: Option<&'a Chunk>,
pub back: Option<&'a Chunk>,
}
impl<'a> ChunksNeighbors<'a> {
pub fn all(&self) -> Option<AllChunksNeighbors<'a>> {
Some(AllChunksNeighbors {
center: self.center?,
top: self.top?,
bottom: self.bottom?,
left: self.left?,
right: self.right?,
front: self.front?,
back: self.back?,
})
}
}
#[derive(Default, Unique)] #[derive(Default, Unique)]
#[track(Modification)] #[track(Modification)]
@ -66,40 +28,6 @@ impl ChunkStorage {
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
} }
pub fn neighbors(&self, coords: IVec3) -> ChunksNeighbors {
ChunksNeighbors {
center: self.chunks.get(&coords),
top: self.chunks.get(&(coords - ivec3(0, 1, 0))),
bottom: self.chunks.get(&(coords + ivec3(0, 1, 0))),
left: self.chunks.get(&(coords - ivec3(1, 0, 0))),
right: self.chunks.get(&(coords + ivec3(1, 0, 0))),
front: self.chunks.get(&(coords - ivec3(0, 0, 1))),
back: self.chunks.get(&(coords + ivec3(0, 0, 1))),
}
}
pub fn neighbors_all(&self, coords: IVec3) -> Option<AllChunksNeighbors> {
self.neighbors(coords).all()
}
pub fn neighbors_all_mut(&mut self, coords: IVec3) -> Option<AllChunksNeighborsMut> {
let mut refs = self.chunks.get_many_mut([
&coords,
&(coords - ivec3(0, 1, 0)),
&(coords + ivec3(0, 1, 0)),
&(coords - ivec3(1, 0, 0)),
&(coords + ivec3(1, 0, 0)),
&(coords - ivec3(0, 0, 1)),
&(coords + ivec3(0, 0, 1)),
])?.map(Some);
Some(AllChunksNeighborsMut {
center: std::mem::take(&mut refs[0]).unwrap(),
top: std::mem::take(&mut refs[1]).unwrap(),
bottom: std::mem::take(&mut refs[2]).unwrap(),
left: std::mem::take(&mut refs[3]).unwrap(),
right: std::mem::take(&mut refs[4]).unwrap(),
front: std::mem::take(&mut refs[5]).unwrap(),
back: std::mem::take(&mut refs[6]).unwrap(),
})
}
} }

View file

@ -4,9 +4,10 @@ use super::{block::Block, render::ChunkVertex};
pub const CHUNK_SIZE: usize = 32; pub const CHUNK_SIZE: usize = 32;
type ChunkBlockData = Box<[[[Block; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>; pub type BlockData = Box<[[[Block; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>;
pub struct ChunkData { pub struct ChunkData {
pub blocks: ChunkBlockData, pub blocks: BlockData,
pub has_renderable_blocks: bool, pub has_renderable_blocks: bool,
} }
impl ChunkData { impl ChunkData {

122
src/world/neighbors.rs Normal file
View file

@ -0,0 +1,122 @@
use glam::{IVec3, ivec3};
use super::chunk::Chunk;
#[derive(Clone, Copy)]
pub struct ChunkNeighbors<'a> {
pub center: Option<&'a Chunk>,
pub top: Option<&'a Chunk>,
pub bottom: Option<&'a Chunk>,
pub left: Option<&'a Chunk>,
pub right: Option<&'a Chunk>,
pub front: Option<&'a Chunk>,
pub back: Option<&'a Chunk>,
}
#[derive(Clone, Copy)]
pub struct AllChunkNeighbors<'a> {
pub center: &'a Chunk,
pub top: &'a Chunk,
pub bottom: &'a Chunk,
pub left: &'a Chunk,
pub right: &'a Chunk,
pub front: &'a Chunk,
pub back: &'a Chunk,
}
pub struct AllChunkNeighborsMut<'a> {
pub center: &'a mut Chunk,
pub top: &'a mut Chunk,
pub bottom: &'a mut Chunk,
pub left: &'a mut Chunk,
pub right: &'a mut Chunk,
pub front: &'a mut Chunk,
pub back: &'a mut Chunk,
}
impl<'a> ChunkNeighbors<'a> {
pub fn all(&self) -> Option<AllChunkNeighbors<'a>> {
Some(AllChunkNeighbors {
center: self.center?,
top: self.top?,
bottom: self.bottom?,
left: self.left?,
right: self.right?,
front: self.front?,
back: self.back?,
})
}
}
impl<'a> From<AllChunkNeighborsMut<'a>> for AllChunkNeighbors<'a> {
fn from(neighbors: AllChunkNeighborsMut<'a>) -> Self {
AllChunkNeighbors {
center: neighbors.center,
top: neighbors.top,
bottom: neighbors.bottom,
left: neighbors.left,
right: neighbors.right,
front: neighbors.front,
back: neighbors.back,
}
}
}
impl<'a> From<AllChunkNeighbors<'a>> for ChunkNeighbors<'a> {
fn from(neighbors: AllChunkNeighbors<'a>) -> Self {
ChunkNeighbors {
center: Some(neighbors.center),
top: Some(neighbors.top),
bottom: Some(neighbors.bottom),
left: Some(neighbors.left),
right: Some(neighbors.right),
front: Some(neighbors.front),
back: Some(neighbors.back),
}
}
}
impl<'a> From<AllChunkNeighborsMut<'a>> for ChunkNeighbors<'a> {
fn from(neighbors: AllChunkNeighborsMut<'a>) -> Self {
ChunkNeighbors {
center: Some(neighbors.center),
top: Some(neighbors.top),
bottom: Some(neighbors.bottom),
left: Some(neighbors.left),
right: Some(neighbors.right),
front: Some(neighbors.front),
back: Some(neighbors.back),
}
}
}
impl super::ChunkStorage {
pub fn neighbors(&self, coords: IVec3) -> ChunkNeighbors {
ChunkNeighbors {
center: self.chunks.get(&coords),
top: self.chunks.get(&(coords - ivec3(0, 1, 0))),
bottom: self.chunks.get(&(coords + ivec3(0, 1, 0))),
left: self.chunks.get(&(coords - ivec3(1, 0, 0))),
right: self.chunks.get(&(coords + ivec3(1, 0, 0))),
front: self.chunks.get(&(coords - ivec3(0, 0, 1))),
back: self.chunks.get(&(coords + ivec3(0, 0, 1))),
}
}
pub fn neighbors_all(&self, coords: IVec3) -> Option<AllChunkNeighbors> {
self.neighbors(coords).all()
}
pub fn neighbors_all_mut(&mut self, coords: IVec3) -> Option<AllChunkNeighborsMut> {
let mut refs = self.chunks.get_many_mut([
&coords,
&(coords - ivec3(0, 1, 0)),
&(coords + ivec3(0, 1, 0)),
&(coords - ivec3(1, 0, 0)),
&(coords + ivec3(1, 0, 0)),
&(coords - ivec3(0, 0, 1)),
&(coords + ivec3(0, 0, 1)),
])?.map(Some);
Some(AllChunkNeighborsMut {
center: std::mem::take(&mut refs[0]).unwrap(),
top: std::mem::take(&mut refs[1]).unwrap(),
bottom: std::mem::take(&mut refs[2]).unwrap(),
left: std::mem::take(&mut refs[3]).unwrap(),
right: std::mem::take(&mut refs[4]).unwrap(),
front: std::mem::take(&mut refs[5]).unwrap(),
back: std::mem::take(&mut refs[6]).unwrap(),
})
}
}

View file

@ -0,0 +1,42 @@
use flume::{Sender, Receiver};
use glam::IVec3;
use super::{
chunk::BlockData,
render::ChunkVertex
};
pub enum ChunkTask {
LoadChunk {
position: IVec3
},
GenerateMesh {
position: IVec3,
}
}
pub enum ChunkTaskResponse {
LoadedChunk {
position: IVec3,
chunk_data: BlockData,
},
GeneratedMesh {
position: IVec3,
vertices: Vec<ChunkVertex>,
indexes: Vec<u32>
},
}
pub struct ChunkTaskManager {
channel: (Sender<ChunkTaskResponse>, Receiver<ChunkTaskResponse>),
}
impl ChunkTaskManager {
pub fn new() -> Self {
Self {
channel: flume::bounded::<ChunkTaskResponse>(0),
}
}
pub fn spawn_task() {
}
}