use bevy::prelude::*;
use bevy::reflect::TypePath;
use crate::math::Region;
pub trait BlockData: Default + Copy + Send + Sync + TypePath + 'static {}
impl<T> BlockData for T where T: Default + Copy + Send + Sync + TypePath + 'static {}
#[derive(Debug, Component, Reflect)]
pub struct VoxelStorage<T>
where
T: BlockData,
{
#[reflect(ignore)]
blocks: Option<Box<[T; 4096]>>,
}
impl<T> Default for VoxelStorage<T>
where
T: BlockData,
{
fn default() -> Self {
Self {
blocks: None,
}
}
}
impl<T> VoxelStorage<T>
where
T: BlockData,
{
pub fn get_block(&self, local_pos: IVec3) -> T {
let index = Region::CHUNK.point_to_index(local_pos & 15).unwrap();
match &self.blocks {
Some(arr) => arr[index],
None => T::default(),
}
}
pub fn set_block(&mut self, local_pos: IVec3, data: T) {
let index = Region::CHUNK.point_to_index(local_pos & 15).unwrap();
match &mut self.blocks {
Some(arr) => arr[index] = data,
None => {
let mut chunk = Box::new([T::default(); 4096]);
chunk[index] = data;
self.blocks = Some(chunk);
},
}
}
}