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 server src populate ores.rs
//! Ports of `WorldGenMinable` and `WorldGenClay`: blobs along a random segment.
use std::f32::consts::PI;
use common::JavaRandom;
use common::math::{self, floor_f64};
use common::world::{Block, Material};
use crate::level::Level;
/// `WorldGenMinable`: replaces stone.
pub fn vein(level: &mut Level, pos: [i32; 3], rand: &mut JavaRandom, ore: Block, size: i32) {
blob(level, pos, rand, size, [Block::STONE, ore]);
}
/// `WorldGenClay`: replaces sand, starting only in water.
pub fn clay(level: &mut Level, [x, y, z]: [i32; 3], rand: &mut JavaRandom, size: i32) {
if level.material(x, y, z) == Material::Water {
blob(level, [x, y, z], rand, size, [Block::SAND, Block::CLAY]);
}
}
/// `size + 1` spheres of varying radii along a segment centered around (x + 8, z + 8),
/// replacing `from` with `to`.
fn blob(
level: &mut Level,
[x, y, z]: [i32; 3],
rand: &mut JavaRandom,
size: i32,
[from, to]: [Block; 2],
) {
let angle = rand.next_float() * PI;
let reach = |offset: f32| offset * size as f32 / 8.0;
let (sin, cos) = (reach(math::sin(angle)), reach(math::cos(angle)));
let (x, z) = ((x + 8) as f32, (z + 8) as f32);
let start = [
f64::from(x + sin),
f64::from(y + rand.next_int(3) + 2),
f64::from(z + cos),
];
let end = [
f64::from(x - sin),
f64::from(y + rand.next_int(3) + 2),
f64::from(z - cos),
];
for step in 0..=size {
let t = |axis: usize| {
start[axis] + (end[axis] - start[axis]) * f64::from(step) / f64::from(size)
};
let (cx, cy, cz) = (t(0), t(1), t(2));
let scale = rand.next_double() * f64::from(size) / 16.0;
let bulge = math::sin(step as f32 * PI / size as f32) + 1.0;
let radius = (f64::from(bulge) * scale + 1.0) / 2.0;
for bx in floor_f64(cx - radius)..=floor_f64(cx + radius) {
let dx = (f64::from(bx) + 0.5 - cx) / radius;
if dx * dx >= 1.0 {
continue;
}
for by in floor_f64(cy - radius)..=floor_f64(cy + radius) {
let dy = (f64::from(by) + 0.5 - cy) / radius;
if dx * dx + dy * dy >= 1.0 {
continue;
}
for bz in floor_f64(cz - radius)..=floor_f64(cz + radius) {
let dz = (f64::from(bz) + 0.5 - cz) / radius;
if dx * dx + dy * dy + dz * dz < 1.0 && level.block(bx, by, bz) == from {
level.set_block(bx, by, bz, to);
}
}
}
}
}
}