Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "traster.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tspectrumparam.h"
Campbell Barton 8c6c57
Campbell Barton 8c6c57
#include "gradients.h"
Campbell Barton 8c6c57
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void doComputeRadialT(TRasterPT<t> ras, TPointD posTrasf,</t>
Shinya Kitaoka 120a6e
                      const TSpectrumT<t> &spectrum, double period,</t>
shun-iwasawa a92a49
                      double count, double cycle, const TAffine &aff,
shun-iwasawa a92a49
                      double inner = 0.0, GradientCurveType type = Linear) {
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
  double maxRadius = period * count;
Shinya Kitaoka 120a6e
  double freq      = 1.0 / period;
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  for (j = 0; j < ras->getLy(); j++) {
Shinya Kitaoka 120a6e
    TPointD posAux = posTrasf;
Shinya Kitaoka 120a6e
    T *pix         = ras->pixels(j);
Shinya Kitaoka 120a6e
    T *endPix      = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      double radius = norm(posAux);
Shinya Kitaoka 120a6e
      double t      = 1;
Shinya Kitaoka 120a6e
      if (radius < maxRadius) {
Shinya Kitaoka 120a6e
        t = (radius + cycle) * freq;
Shinya Kitaoka 120a6e
        t -= floor(t);
Shinya Kitaoka 120a6e
      }
shun-iwasawa a92a49
shun-iwasawa a92a49
      if (t <= inner)
shun-iwasawa a92a49
        t = 0;
shun-iwasawa a92a49
      else
shun-iwasawa a92a49
        t = (t - inner) / (1.0 - inner);
shun-iwasawa a92a49
shun-iwasawa a92a49
      double factor;
shun-iwasawa a92a49
      switch (type) {
shun-iwasawa a92a49
      case Linear:
shun-iwasawa a92a49
        factor = t;
shun-iwasawa a92a49
        break;
shun-iwasawa a92a49
      case EaseIn:
shun-iwasawa a92a49
        factor = t * t;
shun-iwasawa a92a49
        break;
shun-iwasawa a92a49
      case EaseOut:
shun-iwasawa a92a49
        factor = 1.0 - (1.0 - t) * (1.0 - t);
shun-iwasawa a92a49
        break;
shun-iwasawa a92a49
      case EaseInOut:
shun-iwasawa a92a49
      default:
shun-iwasawa a92a49
        factor = (-2 * t + 3) * (t * t);
shun-iwasawa a92a49
        break;
shun-iwasawa a92a49
      }
shun-iwasawa a92a49
      *pix++ = spectrum.getPremultipliedValue(factor);
shun-iwasawa a92a49
Shinya Kitaoka 120a6e
      posAux.x += aff.a11;
Shinya Kitaoka 120a6e
      posAux.y += aff.a21;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    posTrasf.x += aff.a12;
Shinya Kitaoka 120a6e
    posTrasf.y += aff.a22;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
shun-iwasawa a92a49
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void multiRadial(const TRasterP &ras, TPointD posTrasf,
Shinya Kitaoka 120a6e
                 const TSpectrumParamP colors, double period, double count,
shun-iwasawa a92a49
                 double cycle, const TAffine &aff, double frame, double inner,
shun-iwasawa a92a49
                 GradientCurveType type) {
Shinya Kitaoka 120a6e
  if ((TRaster32P)ras)
Shinya Kitaoka 120a6e
    doComputeRadialT<tpixel32>(ras, posTrasf, colors->getValue(frame), period,</tpixel32>
shun-iwasawa a92a49
                               count, cycle, aff, inner, type);
Shinya Kitaoka 120a6e
  else if ((TRaster64P)ras)
Shinya Kitaoka 120a6e
    doComputeRadialT<tpixel64>(ras, posTrasf, colors->getValue64(frame), period,</tpixel64>
shun-iwasawa a92a49
                               count, cycle, aff, inner, type);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    throw TException("MultiRadialGradientFx: unsupported Pixel Type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void doComputeLinearT(TRasterPT<t> ras, TPointD posTrasf,</t>
Shinya Kitaoka 120a6e
                      const TSpectrumT<t> &spectrum, double period,</t>
Shinya Kitaoka 120a6e
                      double count, double w_amplitude, double w_freq,
shun-iwasawa a92a49
                      double w_phase, double cycle, const TAffine &aff,
shun-iwasawa a92a49
                      GradientCurveType type = EaseInOut) {
Shinya Kitaoka 120a6e
  double shift     = 0;
Shinya Kitaoka 120a6e
  double maxRadius = period * count / 2.;
Shinya Kitaoka 120a6e
  double freq      = 1.0 / period;
Shinya Kitaoka 120a6e
  int j;
Shinya Kitaoka 120a6e
  ras->lock();
Shinya Kitaoka 120a6e
  for (j = 0; j < ras->getLy(); j++) {
Shinya Kitaoka 120a6e
    TPointD posAux = posTrasf;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // TPointD pos = tile.m_pos;
Shinya Kitaoka 120a6e
    // pos.y += j;
Shinya Kitaoka 120a6e
    T *pix    = ras->pixels(j);
Shinya Kitaoka 120a6e
    T *endPix = pix + ras->getLx();
Shinya Kitaoka 120a6e
    while (pix < endPix) {
Shinya Kitaoka 120a6e
      if (w_amplitude) shift = w_amplitude * sin(w_freq * posAux.y + w_phase);
shun-iwasawa a92a49
      double radius = posAux.x + shift;
shun-iwasawa a92a49
      double t      = 1;
Shinya Kitaoka 120a6e
      if (fabs(radius) < maxRadius) {
Shinya Kitaoka 120a6e
        t = (radius + maxRadius + cycle) * freq;
Shinya Kitaoka 120a6e
        t -= floor(t);
Shinya Kitaoka 120a6e
      } else if (radius < 0)
shun-iwasawa a92a49
        t = 0;
shun-iwasawa a92a49
shun-iwasawa a92a49
      double factor;
shun-iwasawa a92a49
      switch (type) {
shun-iwasawa a92a49
      case Linear:
shun-iwasawa a92a49
        factor = t;
shun-iwasawa a92a49
        break;
shun-iwasawa a92a49
      case EaseIn:
shun-iwasawa a92a49
        factor = t * t;
shun-iwasawa a92a49
        break;
shun-iwasawa a92a49
      case EaseOut:
shun-iwasawa a92a49
        factor = 1.0 - (1.0 - t) * (1.0 - t);
shun-iwasawa a92a49
        break;
shun-iwasawa a92a49
      case EaseInOut:
shun-iwasawa a92a49
      default:
shun-iwasawa a92a49
        factor = (-2 * t + 3) * (t * t);
shun-iwasawa a92a49
        break;
shun-iwasawa a92a49
      }
Shinya Kitaoka 120a6e
      // pos.x += 1.0;
shun-iwasawa a92a49
      *pix++ = spectrum.getPremultipliedValue(factor);
Shinya Kitaoka 120a6e
      posAux.x += aff.a11;
Shinya Kitaoka 120a6e
      posAux.y += aff.a21;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    posTrasf.x += aff.a12;
Shinya Kitaoka 120a6e
    posTrasf.y += aff.a22;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  ras->unlock();
Toshihiro Shimizu 890ddd
}
shun-iwasawa a92a49
}  // namespace
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void multiLinear(const TRasterP &ras, TPointD posTrasf,
Shinya Kitaoka 120a6e
                 const TSpectrumParamP colors, double period, double count,
Shinya Kitaoka 120a6e
                 double amplitude, double freq, double phase, double cycle,
shun-iwasawa a92a49
                 const TAffine &aff, double frame, GradientCurveType type) {
Shinya Kitaoka 120a6e
  if ((TRaster32P)ras)
Shinya Kitaoka 120a6e
    doComputeLinearT<tpixel32>(ras, posTrasf, colors->getValue(frame), period,</tpixel32>
shun-iwasawa a92a49
                               count, amplitude, freq, phase, cycle, aff, type);
Shinya Kitaoka 120a6e
  else if ((TRaster64P)ras)
Shinya Kitaoka 120a6e
    doComputeLinearT<tpixel64>(ras, posTrasf, colors->getValue64(frame), period,</tpixel64>
shun-iwasawa a92a49
                               count, amplitude, freq, phase, cycle, aff, type);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    throw TException("MultiLinearGradientFx: unsupported Pixel Type");
Toshihiro Shimizu 890ddd
}