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 in self.vox or
  • (b) 255, otherwise. That case represents that the whole group consists only of self.default voxels.

(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 Chunk and an almost empty Chunk shall 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>

source

pub const GROUP_COUNT: Vec3<u32> = _

source

const GROUP_COUNT_TOTAL: u32 = _

GROUP_COUNT_TOTAL is always 256, except if VOLUME < 256

source

const GROUP_LONG_SIDE_LEN: u32 = _

source

const GROUP_SIZE: Vec3<u32> = _

source

const GROUP_VOLUME: u32 = _

source

const VOLUME: u32 = _

source

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.

source

pub fn defragment(&mut self)
where V: Clone + Eq + Hash,

Compress this subchunk by frequency.

source

pub fn metadata(&self) -> &M

Get a reference to the internal metadata.

source

pub fn metadata_mut(&mut self) -> &mut M

Get a mutable reference to the internal metadata.

source

pub fn num_groups(&self) -> usize

source

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.

source

fn grp_idx(pos: Vec3<i32>) -> u32

source

fn rel_idx(pos: Vec3<i32>) -> u32

source

fn idx_unchecked(&self, pos: Vec3<i32>) -> Option<usize>

source

fn force_idx_unchecked(&mut self, pos: Vec3<i32>) -> usize
where V: Clone,

source

fn get_unchecked(&self, pos: Vec3<i32>) -> &V

source

fn set_unchecked(&mut self, pos: Vec3<i32>, vox: V) -> V
where V: Clone + PartialEq,

source§

impl<V, S: VolSize, M> Chunk<V, S, M>

source

pub fn pos_iter( lower_bound: Vec3<i32>, upper_bound: Vec3<i32> ) -> ChunkPosIter<V, S, M>

It’s possible to obtain a positional iterator without having a Chunk instance.

Trait Implementations§

source§

impl<V, S: VolSize, M> BaseVol for Chunk<V, S, M>

§

type Error = ChunkError

§

type Vox = V

source§

fn scaled_by(self, scale: Vec3<f32>) -> Scaled<Self>
where Self: Sized,

source§

impl<V: Clone, S: Clone + VolSize, M: Clone> Clone for Chunk<V, S, M>

source§

fn clone(&self) -> Chunk<V, S, M>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<V: Debug, S: Debug + VolSize, M: Debug> Debug for Chunk<V, S, M>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

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>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<'a, V, S: VolSize, M> IntoPosIterator for &'a Chunk<V, S, M>

§

type IntoIter = ChunkPosIter<V, S, M>

source§

fn pos_iter( self, lower_bound: Vec3<i32>, upper_bound: Vec3<i32> ) -> Self::IntoIter

source§

impl<'a, V, S: VolSize, M> IntoVolIterator<'a> for &'a Chunk<V, S, M>

§

type IntoIter = ChunkVolIter<'a, V, S, M>

source§

fn vol_iter( self, lower_bound: Vec3<i32>, upper_bound: Vec3<i32> ) -> Self::IntoIter

source§

impl<V, S: VolSize, M> RasterableVol for Chunk<V, S, M>

source§

const SIZE: Vec3<u32> = S::SIZE

source§

impl<V, S: VolSize, M> ReadVol for Chunk<V, S, M>

source§

fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error>

Get a reference to the voxel at the provided position in the volume.
source§

fn get_unchecked(&self, pos: Vec3<i32>) -> &Self::Vox

Get a reference to the voxel at the provided position in the volume. Many volumes provide a fast path, provided the position is always in-bounds. Note that this function is still safe.
source§

fn for_each_in(&self, aabb: Aabb<i32>, f: impl FnMut(Vec3<i32>, Self::Vox))
where Self::Vox: Copy,

Call provided closure with each block in the supplied Aabb Portions of the Aabb outside the volume are ignored
source§

fn ray( &self, from: Vec3<f32>, to: Vec3<f32> ) -> Ray<'_, Self, fn(_: &Self::Vox) -> bool, fn(_: &Self::Vox, _: Vec3<i32>)>
where Self: Sized,

NOTE: By default, this ray will simply run from from to to without stopping. To make something interesting happen, call until or for_each.
source§

impl<V, S: VolSize, M> Serialize for Chunk<V, S, M>
where V: Serialize, M: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<V: Clone + PartialEq, S: VolSize, M> WriteVol for Chunk<V, S, M>

source§

fn set( &mut self, pos: Vec3<i32>, vox: Self::Vox ) -> Result<Self::Vox, Self::Error>

Set the voxel at the provided position in the volume to the provided value.

Auto Trait Implementations§

§

impl<V, S, M> RefUnwindSafe for Chunk<V, S, M>

§

impl<V, S, M> Send for Chunk<V, S, M>
where M: Send, S: Send, V: Send,

§

impl<V, S, M> Sync for Chunk<V, S, M>
where M: Sync, S: Sync, V: Sync,

§

impl<V, S, M> Unpin for Chunk<V, S, M>
where M: Unpin, S: Unpin, V: Unpin,

§

impl<V, S, M> UnwindSafe for Chunk<V, S, M>
where M: UnwindSafe, S: UnwindSafe, V: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<C, M> ConvertSaveload<M> for C

§

type Data = C

(De)Serializable data representation for data type
§

type Error = Infallible

Error may occur during serialization or deserialization of component
§

fn convert_into<F>( &self, _: F ) -> Result<<C as ConvertSaveload<M>>::Data, <C as ConvertSaveload<M>>::Error>
where F: FnMut(Entity) -> Option<M>,

Convert this data type into serializable form (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>
where F: FnMut(M) -> Option<Entity>,

Convert this data from a deserializable form (Data) using entity to marker mapping function
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<V> SizedVol for V
where V: RasterableVol,

source§

fn lower_bound(&self) -> Vec3<i32>

Returns the (inclusive) lower bound of the volume.
source§

fn upper_bound(&self) -> Vec3<i32>

Returns the (exclusive) upper bound of the volume.
source§

fn size(&self) -> Vec3<u32>

Returns the size of the volume.
source§

impl<Context> SubContext<Context> for Context

source§

fn sub_context(self) -> Context

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<T> Event for T
where T: Send + Sync + 'static,

§

impl<T> Resource for T
where T: Any + Send + Sync,