--- deliantra/server/common/noise.C 2011/04/30 11:02:25 1.14 +++ deliantra/server/common/noise.C 2011/05/01 08:19:17 1.17 @@ -628,11 +628,18 @@ return blend (a, b,border, U(0), W); } +// highest mountains, deepest sea == 200 .. -200 + +#define FANCY_GRAPHICS 1 + static void -gen_height (int x, int y) +gen_quadspace (int x, int y, int z) { vec2d P = vec2d (x, y); + const int deep_sea_z = -200; + const int mountain_z = 200; + static frac2d gen(13); static frac2d vec_gen1 (6, 2, 0.5, 1); @@ -656,67 +663,117 @@ static frac2d continent_gen (13, 2.13, 0.5); float continent = continent_gen.fBm (P_continent) + 0.05f; - float land_gradient = sigmoid1 (P[0] * (1. / 25000)); + float x_gradient = P[0] * (1. / 25000); + float y_gradient = P[1] * (1. / 25000); + float xy_gradient = (P[0] + P[1]) * (0.5 / 25000); - const float W = 1000 * continent_scale; const float N = (25000 - 1) * continent_scale; + // we clip a large border on the perturbed shape, to get irregular coastline + // and then clip a smaller border around the real shape continent = border_blend (-1.f, continent, P_continent , N, 400 * continent_scale); continent = border_blend (-1.f, continent, P * continent_scale + perturb * 0.1, N, 100 * continent_scale); + enum { + T_NONE, + T_OCEAN, + T_RIVER, + T_VALLEY, + T_MOUNTAIN, + T_UNDERGROUND, + T_ACQUIFER, + } t = T_NONE; + vec3d c; - float v; + int h = 1000000; // height form heightmap - if (continent < 0) + // the continent increases in height from 0 to ~700 levels in the absence of anything else + // thats about one step every 7 maps. + int base_height = blend (0, 300, xy_gradient, 0.2f, 0.9f); + int river_height = base_height * 9 / 10; + + // add this to rivers to "dry them out" + float dry_out = max (0.f, lerp (xy_gradient, 0.7f, 1.f, 0.f, 0.3f)); + + static frac2d river_gen (2); + float river1 = abs (river_gen.fBm (P * 0.001 + perturb * 4)) + dry_out; + float river2 = river_gen.ridgedmultifractal (P * 0.04, 0.8, 10) - y_gradient * 0.2 - 0.16 - dry_out; + + float valley = river1 - 0.2f; + + static frac2d mountain_gen (8, 2.14, 0.5); + float mountain = mountain_gen.ridgedmultifractal (P * 0.004); + + t = valley < 0 ? T_VALLEY : T_MOUNTAIN; + c = blend0 (vec3d (0, 0.8, 0), vec3d (0.8, 0, 0), valley, 0.1f); + h = blend0 (base_height + continent * 300, base_height + mountain * xy_gradient * 400, valley, 0.1f); + + if (river1 < 0.01f) { - // ocean + // main rivers - they cut deeply into the mountains (base_height * 0.9f) + t = T_RIVER; + c = vec3d (0.2, 0.2, 1); + min_it (h, river_height + lerp (river1, 0.f, 0.01f, -20, -1)); + } - v = min (continent * 10, -0.2f); - c = vec3d (0, 0, 1); + if (river2 > 0) + { + t = T_RIVER; + c = vec3d (0.2, 0.2, 1); + min_it (h, river_height + lerp (river1, 0.f, 0.01f, -5, -1)); } - else + + if (continent < 0) { - // continent + t = T_OCEAN; + min_it (h, min (continent * 200, -1)); + c = vec3d (0, 0, 1); + } - // big rivers - static frac2d river_gen (1); - float river1 = abs (river_gen.fBm (P * 0.001 + perturb * 4)); - float river2 = river_gen.ridgedmultifractal (P * 0.04 + vec2d (3, 5), 0.8, 10) - (P[1] / 25000) * 0.1; + // now we have the base height, and base terrain - if (river1 < 0.03f) - { - v = min (-0.1f, -river1); - c = vec3d (0.2, 0.2, 1); - } - else if (river1 < 0.2f && river2 > 0.1f) - { - v = -0.05f; - c = vec3d (0.4, 0.4, 1); - } - else - { - river1 += 0.07f; +#if FANCY_GRAPHICS + z = h; // show the surface, not the given z layer +#endif + + // everything below the surface is underground, or a variant + if (z < h) + { + t = T_UNDERGROUND; + } - //c = river1 > 0 ? vec3d (0.8, 0.8, 0) : vec3d (0.8, 0, 0); - c = blend0 (vec3d (0.8, 0, 0), vec3d (0.8, 0.8, 0), 0.01f, river1);; + // put acquifers a bit below the surface, to reduce them leaking out (will still happen) + if (z < h - 3) + { + static frac3d acquifer_gen (4); + float acquifer = acquifer_gen.ridgedmultifractal (vec3d (x * 0.001, y * 0.001, z * 0.01), 1.003, 2); - static frac2d mountain_gen (8, 2.14, 0.5); - float mountain = mountain_gen.ridgedmultifractal (P * 0.004); - v = blend0 (mountain * 3 - 1, continent, 0.05f, river1); + if (acquifer > 0.48) + { + t = T_ACQUIFER; + c = vec3d (1,1,1); } } - c *= v * 0.5 + 0.5; + // TODO: caves + // TODO: chees areas + // TODO: minerals + // TODO: monsters + +#if FANCY_GRAPHICS + float v = clamp (lerp (h, deep_sea_z, mountain_z*0+800, 0.f, 1.f), 0.f, 1.f); + c *= v; putc (clamp (255 * c[0], 0, 255), stdout); putc (clamp (255 * c[1], 0, 255), stdout); putc (clamp (255 * c[2], 0, 255), stdout); +#endif } void noise_test (); void noise_test () { -#if 1 +#if 0 int Nw = 700; printf ("P6 %d %d 255\n", Nw * 3, Nw * 2); @@ -725,18 +782,18 @@ { if (!(y&63))fprintf (stderr, "y %d\n", y * 50 / Nw);//D - for (int x = 0; x < Nw; ++x) gen_height (x * 25000 / Nw, y * 25000 / Nw); + for (int x = 0; x < Nw; ++x) gen_quadspace (x * 25000 / Nw, y * 25000 / Nw, 0); - for (int x = 0; x < Nw; ++x) gen_height (x, y); - for (int x = 0; x < Nw; ++x) gen_height (x + 22000, y + 2000); + for (int x = 0; x < Nw; ++x) gen_quadspace (x + 400, y, 0); + for (int x = 0; x < Nw; ++x) gen_quadspace (x + 22000, y + 2000, 0); } for (int y = 0; y < Nw; ++y) { if (!(y&63))fprintf (stderr, "y %d\n", y * 50 / Nw+50);//D - for (int x = 0; x < Nw; ++x) gen_height (x + 1000, y + 22000); - for (int x = 0; x < Nw; ++x) gen_height (x + 12000, y + 12000); - for (int x = 0; x < Nw; ++x) gen_height (x + 22000, y + 22000); + for (int x = 0; x < Nw; ++x) gen_quadspace (x + 1000, y + 22000, 0); + for (int x = 0; x < Nw; ++x) gen_quadspace (x + 12500, y + 12500, 0); + for (int x = 0; x < Nw; ++x) gen_quadspace (x + 22000, y + 22500, 0); } //putc (127 * gen.noise (vec2d (x * 0.01, y * 0.01)) + 128, stdout); @@ -748,26 +805,30 @@ //putc (256 * gen.fBm (vec2d (x * 0.002, y * 0.002), 2), stdout); //putc (127.49 * gen.billowfractal (vec2d (x * 0.01, y * 0.01), 9) + 128, stdout); #else - int N = 128; + int N = 200; //printf ("P6 %d %d 255\n", N, N); // pmake&&server/deliantra-server >x&&convert -depth 8 -size 512xx512 gray:x x.ppm&& cv x.ppm - frac3d gen3 (3);; for (int z = 0; z < N; ++z) { if (!(z&7))fprintf (stderr, "z %d\n", z);//D for (int y = 0; y < N; ++y) for (int x = 0; x < N; ++x) { +#if 0 float v = gen3.ridgedmultifractal (vec3d (x * 0.001 + 0.2, y * 0.001 + 0.2, z * 0.01 + 0.2), 1.03, 2) * 2; -#if 0 if (z < 64) v = v * (z * z) / (64 * 64); -#endif if (v <= 0.9) continue; +#endif + static frac3d gen3 (10); + //float v = gen3.turbulence (vec3d (x * 0.01, y * 0.01, z * 0.01)); + float v = gen3.ridgedmultifractal (vec3d (x * 0.001, y * 0.001, z * 0.001), 1.003, 2); + + if (v <= 0.48) continue; float r[4]; int i[4];