use glam::DVec3; use noise::NoiseFn; use crate::utility::barycentric_value; #[derive(Clone, Copy)] pub struct Octave { pub frequency:f64, pub amplitude:f64, pub offset:DVec3, } impl Octave { pub fn new() -> Self { Self { frequency:1., amplitude:1., offset:DVec3::ZERO, } } } #[derive(Clone)] pub struct Source { pub position:DVec3, pub elevation:f64, pub octaves:Vec, } impl Source { pub fn new() -> Self { Self { position:DVec3::ZERO, elevation:0., octaves:Vec::::new(), } } } #[derive(Clone)] pub struct Generator { pub generator:noise::Perlin, pub sources:[Source; 3], } impl Generator { pub fn new() -> Self { Self { generator:noise::Perlin::new(12), sources:[Source::new(), Source::new(), Source::new()], } } pub fn generate(&mut self, position:DVec3) -> f64 { let mut heights = vec![0.; 3]; for src in 0..heights.len() { heights[src] = self.sources[src].elevation; for octave in &self.sources[src].octaves { heights[src] += octave.amplitude * self.generator.get([ octave.frequency * (position.x + octave.offset.x), octave.frequency * (position.y + octave.offset.y), octave.frequency * (position.z + octave.offset.z), ]); } //heights[src] /= self.sources[src].octaves.len().max(1) as f64; } barycentric_value( (self.sources[0].position, self.sources[1].position, self.sources[2].position), (heights[0], heights[1], heights[2]), position ) } }