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.21 by root, Wed Nov 16 23:41:59 2016 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 (©) 2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * 5 *
6 * Deliantra is free software: you can redistribute it and/or modify it under 6 * 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 7 * 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 8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version. 9 * option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the Affero GNU General Public License 16 * 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 17 * and the GNU General Public License along with this program. If not, see
18 * <http://www.gnu.org/licenses/>. 18 * <http://www.gnu.org/licenses/>.
19 * 19 *
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
241 241
242template class permutation<256, uint8_t>; 242template class permutation<256, uint8_t>;
243 243
244///////////////////////////////////////////////////////////////////////////// 244/////////////////////////////////////////////////////////////////////////////
245 245
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> 246template<class vec_t>
320void 247void
321noise_gen_base<vec_t>::seed (seedable_rand_gen &rng) 248noise_gen_base<vec_t>::seed (seedable_rand_gen &rng)
322{ 249{
323 for (int i = 0; i < array_length (rvmap); ++i) 250 for (int i = 0; i < array_length (rvmap); ++i)
333 this->seed (rng); 260 this->seed (rng);
334} 261}
335 262
336template<> 263template<>
337vec2d::T_numtype 264vec2d::T_numtype
338noise_gen_base<vec2d>::operator() (vec2d P) 265noise_gen_base<vec2d>::operator() (vec2d P, uint32_t seed)
339{ 266{
340 vec2d I = floor (P); 267 vec2d I = floor (P);
341 vec2d F = P - I; 268 vec2d F = P - I;
342 269
343 float v = 0; 270 value_t v = 0;
271
272 seed *= 3039177861;
273 uint8_t i1 = uint8_t (I[1]) + (seed >> 16);
274 uint8_t i0 = uint8_t (I[0]) + (seed >> 8);
275
276 uint8_t h2 = rvmap[2](seed);
344 277
345 for (int j = -1; j <= 2; ++j) 278 for (int j = -1; j <= 2; ++j)
279 {
280 uint8_t h1 = rvmap[1](i1 + j) ^ h2;
281
346 for (int i = -1; i <= 2; ++i) 282 for (int i = -1; i <= 2; ++i)
347 { 283 {
348 vec2d A = F - vec2d (i, j); 284 vec2d A = F - vec2d (i, j);
349
350 float d = dot (A, A); 285 value_t d = dot (A, A);
351 286
352 if (d < 4) 287 if (d < 4)
353 { 288 {
354 float t1 = 1 - d / 4; 289 value_t t1 = 1 - d / 4;
355 float t2 = t1 * t1; 290 value_t t2 = t1 * t1;
356 float t4 = t2 * t2; 291 value_t t4 = t2 * t2;
357 292
358 float p = (4 * t1 - 3) * t4; 293 value_t p = (4 * t1 - 3) * t4;
359 294
360 int h = rvmap[0](I[0] + i) ^ rvmap[1](I[1] + j); 295 uint8_t h = rvmap[0](i0 + i) ^ h1;
361 vec2d G = charges2[h & 0xff]; 296 vec2d G = charges2[h & 0xff];
362 297
363 v += dot (A, G) * p; 298 v += dot (A, G) * p;
364 } 299 }
365 } 300 }
301 }
366 302
367 return v; 303 return v;
368} 304}
369 305
370///////////////////////////////////////////////////////////////////////////// 306/////////////////////////////////////////////////////////////////////////////
371 307
372template<> 308template<>
373vec3d::T_numtype 309vec3d::T_numtype
374noise_gen_base<vec3d>::operator() (vec3d P) 310noise_gen_base<vec3d>::operator() (vec3d P, uint32_t seed)
375{ 311{
376 vec3d I = floor (P); 312 vec3d I = floor (P);
377 vec3d F = P - I; 313 vec3d F = P - I;
378 314
379 float v = 0; 315 seed *= 3039177861;
316 uint8_t i2 = uint8_t (I[2]) + (seed >> 24);
317 uint8_t i1 = uint8_t (I[1]) + (seed >> 16);
318 uint8_t i0 = uint8_t (I[0]) + (seed >> 8);
380 319
381 for (int j = -1; j <= 2; ++j) 320 uint8_t h3 = rvmap[3](seed);
382 for (int i = -1; i <= 2; ++i) 321
322 value_t v = 0;
323
383 for (int k = -1; k <= 2; ++k) 324 for (int k = -1; k <= 2; ++k)
325 {
326 uint8_t h2 = rvmap[2](i2 + k) ^ h3;
327
328 for (int j = -1; j <= 2; ++j)
384 { 329 {
385 vec3d A = F - vec3d (i, j, k); 330 uint8_t h1 = rvmap[1](i1 + j) ^ h2;
386 float d = dot (A, A);
387 331
388 if (d < 4) 332 for (int i = -1; i <= 2; ++i)
389 { 333 {
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); 334 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); 335 value_t d = dot (A, A);
427 336
428 if (d < 4) 337 if (d < 4)
429 { 338 {
430 float t1 = 1 - d / 4; 339 value_t t1 = 1 - d / 4;
431 float t2 = t1 * t1; 340 value_t t2 = t1 * t1;
432 float t4 = t2 * t2; 341 value_t t4 = t2 * t2;
433 342
434 float o2 = o * o;
435
436 // (4t⁵ - 3t⁴) * (3o³ - 2o²) 343 // (4t⁵ - 3t⁴)
437 // alternative? ((o * 6 - 15) * o + 10) * o³ 344 value_t p = (4 * t1 - 3) * t4;
438 float p = (4 * t1 - 3) * t4 * (3 * o2 - 2 * o2 * o);
439 345
440 int h = rvmap[0](I[0] + i) ^ rvmap[1](I[1] + j) ^ rvmap[2](I[2] + k); 346 uint8_t h = rvmap[0](i0 + i) ^ h1;
441 const float *G = charges3[h & 0xff]; 347 const value_t *G = charges3[h & 0xff];
442 348
443 v += dot (A, vec3d (G[0], G[1], G[2])) * p; 349 v += dot (A, vec3d (G[0], G[1], G[2])) * p;
444 } 350 }
445 } 351 }
446 } 352 }
353 }
354
355 return v * 2;
356}
357
358vec3d::T_numtype
359noise_gen<vec3d>::operator() (vec3d P, vec3d N, uint32_t seed)
360{
361 vec3d I = floor (P);
362 vec3d F = P - I;
363
364 seed *= 3039177861;
365 uint8_t i2 = uint8_t (I[2]) + (seed >> 24);
366 uint8_t i1 = uint8_t (I[1]) + (seed >> 16);
367 uint8_t i0 = uint8_t (I[0]) + (seed >> 8);
368
369 uint8_t h3 = rvmap[3](seed);
370
371 value_t v = 0;
372
373 for (int k = -1; k <= 2; ++k)
374 {
375 uint8_t h2 = rvmap[2](i2 + k) ^ h3;
376
377 for (int j = -1; j <= 2; ++j)
378 {
379 uint8_t h1 = rvmap[1](i1 + j) ^ h2;
380
381 for (int i = -1; i <= 2; ++i)
382 {
383 vec3d D = F - vec3d (i, j, k);
384 value_t e = dot (D, N);
385 value_t o = 1 - abs (e);
386
387 if (o > 0)
388 {
389 vec3d A = D - e * N;
390 value_t d = dot (A, A);
391
392 if (d < 4)
393 {
394 value_t t1 = 1 - d / 4;
395 value_t t2 = t1 * t1;
396 value_t t4 = t2 * t2;
397
398 value_t o2 = o * o;
399
400 // (4t⁵ - 3t⁴) * (3o³ - 2o²)
401 // alternative? ((o * 6 - 15) * o + 10) * o³
402 value_t p = (4 * t1 - 3) * t4 * (3 * o2 - 2 * o2 * o);
403
404 uint8_t h = rvmap[0](i0 + i) ^ h1;
405 const value_t *G = charges3[h & 0xff];
406
407 v += dot (A, vec3d (G[0], G[1], G[2])) * p;
408 }
409 }
410 }
411 }
412 }
447 413
448 return v; 414 return v;
449} 415}
450 416
451template class noise_gen<vec2d>; 417template class noise_gen<vec2d>;
452template class noise_gen<vec3d>; 418template class noise_gen<vec3d>;
453 419
454///////////////////////////////////////////////////////////////////////////// 420/////////////////////////////////////////////////////////////////////////////
455 421
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> 422template<class vec_t>
460static vec_t 423frac_gen<vec_t>::frac_gen (int octaves, value_t lacunarity, value_t hurst_expo, seed_t seed)
461ith_octave (vec_t P, int i) 424: 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{ 425{
473 this->seed (seed); 426 this->seed (seed);
474 427
475 value_t exsum = 0; 428 value_t exsum = 0;
476 value_t phi = noise (vec_t (value_t (0))) * 0.5 + 1; 429 value_t phi = noise (vec_t (value_t (0))) * 0.5 + 1;
477 430
478 for (int i = 0; i < MAX_OCTAVES; ++i) 431 for (int i = 0; i < octaves; ++i)
479 { 432 {
480 ex [i] = pow (lac, -h * i); 433 ex [i] = pow (lac, -h * i);
481 exsum += ex [i]; 434 exsum += ex [i];
482 fbm_mul [i] = 0.5 / (exsum * 0.75); // .75 is a heuristic 435 fbm_mul [i] = 0.5 / (exsum * 0.75); // .75 is a heuristic
483 rot [i].set (phi * i + 1); 436 rot [i].set (phi * i + 1);
484 } 437 }
485} 438}
486 439
487template<class vec_t> 440template<class vec_t>
488typename frac_gen<vec_t>::value_t 441typename frac_gen<vec_t>::value_t
489frac_gen<vec_t>::fBm (vec_t P, int octaves) 442frac_gen<vec_t>::fBm (vec_t P)
490{ 443{
491 value_t v = 0; 444 value_t v = 0;
492 445
493 for (int i = 0; i < octaves; ++i) 446 for (int i = 0; i < octaves; ++i)
494 { 447 {
495 rot [i](P); 448 rot [i](P);
496 v += noise (ith_octave (P, i)) * ex [i]; 449 v += noise (P, i) * ex [i];
497 P *= lac; 450 P *= lac;
498 } 451 }
499 452
500 return v * fbm_mul [octaves - 1]; 453 return v * fbm_mul [octaves - 1];
501} 454}
502 455
503template<class vec_t> 456template<class vec_t>
504typename frac_gen<vec_t>::value_t 457typename frac_gen<vec_t>::value_t
505frac_gen<vec_t>::turbulence (vec_t P, int octaves) 458frac_gen<vec_t>::turbulence (vec_t P)
506{ 459{
507 value_t v = 0; 460 value_t v = 0;
508 461
509 for (int i = 0; i < octaves; ++i) 462 for (int i = 0; i < octaves; ++i)
510 { 463 {
511 rot [i](P); 464 rot [i](P);
512 v += abs (noise (ith_octave (P, i))) * ex [i]; 465 v += abs (noise (P, i)) * ex [i];
513 P *= lac; 466 P *= lac;
514 } 467 }
515 468
516 return v * fbm_mul [octaves - 1] * (0.5 / noise_gen<vec_t>::abs_avg ()); 469 return v * fbm_mul [octaves - 1] * (0.5 / noise_gen<vec_t>::abs_avg ());
517} 470}
518 471
519template<class vec_t> 472template<class vec_t>
520typename frac_gen<vec_t>::value_t 473typename frac_gen<vec_t>::value_t
521frac_gen<vec_t>::multifractal (vec_t P, int octaves, value_t offset) 474frac_gen<vec_t>::multifractal (vec_t P, value_t offset)
522{ 475{
523 value_t v = 1; 476 value_t v = 1;
524 477
525 for (int i = 0; i < octaves; ++i) 478 for (int i = 0; i < octaves; ++i)
526 { 479 {
532 return v * value_t (0.5); 485 return v * value_t (0.5);
533} 486}
534 487
535template<class vec_t> 488template<class vec_t>
536typename frac_gen<vec_t>::value_t 489typename frac_gen<vec_t>::value_t
537frac_gen<vec_t>::heterofractal (vec_t P, int octaves, value_t offset) 490frac_gen<vec_t>::heterofractal (vec_t P, value_t offset)
538{ 491{
539 value_t v = noise (P) + offset; 492 value_t v = noise (P) + offset;
540 493
541 for (int i = 1; i < octaves; ++i) 494 for (int i = 1; i < octaves; ++i)
542 { 495 {
548 return v / (1 << octaves); 501 return v / (1 << octaves);
549} 502}
550 503
551template<class vec_t> 504template<class vec_t>
552typename frac_gen<vec_t>::value_t 505typename frac_gen<vec_t>::value_t
553frac_gen<vec_t>::hybridfractal (vec_t P, int octaves, value_t offset, value_t gain) 506frac_gen<vec_t>::hybridfractal (vec_t P, value_t offset, value_t gain)
554{ 507{
555 value_t v = (noise (P) + offset) * ex [0]; 508 value_t v = (noise (P) + offset) * ex [0];
556 value_t weight = v; 509 value_t weight = v;
557 510
558 for (int i = 1; i < octaves; ++i) 511 for (int i = 1; i < octaves; ++i)
570 return v * value_t (0.5) + value_t (0.5); 523 return v * value_t (0.5) + value_t (0.5);
571} 524}
572 525
573template<class vec_t> 526template<class vec_t>
574typename frac_gen<vec_t>::value_t 527typename frac_gen<vec_t>::value_t
575frac_gen<vec_t>::ridgedmultifractal (vec_t P, int octaves, value_t offset, value_t gain) 528frac_gen<vec_t>::ridgedmultifractal (vec_t P, value_t offset, value_t gain)
576{ 529{
577 value_t sig = offset - abs (noise (P)); 530 value_t sig = offset - abs (noise (P));
578 sig *= sig; 531 sig *= sig;
579 value_t v = sig; 532 value_t v = sig;
580 533
581 for (int i = 1; i < octaves; ++i) 534 for (int i = 1; i < octaves; ++i)
582 { 535 {
583 rot [i](P); 536 rot [i](P);
584 P *= lac; 537 P *= lac;
585 538
539 // weight higher octaves by previous signal
586 value_t w = clamp (sig * gain, 0, 1); 540 value_t w = clamp (sig * gain, 0, 1);
587 541
588 sig = offset - abs (noise (P)); 542 sig = offset - abs (noise (P));
589 sig *= sig; 543 sig *= sig;
590 sig *= w; 544 sig *= w;
595 return v * value_t (0.25); 549 return v * value_t (0.25);
596} 550}
597 551
598template<class vec_t> 552template<class vec_t>
599typename frac_gen<vec_t>::value_t 553typename frac_gen<vec_t>::value_t
600frac_gen<vec_t>::billowfractal (vec_t P, int octaves, value_t offset, value_t gain) 554frac_gen<vec_t>::billowfractal (vec_t P, value_t offset, value_t gain)
601{ 555{
602 value_t v = 0; 556 value_t v = 0;
603 557
604 offset += 2 * noise_gen<vec_t>::abs_avg () - 1; 558 offset += 2 * noise_gen<vec_t>::abs_avg () - 1;
605 559
606 for (int i = 0; i < octaves; ++i) 560 for (int i = 0; i < octaves; ++i)
607 { 561 {
608 rot [i](P); 562 rot [i](P);
609 v += (abs (noise (ith_octave (P, i))) * gain - offset) * ex [i]; 563 v += (abs (noise (P, i)) * gain - offset) * ex [i];
610 P *= lac; 564 P *= lac;
611 } 565 }
612 566
613 return v; 567 return v;
614} 568}
615 569
616// http://www.gamasutra.com/view/feature/3098/a_realtime_procedural_universe_.php?page=2 570// http://www.gamasutra.com/view/feature/3098/a_realtime_procedural_universe_.php?page=2
617template<class vec_t> 571template<class vec_t>
618typename frac_gen<vec_t>::value_t 572typename frac_gen<vec_t>::value_t
619frac_gen<vec_t>::terrain (vec_t P, int octaves) 573frac_gen<vec_t>::terrain (vec_t P)
620{ 574{
621 value_t v = 0; 575 value_t v = 0;
622 576
623 for (int i = 0; i < octaves; ++i) 577 for (int i = 0; i < octaves; ++i)
624 { 578 {
632 return v <= 0 ? - pow (-v, 0.7) : pow (v, 1 + noise (P) * v); 586 return v <= 0 ? - pow (-v, 0.7) : pow (v, 1 + noise (P) * v);
633} 587}
634 588
635template<class vec_t> 589template<class vec_t>
636typename frac_gen<vec_t>::value_t 590typename frac_gen<vec_t>::value_t
637frac_gen<vec_t>::terrain2 (vec_t P, int octaves) 591frac_gen<vec_t>::terrain2 (vec_t P)
638{ 592{
639 value_t a = fBm (P, octaves); 593 value_t a = fBm (P);
640 value_t b = ridgedmultifractal (P, octaves, 1, 8); 594 value_t b = ridgedmultifractal (P, 1, 8);
641 value_t fade = fBm (P + vec_t(10.3), octaves); 595 value_t fade = fBm (P + vec_t(10.3));
642 596
643 const value_t width = 0.05; 597 const value_t width = 0.05;
644 598
645 if (fade > 0.5 + width) 599 if (fade > 0.5 + width)
646 return a; 600 return a;
656} 610}
657 611
658template class frac_gen<vec2d>; 612template class frac_gen<vec2d>;
659template class frac_gen<vec3d>; 613template class frac_gen<vec3d>;
660 614
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