… | |
… | |
20 | * The authors can be reached via e-mail to <support@deliantra.net> |
20 | * The authors can be reached via e-mail to <support@deliantra.net> |
21 | */ |
21 | */ |
22 | |
22 | |
23 | #include "noise.h" |
23 | #include "noise.h" |
24 | |
24 | |
|
|
25 | ///////////////////////////////////////////////////////////////////////////// |
|
|
26 | |
25 | noise_gen::noise_gen (uint32_t seed) |
27 | noise2d::noise2d (uint32_t seed) |
26 | { |
28 | { |
27 | seedable_rand_gen rng (seed); |
29 | seedable_rand_gen rng (seed); |
28 | |
30 | |
29 | for (int i = 0; i < 256; ++i) |
31 | for (int i = 0; i < 256; ++i) |
30 | { |
32 | { |
31 | for (int j = 0; j < 2; ++j) |
33 | vec2d rv; |
32 | rvec [i][j] = rng () - 0.5f; |
34 | rv[0] = rng () - 0.5f; |
|
|
35 | rv[1] = rng () - 0.5f; |
33 | |
36 | |
34 | // normalise |
37 | // normalise |
35 | float mag = 1.f / sqrtf (rvec [i][0] * rvec [i][0] + rvec [i][1] * rvec [i][1]); |
38 | float mag = 1.f / sqrtf (rv[0] * rv[0] + rv[1] * rv[1]); |
36 | |
39 | |
37 | rvec [i][0] *= mag; |
40 | rv[0] *= mag; |
38 | rvec [i][1] *= mag; |
41 | rv[1] *= mag; |
39 | } |
|
|
40 | |
42 | |
|
|
43 | rvec[i][0] = rv[0]; |
|
|
44 | rvec[i][1] = rv[1]; |
|
|
45 | } |
|
|
46 | |
41 | rvmap [0].seed (rng); |
47 | rvmap[0].seed (rng); |
42 | rvmap [1].seed (rng); |
48 | rvmap[1].seed (rng); |
43 | } |
49 | } |
44 | |
50 | |
45 | float |
51 | float |
46 | noise_gen::noise (float x, float y) |
52 | noise2d::noise (float x, float y) |
47 | { |
53 | { |
48 | int ix = floorf (x); float fx = x - ix; |
54 | int ix = floorf (x); float fx = x - ix; |
49 | int iy = floorf (y); float fy = y - iy; |
55 | int iy = floorf (y); float fy = y - iy; |
50 | |
56 | |
51 | float v = 0; |
57 | float v = 0; |
… | |
… | |
54 | for (int i = -1; i <= 2; ++i) |
60 | for (int i = -1; i <= 2; ++i) |
55 | { |
61 | { |
56 | float Ax = fx - i; |
62 | float Ax = fx - i; |
57 | float Ay = fy - j; |
63 | float Ay = fy - j; |
58 | |
64 | |
59 | float d = Ax * Ax + Ay * Ay; |
65 | float d = Ax * Ax + Ay * Ay; |
60 | |
66 | |
61 | if (d < 4) |
67 | if (d < 4) |
62 | { |
68 | { |
63 | int h = rvmap [0](ix + i) ^ rvmap [1](iy + j); |
|
|
64 | float *G = rvec [h & 0xff]; |
|
|
65 | |
|
|
66 | float t1 = 1 - d / 4; |
69 | float t1 = 1 - d / 4; |
67 | float t2 = t1 * t1; |
70 | float t2 = t1 * t1; |
68 | float t4 = t2 * t2; |
71 | float t4 = t2 * t2; |
69 | |
72 | |
70 | float p = (4 * t1 - 3) * t4; |
73 | float p = (4 * t1 - 3) * t4; |
|
|
74 | |
|
|
75 | int h = rvmap[0](ix + i) ^ rvmap[1](iy + j); |
|
|
76 | float G0 = rvec[h & 0xff][0]; |
|
|
77 | float G1 = rvec[h & 0xff][1]; |
|
|
78 | //vec2d G = rvec[h & 0xff]; |
|
|
79 | |
71 | v += (Ax * G[0] + Ay * G[1]) * p; |
80 | v += (Ax * G0 + Ay * G1) * p; |
72 | } |
81 | } |
73 | } |
82 | } |
74 | |
83 | |
75 | return clamp (v * 2, -.9999999f, .9999999f); |
84 | return clamp (v * 2, -.9999999f, .9999999f); |
76 | } |
85 | } |
77 | |
86 | |
|
|
87 | #if 0||ABSTRACTION_PENALTY_IS_GONE |
|
|
88 | float |
|
|
89 | noise2d::noise (float x, float y) |
|
|
90 | { |
|
|
91 | vec2d X = vec2d (x, y); |
|
|
92 | gen_vec<2,int> I = floor (X); |
|
|
93 | vec2d F = X - I; |
|
|
94 | |
|
|
95 | float v = 0; |
|
|
96 | |
|
|
97 | for (int j = -1; j <= 2; ++j) |
|
|
98 | for (int i = -1; i <= 2; ++i) |
|
|
99 | { |
|
|
100 | vec2d A = F - vec2d (i, j); |
|
|
101 | |
|
|
102 | float d = A * A; |
|
|
103 | |
|
|
104 | if (d < 4) |
|
|
105 | { |
|
|
106 | int h = rvmap [0](I[0] + i) ^ rvmap [1](I[1] + j); |
|
|
107 | float *G = rvec [h & 0xff]; |
|
|
108 | |
|
|
109 | float t1 = 1 - d / 4; |
|
|
110 | float t2 = t1 * t1; |
|
|
111 | float t4 = t2 * t2; |
|
|
112 | |
|
|
113 | float p = (4 * t1 - 3) * t4; |
|
|
114 | v += A * vec2d (G[0], G[1]) * p; |
|
|
115 | } |
|
|
116 | } |
|
|
117 | |
|
|
118 | return clamp (v * 2, -.9999999f, .9999999f); |
|
|
119 | } |
|
|
120 | #endif |
|
|
121 | |
|
|
122 | ///////////////////////////////////////////////////////////////////////////// |
|
|
123 | |
|
|
124 | noise3d::noise3d (uint32_t seed) |
|
|
125 | { |
|
|
126 | seedable_rand_gen rng (seed); |
|
|
127 | |
|
|
128 | for (int i = 0; i < 256; ++i) |
|
|
129 | { |
|
|
130 | for (int j = 0; j < 3; ++j) |
|
|
131 | rvec [i][j] = rng () - 0.5f; |
|
|
132 | |
|
|
133 | // normalise |
|
|
134 | float mag = 1.f / sqrtf (rvec [i][0] * rvec [i][0] |
|
|
135 | + rvec [i][1] * rvec [i][1] |
|
|
136 | + rvec [i][2] * rvec [i][2]); |
|
|
137 | |
|
|
138 | rvec [i][0] *= mag; |
|
|
139 | rvec [i][1] *= mag; |
|
|
140 | rvec [i][2] *= mag; |
|
|
141 | } |
|
|
142 | |
|
|
143 | rvmap [0].seed (rng); |
|
|
144 | rvmap [1].seed (rng); |
|
|
145 | rvmap [2].seed (rng); |
|
|
146 | } |
|
|
147 | |
|
|
148 | float |
|
|
149 | noise3d::noise (float x, float y, float z) |
|
|
150 | { |
|
|
151 | int ix = floorf (x); float fx = x - ix; |
|
|
152 | int iy = floorf (y); float fy = y - iy; |
|
|
153 | int iz = floorf (z); float fz = z - iz; |
|
|
154 | |
|
|
155 | float v = 0; |
|
|
156 | |
|
|
157 | for (int j = -1; j <= 2; ++j) |
|
|
158 | for (int i = -1; i <= 2; ++i) |
|
|
159 | for (int k = -1; k <= 2; ++k) |
|
|
160 | { |
|
|
161 | float Ax = fx - i; |
|
|
162 | float Ay = fy - j; |
|
|
163 | float Az = fz - k; |
|
|
164 | |
|
|
165 | float d = Ax * Ax + Ay * Ay + Az * Az; |
|
|
166 | |
|
|
167 | if (d < 4) |
|
|
168 | { |
|
|
169 | int h = rvmap [0](ix + i) ^ rvmap [1](iy + j) ^ rvmap [2](iz + k); |
|
|
170 | float *G = rvec [h & 0xff]; |
|
|
171 | |
|
|
172 | float t1 = 1 - d / 4; |
|
|
173 | float t2 = t1 * t1; |
|
|
174 | float t4 = t2 * t2; |
|
|
175 | |
|
|
176 | // (4t⁵ - 3t⁴) |
|
|
177 | float p = (4 * t1 - 3) * t4; |
|
|
178 | v += (Ax * G[0] + Ay * G[1] + Az * G[2]) * p; |
|
|
179 | } |
|
|
180 | } |
|
|
181 | |
|
|
182 | return clamp (v * 2, -.9999999f, .9999999f); |
|
|
183 | } |
|
|
184 | |
|
|
185 | float |
|
|
186 | noise3d::noise (float x, float y, float z, float nx, float ny, float nz) |
|
|
187 | { |
|
|
188 | int ix = floorf (x); float fx = x - ix; |
|
|
189 | int iy = floorf (y); float fy = y - iy; |
|
|
190 | int iz = floorf (z); float fz = z - iz; |
|
|
191 | |
|
|
192 | float v = 0; |
|
|
193 | |
|
|
194 | for (int j = -1; j <= 2; ++j) |
|
|
195 | for (int i = -1; i <= 2; ++i) |
|
|
196 | for (int k = -1; k <= 2; ++k) |
|
|
197 | { |
|
|
198 | float Dx = fx - i; |
|
|
199 | float Dy = fy - j; |
|
|
200 | float Dz = fz - k; |
|
|
201 | |
|
|
202 | float e = Dx * nx + Dy * ny + Dz * nz; |
|
|
203 | |
|
|
204 | float o = 1 - abs (e); |
|
|
205 | |
|
|
206 | if (o > 0) |
|
|
207 | { |
|
|
208 | float Ax = Dx - e * nx; |
|
|
209 | float Ay = Dy - e * ny; |
|
|
210 | float Az = Dz - e * nz; |
|
|
211 | |
|
|
212 | float d = Ax * Ax + Ay * Ay + Az * Az; |
|
|
213 | |
|
|
214 | if (d < 4) |
|
|
215 | { |
|
|
216 | int h = rvmap [0](ix + i) ^ rvmap [1](iy + j) ^ rvmap [2](iz + k); |
|
|
217 | float *G = rvec [h & 0xff]; |
|
|
218 | |
|
|
219 | float t1 = 1 - d / 4; |
|
|
220 | float t2 = t1 * t1; |
|
|
221 | float t4 = t2 * t2; |
|
|
222 | |
|
|
223 | float o2 = o * o; |
|
|
224 | |
|
|
225 | // (4t⁵ - 3t⁴) * (3o³ - 2o²) |
|
|
226 | float p = (4 * t1 - 3) * t4 * (3 * o2 - 2 * o2 * o); |
|
|
227 | v += (Ax * G[0] + Ay * G[1] + Az * G[2]) * p; |
|
|
228 | } |
|
|
229 | } |
|
|
230 | } |
|
|
231 | |
|
|
232 | return clamp (v * 2, -.9999999f, .9999999f); |
|
|
233 | } |
|
|
234 | |
78 | frac_gen::frac_gen (float hurst_expo, float lacunarity) |
235 | frac_gen::frac_gen (float hurst_expo, float lacunarity) |
79 | : h (hurst_expo), lac (lacunarity), noise_gen (0) |
236 | : h (hurst_expo), lac (lacunarity), noise2d (0) |
80 | { |
237 | { |
81 | float exsum = 0; |
238 | float exsum = 0; |
82 | |
239 | |
83 | for (int i = 0; i < MAX_OCTAVES; ++i) |
240 | for (int i = 0; i < MAX_OCTAVES; ++i) |
84 | { |
241 | { |
… | |
… | |
253 | } |
410 | } |
254 | |
411 | |
255 | return clamp (v * 0.25f, 0.f, .9999999f); |
412 | return clamp (v * 0.25f, 0.f, .9999999f); |
256 | } |
413 | } |
257 | |
414 | |
258 | #if 0 |
415 | #if 1 |
259 | void hack() |
416 | void hack() |
260 | { |
417 | { |
261 | frac_gen gen (0.5, 2); |
418 | frac_gen gen (0.5, 2); |
|
|
419 | noise3d n(0); |
262 | |
420 | |
|
|
421 | #if 1 |
263 | int N = 1024; |
422 | int N = 1024; |
264 | |
423 | |
265 | printf ("P5 %d %d 255\n", N, N); |
424 | printf ("P5 %d %d 255\n", N, N); |
266 | // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm |
425 | // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm |
267 | for (int y = 0; y < N; ++y) |
426 | for (int y = 0; y < N; ++y) |
268 | { |
427 | { |
269 | if (!(y&63))fprintf (stderr, "y %d\n", y);//D |
428 | if (!(y&63))fprintf (stderr, "y %d\n", y);//D |
270 | for (int x = 0; x < N; ++x) |
429 | for (int x = 0; x < N; ++x) |
271 | { |
430 | { |
272 | //putc (128 + 128 * gen.noise (x * 0.04, y * 0.04), stdout); |
431 | putc (127 * gen.noise (x * 0.04, y * 0.04) + 128, stdout); |
273 | putc (256 * gen.terrain2 (x * 0.004, y * 0.004, 8), stdout); |
432 | //putc (256 * gen.terrain2 (x * 0.004, y * 0.004, 8), stdout); |
274 | //putc (256 * gen.fBm (x * 0.001, y * 0.001, 3), stdout); |
433 | //putc (256 * gen.fBm (x * 0.01, y * 0.01, 7), stdout); |
275 | //putc (256 * gen.turbulence (x * 0.004 - 1, y * 0.004 - 1, 8), stdout); |
434 | //putc (256 * gen.turbulence (x * 0.004 - 1, y * 0.004 - 1, 8), stdout); |
276 | //putc (256 * gen.heterofractal (x * 0.008, y * 0.008, 8, -1.1, 2.0), stdout); |
435 | //putc (256 * gen.heterofractal (x * 0.008, y * 0.008, 8, -1.1, 2.0), stdout); |
277 | //putc (256 * gen.ridgedmultifractal (x * 0.001, y * 0.001, 32, 1.001, 32), stdout); |
436 | //putc (256 * gen.ridgedmultifractal (x * 0.001, y * 0.001, 32, 1.001, 32), stdout); |
278 | } |
437 | } |
279 | } |
438 | } |
|
|
439 | #else |
|
|
440 | int N = 128; |
|
|
441 | |
|
|
442 | //printf ("P6 %d %d 255\n", N, N); |
|
|
443 | // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm |
|
|
444 | for (int z = 0; z < N; ++z) |
|
|
445 | { |
|
|
446 | if (!(z&4))fprintf (stderr, "z %d\n", z);//D |
|
|
447 | for (int y = 0; y < N; ++y) |
|
|
448 | for (int x = 0; x < N; ++x) |
|
|
449 | { |
|
|
450 | float v = n.noise (x * 0.06 + 0.2, y * 0.06 + 0.2, z * 0.06 + 0.2) * 0.5 + 0.5; |
|
|
451 | |
|
|
452 | if (z < 64) |
|
|
453 | v = v * (z * z) / (64 * 64); |
|
|
454 | |
|
|
455 | if (v <= 0.1) |
|
|
456 | continue; |
|
|
457 | |
|
|
458 | float r[4]; |
|
|
459 | int i[4]; |
|
|
460 | |
|
|
461 | r[0] = x; |
|
|
462 | r[1] = y; |
|
|
463 | r[2] = z; |
|
|
464 | r[3] = v; |
|
|
465 | |
|
|
466 | memcpy (i, r, 16); |
|
|
467 | |
|
|
468 | i[0] = htonl (i[0]); |
|
|
469 | i[1] = htonl (i[1]); |
|
|
470 | i[2] = htonl (i[2]); |
|
|
471 | i[3] = htonl (i[3]); |
|
|
472 | |
|
|
473 | fwrite (i, 4*4, 1, stdout); |
|
|
474 | } |
|
|
475 | } |
|
|
476 | #endif |
280 | |
477 | |
281 | exit (0); |
478 | exit (0); |
282 | } |
479 | } |
283 | #endif |
480 | #endif |