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