Files
fastvoxel/src/chunk/chunk.rs
TheRealKaamy d3c1b7bb5b re-working the editor nodes
de-coupling godot resources from internal runtime logic
2026-03-28 03:12:31 +03:30

88 lines
2.7 KiB
Rust

use godot::prelude::*;
pub const CHUNK_SIZE: i32 = 32;
pub const ARR_SIZE: usize = CHUNK_SIZE.pow(3) as usize;
// 32x32x32 = 32768 bits, stored in u32s (32 bits each) = 1024 u32s
pub const BITPACKED_SIZE: usize = ARR_SIZE / 32;
#[derive(Debug)]
pub struct SubChunk {
// Bitpacked voxel data: 0 = air, 1 = solid
pub voxels: Vec<u32>,
// WORLD COORDINATES
pub world_position: (f64, f64, f64),
modified: bool,
}
impl SubChunk {
/// pos_z and pos_x are `world` coordinates of the chunk, inside the world
pub fn new(world_pos_x: f64, world_pos_y: f64, world_pos_z: f64) -> Self {
SubChunk {
voxels: vec![0u32; BITPACKED_SIZE],
world_position: (world_pos_x, world_pos_y, world_pos_z),
modified: false,
}
}
// #[inline]
// pub fn get_voxel_index(&self, local_pos: Vector3i, chunk_size: Vector3i) -> usize {
// ((local_pos.x * chunk_size.y * chunk_size.z) + (local_pos.y * chunk_size.x) + local_pos.z)
// as usize
// }
#[inline(always)]
fn get_voxel_index(local: Vector3i) -> usize {
((local.x << 10) | (local.y << 5) | local.z) as usize
}
#[inline]
pub fn is_voxel_within_bounds(&self, local_pos: Vector3i, chunk_size: Vector3i) -> bool {
local_pos.x >= 0
&& local_pos.x < chunk_size.x
&& local_pos.y >= 0
&& local_pos.y < chunk_size.y
&& local_pos.z >= 0
&& local_pos.z < chunk_size.z
}
#[inline]
pub fn get_voxel(&self, local_pos: Vector3i, chunk_size: Vector3i) -> bool {
debug_assert!(
self.is_voxel_within_bounds(local_pos, chunk_size),
"Voxel position {:?} out of chunk bounds",
local_pos
);
let index = Self::get_voxel_index(local_pos);
debug_assert!(
index < BITPACKED_SIZE,
"Voxel index {:?} out of chunk bounds",
index
);
let word_index = index >> 5; // divide by 32
let bit_index = index & 31; // modulo 32
(self.voxels[word_index] & (1 << bit_index)) != 0
}
pub fn set_voxel(&mut self, voxel_pos: Vector3i, is_solid: bool, chunk_size: Vector3i) {
debug_assert!(
self.is_voxel_within_bounds(voxel_pos, chunk_size),
"Voxel position {:?} out of chunk bounds",
voxel_pos
);
let index = Self::get_voxel_index(voxel_pos);
let word_index = index >> 5;
let bit_index = index & 31;
if is_solid {
self.voxels[word_index] |= 1 << bit_index;
} else {
self.voxels[word_index] &= !(1 << bit_index);
}
self.modified = true;
}
}