mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
remove main cargo.lock
This commit is contained in:
2312
Cargo.lock
generated
2312
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
1
pumpkin-world/src/world_gen/blender.rs
Normal file
1
pumpkin-world/src/world_gen/blender.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub struct Blender {}
|
||||||
59
pumpkin-world/src/world_gen/chunk.rs
Normal file
59
pumpkin-world/src/world_gen/chunk.rs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
use crate::chunk::ChunkData;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum GenerationState {
|
||||||
|
Empty,
|
||||||
|
StructureStart,
|
||||||
|
StructureRef,
|
||||||
|
Biome,
|
||||||
|
Noise,
|
||||||
|
Surface,
|
||||||
|
Carver,
|
||||||
|
Feature,
|
||||||
|
InitLight,
|
||||||
|
Light,
|
||||||
|
Spawn,
|
||||||
|
Full,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Chunk {
|
||||||
|
data: ChunkData,
|
||||||
|
state: GenerationState,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GenerationShapeConfig {
|
||||||
|
y_min: i32,
|
||||||
|
height: i32,
|
||||||
|
horizontal: i32,
|
||||||
|
vertical: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
//Bits avaliable to encode y-pos
|
||||||
|
const SIZE_BITS_Y: i32 = 12;
|
||||||
|
const MAX_HEIGHT: i32 = (1 << SIZE_BITS_Y) - 32;
|
||||||
|
const MAX_COLUMN_HEIGHT: i32 = (MAX_HEIGHT >> 1) - 1;
|
||||||
|
|
||||||
|
impl GenerationShapeConfig {
|
||||||
|
fn new(y_min: i32, height: i32, horizontal: i32, vertical: i32) -> Self {
|
||||||
|
if (y_min + height) > (MAX_COLUMN_HEIGHT + 1) {
|
||||||
|
panic!("Cannot be higher than max column height");
|
||||||
|
} else if height % 16 != 0 {
|
||||||
|
panic!("Height must be a multiple of 16");
|
||||||
|
} else if y_min % 16 != 0 {
|
||||||
|
panic!("Y min must be a multiple of 16");
|
||||||
|
}
|
||||||
|
Self {
|
||||||
|
y_min,
|
||||||
|
height,
|
||||||
|
horizontal,
|
||||||
|
vertical,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref surface_config: GenerationShapeConfig =
|
||||||
|
GenerationShapeConfig::new(-64, 384, 1, 2);
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
mod blender;
|
||||||
|
mod chunk;
|
||||||
mod generator;
|
mod generator;
|
||||||
mod generic_generator;
|
mod generic_generator;
|
||||||
mod implementation;
|
mod implementation;
|
||||||
|
|||||||
182
pumpkin-world/src/world_gen/noise/density/mod.rs
Normal file
182
pumpkin-world/src/world_gen/noise/density/mod.rs
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use noise::{InternalNoise, NoiseFunction, ShiftedNoiseFunction};
|
||||||
|
use offset::{ShiftAFunction, ShiftBFunction};
|
||||||
|
use unary::{ClampFunction, UnaryFunction, UnaryType};
|
||||||
|
|
||||||
|
use crate::world_gen::blender::Blender;
|
||||||
|
|
||||||
|
mod noise;
|
||||||
|
mod offset;
|
||||||
|
mod unary;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum DensityFunction<'a> {
|
||||||
|
Clamp(ClampFunction<'a>),
|
||||||
|
Unary(UnaryFunction<'a>),
|
||||||
|
Noise(NoiseFunction<'a>),
|
||||||
|
ShiftA(ShiftAFunction<'a>),
|
||||||
|
ShiftB(ShiftBFunction<'a>),
|
||||||
|
ShiftedNoise(ShiftedNoiseFunction<'a>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DensityFunction<'a> {
|
||||||
|
#[inline]
|
||||||
|
pub fn sample(&self, pos: &impl NoisePos) -> f64 {
|
||||||
|
match self {
|
||||||
|
Self::Clamp(func) => func.sample(pos),
|
||||||
|
Self::Unary(func) => func.sample(pos),
|
||||||
|
Self::Noise(func) => func.sample(pos),
|
||||||
|
Self::ShiftA(func) => func.sample(pos),
|
||||||
|
Self::ShiftB(func) => func.sample(pos),
|
||||||
|
Self::ShiftedNoise(func) => func.sample(pos),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn apply(&'a self, visitor: &'a impl Visitor) -> DensityFunction<'a> {
|
||||||
|
match self {
|
||||||
|
Self::Clamp(func) => func.apply(visitor),
|
||||||
|
Self::Unary(func) => func.apply(visitor),
|
||||||
|
Self::Noise(func) => func.apply(visitor),
|
||||||
|
Self::ShiftA(func) => func.apply(visitor),
|
||||||
|
Self::ShiftB(func) => func.apply(visitor),
|
||||||
|
Self::ShiftedNoise(func) => func.apply(visitor),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn fill(&self, densities: &[f64], applier: &impl Applier) -> Vec<f64> {
|
||||||
|
match self {
|
||||||
|
Self::Clamp(func) => func.fill(densities, applier),
|
||||||
|
Self::Unary(func) => func.fill(densities, applier),
|
||||||
|
Self::Noise(func) => func.fill(densities, applier),
|
||||||
|
Self::ShiftA(func) => func.fill(densities, applier),
|
||||||
|
Self::ShiftB(func) => func.fill(densities, applier),
|
||||||
|
Self::ShiftedNoise(func) => func.fill(densities, applier),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn max(&self) -> f64 {
|
||||||
|
match self {
|
||||||
|
Self::Clamp(func) => func.max(),
|
||||||
|
Self::Unary(func) => func.max(),
|
||||||
|
Self::Noise(func) => func.max(),
|
||||||
|
Self::ShiftA(func) => func.max(),
|
||||||
|
Self::ShiftB(func) => func.max(),
|
||||||
|
Self::ShiftedNoise(func) => func.max(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn min(&self) -> f64 {
|
||||||
|
match self {
|
||||||
|
Self::Clamp(func) => func.min(),
|
||||||
|
Self::Unary(func) => func.min(),
|
||||||
|
Self::Noise(func) => func.min(),
|
||||||
|
Self::ShiftA(func) => func.min(),
|
||||||
|
Self::ShiftB(func) => func.min(),
|
||||||
|
Self::ShiftedNoise(func) => func.min(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clamp(&self, max: f64, min: f64) -> Self {
|
||||||
|
Self::Clamp(ClampFunction {
|
||||||
|
input: Rc::new(self.clone()),
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn abs(&self) -> Self {
|
||||||
|
Self::Unary(UnaryFunction::create(UnaryType::Abs, Rc::new(self.clone())))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn square(&self) -> Self {
|
||||||
|
Self::Unary(UnaryFunction::create(
|
||||||
|
UnaryType::Square,
|
||||||
|
Rc::new(self.clone()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cube(&self) -> Self {
|
||||||
|
Self::Unary(UnaryFunction::create(
|
||||||
|
UnaryType::Cube,
|
||||||
|
Rc::new(self.clone()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn half_negative(&self) -> Self {
|
||||||
|
Self::Unary(UnaryFunction::create(
|
||||||
|
UnaryType::HalfNeg,
|
||||||
|
Rc::new(self.clone()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn quarter_negative(&self) -> Self {
|
||||||
|
Self::Unary(UnaryFunction::create(
|
||||||
|
UnaryType::QuartNeg,
|
||||||
|
Rc::new(self.clone()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn squeeze(&self) -> Self {
|
||||||
|
Self::Unary(UnaryFunction::create(
|
||||||
|
UnaryType::Squeeze,
|
||||||
|
Rc::new(self.clone()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait NoisePos {
|
||||||
|
fn x(&self) -> i32;
|
||||||
|
fn y(&self) -> i32;
|
||||||
|
fn z(&self) -> i32;
|
||||||
|
|
||||||
|
fn get_blender(&self) -> &Blender {
|
||||||
|
&Blender {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Applier {
|
||||||
|
fn at(&self, index: i32) -> impl NoisePos;
|
||||||
|
|
||||||
|
fn fill<'a>(&self, densities: &[f64], function: &impl DensityFunctionImpl<'a>) -> Vec<f64>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Visitor {
|
||||||
|
fn apply(&self, function: &DensityFunction) -> DensityFunction;
|
||||||
|
|
||||||
|
fn apply_internal_noise<'a>(&self, function: Rc<InternalNoise<'a>>) -> Rc<InternalNoise<'a>> {
|
||||||
|
function.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait DensityFunctionImpl<'a> {
|
||||||
|
fn sample(&self, pos: &impl NoisePos) -> f64;
|
||||||
|
|
||||||
|
fn fill(&self, densities: &[f64], applier: &impl Applier) -> Vec<f64>;
|
||||||
|
|
||||||
|
fn apply(&'a self, visitor: &'a impl Visitor) -> DensityFunction<'a>;
|
||||||
|
|
||||||
|
fn min(&self) -> f64;
|
||||||
|
|
||||||
|
fn max(&self) -> f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait UnaryDensityFunction<'a>: DensityFunctionImpl<'a> {
|
||||||
|
fn input(&self) -> &DensityFunction;
|
||||||
|
|
||||||
|
fn apply_density(&self, density: f64) -> f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait OffsetDensityFunction<'a>: DensityFunctionImpl<'a> {
|
||||||
|
fn offset_noise(&self) -> &InternalNoise<'a>;
|
||||||
|
|
||||||
|
fn sample_3d(&self, x: f64, y: f64, z: f64) -> f64 {
|
||||||
|
self.offset_noise()
|
||||||
|
.sample(x * 0.25f64, y * 0.25f64, z * 0.25f64)
|
||||||
|
* 4f64
|
||||||
|
}
|
||||||
|
}
|
||||||
107
pumpkin-world/src/world_gen/noise/density/noise.rs
Normal file
107
pumpkin-world/src/world_gen/noise/density/noise.rs
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::world_gen::noise::perlin::{DoublePerlinNoiseParameters, DoublePerlinNoiseSampler};
|
||||||
|
|
||||||
|
use super::{DensityFunction, DensityFunctionImpl};
|
||||||
|
|
||||||
|
pub(crate) struct InternalNoise<'a> {
|
||||||
|
data: DoublePerlinNoiseParameters<'a>,
|
||||||
|
sampler: Option<DoublePerlinNoiseSampler>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> InternalNoise<'a> {
|
||||||
|
pub(crate) fn sample(&self, x: f64, y: f64, z: f64) -> f64 {
|
||||||
|
match &self.sampler {
|
||||||
|
Some(sampler) => sampler.sample(x, y, z),
|
||||||
|
None => 0f64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn max_value(&self) -> f64 {
|
||||||
|
match &self.sampler {
|
||||||
|
Some(sampler) => sampler.max_value(),
|
||||||
|
None => 2f64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct NoiseFunction<'a> {
|
||||||
|
noise: Rc<InternalNoise<'a>>,
|
||||||
|
xz_scale: f64,
|
||||||
|
y_scale: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DensityFunctionImpl<'a> for NoiseFunction<'a> {
|
||||||
|
fn sample(&self, pos: &impl super::NoisePos) -> f64 {
|
||||||
|
self.noise.sample(
|
||||||
|
pos.x() as f64 * self.xz_scale,
|
||||||
|
pos.y() as f64 * self.y_scale,
|
||||||
|
pos.z() as f64 * self.xz_scale,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(&self, densities: &[f64], applier: &impl super::Applier) -> Vec<f64> {
|
||||||
|
applier.fill(densities, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&self, visitor: &'a impl super::Visitor) -> super::DensityFunction<'a> {
|
||||||
|
visitor.apply(&super::DensityFunction::Noise(self.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(&self) -> f64 {
|
||||||
|
self.noise.max_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min(&self) -> f64 {
|
||||||
|
-self.max()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ShiftedNoiseFunction<'a> {
|
||||||
|
shift_x: Rc<DensityFunction<'a>>,
|
||||||
|
shift_y: Rc<DensityFunction<'a>>,
|
||||||
|
shift_z: Rc<DensityFunction<'a>>,
|
||||||
|
noise: Rc<InternalNoise<'a>>,
|
||||||
|
xz_scale: f64,
|
||||||
|
y_scale: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DensityFunctionImpl<'a> for ShiftedNoiseFunction<'a> {
|
||||||
|
fn sample(&self, pos: &impl super::NoisePos) -> f64 {
|
||||||
|
let d = pos.x() as f64 * self.xz_scale + self.shift_x.sample(pos);
|
||||||
|
let e = pos.y() as f64 * self.y_scale + self.shift_y.sample(pos);
|
||||||
|
let f = pos.z() as f64 * self.xz_scale + self.shift_z.sample(pos);
|
||||||
|
|
||||||
|
self.noise.sample(d, e, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(&self, densities: &[f64], applier: &impl super::Applier) -> Vec<f64> {
|
||||||
|
applier.fill(densities, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&'a self, visitor: &'a impl super::Visitor) -> DensityFunction<'a> {
|
||||||
|
let new_x = self.shift_x.apply(visitor);
|
||||||
|
let new_y = self.shift_y.apply(visitor);
|
||||||
|
let new_z = self.shift_z.apply(visitor);
|
||||||
|
let new_noise = visitor.apply_internal_noise(self.noise.clone());
|
||||||
|
|
||||||
|
DensityFunction::ShiftedNoise(ShiftedNoiseFunction {
|
||||||
|
shift_x: Rc::new(new_x),
|
||||||
|
shift_y: Rc::new(new_y),
|
||||||
|
shift_z: Rc::new(new_z),
|
||||||
|
xz_scale: self.xz_scale,
|
||||||
|
y_scale: self.y_scale,
|
||||||
|
noise: new_noise,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(&self) -> f64 {
|
||||||
|
self.noise.max_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min(&self) -> f64 {
|
||||||
|
-self.max()
|
||||||
|
}
|
||||||
|
}
|
||||||
73
pumpkin-world/src/world_gen/noise/density/offset.rs
Normal file
73
pumpkin-world/src/world_gen/noise/density/offset.rs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use super::{noise::InternalNoise, DensityFunction, DensityFunctionImpl, OffsetDensityFunction};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ShiftAFunction<'a> {
|
||||||
|
offset: Rc<InternalNoise<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> OffsetDensityFunction<'a> for ShiftAFunction<'a> {
|
||||||
|
fn offset_noise(&self) -> &InternalNoise<'a> {
|
||||||
|
&self.offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DensityFunctionImpl<'a> for ShiftAFunction<'a> {
|
||||||
|
fn sample(&self, pos: &impl super::NoisePos) -> f64 {
|
||||||
|
self.sample_3d(pos.x() as f64, 0f64, pos.z() as f64)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&'a self, visitor: &'a impl super::Visitor) -> super::DensityFunction<'a> {
|
||||||
|
visitor.apply(&DensityFunction::ShiftA(ShiftAFunction {
|
||||||
|
offset: visitor.apply_internal_noise(self.offset.clone()),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(&self, densities: &[f64], applier: &impl super::Applier) -> Vec<f64> {
|
||||||
|
applier.fill(densities, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(&self) -> f64 {
|
||||||
|
self.offset_noise().max_value() * 4f64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min(&self) -> f64 {
|
||||||
|
-self.max()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ShiftBFunction<'a> {
|
||||||
|
offset: Rc<InternalNoise<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> OffsetDensityFunction<'a> for ShiftBFunction<'a> {
|
||||||
|
fn offset_noise(&self) -> &InternalNoise<'a> {
|
||||||
|
&self.offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DensityFunctionImpl<'a> for ShiftBFunction<'a> {
|
||||||
|
fn sample(&self, pos: &impl super::NoisePos) -> f64 {
|
||||||
|
self.sample_3d(pos.z() as f64, pos.x() as f64, 0f64)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&'a self, visitor: &'a impl super::Visitor) -> super::DensityFunction<'a> {
|
||||||
|
visitor.apply(&DensityFunction::ShiftB(ShiftBFunction {
|
||||||
|
offset: visitor.apply_internal_noise(self.offset.clone()),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(&self, densities: &[f64], applier: &impl super::Applier) -> Vec<f64> {
|
||||||
|
applier.fill(densities, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(&self) -> f64 {
|
||||||
|
self.offset_noise().max_value() * 4f64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min(&self) -> f64 {
|
||||||
|
-self.max()
|
||||||
|
}
|
||||||
|
}
|
||||||
147
pumpkin-world/src/world_gen/noise/density/unary.rs
Normal file
147
pumpkin-world/src/world_gen/noise/density/unary.rs
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use super::{DensityFunction, DensityFunctionImpl, UnaryDensityFunction};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ClampFunction<'a> {
|
||||||
|
pub(crate) input: Rc<DensityFunction<'a>>,
|
||||||
|
pub(crate) min: f64,
|
||||||
|
pub(crate) max: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> UnaryDensityFunction<'a> for ClampFunction<'a> {
|
||||||
|
fn input(&self) -> &DensityFunction {
|
||||||
|
&self.input
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_density(&self, density: f64) -> f64 {
|
||||||
|
density.clamp(self.min, self.max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DensityFunctionImpl<'a> for ClampFunction<'a> {
|
||||||
|
fn apply(&'a self, visitor: &'a impl super::Visitor) -> DensityFunction<'a> {
|
||||||
|
DensityFunction::Clamp(ClampFunction {
|
||||||
|
input: Rc::new(self.input().apply(visitor)),
|
||||||
|
min: self.min,
|
||||||
|
max: self.max,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sample(&self, pos: &impl super::NoisePos) -> f64 {
|
||||||
|
self.apply_density(self.input().sample(pos))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(&self, densities: &[f64], applier: &impl super::Applier) -> Vec<f64> {
|
||||||
|
let densities = self.input().fill(densities, applier);
|
||||||
|
densities.iter().map(|x| self.apply_density(*x)).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min(&self) -> f64 {
|
||||||
|
self.min
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(&self) -> f64 {
|
||||||
|
self.max
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) enum UnaryType {
|
||||||
|
Abs,
|
||||||
|
Square,
|
||||||
|
Cube,
|
||||||
|
HalfNeg,
|
||||||
|
QuartNeg,
|
||||||
|
Squeeze,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct UnaryFunction<'a> {
|
||||||
|
action: UnaryType,
|
||||||
|
input: Rc<DensityFunction<'a>>,
|
||||||
|
min: f64,
|
||||||
|
max: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> UnaryFunction<'a> {
|
||||||
|
pub(crate) fn create(action: UnaryType, input: Rc<DensityFunction<'a>>) -> UnaryFunction {
|
||||||
|
let base_min = input.min();
|
||||||
|
let new_min = Self::internal_apply(&action, base_min);
|
||||||
|
let new_max = Self::internal_apply(&action, input.max());
|
||||||
|
match action {
|
||||||
|
UnaryType::Abs | UnaryType::Square => Self {
|
||||||
|
action,
|
||||||
|
input,
|
||||||
|
min: f64::max(0f64, base_min),
|
||||||
|
max: f64::max(new_min, new_max),
|
||||||
|
},
|
||||||
|
_ => Self {
|
||||||
|
action,
|
||||||
|
input,
|
||||||
|
min: new_min,
|
||||||
|
max: new_max,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn internal_apply(action: &UnaryType, density: f64) -> f64 {
|
||||||
|
match action {
|
||||||
|
UnaryType::Abs => density.abs(),
|
||||||
|
UnaryType::Square => density * density,
|
||||||
|
UnaryType::Cube => density * density * density,
|
||||||
|
UnaryType::HalfNeg => {
|
||||||
|
if density > 0f64 {
|
||||||
|
density
|
||||||
|
} else {
|
||||||
|
density * 0.5f64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnaryType::QuartNeg => {
|
||||||
|
if density > 0f64 {
|
||||||
|
density
|
||||||
|
} else {
|
||||||
|
density * 0.25f64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnaryType::Squeeze => {
|
||||||
|
let d = density.clamp(-1f64, 1f64);
|
||||||
|
d / 2f64 - d * d * d / 24f64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> UnaryDensityFunction<'a> for UnaryFunction<'a> {
|
||||||
|
fn apply_density(&self, density: f64) -> f64 {
|
||||||
|
Self::internal_apply(&self.action, density)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn input(&self) -> &DensityFunction {
|
||||||
|
&self.input
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DensityFunctionImpl<'a> for UnaryFunction<'a> {
|
||||||
|
fn sample(&self, pos: &impl super::NoisePos) -> f64 {
|
||||||
|
self.apply_density(self.input().sample(pos))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(&self, densities: &[f64], applier: &impl super::Applier) -> Vec<f64> {
|
||||||
|
let densities = self.input().fill(densities, applier);
|
||||||
|
densities.iter().map(|x| self.apply_density(*x)).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&'a self, visitor: &'a impl super::Visitor) -> DensityFunction<'a> {
|
||||||
|
let raw = Self::create(self.action.clone(), Rc::new(self.input().apply(visitor)));
|
||||||
|
DensityFunction::Unary(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(&self) -> f64 {
|
||||||
|
self.max
|
||||||
|
}
|
||||||
|
|
||||||
|
fn min(&self) -> f64 {
|
||||||
|
self.min
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,174 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
mod density;
|
||||||
mod perlin;
|
mod perlin;
|
||||||
mod simplex;
|
mod simplex;
|
||||||
|
|
||||||
|
pub mod builtin_noise_params {
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
use super::perlin::DoublePerlinNoiseParameters;
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref temperature: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-10, &[1.5f64, 0f64, 1f64, 0f64, 0f64, 0f64,],);
|
||||||
|
pub static ref vegetation: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64, 1f64, 0f64, 0f64, 0f64, 0f64,],);
|
||||||
|
pub static ref continentalness: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(
|
||||||
|
-9,
|
||||||
|
&[1f64, 1f64, 2f64, 2f64, 2f64, 1f64, 1f64, 1f64, 1f64,],
|
||||||
|
);
|
||||||
|
pub static ref erosion: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-9, &[1f64, 1f64, 0f64, 1f64, 1f64,],);
|
||||||
|
pub static ref temperature_large: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-12, &[1.5f64, 0f64, 1f64, 0f64, 0f64, 0f64,],);
|
||||||
|
pub static ref vegetation_large: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-10, &[1f64, 1f64, 0f64, 0f64, 0f64, 0f64,],);
|
||||||
|
pub static ref continentalness_large: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(
|
||||||
|
-11,
|
||||||
|
&[1f64, 1f64, 2f64, 2f64, 2f64, 1f64, 1f64, 1f64, 1f64,],
|
||||||
|
);
|
||||||
|
pub static ref erosion_large: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-11, &[1f64, 1f64, 0f64, 1f64, 1f64,],);
|
||||||
|
pub static ref ridge: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64, 2f64, 1f64, 0f64, 0f64, 0f64],);
|
||||||
|
pub static ref offset: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-3, &[1f64; 4],);
|
||||||
|
pub static ref aquifer_barrier: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-3, &[1f64,],);
|
||||||
|
pub static ref aquifer_barrier_floodedness: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64,],);
|
||||||
|
pub static ref aquifer_lava: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-1, &[1f64,],);
|
||||||
|
pub static ref aquifer_fluid_level_spread: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-5, &[1f64,],);
|
||||||
|
pub static ref pillar: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64; 2],);
|
||||||
|
pub static ref pillar_rareness: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref pillar_thickness: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref spaghetti_2d: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64,],);
|
||||||
|
pub static ref spaghetti_2d_elevation: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref spaghetti_2d_modulator: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-11, &[1f64,],);
|
||||||
|
pub static ref spaghetti_2d_thickness: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-11, &[1f64,],);
|
||||||
|
pub static ref spaghetti_3d_1: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64,],);
|
||||||
|
pub static ref spaghetti_3d_2: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64,],);
|
||||||
|
pub static ref spaghetti_3d_rarity: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-11, &[1f64,],);
|
||||||
|
pub static ref spaghetti_3d_thickness: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref spaghetti_roughness: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-5, &[1f64,],);
|
||||||
|
pub static ref spaghetti_roughness_modulator: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref cave_entrance: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[0.4f64, 0.5f64, 1f64],);
|
||||||
|
pub static ref cave_layer: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref cave_cheese: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(
|
||||||
|
-8,
|
||||||
|
&[0.5f64, 1f64, 2f64, 1f64, 2f64, 1f64, 0f64, 2f64, 0f64,],
|
||||||
|
);
|
||||||
|
pub static ref ore_veininess: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref ore_vein_a: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64,],);
|
||||||
|
pub static ref ore_vein_b: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64,],);
|
||||||
|
pub static ref ore_gap: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-5, &[1f64,],);
|
||||||
|
pub static ref noodle: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref noodle_thickness: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref noodle_ridge_a: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64,],);
|
||||||
|
pub static ref noodle_ridge_b: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64,],);
|
||||||
|
pub static ref jagged: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-16, &[1f64; 16],);
|
||||||
|
pub static ref surface: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-6, &[1f64; 3],);
|
||||||
|
pub static ref surface_secondary: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-6, &[1f64, 1f64, 0f64, 1f64,],);
|
||||||
|
pub static ref clay_bands_offset: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref badlands_pillar: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-2, &[1f64; 4],);
|
||||||
|
pub static ref badlands_pillar_roof: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64,],);
|
||||||
|
pub static ref badlands_surface: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-6, &[1f64; 3],);
|
||||||
|
pub static ref iceberg_pillar: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-6, &[1f64; 4],);
|
||||||
|
pub static ref iceberg_pillar_roof: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-3, &[1f64,],);
|
||||||
|
pub static ref iceberg_surface: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-6, &[1f64; 3],);
|
||||||
|
pub static ref surface_swamp: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-2, &[1f64,],);
|
||||||
|
pub static ref calcite: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-9, &[1f64; 4],);
|
||||||
|
pub static ref gravel: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-8, &[1f64; 4],);
|
||||||
|
pub static ref powder_snow: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-6, &[1f64; 4],);
|
||||||
|
pub static ref packed_ice: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-7, &[1f64; 4],);
|
||||||
|
pub static ref ice: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-4, &[1f64; 4],);
|
||||||
|
pub static ref soul_sand_layer: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(
|
||||||
|
-8,
|
||||||
|
&[
|
||||||
|
1f64,
|
||||||
|
1f64,
|
||||||
|
1f64,
|
||||||
|
1f64,
|
||||||
|
0f64,
|
||||||
|
0f64,
|
||||||
|
0f64,
|
||||||
|
0f64,
|
||||||
|
0.013333333333333334f64,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
pub static ref gravel_layer: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(
|
||||||
|
-8,
|
||||||
|
&[
|
||||||
|
1f64,
|
||||||
|
1f64,
|
||||||
|
1f64,
|
||||||
|
1f64,
|
||||||
|
0f64,
|
||||||
|
0f64,
|
||||||
|
0f64,
|
||||||
|
0f64,
|
||||||
|
0.013333333333333334f64,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
pub static ref patch: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(
|
||||||
|
-5,
|
||||||
|
&[1f64, 0f64, 0f64, 0f64, 0f64, 0.013333333333333334f64,],
|
||||||
|
);
|
||||||
|
pub static ref netherrack: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-3, &[1f64, 0f64, 0f64, 0.35f64,],);
|
||||||
|
pub static ref nether_wart: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-3, &[1f64, 0f64, 0f64, 0.9f64,],);
|
||||||
|
pub static ref nether_state_selector: DoublePerlinNoiseParameters<'static> =
|
||||||
|
DoublePerlinNoiseParameters::new(-4, &[1f64,],);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lerp(delta: f64, start: f64, end: f64) -> f64 {
|
pub fn lerp(delta: f64, start: f64, end: f64) -> f64 {
|
||||||
start + delta * (end - start)
|
start + delta * (end - start)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,6 +286,20 @@ impl OctavePerlinNoiseSampler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct DoublePerlinNoiseParameters<'a> {
|
||||||
|
first_octave: i32,
|
||||||
|
amplitudes: &'a [f64],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DoublePerlinNoiseParameters<'a> {
|
||||||
|
pub fn new(first_octave: i32, amplitudes: &'a [f64]) -> Self {
|
||||||
|
Self {
|
||||||
|
first_octave,
|
||||||
|
amplitudes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct DoublePerlinNoiseSampler {
|
pub struct DoublePerlinNoiseSampler {
|
||||||
first_sampler: OctavePerlinNoiseSampler,
|
first_sampler: OctavePerlinNoiseSampler,
|
||||||
second_sampler: OctavePerlinNoiseSampler,
|
second_sampler: OctavePerlinNoiseSampler,
|
||||||
@@ -298,7 +312,14 @@ impl DoublePerlinNoiseSampler {
|
|||||||
0.1f64 * (1f64 + 1f64 / (octaves + 1) as f64)
|
0.1f64 * (1f64 + 1f64 / (octaves + 1) as f64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(rand: &mut RandomGenerator, first_octave: i32, amplitudes: &[f64]) -> Self {
|
pub fn max_value(&self) -> f64 {
|
||||||
|
self.max_value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(rand: &mut RandomGenerator, parameters: &DoublePerlinNoiseParameters) -> Self {
|
||||||
|
let first_octave = parameters.first_octave;
|
||||||
|
let amplitudes = parameters.amplitudes;
|
||||||
|
|
||||||
let first_sampler = OctavePerlinNoiseSampler::new(rand, first_octave, amplitudes);
|
let first_sampler = OctavePerlinNoiseSampler::new(rand, first_octave, amplitudes);
|
||||||
let second_sampler = OctavePerlinNoiseSampler::new(rand, first_octave, amplitudes);
|
let second_sampler = OctavePerlinNoiseSampler::new(rand, first_octave, amplitudes);
|
||||||
|
|
||||||
@@ -336,7 +357,9 @@ impl DoublePerlinNoiseSampler {
|
|||||||
mod double_perlin_noise_sampler_test {
|
mod double_perlin_noise_sampler_test {
|
||||||
use pumpkin_core::random::{legacy_rand::LegacyRand, xoroshiro128::Xoroshiro, RandomImpl};
|
use pumpkin_core::random::{legacy_rand::LegacyRand, xoroshiro128::Xoroshiro, RandomImpl};
|
||||||
|
|
||||||
use crate::world_gen::noise::perlin::{DoublePerlinNoiseSampler, RandomGenerator};
|
use crate::world_gen::noise::perlin::{
|
||||||
|
DoublePerlinNoiseParameters, DoublePerlinNoiseSampler, RandomGenerator,
|
||||||
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sample_legacy() {
|
fn sample_legacy() {
|
||||||
@@ -344,7 +367,11 @@ mod double_perlin_noise_sampler_test {
|
|||||||
assert_eq!(rand.next_i32(), -1302745855);
|
assert_eq!(rand.next_i32(), -1302745855);
|
||||||
|
|
||||||
let mut rand_gen = RandomGenerator::Legacy(rand);
|
let mut rand_gen = RandomGenerator::Legacy(rand);
|
||||||
let sampler = DoublePerlinNoiseSampler::new(&mut rand_gen, 0, &[4f64]);
|
let params = DoublePerlinNoiseParameters {
|
||||||
|
first_octave: 0,
|
||||||
|
amplitudes: &[4f64],
|
||||||
|
};
|
||||||
|
let sampler = DoublePerlinNoiseSampler::new(&mut rand_gen, ¶ms);
|
||||||
|
|
||||||
let values = [
|
let values = [
|
||||||
(
|
(
|
||||||
@@ -440,7 +467,13 @@ mod double_perlin_noise_sampler_test {
|
|||||||
assert_eq!(rand.next_i32(), -1678727252);
|
assert_eq!(rand.next_i32(), -1678727252);
|
||||||
|
|
||||||
let mut rand_gen = RandomGenerator::Xoroshiro(rand);
|
let mut rand_gen = RandomGenerator::Xoroshiro(rand);
|
||||||
let sampler = DoublePerlinNoiseSampler::new(&mut rand_gen, 1, &[2f64, 4f64]);
|
|
||||||
|
let params = DoublePerlinNoiseParameters {
|
||||||
|
first_octave: 1,
|
||||||
|
amplitudes: &[2f64, 4f64],
|
||||||
|
};
|
||||||
|
|
||||||
|
let sampler = DoublePerlinNoiseSampler::new(&mut rand_gen, ¶ms);
|
||||||
|
|
||||||
let values = [
|
let values = [
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user