Toshihiro Shimizu 890ddd
/*------------------------------------
Toshihiro Shimizu 890ddd
 Iwa_GradientWarpFx iwasawa
Toshihiro Shimizu 890ddd
 参照画像の勾配方向にWarpするエフェクト
Toshihiro Shimizu 890ddd
------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "iwa_gradientwarpfx.h"
shun-iwasawa 481b59
#include "trop.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 ソース画像を0〜1に正規化してホストメモリに読み込む
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Shinya Kitaoka 120a6e
void Iwa_GradientWarpFx::setSourceRaster(const RASTER srcRas, float4 *dstMem,
Shinya Kitaoka 120a6e
                                         TDimensionI dim) {
Shinya Kitaoka 120a6e
  float4 *chann_p = dstMem;
Shinya Kitaoka 120a6e
  for (int j = 0; j < dim.ly; j++) {
Shinya Kitaoka 120a6e
    PIXEL *pix = srcRas->pixels(j);
Shinya Kitaoka 120a6e
    for (int i = 0; i < dim.lx; i++, pix++, chann_p++) {
Shinya Kitaoka 120a6e
      (*chann_p).x = (float)pix->r / (float)PIXEL::maxChannelValue;
Shinya Kitaoka 120a6e
      (*chann_p).y = (float)pix->g / (float)PIXEL::maxChannelValue;
Shinya Kitaoka 120a6e
      (*chann_p).z = (float)pix->b / (float)PIXEL::maxChannelValue;
Shinya Kitaoka 120a6e
      (*chann_p).w = (float)pix->m / (float)PIXEL::maxChannelValue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 参照画像の輝度値を0〜1に正規化してホストメモリに読み込む
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Shinya Kitaoka 120a6e
void Iwa_GradientWarpFx::setWarperRaster(const RASTER warperRas, float *dstMem,
Shinya Kitaoka 120a6e
                                         TDimensionI dim) {
shun-iwasawa 481b59
  auto clamp01 = [](float val) { return std::min(1.f, std::max(0.f, val)); };
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
  float *chann_p = dstMem;
Shinya Kitaoka 120a6e
  for (int j = 0; j < dim.ly; j++) {
Shinya Kitaoka 120a6e
    PIXEL *pix = warperRas->pixels(j);
Shinya Kitaoka 120a6e
    for (int i = 0; i < dim.lx; i++, pix++, chann_p++) {
Shinya Kitaoka 120a6e
      float r = (float)pix->r / (float)PIXEL::maxChannelValue;
Shinya Kitaoka 120a6e
      float g = (float)pix->g / (float)PIXEL::maxChannelValue;
Shinya Kitaoka 120a6e
      float b = (float)pix->b / (float)PIXEL::maxChannelValue;
Shinya Kitaoka 120a6e
shun-iwasawa 481b59
      (*chann_p) = clamp01(0.298912f * r + 0.586611f * g + 0.114478f * b);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 出力結果をChannel値に変換してタイルに格納
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Shinya Kitaoka 120a6e
void Iwa_GradientWarpFx::setOutputRaster(float4 *srcMem, const RASTER dstRas,
Shinya Kitaoka 120a6e
                                         TDimensionI dim, int2 margin) {
Shinya Kitaoka 120a6e
  int out_j = 0;
Shinya Kitaoka 120a6e
  for (int j = margin.y; j < dstRas->getLy() + margin.y; j++, out_j++) {
Shinya Kitaoka 120a6e
    PIXEL *pix     = dstRas->pixels(out_j);
Shinya Kitaoka 120a6e
    float4 *chan_p = srcMem;
Shinya Kitaoka 120a6e
    chan_p += j * dim.lx + margin.x;
Shinya Kitaoka 120a6e
    for (int i = 0; i < dstRas->getLx(); i++, pix++, chan_p++) {
Shinya Kitaoka 120a6e
      float val;
Shinya Kitaoka 120a6e
      val    = (*chan_p).x * (float)PIXEL::maxChannelValue + 0.5f;
Shinya Kitaoka 120a6e
      pix->r = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue)
Shinya Kitaoka 120a6e
                                             ? (float)PIXEL::maxChannelValue
Shinya Kitaoka 120a6e
                                             : val);
Shinya Kitaoka 120a6e
      val    = (*chan_p).y * (float)PIXEL::maxChannelValue + 0.5f;
Shinya Kitaoka 120a6e
      pix->g = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue)
Shinya Kitaoka 120a6e
                                             ? (float)PIXEL::maxChannelValue
Shinya Kitaoka 120a6e
                                             : val);
Shinya Kitaoka 120a6e
      val    = (*chan_p).z * (float)PIXEL::maxChannelValue + 0.5f;
Shinya Kitaoka 120a6e
      pix->b = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue)
Shinya Kitaoka 120a6e
                                             ? (float)PIXEL::maxChannelValue
Shinya Kitaoka 120a6e
                                             : val);
Shinya Kitaoka 120a6e
      val    = (*chan_p).w * (float)PIXEL::maxChannelValue + 0.5f;
Shinya Kitaoka 120a6e
      pix->m = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue)
Shinya Kitaoka 120a6e
                                             ? (float)PIXEL::maxChannelValue
Shinya Kitaoka 120a6e
                                             : val);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
template <>
shun-iwasawa 481b59
void Iwa_GradientWarpFx::setOutputRaster<trasterfp, tpixelf="">(</trasterfp,>
shun-iwasawa 481b59
    float4 *srcMem, const TRasterFP dstRas, TDimensionI dim, int2 margin) {
shun-iwasawa 481b59
  int out_j = 0;
shun-iwasawa 481b59
  for (int j = margin.y; j < dstRas->getLy() + margin.y; j++, out_j++) {
shun-iwasawa 481b59
    TPixelF *pix   = dstRas->pixels(out_j);
shun-iwasawa 481b59
    float4 *chan_p = srcMem;
shun-iwasawa 481b59
    chan_p += j * dim.lx + margin.x;
shun-iwasawa 481b59
    for (int i = 0; i < dstRas->getLx(); i++, pix++, chan_p++) {
shun-iwasawa 481b59
      pix->r = (*chan_p).x;
shun-iwasawa 481b59
      pix->g = (*chan_p).y;
shun-iwasawa 481b59
      pix->b = (*chan_p).z;
shun-iwasawa 481b59
      pix->m = (*chan_p).w;
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
}
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Iwa_GradientWarpFx::Iwa_GradientWarpFx()
shun-iwasawa 748a28
    : m_h_maxlen(0.0), m_v_maxlen(0.0), m_scale(1.0), m_sampling_size(1.0) {
Shinya Kitaoka 120a6e
  /*- 共通パラメータのバインド -*/
