#include "trandom.h" //#include "tfxparam.h" #include "perlinnoise.h" // using std::cout; // using std::endl; //------------------------------------------------------------------- double PerlinNoise::LinearNoise(double x, double y, double t) { int ix, iy, it, ix1, iy1, it1; double dx, dy, dt, val1, val2, val3, val4, val5, val6; ix = (int)x; iy = (int)y; it = (int)t; dx = x - ix; dy = y - iy; dt = t - it; ix = ix % Size; iy = iy % Size; it = it % TimeSize; ix1 = (ix + 1) % Size; iy1 = (iy + 1) % Size; it1 = (it + 1) % TimeSize; val1 = Noise[it + TimeSize * iy + TimeSize * Size * ix] + dx * (Noise[it + TimeSize * iy + TimeSize * Size * ix1] - Noise[it + TimeSize * iy + TimeSize * Size * ix]); val2 = Noise[it + TimeSize * iy1 + TimeSize * Size * ix] + dx * (Noise[it + TimeSize * iy1 + TimeSize * Size * ix1] - Noise[it + TimeSize * iy1 + TimeSize * Size * ix]); val3 = Noise[it1 + TimeSize * iy + TimeSize * Size * ix] + dx * (Noise[it1 + TimeSize * iy + TimeSize * Size * ix1] - Noise[it1 + TimeSize * iy + TimeSize * Size * ix]); val4 = Noise[it1 + TimeSize * iy1 + TimeSize * Size * ix] + dx * (Noise[it1 + TimeSize * iy1 + TimeSize * Size * ix1] - Noise[it1 + TimeSize * iy1 + TimeSize * Size * ix]); val5 = (val1 + dy * (val2 - val1)); val6 = (val3 + dy * (val4 - val3)); return (val5 + dt * (val6 - val5)); } double PerlinNoise::Turbolence(double u, double v, double k, double grain) { u += Offset; v += Offset; Pixel_size = 0.05; double t = 0.0, scale = 1.0, tscale = 0; u /= grain; v /= grain; k /= 10; while (scale > Pixel_size) { tscale += scale; t += LinearNoise(u / scale, v / scale, k / scale) * scale; scale /= 2.0; } return t / tscale; } double PerlinNoise::Turbolence(double u, double v, double k, double grain, double min, double max) { u += Offset; v += Offset; Pixel_size = 0.05; double t = 0.0, scale = 1.0, tscale = 0; u /= grain; v /= grain; k /= 10; while (scale > Pixel_size) { tscale += scale; t += LinearNoise(u / scale, v / scale, k / scale) * scale; scale /= 2.0; } t = t / tscale; if (t < min) t = 0; else { if (t > max) t = 1; else t = (t - min) / ((max - min)); } return t; } double PerlinNoise::Marble(double u, double v, double k, double grain) { u += Offset; v += Offset; Pixel_size = 0.05; double t = 0.0, scale = 1.0, tscale = 0; u /= grain; v /= grain; k /= 10; while (scale > Pixel_size) { tscale += scale; t += LinearNoise(u / scale, v / scale, k / scale) * scale; scale /= 2.0; } t = 10 * t; return (t - (int)t); } double PerlinNoise::Marble(double u, double v, double k, double grain, double min, double max) { u += Offset; v += Offset; Pixel_size = 0.05; double t = 0.0, scale = 1.0, tscale = 0; u /= grain; v /= grain; k /= 10; while (scale > Pixel_size) { tscale += scale; t += LinearNoise(u / scale, v / scale, k / scale) * scale; scale /= 2.0; } t = 10 * t; t = (t - (int)t); if (t < min) t = 0; else { if (t > max) t = 1; else t = (t - min) / ((max - min)); } return t; } PerlinNoise::PerlinNoise() : Noise(new float[Size * Size * TimeSize]) { TRandom random(1); for (int i = 0; i < Size; i++) { for (int j = 0; j < Size; j++) { for (int k = 0; k < TimeSize; k++) { float tmp = random.getFloat(); // cout << "tmp = " << tmp << "HM = "<< HowMany<< endl; Noise[k + TimeSize * j + TimeSize * Size * i] = tmp; } } } // cout << "HowMany = " << HowMany < void doCloudsT(const TRasterPT &ras, const TSpectrumT &spectrum, TPointD &tilepos, double evolution, double size, double min, double max, int type, double scale) { int j; TAffine aff = TScale(1 / scale); PerlinNoise Noise; ras->lock(); if (type == PNOISE_CLOUDS) { for (j = 0; j < ras->getLy(); j++) { TPointD pos = tilepos; pos.y += j; PIXEL *pix = ras->pixels(j); PIXEL *endPix = pix + ras->getLx(); while (pix < endPix) { TPointD posAff = aff * pos; double pnoise = Noise.Turbolence(posAff.x, posAff.y, evolution, size, min, max); pos.x += 1.0; *pix++ = spectrum.getPremultipliedValue(pnoise); } } } else { for (j = 0; j < ras->getLy(); j++) { TPointD pos = tilepos; pos.y += j; PIXEL *pix = ras->pixels(j); PIXEL *endPix = pix + ras->getLx(); while (pix < endPix) { TPointD posAff = aff * pos; double pnoise = Noise.Marble(posAff.x, posAff.y, evolution, size, min, max); pos.x += 1.0; *pix++ = spectrum.getPremultipliedValue(pnoise); } } } ras->unlock(); } } void doClouds(const TRasterP &ras, const TSpectrumParamP colors, TPointD pos, double evolution, double size, double min, double max, int type, double scale, double frame) { if ((TRaster32P)ras) doCloudsT(ras, colors->getValue(frame), pos, evolution, size, min, max, type, scale); else if ((TRaster64P)ras) doCloudsT(ras, colors->getValue64(frame), pos, evolution, size, min, max, type, scale); else throw TException("CloudsFx: unsupported Pixel Type"); }