pub struct Chunk<V, S: VolSize, M> {
indices: Vec<u8>,
vox: Vec<V>,
default: V,
meta: M,
phantom: PhantomData<S>,
}Expand description
The volume is spatially subdivided into groups of 4*4*4 blocks. Since a
Chunk is of total size 32*32*16, this implies that there are 8*8*4
groups. (These numbers are generic in the actual code such that there are
always 256 groups. I.e. the group size is chosen depending on the desired
total size of the Chunk.)
There’s a single vector self.vox which consecutively stores these groups.
Each group might or might not be contained in self.vox. A group that is
not contained represents that the full group consists only of self.default
voxels. This saves a lot of memory because oftentimes a Chunk consists of
either a lot of air or a lot of stone.
To track whether a group is contained in self.vox, there’s an index buffer
self.indices : [u8; 256]. It contains for each group
- (a) the order in which it has been inserted into
self.vox, if the group is contained inself.voxor - (b) 255, otherwise. That case represents that the whole group consists
only of
self.defaultvoxels.
(Note that 255 is a valid insertion order for case (a) only if self.vox is
full and then no other group has the index 255. Therefore there’s no
ambiguity.)
§Rationale:
The index buffer should be small because:
- Small size increases the probability that it will always be in cache.
- The index buffer is allocated for every
Chunkand an almost emptyChunkshall not consume too much memory.
The number of 256 groups is particularly nice because it means that the
index buffer can consist of u8s. This keeps the space requirement for the
index buffer as low as 4 cache lines.
Fields§
§indices: Vec<u8>§vox: Vec<V>§default: V§meta: M§phantom: PhantomData<S>Implementations§
Source§impl<V, S: VolSize, M> Chunk<V, S, M>
impl<V, S: VolSize, M> Chunk<V, S, M>
pub const GROUP_COUNT: Vec3<u32>
Sourceconst GROUP_COUNT_TOTAL: u32
const GROUP_COUNT_TOTAL: u32
GROUP_COUNT_TOTAL is always 256, except if VOLUME < 256
const GROUP_LONG_SIDE_LEN: u32
const GROUP_SIZE: Vec3<u32>
const GROUP_VOLUME: u32
const VOLUME: u32
Sourcepub fn filled(default: V, meta: M) -> Self
pub fn filled(default: V, meta: M) -> Self
Creates a new Chunk with the provided dimensions and all voxels filled
with duplicates of the provided voxel.
Sourcepub fn defragment(&mut self)
pub fn defragment(&mut self)
Compress this subchunk by frequency.
Sourcepub fn metadata_mut(&mut self) -> &mut M
pub fn metadata_mut(&mut self) -> &mut M
Get a mutable reference to the internal metadata.
pub fn num_groups(&self) -> usize
Sourcepub fn homogeneous(&self) -> Option<&V>
pub fn homogeneous(&self) -> Option<&V>
Returns Some(v) if the block is homogeneous and contains nothing but
voxels of value v, and None otherwise. This method is
conservative (it may return None when the chunk is
actually homogeneous) unless called immediately after defragment.
fn grp_idx(pos: Vec3<i32>) -> u32
fn rel_idx(pos: Vec3<i32>) -> u32
fn idx_unchecked(&self, pos: Vec3<i32>) -> Option<usize>
fn force_idx_unchecked(&mut self, pos: Vec3<i32>) -> usizewhere
V: Clone,
fn get_unchecked(&self, pos: Vec3<i32>) -> &V
fn set_unchecked(&mut self, pos: Vec3<i32>, vox: V) -> V
Trait Implementations§
Source§impl<'de, V, S: VolSize, M> Deserialize<'de> for Chunk<V, S, M>where
V: Deserialize<'de>,
M: Deserialize<'de>,
impl<'de, V, S: VolSize, M> Deserialize<'de> for Chunk<V, S, M>where
V: Deserialize<'de>,
M: Deserialize<'de>,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<V, S: VolSize, M> IntoPosIterator for &Chunk<V, S, M>
impl<V, S: VolSize, M> IntoPosIterator for &Chunk<V, S, M>
Source§impl<'a, V, S: VolSize, M> IntoVolIterator<'a> for &'a Chunk<V, S, M>
impl<'a, V, S: VolSize, M> IntoVolIterator<'a> for &'a Chunk<V, S, M>
Source§impl<V, S: VolSize, M> RasterableVol for Chunk<V, S, M>
impl<V, S: VolSize, M> RasterableVol for Chunk<V, S, M>
Source§impl<V, S: VolSize, M> ReadVol for Chunk<V, S, M>
impl<V, S: VolSize, M> ReadVol for Chunk<V, S, M>
Source§fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error>
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error>
Source§fn get_unchecked(&self, pos: Vec3<i32>) -> &Self::Vox
fn get_unchecked(&self, pos: Vec3<i32>) -> &Self::Vox
Auto Trait Implementations§
impl<V, S, M> Freeze for Chunk<V, S, M>
impl<V, S, M> RefUnwindSafe for Chunk<V, S, M>
impl<V, S, M> Send for Chunk<V, S, M>
impl<V, S, M> Sync for Chunk<V, S, M>
impl<V, S, M> Unpin for Chunk<V, S, M>
impl<V, S, M> UnwindSafe for Chunk<V, S, M>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<C, M> ConvertSaveload<M> for C
impl<C, M> ConvertSaveload<M> for C
§type Error = Infallible
type Error = Infallible
§fn convert_into<F>(
&self,
_: F,
) -> Result<<C as ConvertSaveload<M>>::Data, <C as ConvertSaveload<M>>::Error>
fn convert_into<F>( &self, _: F, ) -> Result<<C as ConvertSaveload<M>>::Data, <C as ConvertSaveload<M>>::Error>
Data) using
entity to marker mapping function§fn convert_from<F>(
data: <C as ConvertSaveload<M>>::Data,
_: F,
) -> Result<C, <C as ConvertSaveload<M>>::Error>
fn convert_from<F>( data: <C as ConvertSaveload<M>>::Data, _: F, ) -> Result<C, <C as ConvertSaveload<M>>::Error>
Data) using
entity to marker mapping function§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more