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