alex/beta-minecraft-rust
Minecraft Beta 1.7.3 Rewrite
BRANCH 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
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;
}
}