--- deliantra/server/common/noise.C 2010/07/11 04:01:48 1.1 +++ deliantra/server/common/noise.C 2011/04/22 02:03:10 1.2 @@ -22,7 +22,9 @@ #include "noise.h" -noise_gen::noise_gen (uint32_t seed) +///////////////////////////////////////////////////////////////////////////// + +noise2d::noise2d (uint32_t seed) { seedable_rand_gen rng (seed); @@ -43,7 +45,7 @@ } float -noise_gen::noise (float x, float y) +noise2d::noise (float x, float y) { int ix = floorf (x); float fx = x - ix; int iy = floorf (y); float fy = y - iy; @@ -56,7 +58,7 @@ float Ax = fx - i; float Ay = fy - j; - float d = Ax * Ax + Ay * Ay; + float d = Ax * Ax + Ay * Ay; if (d < 4) { @@ -75,8 +77,156 @@ return clamp (v * 2, -.9999999f, .9999999f); } +#if 0||ABSTRACTION_PENALTY_IS_GONE +float +noise2d::noise (float x, float y) +{ + vec2d X = vec2d (x, y); + gen_vec<2,int> I = floor (X); + vec2d F = X - I; + + float v = 0; + + for (int j = -1; j <= 2; ++j) + for (int i = -1; i <= 2; ++i) + { + vec2d A = F - vec2d (i, j); + + float d = A * A; + + if (d < 4) + { + int h = rvmap [0](I[0] + i) ^ rvmap [1](I[1] + j); + float *G = rvec [h & 0xff]; + + float t1 = 1 - d / 4; + float t2 = t1 * t1; + float t4 = t2 * t2; + + float p = (4 * t1 - 3) * t4; + v += A * vec2d (G[0], G[1]) * p; + } + } + + return clamp (v * 2, -.9999999f, .9999999f); +} +#endif + +///////////////////////////////////////////////////////////////////////////// + +noise3d::noise3d (uint32_t seed) +{ + seedable_rand_gen rng (seed); + + for (int i = 0; i < 256; ++i) + { + for (int j = 0; j < 3; ++j) + rvec [i][j] = rng () - 0.5f; + + // normalise + float mag = 1.f / sqrtf (rvec [i][0] * rvec [i][0] + + rvec [i][1] * rvec [i][1] + + rvec [i][2] * rvec [i][2]); + + rvec [i][0] *= mag; + rvec [i][1] *= mag; + rvec [i][2] *= mag; + } + + rvmap [0].seed (rng); + rvmap [1].seed (rng); + rvmap [2].seed (rng); +} + +float +noise3d::noise (float x, float y, float z) +{ + int ix = floorf (x); float fx = x - ix; + int iy = floorf (y); float fy = y - iy; + int iz = floorf (z); float fz = z - iz; + + float v = 0; + + for (int j = -1; j <= 2; ++j) + for (int i = -1; i <= 2; ++i) + for (int k = -1; k <= 2; ++k) + { + float Ax = fx - i; + float Ay = fy - j; + float Az = fz - k; + + float d = Ax * Ax + Ay * Ay + Az * Az; + + if (d < 4) + { + int h = rvmap [0](ix + i) ^ rvmap [1](iy + j) ^ rvmap [2](iz + k); + float *G = rvec [h & 0xff]; + + float t1 = 1 - d / 4; + float t2 = t1 * t1; + float t4 = t2 * t2; + + // (4t⁵ - 3t⁴) + float p = (4 * t1 - 3) * t4; + v += (Ax * G[0] + Ay * G[1] + Az * G[2]) * p; + } + } + + return clamp (v * 2, -.9999999f, .9999999f); +} + +float +noise3d::noise (float x, float y, float z, float nx, float ny, float nz) +{ + int ix = floorf (x); float fx = x - ix; + int iy = floorf (y); float fy = y - iy; + int iz = floorf (z); float fz = z - iz; + + float v = 0; + + for (int j = -1; j <= 2; ++j) + for (int i = -1; i <= 2; ++i) + for (int k = -1; k <= 2; ++k) + { + float Dx = fx - i; + float Dy = fy - j; + float Dz = fz - k; + + float e = Dx * nx + Dy * ny + Dz * nz; + + float o = 1 - abs (e); + + if (o > 0) + { + float Ax = Dx - e * nx; + float Ay = Dy - e * ny; + float Az = Dz - e * nz; + + float d = Ax * Ax + Ay * Ay + Az * Az; + + if (d < 4) + { + int h = rvmap [0](ix + i) ^ rvmap [1](iy + j) ^ rvmap [2](iz + k); + float *G = rvec [h & 0xff]; + + float t1 = 1 - d / 4; + float t2 = t1 * t1; + float t4 = t2 * t2; + + float o2 = o * o; + + // (4t⁵ - 3t⁴) * (3o³ - 2o²) + float p = (4 * t1 - 3) * t4 * (3 * o2 - 2 * o2 * o); + v += (Ax * G[0] + Ay * G[1] + Az * G[2]) * p; + } + } + } + + return clamp (v * 2, -.9999999f, .9999999f); +} + frac_gen::frac_gen (float hurst_expo, float lacunarity) -: h (hurst_expo), lac (lacunarity), noise_gen (0) +: h (hurst_expo), lac (lacunarity), noise2d (0) { float exsum = 0; @@ -259,24 +409,66 @@ void hack() { frac_gen gen (0.5, 2); + noise3d n(0); +#if 0 int N = 1024; - printf ("P5 %d %d 255\n", N, N); + 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 for (int y = 0; y < N; ++y) { if (!(y&63))fprintf (stderr, "y %d\n", y);//D for (int x = 0; x < N; ++x) { - //putc (128 + 128 * gen.noise (x * 0.04, y * 0.04), stdout); - putc (256 * gen.terrain2 (x * 0.004, y * 0.004, 8), stdout); + putc (128 + 128 * n.noise (x * 0.04 + 0.2, y * 0.04 + 0.2), stdout); + putc (128 + 128 * n.noise (x * 0.04 + 0.2, y * 0.08 + 0.2), stdout); + putc (128 + 128 * n.noise (x * 0.08 + 0.2, y * 0.04 + 0.2), stdout); + //putc (256 * gen.terrain2 (x * 0.004, y * 0.004, 8), stdout); //putc (256 * gen.fBm (x * 0.001, y * 0.001, 3), stdout); //putc (256 * gen.turbulence (x * 0.004 - 1, y * 0.004 - 1, 8), stdout); //putc (256 * gen.heterofractal (x * 0.008, y * 0.008, 8, -1.1, 2.0), stdout); //putc (256 * gen.ridgedmultifractal (x * 0.001, y * 0.001, 32, 1.001, 32), stdout); } } +#else + int N = 128; + + //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 + for (int z = 0; z < N; ++z) + { + if (!(z&4))fprintf (stderr, "z %d\n", z);//D + for (int y = 0; y < N; ++y) + for (int x = 0; x < N; ++x) + { + float v = n.noise (x * 0.06 + 0.2, y * 0.06 + 0.2, z * 0.06 + 0.2) * 0.5 + 0.5; + + if (z < 64) + v = v * (z * z) / (64 * 64); + + if (v <= 0.1) + continue; + + float r[4]; + int i[4]; + + r[0] = x; + r[1] = y; + r[2] = z; + r[3] = v; + + memcpy (i, r, 16); + + i[0] = htonl (i[0]); + i[1] = htonl (i[1]); + i[2] = htonl (i[2]); + i[3] = htonl (i[3]); + + fwrite (i, 4*4, 1, stdout); + } + } +#endif exit (0); }