Skip to content

Commit

Permalink
implement populate noise step of chunk generation
Browse files Browse the repository at this point in the history
  • Loading branch information
kralverde committed Nov 23, 2024
1 parent e83e5d7 commit 96b79a2
Show file tree
Hide file tree
Showing 44 changed files with 27,105 additions and 3,067 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,10 @@ docs/.vitepress/dist
docs/.vitepress/cache
node_modules

<<<<<<< HEAD
# Benchmarking
*perf.data*
*flamegraph.svg
=======
run/
>>>>>>> master
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ edition = "2021"
lto = true
codegen-units = 1

[profile.bench]
debug = true

[profile.profiling]
inherits = "release"
debug = true
Expand Down
1 change: 1 addition & 0 deletions pumpkin-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ fastnbt = { git = "https://github.com/owengage/fastnbt.git" }
colored = "2"
md5 = "0.7.0"

enum_dispatch = "0.3.13"
59 changes: 59 additions & 0 deletions pumpkin-core/src/math/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use num_traits::PrimInt;

pub mod boundingbox;
pub mod position;
pub mod vector2;
Expand Down Expand Up @@ -30,3 +32,60 @@ pub fn magnitude(a: f64, b: f64, c: f64) -> f64 {
pub const fn get_section_cord(coord: i32) -> i32 {
coord >> 4
}

const MULTIPLY_DE_BRUIJN_BIT_POSITION: [u8; 32] = [
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26,
12, 18, 6, 11, 5, 10, 9,
];

/// Maximum return value: 31
pub const fn ceil_log2(value: u32) -> u8 {
let value = if value.is_power_of_two() {
value
} else {
smallest_encompassing_power_of_two(value)
};

MULTIPLY_DE_BRUIJN_BIT_POSITION[(((value as usize) * 125613361) >> 27) & 31]
}

/// Maximum return value: 30
pub const fn floor_log2(value: u32) -> u8 {
ceil_log2(value) - if value.is_power_of_two() { 0 } else { 1 }
}

pub const fn smallest_encompassing_power_of_two(value: u32) -> u32 {
let mut i = value - 1;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i + 1
}

#[inline]
pub fn floor_div<T>(x: T, y: T) -> T
where
T: PrimInt + From<i8>,
{
let div = x / y;
if (x ^ y) < 0.into() && div * y != x {
div - 1.into()
} else {
div
}
}

#[inline]
pub fn floor_mod<T>(x: T, y: T) -> T
where
T: PrimInt + From<i8>,
{
let rem = x % y;
if (x ^ y) < 0.into() && rem != 0.into() {
rem + y
} else {
rem
}
}
5 changes: 3 additions & 2 deletions pumpkin-core/src/math/vector2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use std::ops::{Add, Div, Mul, Neg, Sub};

use num_traits::Float;

#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq, Default)]
pub struct Vector2<T> {
pub x: T,
pub z: T,
}

impl<T: Math + Copy> Vector2<T> {
pub fn new(x: T, z: T) -> Self {
pub const fn new(x: T, z: T) -> Self {
Vector2 { x, z }
}

Expand Down Expand Up @@ -103,3 +103,4 @@ impl Math for f64 {}
impl Math for f32 {}
impl Math for i32 {}
impl Math for i64 {}
impl Math for i8 {}
9 changes: 6 additions & 3 deletions pumpkin-core/src/math/vector3.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::ops::{Add, Div, Mul, Neg, Sub};
use std::ops::{Add, Div, Mul, Sub};

use num_traits::Float;

#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq, Default)]
pub struct Vector3<T> {
pub x: T,
pub y: T,
Expand Down Expand Up @@ -80,6 +80,7 @@ impl<T: Math + Copy> Add for Vector3<T> {
}
}

/*
impl<T: Math + Copy> Neg for Vector3<T> {
type Output = Self;
Expand All @@ -91,6 +92,7 @@ impl<T: Math + Copy> Neg for Vector3<T> {
}
}
}
*/

impl<T> From<(T, T, T)> for Vector3<T> {
#[inline(always)]
Expand All @@ -108,7 +110,7 @@ impl<T> From<Vector3<T>> for (T, T, T) {

pub trait Math:
Mul<Output = Self>
+ Neg<Output = Self>
//+ Neg<Output = Self>
+ Add<Output = Self>
+ Div<Output = Self>
+ Sub<Output = Self>
Expand All @@ -119,3 +121,4 @@ impl Math for f64 {}
impl Math for f32 {}
impl Math for i32 {}
impl Math for i64 {}
impl Math for u8 {}
38 changes: 25 additions & 13 deletions pumpkin-core/src/random/legacy_rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ pub struct LegacyRand {
}

impl LegacyRand {
fn next_random(&mut self) -> u64 {
let l = self.seed;
fn next_random(&mut self) -> i64 {
let l = self.seed as i64;
let m = l.wrapping_mul(0x5DEECE66D).wrapping_add(11) & 0xFFFFFFFFFFFF;
self.seed = m;
self.seed = m as u64;
m
}

fn next(&mut self, bits: u64) -> i32 {
(self.next_random() >> (48 - bits)) as i32
}
}

impl GaussianGenerator for LegacyRand {
Expand All @@ -34,16 +38,12 @@ impl RandomImpl for LegacyRand {
}
}

fn next(&mut self, bits: u64) -> u64 {
self.next_random() >> (48 - bits)
}

fn split(&mut self) -> Self {
LegacyRand::from_seed(self.next_i64() as u64)
}

fn next_i32(&mut self) -> i32 {
self.next(32) as i32
self.next(32)
}

fn next_i64(&mut self) -> i64 {
Expand All @@ -59,7 +59,7 @@ impl RandomImpl for LegacyRand {
fn next_f64(&mut self) -> f64 {
let i = self.next(26);
let j = self.next(27);
let l = (i << 27).wrapping_add(j);
let l = ((i as i64) << 27).wrapping_add(j as i64);
l as f64 * 1.110223E-16f32 as f64
}

Expand All @@ -78,10 +78,10 @@ impl RandomImpl for LegacyRand {

fn next_bounded_i32(&mut self, bound: i32) -> i32 {
if (bound & bound.wrapping_sub(1)) == 0 {
((bound as u64).wrapping_mul(self.next(31)) >> 31) as i32
((bound as i64).wrapping_mul(self.next(31) as i64) >> 31) as i32
} else {
loop {
let i = self.next(31) as i32;
let i = self.next(31);
let j = i % bound;
if (i.wrapping_sub(j).wrapping_add(bound.wrapping_sub(1))) >= 0 {
return j;
Expand All @@ -91,6 +91,7 @@ impl RandomImpl for LegacyRand {
}
}

#[derive(Clone)]
pub struct LegacySplitter {
seed: u64,
}
Expand Down Expand Up @@ -120,7 +121,7 @@ impl RandomDeriverImpl for LegacySplitter {

#[cfg(test)]
mod test {
use crate::random::{RandomDeriverImpl, RandomImpl};
use crate::random::{legacy_rand::LegacySplitter, RandomDeriverImpl, RandomImpl};

use super::LegacyRand;

Expand Down Expand Up @@ -308,8 +309,19 @@ mod test {
#[test]
fn test_split() {
let mut original_rand = LegacyRand::from_seed(0);
let mut new_rand = original_rand.split();
assert_eq!(original_rand.next_i64(), -4962768465676381896i64);

let mut original_rand = LegacyRand::from_seed(0);
{
let splitter: LegacySplitter = original_rand.next_splitter();
assert_eq!(splitter.seed, (-4962768465676381896i64) as u64);

let mut rand = splitter.split_string("minecraft:offset");
assert_eq!(rand.next_i32(), 103436829);
}

let mut original_rand = LegacyRand::from_seed(0);
let mut new_rand = original_rand.split();
{
let splitter = new_rand.next_splitter();

Expand Down
33 changes: 7 additions & 26 deletions pumpkin-core/src/random/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ pub mod xoroshiro128;
pub enum RandomGenerator {
Xoroshiro(Xoroshiro),
Legacy(LegacyRand),
LegacyXoroshiro(Xoroshiro),
}

impl RandomGenerator {
#[inline]
pub fn split(&mut self) -> Self {
match self {
Self::Xoroshiro(rand) => Self::Xoroshiro(rand.split()),
Self::LegacyXoroshiro(rand) => Self::LegacyXoroshiro(rand.split()),
Self::Legacy(rand) => Self::Legacy(rand.split()),
}
}
Expand All @@ -25,25 +23,14 @@ impl RandomGenerator {
pub fn next_splitter(&mut self) -> RandomDeriver {
match self {
Self::Xoroshiro(rand) => RandomDeriver::Xoroshiro(rand.next_splitter()),
Self::LegacyXoroshiro(rand) => RandomDeriver::Xoroshiro(rand.next_splitter()),
Self::Legacy(rand) => RandomDeriver::Legacy(rand.next_splitter()),
}
}

#[inline]
pub fn next(&mut self, bits: u64) -> u64 {
match self {
Self::Xoroshiro(rand) => rand.next(bits),
Self::LegacyXoroshiro(rand) => rand.next(bits),
Self::Legacy(rand) => rand.next(bits),
}
}

#[inline]
pub fn next_i32(&mut self) -> i32 {
match self {
Self::Xoroshiro(rand) => rand.next_i32(),
Self::LegacyXoroshiro(rand) => rand.next_i32(),
Self::Legacy(rand) => rand.next_i32(),
}
}
Expand All @@ -52,7 +39,6 @@ impl RandomGenerator {
pub fn next_bounded_i32(&mut self, bound: i32) -> i32 {
match self {
Self::Xoroshiro(rand) => rand.next_bounded_i32(bound),
Self::LegacyXoroshiro(rand) => rand.next_bounded_i32(bound),
Self::Legacy(rand) => rand.next_bounded_i32(bound),
}
}
Expand All @@ -66,7 +52,6 @@ impl RandomGenerator {
pub fn next_i64(&mut self) -> i64 {
match self {
Self::Xoroshiro(rand) => rand.next_i64(),
Self::LegacyXoroshiro(rand) => rand.next_i64(),
Self::Legacy(rand) => rand.next_i64(),
}
}
Expand All @@ -75,7 +60,6 @@ impl RandomGenerator {
pub fn next_bool(&mut self) -> bool {
match self {
Self::Xoroshiro(rand) => rand.next_bool(),
Self::LegacyXoroshiro(rand) => rand.next_bool(),
Self::Legacy(rand) => rand.next_bool(),
}
}
Expand All @@ -84,7 +68,6 @@ impl RandomGenerator {
pub fn next_f32(&mut self) -> f32 {
match self {
Self::Xoroshiro(rand) => rand.next_f32(),
Self::LegacyXoroshiro(rand) => rand.next_f32(),
Self::Legacy(rand) => rand.next_f32(),
}
}
Expand All @@ -93,7 +76,6 @@ impl RandomGenerator {
pub fn next_f64(&mut self) -> f64 {
match self {
Self::Xoroshiro(rand) => rand.next_f64(),
Self::LegacyXoroshiro(rand) => rand.next_f64(),
Self::Legacy(rand) => rand.next_f64(),
}
}
Expand All @@ -102,7 +84,6 @@ impl RandomGenerator {
pub fn next_gaussian(&mut self) -> f64 {
match self {
Self::Xoroshiro(rand) => rand.next_gaussian(),
Self::LegacyXoroshiro(rand) => rand.next_gaussian(),
Self::Legacy(rand) => rand.next_gaussian(),
}
}
Expand All @@ -125,6 +106,7 @@ impl RandomGenerator {
}
}

#[derive(Clone)]
pub enum RandomDeriver {
Xoroshiro(XoroshiroSplitter),
Legacy(LegacySplitter),
Expand Down Expand Up @@ -163,8 +145,6 @@ pub trait RandomImpl {

fn next_splitter(&mut self) -> impl RandomDeriverImpl;

fn next(&mut self, bits: u64) -> u64;

fn next_i32(&mut self) -> i32;

fn next_bounded_i32(&mut self, bound: i32) -> i32;
Expand Down Expand Up @@ -215,17 +195,17 @@ fn hash_block_pos(x: i32, y: i32, z: i32) -> i64 {
l >> 16
}

fn java_string_hash(string: &str) -> u32 {
fn java_string_hash(string: &str) -> i32 {
// All byte values of latin1 align with
// the values of U+0000 - U+00FF making this code
// equivalent to both java hash implementations

let mut result = 0u32;
let mut result = 0i32;

for char_encoding in string.encode_utf16() {
result = 31u32
result = 31i32
.wrapping_mul(result)
.wrapping_add(char_encoding as u32);
.wrapping_add(char_encoding as i32);
}
result
}
Expand Down Expand Up @@ -271,12 +251,13 @@ mod tests {
ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄ\
ÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞ\
ßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ",
(-1992287231i32) as u32,
-1992287231i32,
),
("求同存异", 847053876),
// This might look wierd because hebrew is text is right to left
("אבְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ:", 1372570871),
("संस्कृत-", 1748614838),
("minecraft:offset", -920384768i32),
];

for (string, value) in values {
Expand Down
Loading

0 comments on commit 96b79a2

Please sign in to comment.