messy state
This commit is contained in:
89
src/chunk/column.rs
Normal file
89
src/chunk/column.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
use godot::classes::class_macros::private::virtuals::Os::Vector3i;
|
||||
|
||||
use super::chunk::{CHUNK_SIZE, Chunk};
|
||||
|
||||
pub const CHUNKS_PER_COLUMN: usize = 8;
|
||||
|
||||
pub struct ChunkColumn {
|
||||
// from bottom to top
|
||||
// TODO: replace with vec![]
|
||||
pub chunks: [Option<Chunk>; CHUNKS_PER_COLUMN],
|
||||
pub world_position: (i32, i32), // XZ
|
||||
pub chunk_size: Vector3i,
|
||||
}
|
||||
|
||||
impl ChunkColumn {
|
||||
pub fn new(x: i32, z: i32, chunk_size: Vector3i) -> Self {
|
||||
ChunkColumn {
|
||||
chunks: [None, None, None, None, None, None, None, None],
|
||||
world_position: (x, z),
|
||||
chunk_size,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_chunk_index(chunk_size_y: i32, world_y: i32) -> usize {
|
||||
(world_y / chunk_size_y) as usize
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_local_y(chunk_size_y: i32, world_y: i32) -> i32 {
|
||||
world_y % chunk_size_y
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_world_y(chunk_size_y: i32, chunk_index: i32, local_y: i32) -> i32 {
|
||||
(chunk_index * chunk_size_y) + local_y
|
||||
}
|
||||
|
||||
pub fn get_or_create_chunk(&mut self, chunk_y_index: i32) -> &mut Chunk {
|
||||
if self.chunks[chunk_y_index as usize].is_none() {
|
||||
let (world_x, world_z) = self.world_position;
|
||||
self.chunks[chunk_y_index as usize] = Some(Chunk::new(
|
||||
world_x as f64,
|
||||
chunk_y_index as f64,
|
||||
world_z as f64,
|
||||
self.chunk_size,
|
||||
));
|
||||
}
|
||||
self.chunks[chunk_y_index as usize].as_mut().unwrap()
|
||||
}
|
||||
|
||||
pub fn get_chunk(&self, chunk_y_index: usize) -> Option<&Chunk> {
|
||||
self.chunks[chunk_y_index].as_ref()
|
||||
}
|
||||
|
||||
pub fn get_chunk_mut(&mut self, chunk_y_index: usize) -> Option<&mut Chunk> {
|
||||
self.chunks[chunk_y_index].as_mut()
|
||||
}
|
||||
|
||||
pub fn set_voxel(&mut self, world_pos: Vector3i, is_solid: bool) -> bool {
|
||||
let chunk_index = Self::get_chunk_index(self.chunk_size.y, world_pos.y);
|
||||
if chunk_index < CHUNKS_PER_COLUMN {
|
||||
let size = self.chunk_size.clone();
|
||||
let chunk = self.get_or_create_chunk(chunk_index as i32);
|
||||
|
||||
let local_x = world_pos.x.rem_euclid(size.x);
|
||||
let local_y = Self::get_local_y(size.y, world_pos.y);
|
||||
let local_z = world_pos.z.rem_euclid(size.z);
|
||||
|
||||
chunk.set_voxel(Vector3i::new(local_x, local_y, local_z), is_solid, size);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_voxel(&self, world_pos: Vector3i) -> bool {
|
||||
let chunk_index = Self::get_chunk_index(self.chunk_size.y, world_pos.y);
|
||||
if let Some(chunk) = self.get_chunk(chunk_index) {
|
||||
let local_x = world_pos.x.rem_euclid(CHUNK_SIZE);
|
||||
let local_y = Self::get_local_y(self.chunk_size.y, world_pos.y);
|
||||
let local_z = world_pos.z.rem_euclid(CHUNK_SIZE);
|
||||
|
||||
chunk.get_voxel(Vector3i::new(local_x, local_y, local_z), self.chunk_size)
|
||||
} else {
|
||||
false // Air by default
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user