|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "perlinnoise.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamuiconcept.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class PerlinNoiseFx : public TStandardRasterFx
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_DECLARATION(PerlinNoiseFx)
|
|
Toshihiro Shimizu |
890ddd |
TRasterFxPort m_input;
|
|
Toshihiro Shimizu |
890ddd |
TIntEnumParamP m_type;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_size;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_min;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_max;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_evol;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_offsetx;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_offsety;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_intensity;
|
|
Toshihiro Shimizu |
890ddd |
TBoolParamP m_matte;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
PerlinNoiseFx()
|
|
Toshihiro Shimizu |
890ddd |
: m_type(new TIntEnumParam(PNOISE_CLOUDS, "Clouds")), m_size(100.0), m_min(0.0), m_max(1.0), m_evol(0.0), m_intensity(40.0), m_offsetx(0.0), m_offsety(0.0), m_matte(1.0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_offsetx->setMeasureName("fxLength");
|
|
Toshihiro Shimizu |
890ddd |
m_offsety->setMeasureName("fxLength");
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "type", m_type);
|
|
Toshihiro Shimizu |
890ddd |
m_type->addItem(PNOISE_WOODS, "Marble/Wood");
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "size", m_size);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "evolution", m_evol);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "intensity", m_intensity);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "offsetx", m_offsetx);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "offsety", m_offsety);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "matte", m_matte);
|
|
Toshihiro Shimizu |
890ddd |
addInputPort("Source", m_input);
|
|
Toshihiro Shimizu |
890ddd |
m_size->setValueRange(0, 200);
|
|
Toshihiro Shimizu |
890ddd |
m_intensity->setValueRange(0, 300);
|
|
Toshihiro Shimizu |
890ddd |
m_min->setValueRange(0, 1.0);
|
|
Toshihiro Shimizu |
890ddd |
m_max->setValueRange(0, 1.0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
~PerlinNoiseFx(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_input.isConnected()) {
|
|
Toshihiro Shimizu |
890ddd |
m_input->doGetBBox(frame, bBox, info);
|
|
Toshihiro Shimizu |
890ddd |
bBox = bBox.enlarge(m_intensity->getValue(frame));
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
bBox = TRectD();
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void transform(double frame,
|
|
Toshihiro Shimizu |
890ddd |
int port,
|
|
Toshihiro Shimizu |
890ddd |
const TRectD &rectOnOutput,
|
|
Toshihiro Shimizu |
890ddd |
const TRenderSettings &infoOnOutput,
|
|
Toshihiro Shimizu |
890ddd |
TRectD &rectOnInput,
|
|
Toshihiro Shimizu |
890ddd |
TRenderSettings &infoOnInput);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void doCompute(TTile &tile, double frame, const TRenderSettings &ri);
|
|
Toshihiro Shimizu |
890ddd |
int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info);
|
|
Toshihiro Shimizu |
890ddd |
bool canHandle(const TRenderSettings &info, double frame)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void getParamUIs(TParamUIConcept *&concepts, int &length)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
concepts = new TParamUIConcept[length = 1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
concepts[0].m_type = TParamUIConcept::POINT_2;
|
|
Toshihiro Shimizu |
890ddd |
concepts[0].m_label = "Offset";
|
|
Toshihiro Shimizu |
890ddd |
concepts[0].m_params.push_back(m_offsetx);
|
|
Toshihiro Shimizu |
890ddd |
concepts[0].m_params.push_back(m_offsety);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
template <typename channel_type="" pixel,="" typename=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void doPerlinNoise(const TRasterPT<pixel> &rasOut, const TRasterPT<pixel> &rasIn, TPointD &tilepos,</pixel></pixel>
|
|
Toshihiro Shimizu |
890ddd |
double evolution, double size, double min, double max,
|
|
Toshihiro Shimizu |
890ddd |
double offsetx, double offsety, int type, int brad, int matte, double scale)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
PerlinNoise Noise;
|
|
Toshihiro Shimizu |
890ddd |
rasOut->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TAffine aff = TScale(1 / scale);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (type == PNOISE_CLOUDS)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int j = 0; j < rasOut->getLy(); ++j) {
|
|
Toshihiro Shimizu |
890ddd |
PIXEL *pixout = rasOut->pixels(j);
|
|
Toshihiro Shimizu |
890ddd |
PIXEL *endPixOut = pixout + rasOut->getLx();
|
|
Toshihiro Shimizu |
890ddd |
PIXEL *pix = rasIn->pixels(j + brad) + brad;
|
|
Toshihiro Shimizu |
890ddd |
TPointD pos = tilepos;
|
|
Toshihiro Shimizu |
890ddd |
pos.y += j;
|
|
Toshihiro Shimizu |
890ddd |
while (pixout < endPixOut) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD posAff = aff * pos;
|
|
Toshihiro Shimizu |
890ddd |
double pnoise = Noise.Turbolence(posAff.x + offsetx, posAff.y + offsety, evolution, size, min, max);
|
|
Toshihiro Shimizu |
890ddd |
int sval = (int)(brad * (pnoise - 0.5));
|
|
Toshihiro Shimizu |
890ddd |
int pixshift = sval + rasIn->getWrap() * (sval);
|
|
Toshihiro Shimizu |
890ddd |
pos.x += 1.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (matte) {
|
|
Toshihiro Shimizu |
890ddd |
pixout->r = (CHANNEL_TYPE)((pix + pixshift)->r * pnoise);
|
|
Toshihiro Shimizu |
890ddd |
pixout->g = (CHANNEL_TYPE)((pix + pixshift)->g * pnoise);
|
|
Toshihiro Shimizu |
890ddd |
pixout->b = (CHANNEL_TYPE)((pix + pixshift)->b * pnoise);
|
|
Toshihiro Shimizu |
890ddd |
pixout->m = (CHANNEL_TYPE)((pix + pixshift)->m * pnoise);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
pixout->r = (CHANNEL_TYPE)((pix + pixshift)->r);
|
|
Toshihiro Shimizu |
890ddd |
pixout->g = (CHANNEL_TYPE)((pix + pixshift)->g);
|
|
Toshihiro Shimizu |
890ddd |
pixout->b = (CHANNEL_TYPE)((pix + pixshift)->b);
|
|
Toshihiro Shimizu |
890ddd |
pixout->m = (CHANNEL_TYPE)((pix + pixshift)->m);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*pix++;
|
|
Toshihiro Shimizu |
890ddd |
*pixout++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
for (int j = 0; j < rasOut->getLy(); ++j) {
|
|
Toshihiro Shimizu |
890ddd |
PIXEL *pixout = rasOut->pixels(j);
|
|
Toshihiro Shimizu |
890ddd |
PIXEL *endPixOut = pixout + rasOut->getLx();
|
|
Toshihiro Shimizu |
890ddd |
PIXEL *pix = rasIn->pixels(j + brad) + brad;
|
|
Toshihiro Shimizu |
890ddd |
TPointD pos = tilepos;
|
|
Toshihiro Shimizu |
890ddd |
pos.y += j;
|
|
Toshihiro Shimizu |
890ddd |
while (pixout < endPixOut) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD posAff = aff * pos;
|
|
Toshihiro Shimizu |
890ddd |
double pnoisex = Noise.Marble(posAff.x + offsetx, posAff.y + offsety, evolution, size, min, max);
|
|
Toshihiro Shimizu |
890ddd |
double pnoisey = Noise.Marble(posAff.x + offsetx, posAff.y + offsety, evolution + 100, size, min, max);
|
|
Toshihiro Shimizu |
890ddd |
int svalx = (int)(brad * (pnoisex - 0.5));
|
|
Toshihiro Shimizu |
890ddd |
int svaly = (int)(brad * (pnoisey - 0.5));
|
|
Toshihiro Shimizu |
890ddd |
int pixshift = svalx + rasIn->getWrap() * (svaly);
|
|
Toshihiro Shimizu |
890ddd |
pos.x += 1.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (matte) {
|
|
Toshihiro Shimizu |
890ddd |
pixout->r = (CHANNEL_TYPE)((pix + pixshift)->r * pnoisex);
|
|
Toshihiro Shimizu |
890ddd |
pixout->g = (CHANNEL_TYPE)((pix + pixshift)->g * pnoisex);
|
|
Toshihiro Shimizu |
890ddd |
pixout->b = (CHANNEL_TYPE)((pix + pixshift)->b * pnoisex);
|
|
Toshihiro Shimizu |
890ddd |
pixout->m = (CHANNEL_TYPE)((pix + pixshift)->m * pnoisex);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
pixout->r = (CHANNEL_TYPE)((pix + pixshift)->r);
|
|
Toshihiro Shimizu |
890ddd |
pixout->g = (CHANNEL_TYPE)((pix + pixshift)->g);
|
|
Toshihiro Shimizu |
890ddd |
pixout->b = (CHANNEL_TYPE)((pix + pixshift)->b);
|
|
Toshihiro Shimizu |
890ddd |
pixout->m = (CHANNEL_TYPE)((pix + pixshift)->m);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*pix++;
|
|
Toshihiro Shimizu |
890ddd |
*pixout++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
rasOut->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PerlinNoiseFx::transform(
|
|
Toshihiro Shimizu |
890ddd |
double frame,
|
|
Toshihiro Shimizu |
890ddd |
int port,
|
|
Toshihiro Shimizu |
890ddd |
const TRectD &rectOnOutput,
|
|
Toshihiro Shimizu |
890ddd |
const TRenderSettings &infoOnOutput,
|
|
Toshihiro Shimizu |
890ddd |
TRectD &rectOnInput,
|
|
Toshihiro Shimizu |
890ddd |
TRenderSettings &infoOnInput)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
infoOnInput = infoOnOutput;
|
|
Toshihiro Shimizu |
890ddd |
TRectD rectOut(rectOnOutput);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double scale = sqrt(fabs(infoOnInput.m_affine.det()));
|
|
Toshihiro Shimizu |
890ddd |
int brad = (int)m_intensity->getValue(frame) * scale;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!brad) {
|
|
Toshihiro Shimizu |
890ddd |
rectOnInput = rectOut;
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int rasInLx = tround(rectOut.getLx());
|
|
Toshihiro Shimizu |
890ddd |
int rasInLy = tround(rectOut.getLy());
|
|
Toshihiro Shimizu |
890ddd |
rectOnInput = TRectD(rectOut.getP00(), TDimensionD(rasInLx, rasInLy));
|
|
Toshihiro Shimizu |
890ddd |
rectOnInput.enlarge(brad);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void PerlinNoiseFx::doCompute(
|
|
Toshihiro Shimizu |
890ddd |
TTile &tile,
|
|
Toshihiro Shimizu |
890ddd |
double frame,
|
|
Toshihiro Shimizu |
890ddd |
const TRenderSettings &ri)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_input.isConnected())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double scale = sqrt(fabs(ri.m_affine.det()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double evolution = m_evol->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
double size = m_size->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
int brad = (int)m_intensity->getValue(frame) * scale;
|
|
Toshihiro Shimizu |
890ddd |
int matte = (int)m_matte->getValue();
|
|
Toshihiro Shimizu |
890ddd |
int type = (int)m_type->getValue();
|
|
Toshihiro Shimizu |
890ddd |
double offsetx = m_offsetx->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
double offsety = m_offsety->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
double min = m_min->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
double max = m_max->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (brad < 0)
|
|
Toshihiro Shimizu |
890ddd |
brad = abs(brad);
|
|
Toshihiro Shimizu |
890ddd |
if (size < 0.01)
|
|
Toshihiro Shimizu |
890ddd |
size = 0.01;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!brad) {
|
|
Toshihiro Shimizu |
890ddd |
m_input->compute(tile, frame, ri);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TRectD rectIn = convert(tile.getRaster()->getBounds()) + tile.m_pos;
|
|
Toshihiro Shimizu |
890ddd |
rectIn = rectIn.enlarge(brad);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int rasInLx = tround(rectIn.getLx());
|
|
Toshihiro Shimizu |
890ddd |
int rasInLy = tround(rectIn.getLy());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TTile tileIn;
|
|
Toshihiro Shimizu |
890ddd |
m_input->allocateAndCompute(tileIn, rectIn.getP00(),
|
|
Toshihiro Shimizu |
890ddd |
TDimension(rasInLx, rasInLy),
|
|
Toshihiro Shimizu |
890ddd |
tile.getRaster(), frame, ri);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD pos = tile.m_pos;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRaster32P rasOut = tile.getRaster();
|
|
Toshihiro Shimizu |
890ddd |
TRaster32P rasIn = tileIn.getRaster();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (rasOut)
|
|
Toshihiro Shimizu |
890ddd |
doPerlinNoise<tpixel32, uchar="">(rasOut, rasIn, pos, evolution, size, min, max,</tpixel32,>
|
|
Toshihiro Shimizu |
890ddd |
offsetx, offsety,
|
|
Toshihiro Shimizu |
890ddd |
type, brad, matte, scale);
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
TRaster64P rasOut = tile.getRaster();
|
|
Toshihiro Shimizu |
890ddd |
TRaster64P rasIn = tileIn.getRaster();
|
|
Toshihiro Shimizu |
890ddd |
if (rasOut)
|
|
Toshihiro Shimizu |
890ddd |
doPerlinNoise<tpixel64, ushort="">(rasOut, rasIn, pos, evolution, size, min, max,</tpixel64,>
|
|
Toshihiro Shimizu |
890ddd |
offsetx, offsety, type, brad, matte, scale);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
throw TException("Brightness&Contrast: unsupported Pixel Type");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int PerlinNoiseFx::getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double scale = sqrt(fabs(info.m_affine.det()));
|
|
Toshihiro Shimizu |
890ddd |
int brad = (int)m_intensity->getValue(frame) * scale;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return TRasterFx::memorySize(rect.enlarge(brad), info.m_bpp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(PerlinNoiseFx, "perlinNoiseFx")
|