155 lines
5.0 KiB
Rust
155 lines
5.0 KiB
Rust
use godot::{
|
|
classes::{FastNoiseLite, Resource},
|
|
obj::{Base, Gd},
|
|
prelude::{Export, GodotClass, GodotConvert, Var},
|
|
};
|
|
|
|
use crate::runtime::types::IntoRuntime;
|
|
use fastnoise_lite::FastNoiseLite as RustNoise;
|
|
|
|
#[derive(GodotConvert, Var, Export, Debug, Clone, Copy, PartialEq)]
|
|
#[godot(via = i64)]
|
|
pub enum WorldGeneratorType {
|
|
Noise2D,
|
|
Noise3D,
|
|
Graph,
|
|
Flat,
|
|
}
|
|
|
|
impl Default for WorldGeneratorType {
|
|
fn default() -> Self {
|
|
WorldGeneratorType::Noise2D
|
|
}
|
|
}
|
|
|
|
#[derive(GodotClass, Debug)]
|
|
#[class(init, base=Resource)]
|
|
pub struct WorldGeneratorResource {
|
|
#[base]
|
|
base: Base<Resource>,
|
|
|
|
#[export]
|
|
pub noise2d: Option<Gd<FastNoiseLite>>,
|
|
}
|
|
impl WorldGeneratorResource {
|
|
fn convert_noise_type(
|
|
ty: godot::classes::fast_noise_lite::NoiseType,
|
|
) -> fastnoise_lite::NoiseType {
|
|
use fastnoise_lite::NoiseType as R;
|
|
use godot::classes::fast_noise_lite::NoiseType as G;
|
|
|
|
match ty {
|
|
G::SIMPLEX => R::OpenSimplex2,
|
|
G::SIMPLEX_SMOOTH => R::OpenSimplex2S,
|
|
G::PERLIN => R::Perlin,
|
|
G::VALUE => R::Value,
|
|
G::VALUE_CUBIC => R::ValueCubic,
|
|
G::CELLULAR => R::Cellular,
|
|
_ => R::OpenSimplex2S, // reasonable default
|
|
}
|
|
}
|
|
|
|
fn convert_fractal_type(
|
|
ft: godot::classes::fast_noise_lite::FractalType,
|
|
dft: godot::classes::fast_noise_lite::DomainWarpFractalType,
|
|
) -> fastnoise_lite::FractalType {
|
|
use fastnoise_lite::FractalType as R;
|
|
use godot::classes::fast_noise_lite::DomainWarpFractalType as D;
|
|
use godot::classes::fast_noise_lite::FractalType as G;
|
|
|
|
// Priority: domain-warp fractals first
|
|
let domain_fractal = match dft {
|
|
D::PROGRESSIVE => Some(R::DomainWarpProgressive),
|
|
D::INDEPENDENT => Some(R::DomainWarpIndependent),
|
|
D::NONE => None,
|
|
_ => None,
|
|
};
|
|
|
|
if let Some(df) = domain_fractal {
|
|
return df;
|
|
}
|
|
|
|
// Then normal fractals
|
|
match ft {
|
|
G::NONE => R::None,
|
|
G::FBM => R::FBm,
|
|
G::RIDGED => R::Ridged,
|
|
G::PING_PONG => R::PingPong,
|
|
_ => R::None,
|
|
}
|
|
}
|
|
fn convert_cellular_distance_function(
|
|
fnc: godot::classes::fast_noise_lite::CellularDistanceFunction,
|
|
) -> fastnoise_lite::CellularDistanceFunction {
|
|
use fastnoise_lite::CellularDistanceFunction as R;
|
|
use godot::classes::fast_noise_lite::CellularDistanceFunction as G;
|
|
|
|
match fnc {
|
|
G::EUCLIDEAN => R::Euclidean,
|
|
G::EUCLIDEAN_SQUARED => R::EuclideanSq,
|
|
G::MANHATTAN => R::Manhattan,
|
|
G::HYBRID => R::Hybrid,
|
|
_ => R::Euclidean,
|
|
}
|
|
}
|
|
fn convert_cellular_return_type(
|
|
ret: godot::classes::fast_noise_lite::CellularReturnType,
|
|
) -> fastnoise_lite::CellularReturnType {
|
|
use fastnoise_lite::CellularReturnType as R;
|
|
use godot::classes::fast_noise_lite::CellularReturnType as G;
|
|
|
|
match ret {
|
|
G::CELL_VALUE => R::CellValue,
|
|
G::DISTANCE => R::Distance,
|
|
G::DISTANCE2 => R::Distance2,
|
|
G::DISTANCE2_ADD => R::Distance2Add,
|
|
G::DISTANCE2_SUB => R::Distance2Sub,
|
|
G::DISTANCE2_MUL => R::Distance2Mul,
|
|
G::DISTANCE2_DIV => R::Distance2Div,
|
|
_ => R::CellValue,
|
|
}
|
|
}
|
|
fn convert_domain_warp_type(
|
|
warp: godot::classes::fast_noise_lite::DomainWarpType,
|
|
) -> fastnoise_lite::DomainWarpType {
|
|
use fastnoise_lite::DomainWarpType as R;
|
|
use godot::classes::fast_noise_lite::DomainWarpType as G;
|
|
|
|
match warp {
|
|
G::SIMPLEX => R::OpenSimplex2,
|
|
G::SIMPLEX_REDUCED => R::OpenSimplex2Reduced,
|
|
G::BASIC_GRID => R::BasicGrid,
|
|
_ => R::OpenSimplex2,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl IntoRuntime<RustNoise> for WorldGeneratorResource {
|
|
fn into_runtime(&self) -> RustNoise {
|
|
match &self.noise2d {
|
|
Some(noise) => {
|
|
let mut rn = RustNoise::new();
|
|
rn.set_seed(Some(noise.get_seed()));
|
|
rn.set_frequency(Some(noise.get_frequency()));
|
|
rn.set_noise_type(Some(Self::convert_noise_type(noise.get_noise_type())));
|
|
rn.set_fractal_type(Some(Self::convert_fractal_type(
|
|
noise.get_fractal_type(),
|
|
noise.get_domain_warp_fractal_type(),
|
|
)));
|
|
rn.set_cellular_distance_function(Some(Self::convert_cellular_distance_function(
|
|
noise.get_cellular_distance_function(),
|
|
)));
|
|
rn.set_cellular_return_type(Some(Self::convert_cellular_return_type(
|
|
noise.get_cellular_return_type(),
|
|
)));
|
|
rn.set_domain_warp_type(Some(Self::convert_domain_warp_type(
|
|
noise.get_domain_warp_type(),
|
|
)));
|
|
|
|
return rn;
|
|
}
|
|
None => return RustNoise::new(),
|
|
}
|
|
}
|
|
}
|