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 common src entity vehicle.rs
use glam::{DVec3, IVec3};
use crate::math::floor_f64;
use crate::world::Block;
use crate::world::shape::BlockView;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum VehicleKind {
Boat,
Minecart,
StorageCart,
PoweredCart,
}
impl VehicleKind {
pub fn size(self) -> [f32; 2] {
if self == Self::Boat {
[1.5, 0.6]
} else {
[0.98, 0.7]
}
}
pub fn y_offset(self) -> f32 {
self.size()[1] / 2.0
}
pub fn seat(self, position: DVec3, yaw: f32) -> DVec3 {
if self == Self::Boat {
let yaw = f64::from(yaw) * std::f64::consts::PI / 180.0;
position + DVec3::new(yaw.cos() * 0.4, -f64::from(0.3_f32), yaw.sin() * 0.4)
} else {
position - DVec3::Y * f64::from(0.3_f32)
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct VehiclePose {
pub hit: i32,
pub damage: i32,
pub direction: i32,
}
pub const RAIL_ENDPOINTS: [[[i32; 3]; 2]; 10] = [
[[0, 0, -1], [0, 0, 1]],
[[-1, 0, 0], [1, 0, 0]],
[[-1, -1, 0], [1, 0, 0]],
[[-1, 0, 0], [1, -1, 0]],
[[0, 0, -1], [0, -1, 1]],
[[0, -1, -1], [0, 0, 1]],
[[0, 0, 1], [1, 0, 0]],
[[0, 0, 1], [-1, 0, 0]],
[[0, 0, -1], [-1, 0, 0]],
[[0, 0, -1], [1, 0, 0]],
];
pub fn rail_at(world: &impl BlockView, position: DVec3) -> Option<([i32; 3], u8)> {
let [x, mut y, z] = position.to_array().map(floor_f64);
if is_rail(world.block(x, y - 1, z)) {
y -= 1;
}
let block = world.block(x, y, z);
if !is_rail(block) {
return None;
}
let mask = if block == Block::RAIL { 15 } else { 7 };
let shape = world.metadata(x, y, z) & mask;
(shape < 10).then_some(([x, y, z], shape))
}
pub fn is_rail(block: Block) -> bool {
matches!(
block,
Block::RAIL | Block::POWERED_RAIL | Block::DETECTOR_RAIL
)
}
pub fn rail_position(world: &impl BlockView, position: DVec3) -> Option<DVec3> {
let ([x, y, z], shape) = rail_at(world, position)?;
let endpoints = RAIL_ENDPOINTS[usize::from(shape)];
let base = DVec3::new(f64::from(x) + 0.5, f64::from(y) + 0.5, f64::from(z) + 0.5);
let a = base + DVec3::from_array(endpoints[0].map(f64::from)) * 0.5;
let b = base + DVec3::from_array(endpoints[1].map(f64::from)) * 0.5;
let direction = (b - a) * DVec3::new(1.0, 2.0, 1.0);
let t = if direction.x == 0.0 {
position.z - f64::from(z)
} else if direction.z == 0.0 {
position.x - f64::from(x)
} else {
((position.x - a.x) * direction.x + (position.z - a.z) * direction.z) * 2.0
};
let mut result = a + direction * t;
result.y += if direction.y < 0.0 {
1.0
} else if direction.y > 0.0 {
0.5
} else {
0.0
};
Some(result)
}
pub fn rail_offset(world: &impl BlockView, position: DVec3, offset: f64) -> Option<DVec3> {
let ([_, y, _], shape) = rail_at(world, position)?;
let endpoints = RAIL_ENDPOINTS[usize::from(shape)];
let direction = (IVec3::from(endpoints[1]) - IVec3::from(endpoints[0]))
.as_dvec3()
.with_y(0.0)
.normalize();
let mut shifted =
position.with_y(f64::from(y + i32::from((2..=5).contains(&shape)))) + direction * offset;
let [x, _, z] = position.to_array().map(floor_f64);
for end in endpoints {
if end[1] != 0 && floor_f64(shifted.x) - x == end[0] && floor_f64(shifted.z) - z == end[2] {
shifted.y += f64::from(end[1]);
}
}
rail_position(world, shifted)
}