Theme

alex/beta-minecraft-rust

Minecraft Beta 1.7.3 Rewrite

BRANCH main
main
SNAPSHOT Draw terrain GPU-driven from packed per-section buffers with GPU occlusion culling, add a render distance slider (2-128) with a quad/disk shape, cut chunk bookkeeping at high render distances, and fix a light underflow at y=0
DOWNLOAD
Download file

root / crates / client / src / render / scene / moving.rs

//! `TileEntityRendererPiston`: blocks on their way, drawn with the terrain mesher.

use common::world::{Block, ChunkPos, TileEntity};
use glam::DVec3;

use super::{Geometry, Vertex};
use crate::render::mesher::{self, Moving};
use crate::world::ClientWorld;

/// The terrain settings moving blocks are meshed with.
pub struct Style {
    pub fancy: bool,
    pub smooth_lighting: bool,
}

impl Geometry {
    pub fn moving_blocks(
        &mut self,
        world: &ClientWorld,
        eye: DVec3,
        partial: f32,
        sky_darkness: u32,
        style: Style,
    ) {
        let start = self.vertices.len() as u32;
        for ([x, y, z], tile) in world.moving_blocks() {
            let &TileEntity::Piston {
                block,
                metadata,
                facing,
                progress,
                last_progress,
                extending,
                source,
            } = tile
            else {
                continue;
            };
            let progress = last_progress + (progress - last_progress) * partial;
            let (block, metadata) = (Block(block as u8), metadata as u8);
            if progress >= 1.0 || block.is_air() || !(0..6).contains(&facing) {
                continue;
            }
            let shift = if extending {
                progress - 1.0
            } else {
                1.0 - progress
            };
            let offset = super::SIDES[facing as usize] * f64::from(shift);
            let pos = ChunkPos::containing(x, z);
            let Some(input) = world.mesh_input(pos, y >> 4, style.fancy, style.smooth_lighting)
            else {
                continue;
            };
            let parts = if block == Block::PISTON_HEAD && progress < 0.5 {
                vec![(
                    Moving::Head {
                        metadata,
                        length: 0.5,
                        shift: 8.0,
                    },
                    offset,
                )]
            } else if source && !extending {
                let facing = facing as u8;
                let sticky = if block == Block::STICKY_PISTON { 8 } else { 0 };
                let (length, rod) = if progress < 0.5 {
                    (1.0, 16.0)
                } else {
                    (0.5, 8.0)
                };
                vec![
                    (
                        Moving::Head {
                            metadata: facing | sticky,
                            length,
                            shift: rod,
                        },
                        offset,
                    ),
                    (Moving::Base(block, facing | 8), DVec3::ZERO),
                ]
            } else {
                vec![(Moving::Block(block, metadata), offset)]
            };
            let origin = DVec3::new(
                f64::from(pos.min_block_x()),
                f64::from(y & !15),
                f64::from(pos.min_block_z()),
            );
            for (part, offset) in parts {
                let quads = mesher::moving(&input, [x & 15, y & 15, z & 15], part);
                for quad in &quads {
                    let vertices = quad.vertices.each_ref().map(|vertex| Vertex {
                        position: (origin + vertex.position().as_dvec3() + offset - eye)
                            .as_vec3()
                            .to_array(),
                        uv: vertex.uv(),
                        color: vertex.color(&world.brightness, sky_darkness),
                        texture: 0,
                    });
                    self.vertices
                        .extend([0, 1, 2, 0, 2, 3].map(|i| vertices[i]));
                }
            }
        }
        self.moving = start..self.vertices.len() as u32;
    }
}