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 fishing.rs
use common::entity::Entity;
use common::math::{cos, sin};
use glam::{Mat3, Vec3};
use super::{Geometry, Vertex};
use crate::entities::{Entities, Kind};
use crate::player::LocalPlayer;
impl Geometry {
pub(super) fn hook(&mut self, relative: Vec3, billboard: &Mat3) {
let points = [
Vec3::new(-0.25, 0.25, 0.0),
Vec3::new(0.25, 0.25, 0.0),
Vec3::new(0.25, -0.25, 0.0),
Vec3::new(-0.25, -0.25, 0.0),
]
.map(|p| relative + billboard * p);
self.quad(
points,
[1.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0],
crate::assets::entity_texture("particles.png"),
0xffffffff,
);
}
pub(super) fn fishing_lines(
&mut self,
entities: &Entities,
player: &LocalPlayer,
partial: f32,
) {
for hook in entities.0.values() {
let Kind::Hook(Some(owner)) = hook.kind else {
continue;
};
let local = owner == player.entity.id;
let Some(angler) = (if local {
Some(&player.entity)
} else {
entities
.0
.get(&owner)
.and_then(|e| e.player.as_ref())
.map(|p| &p.entity)
}) else {
continue;
};
let start = hook.previous.lerp(hook.position, f64::from(partial)) - player.eye(partial);
let end = rod_tip(angler, partial, player.third_person || !local) - player.eye(partial);
let delta = (end - start).as_vec3() - Vec3::Y * 0.25;
let start = start.as_vec3();
let point = |i: u32| {
let t = i as f32 / 16.0;
start + Vec3::new(delta.x * t, delta.y * (t * t + t) * 0.5 + 0.25, delta.z * t)
};
for segment in 0..16 {
for position in [point(segment), point(segment + 1)] {
self.vertices.push(Vertex {
position: position.to_array(),
uv: [0.0; 2],
color: 0xff000000,
texture: -1,
});
}
}
}
}
}
fn rod_tip(entity: &Entity, partial: f32, third_person: bool) -> glam::DVec3 {
let yaw = super::lerp(entity.prev_yaw, entity.yaw, partial);
let pitch = super::lerp(entity.prev_pitch, entity.pitch, partial);
let pos = entity.prev_pos.lerp(entity.pos, f64::from(partial));
if third_person {
let body = entity
.living
.as_ref()
.map_or(yaw, |l| {
super::lerp(l.prev_render_yaw_offset, l.render_yaw_offset, partial)
})
.to_radians();
pos + glam::DVec3::new(
-f64::from(cos(body)) * 0.35 - f64::from(sin(body)) * 0.85,
// `posY`: the local player's eyes, other players' feet
-0.45,
-f64::from(sin(body)) * 0.35 + f64::from(cos(body)) * 0.85,
)
} else {
let living = entity.living.as_ref();
let swing = living.map_or(0.0, |l| super::swing(l, partial));
let wave = sin(swing.sqrt() * std::f32::consts::PI);
let rotation = Mat3::from_rotation_x(wave * 0.7)
* Mat3::from_rotation_y(wave * 0.5)
* Mat3::from_rotation_y(-yaw.to_radians())
* Mat3::from_rotation_x(pitch.to_radians());
pos + (rotation * Vec3::new(-0.5, 0.03, 0.8)).as_dvec3()
}
}