chunkgen 0.2.0

Minecraft world generation library
Documentation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DensityVolume {
    pub size_x: i32,
    pub size_y: i32,
    pub size_z: i32,
    pub min_block_x: i32,
    pub min_block_y: i32,
    pub min_block_z: i32,
    pub step_block_x: i32,
    pub step_block_y: i32,
    pub step_block_z: i32,
}

impl DensityVolume {
    pub fn stepped(size: [i32; 3], min_block: [i32; 3], step_block: [i32; 3]) -> Self {
        assert!(
            size.iter().all(|s| *s > 0),
            "Size must be positive, was: {}x{}x{}",
            size[0],
            size[1],
            size[2]
        );
        assert!(
            step_block.iter().all(|s| *s > 0),
            "Step must be positive, was: {}; {}; {}",
            step_block[0],
            step_block[1],
            step_block[2]
        );
        Self {
            size_x: size[0],
            size_y: size[1],
            size_z: size[2],
            min_block_x: min_block[0],
            min_block_y: min_block[1],
            min_block_z: min_block[2],
            step_block_x: step_block[0],
            step_block_y: step_block[1],
            step_block_z: step_block[2],
        }
    }

    pub fn new(size: [i32; 3], min_block: [i32; 3]) -> Self {
        Self::stepped(size, min_block, [1, 1, 1])
    }

    pub const fn index_unchecked(&self, x: i32, y: i32, z: i32) -> usize {
        (y + (x + z * self.size_x) * self.size_y) as usize
    }

    pub const fn block_x(&self, x: i32) -> i32 {
        self.min_block_x + x * self.step_block_x
    }

    pub const fn block_y(&self, y: i32) -> i32 {
        self.min_block_y + y * self.step_block_y
    }

    pub const fn block_z(&self, z: i32) -> i32 {
        self.min_block_z + z * self.step_block_z
    }

    pub const fn max_block_x(&self) -> i32 {
        self.min_block_x + self.size_x * self.step_block_x - 1
    }

    pub const fn max_block_y(&self) -> i32 {
        self.min_block_y + self.size_y * self.step_block_y - 1
    }

    pub const fn max_block_z(&self) -> i32 {
        self.min_block_z + self.size_z * self.step_block_z - 1
    }

    pub const fn size(&self) -> usize {
        (self.size_x * self.size_y * self.size_z) as usize
    }

    const fn contains_block_relative(&self, rx: i32, ry: i32, rz: i32) -> bool {
        rx >= 0
            && ry >= 0
            && rz >= 0
            && rx < self.size_x * self.step_block_x
            && ry < self.size_y * self.step_block_y
            && rz < self.size_z * self.step_block_z
            && rx.rem_euclid(self.step_block_x) == 0
            && ry.rem_euclid(self.step_block_y) == 0
            && rz.rem_euclid(self.step_block_z) == 0
    }

    pub const fn index_of_block(&self, block_x: i32, block_y: i32, block_z: i32) -> Option<usize> {
        let rx = block_x - self.min_block_x;
        let ry = block_y - self.min_block_y;
        let rz = block_z - self.min_block_z;
        if self.step_block_x == 1 && self.step_block_y == 1 && self.step_block_z == 1 {
            if rx >= 0
                && ry >= 0
                && rz >= 0
                && rx < self.size_x
                && ry < self.size_y
                && rz < self.size_z
            {
                return Some(self.index_unchecked(rx, ry, rz));
            }
        } else if self.contains_block_relative(rx, ry, rz) {
            return Some(self.index_unchecked(
                rx.div_euclid(self.step_block_x),
                ry.div_euclid(self.step_block_y),
                rz.div_euclid(self.step_block_z),
            ));
        }
        None
    }
}