Shinya Kitaoka 120a6e
  addInputPort("Source", m_source);
Shinya Kitaoka 120a6e
  addInputPort("Warper", m_warper);
Shinya Kitaoka 120a6e
  bindParam(this, "h_maxlen", m_h_maxlen);
Shinya Kitaoka 120a6e
  bindParam(this, "v_maxlen", m_v_maxlen);
Shinya Kitaoka 120a6e
  bindParam(this, "scale", m_scale);
shun-iwasawa 748a28
  bindParam(this, "sampling_size", m_sampling_size);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_h_maxlen->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_v_maxlen->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  m_h_maxlen->setValueRange(-100.0, 100.0);
Shinya Kitaoka 120a6e
  m_v_maxlen->setValueRange(-100.0, 100.0);
Shinya Kitaoka 120a6e
  m_scale->setValueRange(1.0, 100.0);
shun-iwasawa 748a28
  m_sampling_size->setMeasureName("fxLength");
shun-iwasawa 748a28
  m_sampling_size->setValueRange(0.1, 20.0);
shun-iwasawa 748a28
shun-iwasawa 481b59
  enableComputeInFloat(true);
shun-iwasawa 748a28
  // Version 1: sampling distance had been always 1 pixel.
shun-iwasawa 748a28
  // Version 2: sampling distance can be specified with the parameter.
shun-iwasawa 748a28
  // this must be called after binding the parameters (see onFxVersionSet())
shun-iwasawa 748a28
  setFxVersion(2);
