voxelize 1.0.0

A fast multiplayer voxel engine.
Documentation
use crate::world::voxels::{BlockRotation, ROTATION_MASK, STAGE_MASK, Y_ROTATION_MASK};

/// A set of utility functions for block operations.
pub struct BlockUtils;

impl BlockUtils {
    /// Extract the bits in voxel that stores the voxel id.
    pub fn extract_id(voxel: u32) -> u32 {
        voxel & 0xFFFF
    }

    /// Insert a voxel id into voxel value.
    pub fn insert_id(voxel: u32, id: u32) -> u32 {
        (voxel & 0xFFFF0000) | (id & 0xFFFF)
    }

    /// Extract the bits in voxel that stores the voxel rotation.
    pub fn extract_rotation(voxel: u32) -> BlockRotation {
        let rotation = (voxel >> 16) & 0xF;
        let y_rot = (voxel >> 20) & 0xF;
        BlockRotation::encode(rotation, y_rot)
    }

    /// Insert a voxel rotation into voxel value.
    pub fn insert_rotation(voxel: u32, rotation: &BlockRotation) -> u32 {
        let (rotation, y_rot) = BlockRotation::decode(rotation);
        let value = (voxel & ROTATION_MASK) | ((rotation & 0xF) << 16);
        (value & Y_ROTATION_MASK) | ((y_rot & 0xF) << 20)
    }

    /// Extract the bits in voxel that stores the stage value.
    pub fn extract_stage(voxel: u32) -> u32 {
        (voxel >> 24) & 0xF
    }

    /// Insert a voxel stage into voxel value. Panics if the stage passed in overflows 15.
    pub fn insert_stage(voxel: u32, stage: u32) -> u32 {
        assert!(stage <= 15, "Maximum stage is 15");

        (voxel & STAGE_MASK) | (stage << 24)
    }
}

#[derive(Default)]
pub struct VoxelPacker {
    id: u32,
    rotation: BlockRotation,
    stage: u32,
}

impl VoxelPacker {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn with_id(mut self, id: u32) -> Self {
        self.id = id;
        self
    }

    pub fn with_rotation(mut self, rotation: BlockRotation) -> Self {
        self.rotation = rotation;
        self
    }

    pub fn with_stage(mut self, stage: u32) -> Self {
        self.stage = stage;
        self
    }

    pub fn pack(&self) -> u32 {
        let mut voxel = 0;
        voxel = BlockUtils::insert_id(voxel, self.id);
        voxel = BlockUtils::insert_rotation(voxel, &self.rotation);
        voxel = BlockUtils::insert_stage(voxel, self.stage);
        voxel
    }
}