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