shun-iwasawa 748a28
}
shun-iwasawa 748a28
shun-iwasawa 748a28
//--------------------------------------------
shun-iwasawa 748a28
shun-iwasawa 748a28
void Iwa_GradientWarpFx::onFxVersionSet() {
shun-iwasawa 748a28
  getParams()->getParamVar("sampling_size")->setIsHidden(getFxVersion() == 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_GradientWarpFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                                   const TRenderSettings &settings) {
Shinya Kitaoka 120a6e
  /*- ソース画像が刺さっていなければreturn -*/
Shinya Kitaoka 120a6e
  if (!m_source.isConnected()) {
Shinya Kitaoka 120a6e
    tile.getRaster()->clear();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*- 参照画像が刺さっていなければ、ソース画像をそのまま返す -*/
Shinya Kitaoka 120a6e
  if (!m_warper.isConnected()) {
Shinya Kitaoka 120a6e
    m_source->compute(tile, frame, settings);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*-  計算パラメータを得る -*/
Shinya Kitaoka 120a6e
  /*- 移動距離のピクセルサイズ -*/
Shinya Kitaoka 120a6e
  /*--- 拡大縮小(移動回転しないで)のGeometryを反映させる ---*/
Shinya Kitaoka 120a6e
  double k       = sqrt(fabs(settings.m_affine.det()));
Shinya Kitaoka 120a6e
  double hLength = m_h_maxlen->getValue(frame) * k;
Shinya Kitaoka 120a6e
  double vLength = m_v_maxlen->getValue(frame) * k;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double scale = m_scale->getValue(frame);
Shinya Kitaoka 120a6e
shun-iwasawa 748a28
  double sampling_size = m_sampling_size->getValue(frame);
shun-iwasawa 748a28
  double grad_factor   = 1. / sampling_size;
shun-iwasawa 748a28
  sampling_size *= k;
shun-iwasawa 748a28
Shinya Kitaoka 120a6e
  /*- ワープ距離が0なら、ソース画像をそのまま返す -*/
Shinya Kitaoka 120a6e
  if (hLength == 0.0 && vLength == 0.0) {
Shinya Kitaoka 120a6e
    m_source->compute(tile, frame, settings);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun-iwasawa 748a28
  int margin = static_cast<int>(ceil((std::abs(hLength) < std::abs(vLength))</int>
shun-iwasawa 748a28
                                         ? std::abs(vLength)
shun-iwasawa 748a28
                                         : std::abs(hLength)));
shun-iwasawa 481b59
shun-iwasawa 481b59
  margin = std::max(margin, static_cast<int>(std::ceil(sampling_size)) + 1);</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 素材計算範囲を計算 -*/
Shinya Kitaoka 120a6e
  /*- 出力範囲 -*/
Shinya Kitaoka 120a6e
  TRectD rectOut(tile.m_pos, TDimensionD(tile.getRaster()->getLx(),
Shinya Kitaoka 120a6e
                                         tile.getRaster()->getLy()));
Shinya Kitaoka 120a6e
  TRectD enlargedRect = rectOut.enlarge((double)margin);
Shinya Kitaoka 120a6e
  TDimensionI enlargedDim((int)enlargedRect.getLx(), (int)enlargedRect.getLy());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- ソース画像を正規化して格納 -*/
shun-iwasawa 481b59
  TTile sourceTile;
shun-iwasawa 481b59
  m_source->allocateAndCompute(sourceTile, enlargedRect.getP00(), enlargedDim,
shun-iwasawa 481b59
                               tile.getRaster(), frame, settings);
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
  float4 *source_host;
shun-iwasawa 481b59
  TRasterGR8P source_host_ras;
shun-iwasawa 481b59
  if (tile.getRaster()->getPixelSize() == 4 ||
shun-iwasawa 481b59
      tile.getRaster()->getPixelSize() == 8) {
shun-iwasawa 481b59
    source_host_ras =
shun-iwasawa 481b59
        TRasterGR8P(enlargedDim.lx * sizeof(float4), enlargedDim.ly);
shun-iwasawa 481b59
    source_host_ras->lock();
shun-iwasawa 481b59
    source_host = (float4 *)source_host_ras->getRawData();
shun-iwasawa 481b59
    {
shun-iwasawa 481b59
      /*- タイルの画像を0〜1に正規化してホストメモリに読み込む -*/
shun-iwasawa 481b59
      TRaster32P ras32 = (TRaster32P)sourceTile.getRaster();
shun-iwasawa 481b59
      TRaster64P ras64 = (TRaster64P)sourceTile.getRaster();
shun-iwasawa 481b59
      if (ras32)
shun-iwasawa 481b59
        setSourceRaster<traster32p, tpixel32="">(ras32, source_host, enlargedDim);</traster32p,>
shun-iwasawa 481b59
      else if (ras64)
shun-iwasawa 481b59
        setSourceRaster<traster64p, tpixel64="">(ras64, source_host, enlargedDim);</traster64p,>
shun-iwasawa 481b59
    }
shun-iwasawa 481b59
  } else if (tile.getRaster()->getPixelSize() == 16) {
shun-iwasawa 481b59
    source_host =
shun-iwasawa 481b59
        reinterpret_cast<float4 *="">(sourceTile.getRaster()->getRawData());</float4>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 参照画像を正規化して格納 -*/
Shinya Kitaoka 120a6e
  float *warper_host;
Shinya Kitaoka 120a6e
  TRasterGR8P warper_host_ras(enlargedDim.lx * sizeof(float), enlargedDim.ly);
Shinya Kitaoka 120a6e
  warper_host_ras->lock();
Shinya Kitaoka 120a6e
  warper_host = (float *)warper_host_ras->getRawData();
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    /*-
Shinya Kitaoka 120a6e
     * タイルはこのフォーカス内だけ使用。正規化してwarper_hostに取り込んだらもう使わない
Shinya Kitaoka 120a6e
     * -*/
Shinya Kitaoka 120a6e
    TTile warperTile;
Shinya Kitaoka 120a6e
    m_warper->allocateAndCompute(warperTile, enlargedRect.getP00(), enlargedDim,
Shinya Kitaoka 120a6e
                                 tile.getRaster(), frame, settings);
shun-iwasawa 481b59
    // nonlinearのはず
shun-iwasawa 481b59
    assert(!warperTile.getRaster()->isLinear());
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
    /*- タイルの画像の輝度値を0〜1に正規化してホストメモリに読み込む -*/
Shinya Kitaoka 120a6e
    TRaster32P ras32 = (TRaster32P)warperTile.getRaster();
Shinya Kitaoka 120a6e
    TRaster64P ras64 = (TRaster64P)warperTile.getRaster();
shun-iwasawa 481b59
    TRasterFP rasF   = (TRasterFP)warperTile.getRaster();
Shinya Kitaoka 120a6e
    if (ras32)
Shinya Kitaoka 120a6e
      setWarperRaster<traster32p, tpixel32="">(ras32, warper_host, enlargedDim);</traster32p,>
Shinya Kitaoka 120a6e
    else if (ras64)
Shinya Kitaoka 120a6e
      setWarperRaster<traster64p, tpixel64="">(ras64, warper_host, enlargedDim);</traster64p,>
shun-iwasawa 481b59
    else if (rasF)
shun-iwasawa 481b59
      setWarperRaster<trasterfp, tpixelf="">(rasF, warper_host, enlargedDim);</trasterfp,>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 変位値をScale倍して増やす -*/
Shinya Kitaoka 120a6e
  hLength *= scale;
Shinya Kitaoka 120a6e
  vLength *= scale;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterGR8P result_host_ras;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  result_host_ras =
Shinya Kitaoka 120a6e
      TRasterGR8P(enlargedDim.lx * sizeof(float4), enlargedDim.ly);
Shinya Kitaoka 120a6e
  /*- 結果を収めるメモリ -*/
Shinya Kitaoka 120a6e
  float4 *result_host;
Shinya Kitaoka 120a6e
  result_host_ras->lock();
Shinya Kitaoka 120a6e
  result_host = (float4 *)result_host_ras->getRawData();
Shinya Kitaoka 120a6e
  doCompute_CPU(tile, frame, settings, hLength, vLength, margin, enlargedDim,
shun-iwasawa 748a28
                source_host, warper_host, result_host, sampling_size,
shun-iwasawa 748a28
                grad_factor);
Shinya Kitaoka 120a6e
  /*- ポインタ入れ替え -*/
Shinya Kitaoka 120a6e
  source_host = result_host;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int2 yohaku = {(enlargedDim.lx - tile.getRaster()->getSize().lx) / 2,
Shinya Kitaoka 120a6e
                 (enlargedDim.ly - tile.getRaster()->getSize().ly) / 2};
Shinya Kitaoka 120a6e
  /*- ラスタのクリア -*/
Shinya Kitaoka 120a6e
  tile.getRaster()->clear();
Shinya Kitaoka 120a6e
  TRaster32P outRas32 = (TRaster32P)tile.getRaster();
Shinya Kitaoka 120a6e
  TRaster64P outRas64 = (TRaster64P)tile.getRaster();
shun-iwasawa 481b59
  TRasterFP outRasF   = (TRasterFP)tile.getRaster();
Shinya Kitaoka 120a6e
  if (outRas32)
Shinya Kitaoka 120a6e
    setOutputRaster<traster32p, tpixel32="">(source_host, outRas32, enlargedDim,</traster32p,>
Shinya Kitaoka 120a6e
                                          yohaku);
Shinya Kitaoka 120a6e
  else if (outRas64)
Shinya Kitaoka 120a6e
    setOutputRaster<traster64p, tpixel64="">(source_host, outRas64, enlargedDim,</traster64p,>
Shinya Kitaoka 120a6e
                                          yohaku);
shun-iwasawa 481b59
  else if (outRasF)
shun-iwasawa 481b59
    setOutputRaster<trasterfp, tpixelf="">(source_host, outRasF, enlargedDim,</trasterfp,>
shun-iwasawa 481b59
                                        yohaku);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- ソース画像のメモリ解放 -*/
shun-iwasawa 481b59
  if (source_host_ras) source_host_ras->unlock();
Shinya Kitaoka 120a6e
  /*- 参照画像のメモリ解放 -*/
Shinya Kitaoka 120a6e
  warper_host_ras->unlock();
Shinya Kitaoka 120a6e
  result_host_ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------
Toshihiro Shimizu 890ddd
 Fx計算
Toshihiro Shimizu 890ddd
------------------------------------*/
Toshihiro Shimizu 890ddd
shun-iwasawa 748a28
void Iwa_GradientWarpFx::doCompute_CPU(
shun-iwasawa 748a28
    TTile &tile, const double frame, const TRenderSettings &settings,
shun-iwasawa 748a28
    double hLength, double vLength, int margin, TDimensionI &enlargedDim,
shun-iwasawa 748a28
    float4 *source_host, float *warper_host, float4 *result_host,
shun-iwasawa 748a28
    double sampling_size, double grad_factor) {
shun-iwasawa 748a28
  auto lerp = [](float val0, float val1, double ratio) -> float {
shun-iwasawa 748a28
    return val0 * (1.f - ratio) + val1 * ratio;
shun-iwasawa 748a28
  };
shun-iwasawa 748a28
Shinya Kitaoka 120a6e
  float4 *res_p = result_host + margin * enlargedDim.lx + margin;
Shinya Kitaoka 120a6e
shun-iwasawa 748a28
  if (getFxVersion() == 1) {
shun-iwasawa 748a28
    sampling_size = 1.0;
shun-iwasawa 748a28
    grad_factor   = 1.0;
shun-iwasawa 748a28
  }
shun-iwasawa 748a28
  int size_i   = static_cast<int>(std::floor(sampling_size));</int>
shun-iwasawa 748a28
  double ratio = sampling_size - (double)size_i;
shun-iwasawa 748a28
shun-iwasawa 748a28
  float *warp_up_0 = warper_host + (margin + size_i) * enlargedDim.lx + margin;
shun-iwasawa 748a28
  float *warp_up_1 =
shun-iwasawa 748a28
      warper_host + (margin + size_i + 1) * enlargedDim.lx + margin;
shun-iwasawa 748a28
shun-iwasawa 748a28
  float *warp_down_0 =
shun-iwasawa 748a28
      warper_host + (margin - size_i) * enlargedDim.lx + margin;
shun-iwasawa 748a28
  float *warp_down_1 =
shun-iwasawa 748a28
      warper_host + (margin - size_i - 1) * enlargedDim.lx + margin;
shun-iwasawa 748a28
shun-iwasawa 748a28
  float *warp_right_0 = warper_host + margin * enlargedDim.lx + size_i + margin;
shun-iwasawa 748a28
  float *warp_right_1 =
shun-iwasawa 748a28
      warper_host + margin * enlargedDim.lx + size_i + 1 + margin;
shun-iwasawa 748a28
shun-iwasawa 748a28
  float *warp_left_0 = warper_host + margin * enlargedDim.lx - size_i + margin;
shun-iwasawa 748a28
  float *warp_left_1 =
shun-iwasawa 748a28
      warper_host + margin * enlargedDim.lx - size_i - 1 + margin;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int j = margin; j < enlargedDim.ly - margin; j++) {
shun-iwasawa 748a28
    for (int i = margin; i < enlargedDim.lx - margin; i++, res_p++, warp_up_0++,
shun-iwasawa 748a28
             warp_up_1++, warp_down_0++, warp_down_1++, warp_right_0++,
shun-iwasawa 748a28
             warp_right_1++, warp_left_0++, warp_left_1++) {
Shinya Kitaoka 120a6e
      /*- 勾配を得る -*/
shun-iwasawa 748a28
      float2 grad = {
shun-iwasawa 748a28
          lerp(*warp_right_0 - *warp_left_0, *warp_right_1 - *warp_left_1,
shun-iwasawa 748a28
               ratio),
shun-iwasawa 748a28
          lerp(*warp_up_0 - *warp_down_0, *warp_up_1 - *warp_down_1, ratio)};
shun-iwasawa 748a28
      grad.x *= grad_factor;
shun-iwasawa 748a28
      grad.y *= grad_factor;
Shinya Kitaoka 120a6e
      /*- 参照点 -*/
Shinya Kitaoka 120a6e
      float2 samplePos = {static_cast<float>(i + grad.x * hLength),</float>
Shinya Kitaoka 120a6e
                          static_cast<float>(j + grad.y * vLength)};</float>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      int2 index = {
Shinya Kitaoka 120a6e
          (int)(samplePos.x + (float)enlargedDim.lx) - enlargedDim.lx,
Shinya Kitaoka 120a6e
          (int)(samplePos.y + (float)enlargedDim.ly) - enlargedDim.ly};
Shinya Kitaoka 120a6e
      float2 ratio = {samplePos.x - (float)index.x,
Shinya Kitaoka 120a6e
                      samplePos.y - (float)index.y};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- サンプリング点回りのピクセルを線形補間 -*/
Shinya Kitaoka 120a6e
      float4 col1 = interp_CPU(
Shinya Kitaoka 120a6e
          getSourceVal_CPU(source_host, enlargedDim, index.x, index.y),
Shinya Kitaoka 120a6e
          getSourceVal_CPU(source_host, enlargedDim, index.x + 1, index.y),
Shinya Kitaoka 120a6e
          ratio.x);
Shinya Kitaoka 120a6e
      float4 col2 = interp_CPU(
Shinya Kitaoka 120a6e
          getSourceVal_CPU(source_host, enlargedDim, index.x, index.y + 1),
Shinya Kitaoka 120a6e
          getSourceVal_CPU(source_host, enlargedDim, index.x + 1, index.y + 1),
Shinya Kitaoka 120a6e
          ratio.x);
Shinya Kitaoka 120a6e
      *res_p = interp_CPU(col1, col2, ratio.y);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    res_p += 2 * margin;
shun-iwasawa 748a28
    warp_up_0 += 2 * margin;
shun-iwasawa 748a28
    warp_up_1 += 2 * margin;
shun-iwasawa 748a28
    warp_down_0 += 2 * margin;
shun-iwasawa 748a28
    warp_down_1 += 2 * margin;
shun-iwasawa 748a28
    warp_right_0 += 2 * margin;
shun-iwasawa 748a28
    warp_right_1 += 2 * margin;
shun-iwasawa 748a28
    warp_left_0 += 2 * margin;
shun-iwasawa 748a28
    warp_left_1 += 2 * margin;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
float4 Iwa_GradientWarpFx::getSourceVal_CPU(float4 *source_host,
Shinya Kitaoka 120a6e
                                            TDimensionI &enlargedDim, int pos_x,
Shinya Kitaoka 120a6e
                                            int pos_y) {
Shinya Kitaoka 120a6e
  if (pos_x < 0 || pos_x >= enlargedDim.lx || pos_y < 0 ||
Shinya Kitaoka 120a6e
      pos_y >= enlargedDim.ly)
Shinya Kitaoka 120a6e
    return float4{0.0f, 0.0f, 0.0f, 0.0f};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return source_host[pos_y * enlargedDim.lx + pos_x];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
float4 Iwa_GradientWarpFx::interp_CPU(float4 val1, float4 val2, float ratio) {
Shinya Kitaoka 120a6e
  return float4{(1.0f - ratio) * val1.x + ratio * val2.x,
Shinya Kitaoka 120a6e
                (1.0f - ratio) * val1.y + ratio * val2.y,
Shinya Kitaoka 120a6e
                (1.0f - ratio) * val1.z + ratio * val2.z,
Shinya Kitaoka 120a6e
                (1.0f - ratio) * val1.w + ratio * val2.w};
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Iwa_GradientWarpFx::doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 120a6e
                                   const TRenderSettings &info) {
Shinya Kitaoka 120a6e
  if (!m_source.isConnected()) {
Shinya Kitaoka 120a6e
    bBox = TRectD();
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const bool ret = m_source->doGetBBox(frame, bBox, info);
Shinya Kitaoka 120a6e
  get_render_enlarge(frame, info.m_affine, bBox);
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Iwa_GradientWarpFx::canHandle(const TRenderSettings &info, double frame) {
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_GradientWarpFx::get_render_real_hv(const double frame,
Shinya Kitaoka 120a6e
                                            const TAffine affine,
Shinya Kitaoka 120a6e
                                            double &h_maxlen,
Shinya Kitaoka 120a6e
                                            double &v_maxlen) {
Shinya Kitaoka 120a6e
  /*--- ベクトルにする(プラス値) --- */
Shinya Kitaoka 120a6e
  TPointD rend_vect;
Rozhuk Ivan 823a31
  rend_vect.x = std::abs(m_h_maxlen->getValue(frame));
Rozhuk Ivan 823a31
  rend_vect.y = std::abs(m_v_maxlen->getValue(frame));
Shinya Kitaoka 120a6e
  /*--- 拡大縮小(移動回転しないで)のGeometryを反映させる ---*/
Shinya Kitaoka 120a6e
  rend_vect = rend_vect * sqrt(fabs(affine.det()));
Shinya Kitaoka 120a6e
  /*--- 方向は無視して長さを返す(プラス値) ---*/
Shinya Kitaoka 120a6e
  h_maxlen = rend_vect.x;
Shinya Kitaoka 120a6e
  v_maxlen = rend_vect.y;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_GradientWarpFx::get_render_enlarge(const double frame,
Shinya Kitaoka 120a6e
                                            const TAffine affine,
Shinya Kitaoka 120a6e
                                            TRectD &bBox) {
Shinya Kitaoka 120a6e
  double h_maxlen = 0.0;
Shinya Kitaoka 120a6e
  double v_maxlen = 0.0;
Shinya Kitaoka 120a6e
  this->get_render_real_hv(frame, affine, h_maxlen, v_maxlen);
Shinya Kitaoka 120a6e
  const int margin =
Shinya Kitaoka 120a6e
      static_cast<int>(ceil((h_maxlen < v_maxlen) ? v_maxlen : h_maxlen));</int>
Shinya Kitaoka 120a6e
  if (0 < margin) {
Shinya Kitaoka 120a6e
    bBox = bBox.enlarge(static_cast<double>(margin));</double>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(Iwa_GradientWarpFx, "iwa_GradientWarpFx")