47 lines
1.4 KiB
Rust
47 lines
1.4 KiB
Rust
|
use rand::distributions::{Distribution, Uniform};
|
||
|
use rand::Rng;
|
||
|
use crate::Point3;
|
||
|
|
||
|
pub struct Perlin {
|
||
|
ranfloat: Vec<f64>,
|
||
|
perm_x: Vec<usize>,
|
||
|
perm_y: Vec<usize>,
|
||
|
perm_z: Vec<usize>,
|
||
|
}
|
||
|
|
||
|
impl Perlin {
|
||
|
const POINT_COUNT: usize = 256;
|
||
|
|
||
|
pub fn new() -> Self {
|
||
|
let range = Uniform::from(0.0..1.0);
|
||
|
let mut rng = rand::thread_rng();
|
||
|
let mut ranfloat = Vec::with_capacity(Perlin::POINT_COUNT);
|
||
|
(0..Perlin::POINT_COUNT).for_each(|_i|ranfloat.push(range.sample(&mut rng)));
|
||
|
Perlin {
|
||
|
ranfloat,
|
||
|
perm_x: Perlin::perlin_generate_perm(),
|
||
|
perm_y: Perlin::perlin_generate_perm(),
|
||
|
perm_z: Perlin::perlin_generate_perm(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn noise(&self, point: &Point3) -> f64 {
|
||
|
let i = ((4.0 * point.x()) as i32) & 255;
|
||
|
let j = ((4.0 * point.y()) as i32) & 255;
|
||
|
let k= ((4.0 * point.z()) as i32) & 255;
|
||
|
let idx = self.perm_x[i as usize] ^ self.perm_y[j as usize] ^ self.perm_z[k as usize];
|
||
|
self.ranfloat[idx]
|
||
|
}
|
||
|
|
||
|
fn perlin_generate_perm() -> Vec<usize> {
|
||
|
let mut p = Vec::with_capacity(Perlin::POINT_COUNT);
|
||
|
(0..Perlin::POINT_COUNT).for_each(|i| p.push(i));
|
||
|
let mut rng = rand::thread_rng();
|
||
|
(1..Perlin::POINT_COUNT).rev().for_each(|idx| {
|
||
|
let target = rng.gen_range(0..=idx);
|
||
|
p.swap(idx, target);
|
||
|
});
|
||
|
p
|
||
|
}
|
||
|
}
|