-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathperlin.rs
More file actions
134 lines (111 loc) · 3.63 KB
/
perlin.rs
File metadata and controls
134 lines (111 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use crate::utility::*;
use std::vec::*;
use crate::rvec3::*;
pub struct Perlin{
ranvec : Vec<Rvec3>,
perm_x : Vec<i32>,
perm_y : Vec<i32>,
perm_z : Vec<i32>,
}
impl Default for Perlin{
fn default() -> Self {
Self::new()
}
}
impl Perlin {
const POINT_COUNT : i32 = 256;
pub fn new() -> Self{
let mut tmp : Vec<Rvec3> = Vec::new();
for _i in 0..Perlin::POINT_COUNT {
//tmp.push(Rvec3::unit_vector(&mut Rvec3::random_in_unit_sphere()));
tmp.push(Rvec3::unit_vector(&mut Rvec3::random_vec_range(-1.0, 1.0)));
}
Self {
ranvec : tmp,
perm_x : Perlin::perlin_generate_perm(),
perm_y : Perlin::perlin_generate_perm(),
perm_z : Perlin::perlin_generate_perm(),
}
}
pub fn noise(&self, p : &mut Point3) -> f64{
let u = p.x() - p.x().floor();
let v = p.y() - p.y().floor();
let w = p.z() - p.z().floor();
let i = p.x().floor() as i32;
let j = p.y().floor() as i32;
let k = p.z().floor() as i32;
let mut c = [[[Rvec3::new();2];2];2];
for di in 0i32..2{
for dj in 0i32..2{
for dk in 0i32..2{
c[di as usize][dj as usize][dk as usize] = self.ranvec[(
self.perm_x[((i + di) & 255) as usize] ^
self.perm_y[((j + dj) & 255) as usize] ^
self.perm_z[((k + dk) & 255) as usize]
) as usize];
}
}
}
Perlin::perlin_interp(c,u,v,w)
}
pub fn perlin_generate_perm() -> Vec<i32> {
let mut p : Vec<i32> = Vec::new();
for i in 0..Perlin::POINT_COUNT{
p.push(i);
}
Perlin::permute(&mut p,Perlin::POINT_COUNT);
p
}
pub fn permute(p : &mut [i32], n : i32) {
for i in (1..n).rev(){
let target = random_int(0,i);
p.swap(i as usize, target as usize);
}
}
//deprecated
/*
pub fn trilinear_interp(c :[[[f64;2];2];2], u : f64, v : f64, w : f64) -> f64{
let mut accum = 0.0;
for i in 0..2{
for j in 0..2{
for k in 0..2{
let fi = i as f64;
let fj = j as f64;
let fk = k as f64;
accum += (fi*u + (1.0-fi) * (1.0-u)) * (fj*v + (1.0-fj) * (1.0-v)) * (fk*w + (1.0-fk) * (1.0-w)) * c[i][j][k];
}
}
}
accum
}
*/
pub fn perlin_interp(c : [[[Rvec3;2];2];2], u : f64, v : f64, w : f64) -> f64{
let uu = u*u*(3.0-2.0*u);
let vv = v*v*(3.0-2.0*v);
let ww = w*w*(3.0-2.0*w);
let mut accum = 0.0;
for i in 0..2{
for j in 0..2{
for k in 0..2{
let weight_v = Rvec3::new_arg(u-i as f64,v-j as f64,w-k as f64);
accum += ((i as f64)*uu + (1.0-i as f64)*(1.0-uu))
* ((j as f64)*vv + (1.0-(j as f64)) * (1.0-vv))
* ((k as f64)*ww + (1.0-(k as f64)) * (1.0-ww))
* Rvec3::dot(&c[i as usize][j as usize][k as usize],&weight_v);
}
}
}
accum
}
pub fn turb(&self, p : &Point3, depth : i32) -> f64{
let mut accum : f64 = 0.0;
let mut temp_p = *p;
let mut weight = 1.0;
for _i in 0..depth {
accum += weight * self.noise(&mut temp_p);
weight *= 0.5;
temp_p = temp_p * 2.0;
}
accum.abs()
}
}