ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/noise.C
(Generate patch)

Comparing deliantra/server/common/noise.C (file contents):
Revision 1.12 by root, Tue Apr 26 14:41:35 2011 UTC vs.
Revision 1.25 by root, Wed Dec 5 19:03:26 2018 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2017,2018 Marc Alexander Lehmann / the Deliantra team
4 * Copyright (©) 2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 5 * Copyright (©) 2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * 6 *
6 * Deliantra is free software: you can redistribute it and/or modify it under 7 * Deliantra is free software: you can redistribute it and/or modify it under
7 * the terms of the Affero GNU General Public License as published by the 8 * the terms of the Affero GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your 9 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version. 10 * option) any later version.
10 * 11 *
11 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 15 * GNU General Public License for more details.
15 * 16 *
16 * You should have received a copy of the Affero GNU General Public License 17 * You should have received a copy of the Affero GNU General Public License
17 * and the GNU General Public License along with this program. If not, see 18 * and the GNU General Public License along with this program. If not, see
18 * <http://www.gnu.org/licenses/>. 19 * <http://www.gnu.org/licenses/>.
19 * 20 *
20 * The authors can be reached via e-mail to <support@deliantra.net> 21 * The authors can be reached via e-mail to <support@deliantra.net>
21 */ 22 */
22 23
23#include "noise.h" 24#include "noise.h"
24 25
241 242
242template class permutation<256, uint8_t>; 243template class permutation<256, uint8_t>;
243 244
244///////////////////////////////////////////////////////////////////////////// 245/////////////////////////////////////////////////////////////////////////////
245 246
246// various s-shaped curves, smooth to, first, or second derivative
247// used for smooth interpolation from 0..1
248
249// linear
250template<typename T>
251inline T
252sigmoid0 (T x)
253{
254 return x;
255}
256
257// 3x²-2x³
258template<typename T>
259inline T
260sigmoid1 (T x)
261{
262 return (3 - 2 * x) * x * x;
263}
264
265// 6x⁵ - 15x⁴ + 10x³
266template<typename T>
267inline T
268sigmoid2 (T x)
269{
270#ifdef MORE_PARALLELITY
271 float x2 = x * x;
272 float x4 = x2 * x2;
273
274 return (6 * x4 + 10 * x2) * x - 15 * x4;
275#endif
276
277 // simple horner
278 return ((6 * x - 15) * x + 10) * x * x * x;
279}
280
281// blend between a and b
282// c is the control function - if lower than ca
283// then return a, if higher than cb, return b
284template<typename T, typename U>
285inline T
286blend (T a, T b, U c, U ca, U cb, T weight (U) = sigmoid1)
287{
288 if (c <= ca) return a;
289 if (c >= cb) return b;
290
291 T w = weight (lerp (c, ca, cb, T(0), T(1)));
292 return (T(1) - w) * a + w * b;
293}
294
295// blend between a and b
296// c is the control function - if lower than -c_w
297// then return a, if higher than +c_w then b.
298template<typename T, typename U>
299inline T
300blend0 (T a, T b, U c, U c_w, T weight (U) = sigmoid1)
301{
302 return blend<T,U> (a, b, c, -c_w, c_w, weight);
303}
304
305/////////////////////////////////////////////////////////////////////////////
306
307static vec2d
308floor (vec2d v)
309{
310 return vec2d (fastfloor (v[0]), fastfloor (v[1]));
311}
312
313static vec3d
314floor (vec3d v)
315{
316 return vec3d (fastfloor (v[0]), fastfloor (v[1]), fastfloor (v[2]));
317}
318
319template<class vec_t> 247template<class vec_t>
320void 248void
321noise_gen_base<vec_t>::seed (seedable_rand_gen &rng) 249noise_gen_base<vec_t>::seed (seedable_rand_gen &rng)
322{ 250{
323 for (int i = 0; i < array_length (rvmap); ++i) 251 for (int i = 0; i < ecb_array_length (rvmap); ++i)
324 rvmap[i].seed (rng); 252 rvmap[i].seed (rng);
325} 253}
326 254
327template<class vec_t> 255template<class vec_t>
328void 256void
333 this->seed (rng); 261 this->seed (rng);
334} 262}
335 263
336template<> 264template<>
337vec2d::T_numtype 265vec2d::T_numtype
338noise_gen_base<vec2d>::operator() (vec2d P) 266noise_gen_base<vec2d>::operator() (vec2d P, uint32_t seed)
339{ 267{
340 vec2d I = floor (P); 268 vec2d I = floor (P);
341 vec2d F = P - I; 269 vec2d F = P - I;
342 270
343 float v = 0; 271 value_t v = 0;
272
273 seed *= 3039177861;
274 uint8_t i1 = uint8_t (I[1]) + (seed >> 16);
275 uint8_t i0 = uint8_t (I[0]) + (seed >> 8);
276
277 uint8_t h2 = rvmap[2](seed);
344 278
345 for (int j = -1; j <= 2; ++j) 279 for (int j = -1; j <= 2; ++j)
280 {
281 uint8_t h1 = rvmap[1](i1 + j) ^ h2;
282
346 for (int i = -1; i <= 2; ++i) 283 for (int i = -1; i <= 2; ++i)
347 { 284 {
348 vec2d A = F - vec2d (i, j); 285 vec2d A = F - vec2d (i, j);
349
350 float d = dot (A, A); 286 value_t d = dot (A, A);
351 287
352 if (d < 4) 288 if (d < 4)
353 { 289 {
354 float t1 = 1 - d / 4; 290 value_t t1 = 1 - d / 4;
355 float t2 = t1 * t1; 291 value_t t2 = t1 * t1;
356 float t4 = t2 * t2; 292 value_t t4 = t2 * t2;
357 293
358 float p = (4 * t1 - 3) * t4; 294 value_t p = (4 * t1 - 3) * t4;
359 295
360 int h = rvmap[0](I[0] + i) ^ rvmap[1](I[1] + j); 296 uint8_t h = rvmap[0](i0 + i) ^ h1;
361 vec2d G = charges2[h & 0xff]; 297 vec2d G = charges2[h & 0xff];
362 298
363 v += dot (A, G) * p; 299 v += dot (A, G) * p;
364 } 300 }
365 } 301 }
302 }
366 303
367 return v; 304 return v;
368} 305}
369 306
370///////////////////////////////////////////////////////////////////////////// 307/////////////////////////////////////////////////////////////////////////////
371 308
372template<> 309template<>
373vec3d::T_numtype 310vec3d::T_numtype
374noise_gen_base<vec3d>::operator() (vec3d P) 311noise_gen_base<vec3d>::operator() (vec3d P, uint32_t seed)
375{ 312{
376 vec3d I = floor (P); 313 vec3d I = floor (P);
377 vec3d F = P - I; 314 vec3d F = P - I;
378 315
379 float v = 0; 316 seed *= 3039177861;
317 uint8_t i2 = uint8_t (I[2]) + (seed >> 24);
318 uint8_t i1 = uint8_t (I[1]) + (seed >> 16);
319 uint8_t i0 = uint8_t (I[0]) + (seed >> 8);
380 320
381 for (int j = -1; j <= 2; ++j) 321 uint8_t h3 = rvmap[3](seed);
382 for (int i = -1; i <= 2; ++i) 322
323 value_t v = 0;
324
383 for (int k = -1; k <= 2; ++k) 325 for (int k = -1; k <= 2; ++k)
326 {
327 uint8_t h2 = rvmap[2](i2 + k) ^ h3;
328
329 for (int j = -1; j <= 2; ++j)
384 { 330 {
385 vec3d A = F - vec3d (i, j, k); 331 uint8_t h1 = rvmap[1](i1 + j) ^ h2;
386 float d = dot (A, A);
387 332
388 if (d < 4) 333 for (int i = -1; i <= 2; ++i)
389 { 334 {
390 float t1 = 1 - d / 4;
391 float t2 = t1 * t1;
392 float t4 = t2 * t2;
393
394 // (4t⁵ - 3t⁴)
395 float p = (4 * t1 - 3) * t4;
396
397 int h = rvmap[0](I[0] + i) ^ rvmap[1](I[1] + j) ^ rvmap[2](I[2] + k);
398 const float *G = charges3[h & 0xff];
399
400 v += dot (A, vec3d (G[0], G[1], G[2])) * p;
401 }
402 }
403
404 return v * 2;
405}
406
407vec3d::T_numtype
408noise_gen<vec3d>::operator() (vec3d P, vec3d N)
409{
410 vec3d I = floor (P);
411 vec3d F = P - I;
412
413 float v = 0;
414
415 for (int j = -1; j <= 2; ++j)
416 for (int i = -1; i <= 2; ++i)
417 for (int k = -1; k <= 2; ++k)
418 {
419 vec3d D = F - vec3d (i, j, k); 335 vec3d A = F - vec3d (i, j, k);
420 float e = dot (D, N);
421 float o = 1 - abs (e);
422
423 if (o > 0)
424 {
425 vec3d A = D - e * N;
426 float d = dot (A, A); 336 value_t d = dot (A, A);
427 337
428 if (d < 4) 338 if (d < 4)
429 { 339 {
430 float t1 = 1 - d / 4; 340 value_t t1 = 1 - d / 4;
431 float t2 = t1 * t1; 341 value_t t2 = t1 * t1;
432 float t4 = t2 * t2; 342 value_t t4 = t2 * t2;
433 343
434 float o2 = o * o;
435
436 // (4t⁵ - 3t⁴) * (3o³ - 2o²) 344 // (4t⁵ - 3t⁴)
437 // alternative? ((o * 6 - 15) * o + 10) * o³ 345 value_t p = (4 * t1 - 3) * t4;
438 float p = (4 * t1 - 3) * t4 * (3 * o2 - 2 * o2 * o);
439 346
440 int h = rvmap[0](I[0] + i) ^ rvmap[1](I[1] + j) ^ rvmap[2](I[2] + k); 347 uint8_t h = rvmap[0](i0 + i) ^ h1;
441 const float *G = charges3[h & 0xff]; 348 const value_t *G = charges3[h & 0xff];
442 349
443 v += dot (A, vec3d (G[0], G[1], G[2])) * p; 350 v += dot (A, vec3d (G[0], G[1], G[2])) * p;
444 } 351 }
445 } 352 }
446 } 353 }
354 }
355
356 return v * 2;
357}
358
359vec3d::T_numtype
360noise_gen<vec3d>::operator() (vec3d P, vec3d N, uint32_t seed)
361{
362 vec3d I = floor (P);
363 vec3d F = P - I;
364
365 seed *= 3039177861;
366 uint8_t i2 = uint8_t (I[2]) + (seed >> 24);
367 uint8_t i1 = uint8_t (I[1]) + (seed >> 16);
368 uint8_t i0 = uint8_t (I[0]) + (seed >> 8);
369
370 uint8_t h3 = rvmap[3](seed);
371
372 value_t v = 0;
373
374 for (int k = -1; k <= 2; ++k)
375 {
376 uint8_t h2 = rvmap[2](i2 + k) ^ h3;
377
378 for (int j = -1; j <= 2; ++j)
379 {
380 uint8_t h1 = rvmap[1](i1 + j) ^ h2;
381
382 for (int i = -1; i <= 2; ++i)
383 {
384 vec3d D = F - vec3d (i, j, k);
385 value_t e = dot (D, N);
386 value_t o = 1 - abs (e);
387
388 if (o > 0)
389 {
390 vec3d A = D - e * N;
391 value_t d = dot (A, A);
392
393 if (d < 4)
394 {
395 value_t t1 = 1 - d / 4;
396 value_t t2 = t1 * t1;
397 value_t t4 = t2 * t2;
398
399 value_t o2 = o * o;
400
401 // (4t⁵ - 3t⁴) * (3o³ - 2o²)
402 // alternative? ((o * 6 - 15) * o + 10) * o³
403 value_t p = (4 * t1 - 3) * t4 * (3 * o2 - 2 * o2 * o);
404
405 uint8_t h = rvmap[0](i0 + i) ^ h1;
406 const value_t *G = charges3[h & 0xff];
407
408 v += dot (A, vec3d (G[0], G[1], G[2])) * p;
409 }
410 }
411 }
412 }
413 }
447 414
448 return v; 415 return v;
449} 416}
450 417
451template class noise_gen<vec2d>;
452template class noise_gen<vec3d>;
453
454///////////////////////////////////////////////////////////////////////////// 418/////////////////////////////////////////////////////////////////////////////
455 419
456// find some uncorrelated spot - we assume that noise 2 units away
457// is completely uncorrelated - this is not true for other coordinates,
458// but generally works well.
459template<class vec_t> 420template<class vec_t>
460static vec_t 421frac_gen<vec_t>::frac_gen (int octaves, value_t lacunarity, value_t hurst_expo, seed_t seed)
461ith_octave (vec_t P, int i) 422: octaves (octaves), lac (lacunarity), h (hurst_expo)
462{
463 vec_t r = P;
464 r[0] += i;
465 r[1] += i * 2;
466 return r;
467}
468
469template<class vec_t>
470frac_gen<vec_t>::frac_gen (value_t hurst_expo, value_t lacunarity, seed_t seed)
471: h (hurst_expo), lac (lacunarity)
472{ 423{
473 this->seed (seed); 424 this->seed (seed);
474 425
475 value_t exsum = 0; 426 value_t exsum = 0;
476 value_t phi = noise (vec_t (value_t (0))) * 0.5 + 1; 427 value_t phi = noise (vec_t (value_t (0))) * 0.5 + 1;
477 428
478 for (int i = 0; i < MAX_OCTAVES; ++i) 429 for (int i = 0; i < octaves; ++i)
479 { 430 {
480 ex [i] = pow (lac, -h * i); 431 ex [i] = pow (lac, -h * i);
481 exsum += ex [i]; 432 exsum += ex [i];
482 fbm_mul [i] = 0.5 / (exsum * 0.75); // .75 is a heuristic 433 fbm_mul [i] = 0.5 / (exsum * 0.75); // .75 is a heuristic
483 rot [i].set (phi * i + 1); 434 rot [i].set (phi * i + 1);
484 } 435 }
485} 436}
486 437
487template<class vec_t> 438template<class vec_t>
488typename frac_gen<vec_t>::value_t 439typename frac_gen<vec_t>::value_t
489frac_gen<vec_t>::fBm (vec_t P, int octaves) 440frac_gen<vec_t>::fBm (vec_t P)
490{ 441{
491 value_t v = 0; 442 value_t v = 0;
492 443
493 for (int i = 0; i < octaves; ++i) 444 for (int i = 0; i < octaves; ++i)
494 { 445 {
495 rot [i](P); 446 rot [i](P);
496 v += noise (ith_octave (P, i)) * ex [i]; 447 v += noise (P, i) * ex [i];
497 P *= lac; 448 P *= lac;
498 } 449 }
499 450
500 return v * fbm_mul [octaves - 1]; 451 return v * fbm_mul [octaves - 1];
501} 452}
502 453
503template<class vec_t> 454template<class vec_t>
504typename frac_gen<vec_t>::value_t 455typename frac_gen<vec_t>::value_t
505frac_gen<vec_t>::turbulence (vec_t P, int octaves) 456frac_gen<vec_t>::turbulence (vec_t P)
506{ 457{
507 value_t v = 0; 458 value_t v = 0;
508 459
509 for (int i = 0; i < octaves; ++i) 460 for (int i = 0; i < octaves; ++i)
510 { 461 {
511 rot [i](P); 462 rot [i](P);
512 v += abs (noise (ith_octave (P, i))) * ex [i]; 463 v += abs (noise (P, i)) * ex [i];
513 P *= lac; 464 P *= lac;
514 } 465 }
515 466
516 return v * fbm_mul [octaves - 1] * (0.5 / noise_gen<vec_t>::abs_avg ()); 467 return v * fbm_mul [octaves - 1] * (0.5 / noise_gen<vec_t>::abs_avg ());
517} 468}
518 469
519template<class vec_t> 470template<class vec_t>
520typename frac_gen<vec_t>::value_t 471typename frac_gen<vec_t>::value_t
521frac_gen<vec_t>::multifractal (vec_t P, int octaves, value_t offset) 472frac_gen<vec_t>::multifractal (vec_t P, value_t offset)
522{ 473{
523 value_t v = 1; 474 value_t v = 1;
524 475
525 for (int i = 0; i < octaves; ++i) 476 for (int i = 0; i < octaves; ++i)
526 { 477 {
532 return v * value_t (0.5); 483 return v * value_t (0.5);
533} 484}
534 485
535template<class vec_t> 486template<class vec_t>
536typename frac_gen<vec_t>::value_t 487typename frac_gen<vec_t>::value_t
537frac_gen<vec_t>::heterofractal (vec_t P, int octaves, value_t offset) 488frac_gen<vec_t>::heterofractal (vec_t P, value_t offset)
538{ 489{
539 value_t v = noise (P) + offset; 490 value_t v = noise (P) + offset;
540 491
541 for (int i = 1; i < octaves; ++i) 492 for (int i = 1; i < octaves; ++i)
542 { 493 {
548 return v / (1 << octaves); 499 return v / (1 << octaves);
549} 500}
550 501
551template<class vec_t> 502template<class vec_t>
552typename frac_gen<vec_t>::value_t 503typename frac_gen<vec_t>::value_t
553frac_gen<vec_t>::hybridfractal (vec_t P, int octaves, value_t offset, value_t gain) 504frac_gen<vec_t>::hybridfractal (vec_t P, value_t offset, value_t gain)
554{ 505{
555 value_t v = (noise (P) + offset) * ex [0]; 506 value_t v = (noise (P) + offset) * ex [0];
556 value_t weight = v; 507 value_t weight = v;
557 508
558 for (int i = 1; i < octaves; ++i) 509 for (int i = 1; i < octaves; ++i)
570 return v * value_t (0.5) + value_t (0.5); 521 return v * value_t (0.5) + value_t (0.5);
571} 522}
572 523
573template<class vec_t> 524template<class vec_t>
574typename frac_gen<vec_t>::value_t 525typename frac_gen<vec_t>::value_t
575frac_gen<vec_t>::ridgedmultifractal (vec_t P, int octaves, value_t offset, value_t gain) 526frac_gen<vec_t>::ridgedmultifractal (vec_t P, value_t offset, value_t gain)
576{ 527{
577 value_t sig = offset - abs (noise (P)); 528 value_t sig = offset - abs (noise (P));
578 sig *= sig; 529 sig *= sig;
579 value_t v = sig; 530 value_t v = sig;
580 531
581 for (int i = 1; i < octaves; ++i) 532 for (int i = 1; i < octaves; ++i)
582 { 533 {
583 rot [i](P); 534 rot [i](P);
584 P *= lac; 535 P *= lac;
585 536
537 // weight higher octaves by previous signal
586 value_t w = clamp (sig * gain, 0, 1); 538 value_t w = clamp (sig * gain, 0, 1);
587 539
588 sig = offset - abs (noise (P)); 540 sig = offset - abs (noise (P));
589 sig *= sig; 541 sig *= sig;
590 sig *= w; 542 sig *= w;
595 return v * value_t (0.25); 547 return v * value_t (0.25);
596} 548}
597 549
598template<class vec_t> 550template<class vec_t>
599typename frac_gen<vec_t>::value_t 551typename frac_gen<vec_t>::value_t
600frac_gen<vec_t>::billowfractal (vec_t P, int octaves, value_t offset, value_t gain) 552frac_gen<vec_t>::billowfractal (vec_t P, value_t offset, value_t gain)
601{ 553{
602 value_t v = 0; 554 value_t v = 0;
603 555
604 offset += 2 * noise_gen<vec_t>::abs_avg () - 1; 556 offset += 2 * noise_gen<vec_t>::abs_avg () - 1;
605 557
606 for (int i = 0; i < octaves; ++i) 558 for (int i = 0; i < octaves; ++i)
607 { 559 {
608 rot [i](P); 560 rot [i](P);
609 v += (abs (noise (ith_octave (P, i))) * gain - offset) * ex [i]; 561 v += (abs (noise (P, i)) * gain - offset) * ex [i];
610 P *= lac; 562 P *= lac;
611 } 563 }
612 564
613 return v; 565 return v;
614} 566}
615 567
616// http://www.gamasutra.com/view/feature/3098/a_realtime_procedural_universe_.php?page=2 568// http://www.gamasutra.com/view/feature/3098/a_realtime_procedural_universe_.php?page=2
617template<class vec_t> 569template<class vec_t>
618typename frac_gen<vec_t>::value_t 570typename frac_gen<vec_t>::value_t
619frac_gen<vec_t>::terrain (vec_t P, int octaves) 571frac_gen<vec_t>::terrain (vec_t P)
620{ 572{
621 value_t v = 0; 573 value_t v = 0;
622 574
623 for (int i = 0; i < octaves; ++i) 575 for (int i = 0; i < octaves; ++i)
624 { 576 {
632 return v <= 0 ? - pow (-v, 0.7) : pow (v, 1 + noise (P) * v); 584 return v <= 0 ? - pow (-v, 0.7) : pow (v, 1 + noise (P) * v);
633} 585}
634 586
635template<class vec_t> 587template<class vec_t>
636typename frac_gen<vec_t>::value_t 588typename frac_gen<vec_t>::value_t
637frac_gen<vec_t>::terrain2 (vec_t P, int octaves) 589frac_gen<vec_t>::terrain2 (vec_t P)
638{ 590{
639 value_t a = fBm (P, octaves); 591 value_t a = fBm (P);
640 value_t b = ridgedmultifractal (P, octaves, 1, 8); 592 value_t b = ridgedmultifractal (P, 1, 8);
641 value_t fade = fBm (P + vec_t(10.3), octaves); 593 value_t fade = fBm (P + vec_t(10.3));
642 594
643 const value_t width = 0.05; 595 const value_t width = 0.05;
644 596
645 if (fade > 0.5 + width) 597 if (fade > 0.5 + width)
646 return a; 598 return a;
656} 608}
657 609
658template class frac_gen<vec2d>; 610template class frac_gen<vec2d>;
659template class frac_gen<vec3d>; 611template class frac_gen<vec3d>;
660 612
661/////////////////////////////////////////////////////////////////////////////
662
663void noise_test ();
664void noise_test ()
665{
666 frac_gen<vec2d> gen;
667 frac_gen<vec3d> gen3;
668
669#if 1
670 int N = 1024;
671
672 printf ("P5 %d %d 255\n", N, N);
673 // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm
674 for (int y = 0; y < N; ++y)
675 {
676 if (!(y&63))fprintf (stderr, "y %d\n", y);//D
677 for (int x = 0; x < N; ++x)
678 {
679 vec2d P = vec2d (x, y) * (5000.f / N);
680
681 //putc (127 * gen.noise (vec2d (x * 0.01, y * 0.01)) + 128, stdout);
682 //putc (256 * gen.terrain2 (x * 0.004, y * 0.004, 8), stdout);
683 //putc (256 * gen.fBm (vec2d(x * 0.01, y * 0.01), 16), stdout);
684 //putc (256 * gen.turbulence (vec2d (x * 0.004 - 1, y * 0.004 - 1), 10), stdout);
685 //putc (256 * gen.heterofractal (vec2d (x * 0.008, y * 0.008), 8, 0.9), stdout);
686
687 // mountais or somesuch(?)
688 //putc (256 * gen.hybridfractal (vec2d (x * 0.01, y * 0.01), 8, -.4, -4), stdout);
689
690 // temperature
691 //putc (256 * gen.fBm (vec2d (x * 0.002, y * 0.002), 2), stdout);
692 // rain
693
694 float continent = gen.fBm (P * 0.0004, 12) + 0.1f;
695 float mountain = gen.ridgedmultifractal (P * 0.004, 8, 0.8, 10) * 2;
696 float river = gen.ridgedmultifractal (P * 0.004, 3, 0.8, 10);
697 float sel1 = gen.noise (P * 0.001 + vec2d (5,0));
698
699 {
700 const float W = 100;
701 const float N = 5000 - 1;
702
703 float border = W; // within n places of the border
704
705 min_it (border, P [0]);
706 min_it (border, N - P [0]);
707 min_it (border, P [1]);
708 min_it (border, N - P [1]);
709
710 continent = blend (-1.f, continent, border, 0.f, W);
711 }
712
713 //float v = blend (mountain, 0.f, river + sel1 * 0.2f, 0.25f, 0.1f);
714 float v = blend0 (0.f, 1.f, continent, 0.05f);
715
716
717 putc (255 * clamp (v, 0.f, 1.f), stdout);
718
719 //cells
720 //putc (127.49 * gen.billowfractal (vec2d (x * 0.01, y * 0.01), 9) + 128, stdout);
721 }
722 }
723#else
724 int N = 512;
725
726 //printf ("P6 %d %d 255\n", N, N);
727 // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm
728 for (int z = 0; z < N; ++z)
729 {
730 if (!(z&7))fprintf (stderr, "z %d\n", z);//D
731 for (int y = 0; y < N; ++y)
732 for (int x = 0; x < N; ++x)
733 {
734 float v = gen3.ridgedmultifractal (vec3d (x * 0.01 + 0.2, y * 0.01 + 0.2, z * 0.01 + 0.2), 3, 1.03, 2) * 2;
735
736#if 0
737 if (z < 64)
738 v = v * (z * z) / (64 * 64);
739#endif
740
741 if (v <= 0.9999)
742 continue;
743
744 float r[4];
745 int i[4];
746
747 r[0] = x;
748 r[1] = y;
749 r[2] = z;
750 r[3] = v;
751
752 memcpy (i, r, 16);
753
754 i[0] = htonl (i[0]);
755 i[1] = htonl (i[1]);
756 i[2] = htonl (i[2]);
757 i[3] = htonl (i[3]);
758
759 fwrite (i, 4*4, 1, stdout);
760 }
761 }
762#endif
763
764 exit (0);
765}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines