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