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")