Toshihiro Shimizu 890ddd
/*------------------------------------
Toshihiro Shimizu 890ddd
Iwa_MotionBlurCompFx
Toshihiro Shimizu 890ddd
露光量/オブジェクトの軌跡を考慮したモーションブラー
Toshihiro Shimizu 890ddd
背景との露光値合成を可能にする
Toshihiro Shimizu 890ddd
//------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "iwa_motionblurfx.h"
Toshihiro Shimizu 890ddd
#include "tfxattributes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- ソース画像を0〜1に正規化してホストメモリに読み込む
Shinya Kitaoka 120a6e
        ソース画像がPremultipyされているか、コンボボックスで指定されていない場合は
Shinya Kitaoka 120a6e
        ここで判定する -*/
Toshihiro Shimizu 890ddd
template <typename pixel="" raster,="" typename=""></typename>
Shinya Kitaoka 120a6e
bool Iwa_MotionBlurCompFx::setSourceRaster(const RASTER srcRas, float4 *dstMem,
Shinya Kitaoka 120a6e
                                           TDimensionI dim,
Shinya Kitaoka 120a6e
                                           PremultiTypes type) {
Shinya Kitaoka 120a6e
  bool isPremultiplied = (type == SOURCE_IS_NOT_PREMUTIPLIED) ? false : true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float4 *chann_p = dstMem;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float threshold = 100.0 / (float)TPixel64::maxChannelValue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int max = 0;
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++) {
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
      /*- RGB値がアルファチャンネルより大きいピクセルがあれば、
Shinya Kitaoka 120a6e
              Premutiplyされていないと判断する -*/
Shinya Kitaoka 120a6e
      if (type == AUTO && isPremultiplied &&
Shinya Kitaoka 120a6e
          (((*chann_p).x > (*chann_p).w && (*chann_p).x > threshold) ||
Shinya Kitaoka 120a6e
           ((*chann_p).y > (*chann_p).w && (*chann_p).y > threshold) ||
Shinya Kitaoka 120a6e
           ((*chann_p).z > (*chann_p).w && (*chann_p).z > threshold)))
Shinya Kitaoka 120a6e
        isPremultiplied = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      pix++;
Shinya Kitaoka 120a6e
      chann_p++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (isPremultiplied) {
Shinya Kitaoka 120a6e
    chann_p = dstMem;
Shinya Kitaoka 120a6e
    for (int i = 0; i < dim.lx * dim.ly; i++, chann_p++) {
Shinya Kitaoka 120a6e
      if ((*chann_p).x > (*chann_p).w) (*chann_p).x = (*chann_p).w;
Shinya Kitaoka 120a6e
      if ((*chann_p).y > (*chann_p).w) (*chann_p).y = (*chann_p).w;
Shinya Kitaoka 120a6e
      if ((*chann_p).z > (*chann_p).w) (*chann_p).z = (*chann_p).w;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return isPremultiplied;
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_MotionBlurCompFx::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++) {
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
      pix++;
Shinya Kitaoka 120a6e
      chan_p++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 フィルタをつくり、正規化する
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_MotionBlurCompFx::makeMotionBlurFilter_CPU(
Shinya Kitaoka 120a6e
    float *filter_p, TDimensionI &filterDim, int marginLeft, int marginBottom,
Shinya Kitaoka 120a6e
    float4 *pointsTable, int pointAmount, float startValue, float startCurve,
Shinya Kitaoka 120a6e
    float endValue, float endCurve) {
Shinya Kitaoka 120a6e
  /*- フィルタ値を足しこむための変数 -*/
Shinya Kitaoka 120a6e
  float fil_val_sum = 0.0f;
Shinya Kitaoka 120a6e
  /*- for文の中で回す、現在のフィルタ座標 -*/
Shinya Kitaoka 120a6e
  float *current_fil_p = filter_p;
Shinya Kitaoka 120a6e
  /*- 各フィルタの座標について -*/
Shinya Kitaoka 120a6e
  for (int fily = 0; fily < filterDim.ly; fily++) {
Shinya Kitaoka 120a6e
    for (int filx = 0; filx < filterDim.lx; filx++, current_fil_p++) {
Shinya Kitaoka 120a6e
      /*- フィルタ座標を得る -*/
Shinya Kitaoka 120a6e
      float2 pos = {static_cast<float>(filx - marginLeft),</float>
Shinya Kitaoka 120a6e
                    static_cast<float>(fily - marginBottom)};</float>
Shinya Kitaoka 120a6e
      /*- 更新してゆく値 -*/
Shinya Kitaoka 120a6e
      float nearestDist2         = 100.0f;
Shinya Kitaoka 120a6e
      int nearestIndex           = -1;
Shinya Kitaoka 120a6e
      float nearestFramePosRatio = 0.0f;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- 各サンプル点のペアについて、一番近い点を探す -*/
Shinya Kitaoka 120a6e
      for (int v = 0; v < pointAmount - 1; v++) {
Shinya Kitaoka 120a6e
        float4 p0 = pointsTable[v];
Shinya Kitaoka 120a6e
        float4 p1 = pointsTable[v + 1];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        /*- 範囲内に無ければcontinue -*/
Shinya Kitaoka 120a6e
        if (pos.x < std::min(p0.x, p1.x) - 1.0f ||
Shinya Kitaoka 120a6e
            pos.x > std::max(p0.x, p1.x) + 1.0f ||
Shinya Kitaoka 120a6e
            pos.y < std::min(p0.y, p1.y) - 1.0f ||
Shinya Kitaoka 120a6e
            pos.y > std::max(p0.y, p1.y) + 1.0f)
Shinya Kitaoka 120a6e
          continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        /*- 範囲内にあるので、線分と点の距離を得る -*/
Shinya Kitaoka 120a6e
        /*- P0->サンプル点とP0->P1の内積を求める -*/
Shinya Kitaoka 120a6e
        float2 vec_p0_sample = {static_cast<float>(pos.x - p0.x),</float>
Shinya Kitaoka 120a6e
                                static_cast<float>(pos.y - p0.y)};</float>
Shinya Kitaoka 120a6e
        float2 vec_p0_p1 = {static_cast<float>(p1.x - p0.x),</float>
Shinya Kitaoka 120a6e
                            static_cast<float>(p1.y - p0.y)};</float>
Shinya Kitaoka 120a6e
        float dot =
Shinya Kitaoka 120a6e
            vec_p0_sample.x * vec_p0_p1.x + vec_p0_sample.y * vec_p0_p1.y;
Shinya Kitaoka 120a6e
        /*- 距離の2乗を求める -*/
Shinya Kitaoka 120a6e
        float dist2;
Shinya Kitaoka 120a6e
        float framePosRatio;
Shinya Kitaoka 120a6e
        /*- P0より手前にある場合 -*/
Shinya Kitaoka 120a6e
        if (dot <= 0.0f) {
Shinya Kitaoka 120a6e
          dist2 = vec_p0_sample.x * vec_p0_sample.x +
Shinya Kitaoka 120a6e
                  vec_p0_sample.y * vec_p0_sample.y;
Shinya Kitaoka 120a6e
          framePosRatio = 0.0f;
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          /*- 軌跡ベクトルの長さの2乗を計算する -*/
Shinya Kitaoka 120a6e
          float length2 = p0.z * p0.z;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          /*-  P0〜P1間にある場合
Shinya Kitaoka 120a6e
                   pでの軌跡が点のとき、length2は0になるので、この条件の中に入ることはない。
Shinya Kitaoka 120a6e
                   ので、ZeroDivideになる心配はないはず。 -*/
Shinya Kitaoka 120a6e
          if (dot < length2) {
Shinya Kitaoka 120a6e
            float p0_sample_dist2 = vec_p0_sample.x * vec_p0_sample.x +
Shinya Kitaoka 120a6e
                                    vec_p0_sample.y * vec_p0_sample.y;
Shinya Kitaoka 120a6e
            dist2         = p0_sample_dist2 - dot * dot / length2;
Shinya Kitaoka 120a6e
            framePosRatio = dot / length2;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          /*- P1より先にある場合 -*/
Shinya Kitaoka 120a6e
          else {
Shinya Kitaoka 120a6e
            float2 vec_p1_sample = {pos.x - p1.x, pos.y - p1.y};
Shinya Kitaoka 120a6e
            dist2                = vec_p1_sample.x * vec_p1_sample.x +
Shinya Kitaoka 120a6e
                    vec_p1_sample.y * vec_p1_sample.y;
Shinya Kitaoka 120a6e
            framePosRatio = 1.0f;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        /*- 距離が(√2 + 1)/2より遠かったらcontinue
Shinya Kitaoka 120a6e
         * dist2との比較だから2乗している -*/
Shinya Kitaoka 120a6e
        if (dist2 > 1.4571f) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        /*- 距離がより近かったら更新する -*/
Shinya Kitaoka 120a6e
        if (dist2 < nearestDist2) {
Shinya Kitaoka 120a6e
          nearestDist2         = dist2;
Shinya Kitaoka 120a6e
          nearestIndex         = v;
Shinya Kitaoka 120a6e
          nearestFramePosRatio = framePosRatio;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*-
Shinya Kitaoka 120a6e
       * 現在のピクセルの、近傍ベクトルが見つからなかった場合、フィルタ値は0でreturn
Shinya Kitaoka 120a6e
       * -*/
Shinya Kitaoka 120a6e
      if (nearestIndex == -1) {
Shinya Kitaoka 120a6e
        *current_fil_p = 0.0f;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*-
Shinya Kitaoka 120a6e
         現在のピクセルのサブピクセル(16*16)が、近傍ベクトルからの距離0.5の範囲にどれだけ
Shinya Kitaoka 120a6e
              含まれているかをカウントする。 -*/
Shinya Kitaoka 120a6e
      int count  = 0;
Shinya Kitaoka 120a6e
      float4 np0 = pointsTable[nearestIndex];
Shinya Kitaoka 120a6e
      float4 np1 = pointsTable[nearestIndex + 1];
Shinya Kitaoka 120a6e
      for (int yy = 0; yy < 16; yy++) {
Shinya Kitaoka 120a6e
        /*- サブピクセルのY座標 -*/
Shinya Kitaoka 120a6e
        float subPosY = pos.y + ((float)yy - 7.5f) / 16.0f;
Shinya Kitaoka 120a6e
        for (int xx = 0; xx < 16; xx++) {
Shinya Kitaoka 120a6e
          /*- サブピクセルのX座標 -*/
Shinya Kitaoka 120a6e
          float subPosX = pos.x + ((float)xx - 7.5f) / 16.0f;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          float2 vec_np0_sub = {subPosX - np0.x, subPosY - np0.y};
Shinya Kitaoka 120a6e
          float2 vec_np0_np1 = {np1.x - np0.x, np1.y - np0.y};
Shinya Kitaoka 120a6e
          float dot =
Shinya Kitaoka 120a6e
              vec_np0_sub.x * vec_np0_np1.x + vec_np0_sub.y * vec_np0_np1.y;
Shinya Kitaoka 120a6e
          /*- 距離の2乗を求める -*/
Shinya Kitaoka 120a6e
          float dist2;
Shinya Kitaoka 120a6e
          /*- P0より手前にある場合 -*/
Shinya Kitaoka 120a6e
          if (dot <= 0.0f)
Shinya Kitaoka 120a6e
            dist2 =
Shinya Kitaoka 120a6e
                vec_np0_sub.x * vec_np0_sub.x + vec_np0_sub.y * vec_np0_sub.y;
Shinya Kitaoka 120a6e
          else {
Shinya Kitaoka 120a6e
            /*- 軌跡ベクトルの長さの2乗を計算する -*/
Shinya Kitaoka 120a6e
            float length2 = np0.z * np0.z;
Shinya Kitaoka 120a6e
            /*-  P0〜P1間にある場合 -*/
Shinya Kitaoka 120a6e
            if (dot < length2) {
Shinya Kitaoka 120a6e
              float np0_sub_dist2 =
Shinya Kitaoka 120a6e
                  vec_np0_sub.x * vec_np0_sub.x + vec_np0_sub.y * vec_np0_sub.y;
Shinya Kitaoka 120a6e
              dist2 = np0_sub_dist2 - dot * dot / length2;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
            /*-  P1より先にある場合 -*/
Shinya Kitaoka 120a6e
            else {
Shinya Kitaoka 120a6e
              float2 vec_np1_sub = {subPosX - np1.x, subPosY - np1.y};
Shinya Kitaoka 120a6e
              dist2 =
Shinya Kitaoka 120a6e
                  vec_np1_sub.x * vec_np1_sub.x + vec_np1_sub.y * vec_np1_sub.y;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          /*- 距離の2乗が0.25より近ければカウントをインクリメント -*/
Shinya Kitaoka 120a6e
          if (dist2 <= 0.25f) count++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /*- 保険 カウントが0の場合はフィールド値0でreturn -*/
Shinya Kitaoka 120a6e
      if (count == 0) {
Shinya Kitaoka 120a6e
        *current_fil_p = 0.0f;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- countは Max256 -*/
Shinya Kitaoka 120a6e
      float countRatio = (float)count / 256.0f;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- フィルタ値の明るさは、ベクトルが作る幅1の線の面積に反比例する。
Shinya Kitaoka 120a6e
              ベクトルの前後には半径0.5の半円のキャップがあるので、長さ0のベクトルでも
Shinya Kitaoka 120a6e
              0-divideになることはない。-*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- 近傍ベクトル、幅1のときの面積 -*/
Shinya Kitaoka 120a6e
      float vecMenseki = 0.25f * 3.14159265f + np0.z;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      //-----------------
Shinya Kitaoka 120a6e
      /*- 続いて、ガンマ強弱の値を得る -*/
Shinya Kitaoka 120a6e
      /*- 近傍点のフレームのオフセット値 -*/
Shinya Kitaoka 120a6e
      float curveValue;
Shinya Kitaoka 120a6e
      float frameOffset =
Shinya Kitaoka 120a6e
          np0.w * (1.0f - nearestFramePosRatio) + np1.w * nearestFramePosRatio;
Shinya Kitaoka 120a6e
      /*- フレームがちょうどフレーム原点、又は減衰値が無い場合はcurveValue = 1
Shinya Kitaoka 120a6e
       * -*/
Shinya Kitaoka 120a6e
      if (frameOffset == 0.0f || (frameOffset < 0.0f && startValue == 1.0f) ||
Shinya Kitaoka 120a6e
          (frameOffset > 0.0f && endValue == 1.0f))
Shinya Kitaoka 120a6e
        curveValue = 1.0f;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        /*- オフセットの正負によって変える -*/
Shinya Kitaoka 120a6e
        float value, curve, ratio;
Shinya Kitaoka 120a6e
        if (frameOffset < 0.0f) /*- start側 -*/
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          value = startValue;
Shinya Kitaoka 120a6e
          curve = startCurve;
Shinya Kitaoka 120a6e
          ratio = 1.0f - (frameOffset / pointsTable[0].w);
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          value = endValue;
Shinya Kitaoka 120a6e
          curve = endCurve;
Shinya Kitaoka 120a6e
          ratio = 1.0f - (frameOffset / pointsTable[pointAmount - 1].w);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        curveValue = value + (1.0f - value) * powf(ratio, 1.0f / curve);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      //-----------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- フィールド値の格納 -*/
Shinya Kitaoka 120a6e
      *current_fil_p = curveValue * countRatio / vecMenseki;
Shinya Kitaoka 120a6e
      fil_val_sum += *current_fil_p;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 正規化 -*/
Shinya Kitaoka 120a6e
  current_fil_p = filter_p;
Shinya Kitaoka 120a6e
  for (int f = 0; f < filterDim.lx * filterDim.ly; f++, current_fil_p++) {
Shinya Kitaoka 120a6e
    *current_fil_p /= fil_val_sum;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 残像フィルタをつくり、正規化する
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_MotionBlurCompFx::makeZanzoFilter_CPU(
Shinya Kitaoka 120a6e
    float *filter_p, TDimensionI &filterDim, int marginLeft, int marginBottom,
Shinya Kitaoka 120a6e
    float4 *pointsTable, int pointAmount, float startValue, float startCurve,
Shinya Kitaoka 120a6e
    float endValue, float endCurve) {
Shinya Kitaoka 120a6e
  /*-フィルタ値足しこむための変数-*/
Shinya Kitaoka 120a6e
  float fil_val_sum = 0.0f;
Shinya Kitaoka 120a6e
  /*- for文の中で回す、現在のフィルタ座標 -*/
Shinya Kitaoka 120a6e
  float *current_fil_p = filter_p;
Shinya Kitaoka 120a6e
  /*- 各フィルタの座標について -*/
Shinya Kitaoka 120a6e
  for (int fily = 0; fily < filterDim.ly; fily++) {
Shinya Kitaoka 120a6e
    for (int filx = 0; filx < filterDim.lx; filx++, current_fil_p++) {
Shinya Kitaoka 120a6e
      /*- フィルタ座標を得る -*/
Shinya Kitaoka 120a6e
      float2 pos = {(float)(filx - marginLeft), (float)(fily - marginBottom)};
Shinya Kitaoka 120a6e
      /*- これから積算する変数 -*/
Shinya Kitaoka 120a6e
      float filter_sum = 0.0f;
Shinya Kitaoka 120a6e
      /*- 各サンプル点について距離を測り、濃度を積算していく -*/
Shinya Kitaoka 120a6e
      for (int v = 0; v < pointAmount; v++) {
Shinya Kitaoka 120a6e
        float4 p0 = pointsTable[v];
Shinya Kitaoka 120a6e
        /*- p0の座標を中心として、距離 1 以内に無ければcontinue -*/
Shinya Kitaoka 120a6e
        if (pos.x < p0.x - 1.0f || pos.x > p0.x + 1.0f || pos.y < p0.y - 1.0f ||
Shinya Kitaoka 120a6e
            pos.y > p0.y + 1.0f)
Shinya Kitaoka 120a6e
          continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        /*- 近傍4ピクセルで線形補間する -*/
Shinya Kitaoka 120a6e
        float xRatio = 1.0f - abs(pos.x - p0.x);
Shinya Kitaoka 120a6e
        float yRatio = 1.0f - abs(pos.y - p0.y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        /*- 続いて、ガンマ強弱の値を得る -*/
Shinya Kitaoka 120a6e
        /*- 近傍点のフレームのオフセット値 -*/
Shinya Kitaoka 120a6e
        float curveValue;
Shinya Kitaoka 120a6e
        float frameOffset = p0.w;
Shinya Kitaoka 120a6e
        /*- フレームがちょうどフレーム原点、又は減衰値が無い場合はcurveValue = 1
Shinya Kitaoka 120a6e
         * -*/
Shinya Kitaoka 120a6e
        if (frameOffset == 0.0f || (frameOffset < 0.0f && startValue == 1.0f) ||
Shinya Kitaoka 120a6e
            (frameOffset > 0.0f && endValue == 1.0f))
Shinya Kitaoka 120a6e
          curveValue = 1.0f;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          /*- オフセットの正負によって変える -*/
Shinya Kitaoka 120a6e
          float value, curve, ratio;
Shinya Kitaoka 120a6e
          if (frameOffset < 0.0f) /*- start側 -*/
Shinya Kitaoka 120a6e
          {
Shinya Kitaoka 120a6e
            value = startValue;
Shinya Kitaoka 120a6e
            curve = startCurve;
Shinya Kitaoka 120a6e
            ratio = 1.0f - (frameOffset / pointsTable[0].w);
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            value = endValue;
Shinya Kitaoka 120a6e
            curve = endCurve;
Shinya Kitaoka 120a6e
            ratio = 1.0f - (frameOffset / pointsTable[pointAmount - 1].w);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          curveValue = value + (1.0f - value) * powf(ratio, 1.0f / curve);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        //-----------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        /*- フィルタ値積算 -*/
Shinya Kitaoka 120a6e
        filter_sum += xRatio * yRatio * curveValue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- 値を格納 -*/
Shinya Kitaoka 120a6e
      *current_fil_p = filter_sum;
Shinya Kitaoka 120a6e
      fil_val_sum += *current_fil_p;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 正規化 -*/
Shinya Kitaoka 120a6e
  current_fil_p = filter_p;
Shinya Kitaoka 120a6e
  for (int f = 0; f < filterDim.lx * filterDim.ly; f++, current_fil_p++) {
Shinya Kitaoka 120a6e
    *current_fil_p /= fil_val_sum;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 露光値をdepremultipy→RGB値(0〜1)に戻す→premultiply
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_MotionBlurCompFx::convertRGBtoExposure_CPU(
Shinya Kitaoka 120a6e
    float4 *in_tile_p, TDimensionI &dim, float hardness,
Shinya Kitaoka 120a6e
    bool sourceIsPremultiplied) {
Shinya Kitaoka 120a6e
  float4 *cur_tile_p = in_tile_p;
Shinya Kitaoka 120a6e
  for (int i = 0; i < dim.lx * dim.ly; i++, cur_tile_p++) {
Shinya Kitaoka 120a6e
    /*- アルファが0ならreturn -*/
Shinya Kitaoka 120a6e
    if (cur_tile_p->w == 0.0f) {
Shinya Kitaoka 120a6e
      cur_tile_p->x = 0.0f;
Shinya Kitaoka 120a6e
      cur_tile_p->y = 0.0f;
Shinya Kitaoka 120a6e
      cur_tile_p->z = 0.0f;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- 通常のLevelなど、Premultiplyされている素材に対し、depremultiplyを行う
Shinya Kitaoka 120a6e
            DigiBookなどには行わない -*/
Shinya Kitaoka 120a6e
    if (sourceIsPremultiplied) {
Shinya Kitaoka 120a6e
      /*- depremultiply -*/
Shinya Kitaoka 120a6e
      cur_tile_p->x /= cur_tile_p->w;
Shinya Kitaoka 120a6e
      cur_tile_p->y /= cur_tile_p->w;
Shinya Kitaoka 120a6e
      cur_tile_p->z /= cur_tile_p->w;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- RGBはExposureにする -*/
Shinya Kitaoka 120a6e
    cur_tile_p->x = powf(10, (cur_tile_p->x - 0.5f) * hardness);
Shinya Kitaoka 120a6e
    cur_tile_p->y = powf(10, (cur_tile_p->y - 0.5f) * hardness);
Shinya Kitaoka 120a6e
    cur_tile_p->z = powf(10, (cur_tile_p->z - 0.5f) * hardness);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- その後、アルファチャンネルでmultiply -*/
Shinya Kitaoka 120a6e
    cur_tile_p->x *= cur_tile_p->w;
Shinya Kitaoka 120a6e
    cur_tile_p->y *= cur_tile_p->w;
Shinya Kitaoka 120a6e
    cur_tile_p->z *= cur_tile_p->w;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 露光値をフィルタリングしてぼかす
Toshihiro Shimizu 890ddd
 outDim の範囲だけループで回す
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_MotionBlurCompFx::applyBlurFilter_CPU(
Shinya Kitaoka 120a6e
    float4 *in_tile_p, float4 *out_tile_p, TDimensionI &enlargedDim,
Shinya Kitaoka 120a6e
    float *filter_p, TDimensionI &filterDim, int marginLeft, int marginBottom,
Shinya Kitaoka 120a6e
    int marginRight, int marginTop, TDimensionI &outDim) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < outDim.lx * outDim.ly; i++) {
Shinya Kitaoka 120a6e
    /*- in_tile_devとout_tile_devはlx * ly の寸法でデータが入っている。
Shinya Kitaoka 120a6e
            ので、i を出力用の座標に変換する -*/
Shinya Kitaoka 120a6e
    int2 outPos  = {i % outDim.lx + marginRight, i / outDim.lx + marginTop};
Shinya Kitaoka 120a6e
    int outIndex = outPos.y * enlargedDim.lx + outPos.x;
Shinya Kitaoka 120a6e
    /*- out_tile_dev[outIndex]に結果をおさめていく -*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- 値を積算する入れ物を用意 -*/
Shinya Kitaoka 120a6e
    float4 value = {0.0f, 0.0f, 0.0f, 0.0f};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- フィルタのサイズでループ
Shinya Kitaoka 120a6e
       ただし、フィルタはサンプル点の画像を収集するように
Shinya Kitaoka 120a6e
            用いるため、上下左右反転してサンプルする -*/
Shinya Kitaoka 120a6e
    int filterIndex = 0;
Shinya Kitaoka 120a6e
    for (int fily = -marginBottom; fily < filterDim.ly - marginBottom; fily++) {
Shinya Kitaoka 120a6e
      /*- サンプル座標 と インデックス の このスキャンラインのうしろ -*/
Shinya Kitaoka 120a6e
      int2 samplePos  = {outPos.x + marginLeft, outPos.y - fily};
Shinya Kitaoka 120a6e
      int sampleIndex = samplePos.y * enlargedDim.lx + samplePos.x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (int filx = -marginLeft; filx < filterDim.lx - marginLeft;
Shinya Kitaoka 120a6e
           filx++, filterIndex++, sampleIndex--) {
Shinya Kitaoka 120a6e
        /*- フィルター値が0またはサンプルピクセルが透明ならcontinue -*/
Shinya Kitaoka 120a6e
        if (filter_p[filterIndex] == 0.0f || in_tile_p[sampleIndex].w == 0.0f)
Shinya Kitaoka 120a6e
          continue;
Shinya Kitaoka 120a6e
        /*- サンプル点の値にフィルタ値を掛けて積算する -*/
Shinya Kitaoka 120a6e
        value.x += in_tile_p[sampleIndex].x * filter_p[filterIndex];
Shinya Kitaoka 120a6e
        value.y += in_tile_p[sampleIndex].y * filter_p[filterIndex];
Shinya Kitaoka 120a6e
        value.z += in_tile_p[sampleIndex].z * filter_p[filterIndex];
Shinya Kitaoka 120a6e
        value.w += in_tile_p[sampleIndex].w * filter_p[filterIndex];
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    out_tile_p[outIndex].x = value.x;
Shinya Kitaoka 120a6e
    out_tile_p[outIndex].y = value.y;
Shinya Kitaoka 120a6e
    out_tile_p[outIndex].z = value.z;
Shinya Kitaoka 120a6e
    out_tile_p[outIndex].w = value.w;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 露光値をdepremultipy→RGB値(0〜1)に戻す→premultiply
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_MotionBlurCompFx::convertExposureToRGB_CPU(float4 *out_tile_p,
Shinya Kitaoka 120a6e
                                                    TDimensionI &dim,
Shinya Kitaoka 120a6e
                                                    float hardness) {
Shinya Kitaoka 120a6e
  float4 *cur_tile_p = out_tile_p;
Shinya Kitaoka 120a6e
  for (int i = 0; i < dim.lx * dim.ly; i++, cur_tile_p++) {
Shinya Kitaoka 120a6e
    /*- アルファが0ならreturn -*/
Shinya Kitaoka 120a6e
    if (cur_tile_p->w == 0.0f) {
Shinya Kitaoka 120a6e
      cur_tile_p->x = 0.0f;
Shinya Kitaoka 120a6e
      cur_tile_p->y = 0.0f;
Shinya Kitaoka 120a6e
      cur_tile_p->z = 0.0f;
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // depremultiply
Shinya Kitaoka 120a6e
    cur_tile_p->x /= cur_tile_p->w;
Shinya Kitaoka 120a6e
    cur_tile_p->y /= cur_tile_p->w;
Shinya Kitaoka 120a6e
    cur_tile_p->z /= cur_tile_p->w;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- ExposureをRGB値にする -*/
Shinya Kitaoka 120a6e
    cur_tile_p->x = log10f(cur_tile_p->x) / hardness + 0.5f;
Shinya Kitaoka 120a6e
    cur_tile_p->y = log10f(cur_tile_p->y) / hardness + 0.5f;
Shinya Kitaoka 120a6e
    cur_tile_p->z = log10f(cur_tile_p->z) / hardness + 0.5f;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // multiply
Shinya Kitaoka 120a6e
    cur_tile_p->x *= cur_tile_p->w;
Shinya Kitaoka 120a6e
    cur_tile_p->y *= cur_tile_p->w;
Shinya Kitaoka 120a6e
    cur_tile_p->z *= cur_tile_p->w;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- クランプ -*/
Shinya Kitaoka 120a6e
    cur_tile_p->x = (cur_tile_p->x > 1.0f)
Shinya Kitaoka 120a6e
                        ? 1.0f
Shinya Kitaoka 120a6e
                        : ((cur_tile_p->x < 0.0f) ? 0.0f : cur_tile_p->x);
Shinya Kitaoka 120a6e
    cur_tile_p->y = (cur_tile_p->y > 1.0f)
Shinya Kitaoka 120a6e
                        ? 1.0f
Shinya Kitaoka 120a6e
                        : ((cur_tile_p->y < 0.0f) ? 0.0f : cur_tile_p->y);
Shinya Kitaoka 120a6e
    cur_tile_p->z = (cur_tile_p->z > 1.0f)
Shinya Kitaoka 120a6e
                        ? 1.0f
Shinya Kitaoka 120a6e
                        : ((cur_tile_p->z < 0.0f) ? 0.0f : cur_tile_p->z);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 背景があり、前景が動かない場合、単純にOverする
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Shinya Kitaoka 120a6e
void Iwa_MotionBlurCompFx::composeWithNoMotion(
Shinya Kitaoka 120a6e
    TTile &tile, double frame, const TRenderSettings &settings) {
Shinya Kitaoka 120a6e
  assert(m_background.isConnected());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_background->compute(tile, frame, settings);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TTile fore_tile;
Shinya Kitaoka 120a6e
  m_input->allocateAndCompute(fore_tile, tile.m_pos,
Shinya Kitaoka 120a6e
                              tile.getRaster()->getSize(), tile.getRaster(),
Shinya Kitaoka 120a6e
                              frame, settings);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterP up(fore_tile.getRaster()), down(tile.getRaster());
Shinya Kitaoka 120a6e
  TRop::over(down, up);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 背景を露光値にして通常合成
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Shinya Kitaoka 120a6e
void Iwa_MotionBlurCompFx::composeBackgroundExposure_CPU(
Shinya Kitaoka 120a6e
    float4 *out_tile_p, TDimensionI &enlargedDimIn, int marginRight,
Shinya Kitaoka 120a6e
    int marginTop, TTile &back_tile, TDimensionI &dimOut, float hardness) {
Shinya Kitaoka 120a6e
  /*- ホストのメモリ確保 -*/
Shinya Kitaoka 120a6e
  TRasterGR8P background_host_ras(sizeof(float4) * dimOut.lx, dimOut.ly);
Shinya Kitaoka 120a6e
  background_host_ras->lock();
Shinya Kitaoka 120a6e
  float4 *background_host = (float4 *)background_host_ras->getRawData();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool bgIsPremultiplied;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 背景画像を0〜1に正規化してホストメモリに読み込む -*/
Shinya Kitaoka 120a6e
  TRaster32P backRas32 = (TRaster32P)back_tile.getRaster();
Shinya Kitaoka 120a6e
  TRaster64P backRas64 = (TRaster64P)back_tile.getRaster();
Shinya Kitaoka 120a6e
  if (backRas32)
Shinya Kitaoka 120a6e
    bgIsPremultiplied = setSourceRaster<traster32p, tpixel32="">(</traster32p,>
Shinya Kitaoka 120a6e
        backRas32, background_host, dimOut);
Shinya Kitaoka 120a6e
  else if (backRas64)
Shinya Kitaoka 120a6e
    bgIsPremultiplied = setSourceRaster<traster64p, tpixel64="">(</traster64p,>
Shinya Kitaoka 120a6e
        backRas64, background_host, dimOut);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float4 *bg_p = background_host;
Shinya Kitaoka 120a6e
  float4 *out_p;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int j = 0; j < dimOut.ly; j++) {
Shinya Kitaoka 120a6e
    out_p = out_tile_p + ((marginTop + j) * enlargedDimIn.lx + marginRight);
Shinya Kitaoka 120a6e
    for (int i = 0; i < dimOut.lx; i++, bg_p++, out_p++) {
Shinya Kitaoka 120a6e
      /*- 上レイヤが完全に不透明ならcontinue -*/
Shinya Kitaoka 120a6e
      if ((*out_p).w >= 1.0f) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- 下レイヤが完全に透明でもcontinue -*/
Shinya Kitaoka 120a6e
      if ((*bg_p).w < 0.0001f) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      float3 bgExposure = {(*bg_p).x, (*bg_p).y, (*bg_p).z};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- 通常のLevelなど、Premultiplyされている素材に対し、depremultiplyを行う
Shinya Kitaoka 120a6e
              DigiBookなどには行わない -*/
Shinya Kitaoka 120a6e
      if (bgIsPremultiplied) {
Shinya Kitaoka 120a6e
        // demultiply
Shinya Kitaoka 120a6e
        bgExposure.x /= (*bg_p).w;
Shinya Kitaoka 120a6e
        bgExposure.y /= (*bg_p).w;
Shinya Kitaoka 120a6e
        bgExposure.z /= (*bg_p).w;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- ExposureをRGB値にする -*/
Shinya Kitaoka 120a6e
      bgExposure.x = powf(10, (bgExposure.x - 0.5f) * hardness);
Shinya Kitaoka 120a6e
      bgExposure.y = powf(10, (bgExposure.y - 0.5f) * hardness);
Shinya Kitaoka 120a6e
      bgExposure.z = powf(10, (bgExposure.z - 0.5f) * hardness);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // multiply
Shinya Kitaoka 120a6e
      bgExposure.x *= (*bg_p).w;
Shinya Kitaoka 120a6e
      bgExposure.y *= (*bg_p).w;
Shinya Kitaoka 120a6e
      bgExposure.z *= (*bg_p).w;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- 手前とOver合成 -*/
Shinya Kitaoka 120a6e
      (*out_p).x = (*out_p).x + bgExposure.x * (1.0f - (*out_p).w);
Shinya Kitaoka 120a6e
      (*out_p).y = (*out_p).y + bgExposure.y * (1.0f - (*out_p).w);
Shinya Kitaoka 120a6e
      (*out_p).z = (*out_p).z + bgExposure.z * (1.0f - (*out_p).w);
Shinya Kitaoka 120a6e
      /*- アルファ値もOver合成 -*/
Shinya Kitaoka 120a6e
      (*out_p).w = (*out_p).w + (*bg_p).w * (1.0f - (*out_p).w);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  background_host_ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Iwa_MotionBlurCompFx::Iwa_MotionBlurCompFx()
Shinya Kitaoka 120a6e
    : m_hardness(0.3)
Shinya Kitaoka 120a6e
    /*- 左右をぼかすためのパラメータ -*/
Shinya Kitaoka 120a6e
    , m_startValue(1.0)
Shinya Kitaoka 120a6e
    , m_startCurve(1.0)
Shinya Kitaoka 120a6e
    , m_endValue(1.0)
Shinya Kitaoka 120a6e
    , m_endCurve(1.0)
Shinya Kitaoka 120a6e
    , m_zanzoMode(false)
Shinya Kitaoka 120a6e
    , m_premultiType(new TIntEnumParam(AUTO, "Auto")) {
Shinya Kitaoka 120a6e
  /*- 共通パラメータのバインド -*/
Shinya Kitaoka 120a6e
  addInputPort("Source", m_input);
Shinya Kitaoka 120a6e
  addInputPort("Back", m_background);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "hardness", m_hardness);
Shinya Kitaoka 120a6e
  bindParam(this, "shutterStart", m_shutterStart);
Shinya Kitaoka 120a6e
  bindParam(this, "shutterEnd", m_shutterEnd);
Shinya Kitaoka 120a6e
  bindParam(this, "traceResolution", m_traceResolution);
Shinya Kitaoka 120a6e
  bindParam(this, "motionObjectType", m_motionObjectType);
Shinya Kitaoka 120a6e
  bindParam(this, "motionObjectIndex", m_motionObjectIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "startValue", m_startValue);
Shinya Kitaoka 120a6e
  bindParam(this, "startCurve", m_startCurve);
Shinya Kitaoka 120a6e
  bindParam(this, "endValue", m_endValue);
Shinya Kitaoka 120a6e
  bindParam(this, "endCurve", m_endCurve);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "zanzoMode", m_zanzoMode);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "premultiType", m_premultiType);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 共通パラメータの範囲設定 -*/
Shinya Kitaoka 120a6e
  m_hardness->setValueRange(0.05, 10.0);
Shinya Kitaoka 120a6e
  m_startValue->setValueRange(0.0, 1.0);
Shinya Kitaoka 120a6e
  m_startCurve->setValueRange(0.1, 10.0);
Shinya Kitaoka 120a6e
  m_endValue->setValueRange(0.0, 1.0);
Shinya Kitaoka 120a6e
  m_endCurve->setValueRange(0.1, 10.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_premultiType->addItem(SOURCE_IS_PREMULTIPLIED, "Source is premultiplied");
Shinya Kitaoka 120a6e
  m_premultiType->addItem(SOURCE_IS_NOT_PREMUTIPLIED,
Shinya Kitaoka 120a6e
                          "Source is NOT premultiplied");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  getAttributes()->setIsSpeedAware(true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_MotionBlurCompFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                                     const TRenderSettings &settings) {
Shinya Kitaoka 120a6e
  /*- 接続していない場合は処理しない -*/
Shinya Kitaoka 120a6e
  if (!m_input.isConnected() && !m_background.isConnected()) {
Shinya Kitaoka 120a6e
    tile.getRaster()->clear();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*- BGのみ接続の場合 -*/
Shinya Kitaoka 120a6e
  if (!m_input.isConnected()) {
Shinya Kitaoka 120a6e
    m_background->compute(tile, frame, settings);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 動作パラメータを得る -*/
Shinya Kitaoka 120a6e
  QList<tpointd> points = getAttributes()->getMotionPoints();</tpointd>
Shinya Kitaoka 120a6e
  double hardness       = m_hardness->getValue(frame);
Shinya Kitaoka 120a6e
  double shutterStart   = m_shutterStart->getValue(frame);
Shinya Kitaoka 120a6e
  double shutterEnd     = m_shutterEnd->getValue(frame);
Shinya Kitaoka 120a6e
  int traceResolution   = m_traceResolution->getValue();
Shinya Kitaoka 120a6e
  float startValue      = (float)m_startValue->getValue(frame);
Shinya Kitaoka 120a6e
  float startCurve      = (float)m_startCurve->getValue(frame);
Shinya Kitaoka 120a6e
  float endValue        = (float)m_endValue->getValue(frame);
Shinya Kitaoka 120a6e
  float endCurve        = (float)m_endCurve->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 軌跡データが2つ以上無い場合は、処理しない -*/
Shinya Kitaoka 120a6e
  if (points.size() < 2) {
Shinya Kitaoka 120a6e
    if (!m_background.isConnected()) m_input->compute(tile, frame, settings);
Shinya Kitaoka 120a6e
    /*- 背景があり、前景が動かない場合、単純にOverする -*/
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      composeWithNoMotion(tile, frame, settings);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*-  表示の範囲を得る -*/
Shinya Kitaoka 120a6e
  TRectD bBox =
Shinya Kitaoka 120a6e
      TRectD(tile.m_pos /*- Render画像上(Pixel単位)の位置 -*/
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             TDimensionD(/*- Render画像上(Pixel単位)のサイズ -*/
Shinya Kitaoka 120a6e
                         tile.getRaster()->getLx(), tile.getRaster()->getLy()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 上下左右のマージンを得る -*/
Shinya Kitaoka 120a6e
  double minX = 0.0;
Shinya Kitaoka 120a6e
  double maxX = 0.0;
Shinya Kitaoka 120a6e
  double minY = 0.0;
Shinya Kitaoka 120a6e
  double maxY = 0.0;
Shinya Kitaoka 120a6e
  for (int p = 0; p < points.size(); p++) {
Shinya Kitaoka 120a6e
    if (points.at(p).x > maxX) maxX = points.at(p).x;
Shinya Kitaoka 120a6e
    if (points.at(p).x < minX) minX = points.at(p).x;
Shinya Kitaoka 120a6e
    if (points.at(p).y > maxY) maxY = points.at(p).y;
Shinya Kitaoka 120a6e
    if (points.at(p).y < minY) minY = points.at(p).y;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int marginLeft   = (int)ceil(abs(minX));
Shinya Kitaoka 120a6e
  int marginRight  = (int)ceil(abs(maxX));
Shinya Kitaoka 120a6e
  int marginTop    = (int)ceil(abs(maxY));
Shinya Kitaoka 120a6e
  int marginBottom = (int)ceil(abs(minY));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 動かない(=フィルタマージンが全て0)場合、入力タイルをそのまま返す -*/
Shinya Kitaoka 120a6e
  if (marginLeft == 0 && marginRight == 0 && marginTop == 0 &&
Shinya Kitaoka 120a6e
      marginBottom == 0) {
Shinya Kitaoka 120a6e
    if (!m_background.isConnected()) m_input->compute(tile, frame, settings);
Shinya Kitaoka 120a6e
    /*- 背景があり、前景が動かない場合、単純にOverする -*/
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      composeWithNoMotion(tile, frame, settings);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- マージンは、フィルタの上下左右を反転した寸法になる -*/
Shinya Kitaoka 120a6e
  TRectD enlargedBBox(bBox.x0 - (double)marginRight,
Shinya Kitaoka 120a6e
                      bBox.y0 - (double)marginTop, bBox.x1 + (double)marginLeft,
Shinya Kitaoka 120a6e
                      bBox.y1 + (double)marginBottom);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // std::cout<<"Margin Left:"<
Shinya Kitaoka 120a6e
  //	" Bottom:"<
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TDimensionI enlargedDimIn(/*- Pixel単位に四捨五入 -*/
Shinya Kitaoka 120a6e
                            (int)(enlargedBBox.getLx() + 0.5),
Shinya Kitaoka 120a6e
                            (int)(enlargedBBox.getLy() + 0.5));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TTile enlarge_tile;
Shinya Kitaoka 120a6e
  m_input->allocateAndCompute(enlarge_tile, enlargedBBox.getP00(),
Shinya Kitaoka 120a6e
                              enlargedDimIn, tile.getRaster(), frame, settings);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 背景が必要な場合 -*/
Shinya Kitaoka 120a6e
  TTile back_Tile;
Shinya Kitaoka 120a6e
  if (m_background.isConnected()) {
Shinya Kitaoka 120a6e
    m_background->allocateAndCompute(back_Tile, tile.m_pos,
Shinya Kitaoka 120a6e
                                     tile.getRaster()->getSize(),
Shinya Kitaoka 120a6e
                                     tile.getRaster(), frame, settings);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-------------------------------------------------------
Shinya Kitaoka 120a6e
  /*- 計算範囲 -*/
Shinya Kitaoka 120a6e
  TDimensionI dimOut(tile.getRaster()->getLx(), tile.getRaster()->getLy());
Shinya Kitaoka 120a6e
  TDimensionI filterDim(marginLeft + marginRight + 1,
Shinya Kitaoka 120a6e
                        marginTop + marginBottom + 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- pointsTableの解放は各doCompute内でやっている -*/
Shinya Kitaoka 120a6e
  int pointAmount     = points.size();
Shinya Kitaoka 120a6e
  float4 *pointsTable = new float4[pointAmount];
Shinya Kitaoka 120a6e
  float dt = (float)(shutterStart + shutterEnd) / (float)traceResolution;
Shinya Kitaoka 120a6e
  for (int p = 0; p < pointAmount; p++) {
Shinya Kitaoka 120a6e
    pointsTable[p].x = (float)points.at(p).x;
Shinya Kitaoka 120a6e
    pointsTable[p].y = (float)points.at(p).y;
Shinya Kitaoka 120a6e
    /*- zにはp→p+1のベクトルの距離を格納 -*/
Shinya Kitaoka 120a6e
    if (p < pointAmount - 1) {
Shinya Kitaoka 120a6e
      float2 vec = {(float)(points.at(p + 1).x - points.at(p).x),
Shinya Kitaoka 120a6e
                    (float)(points.at(p + 1).y - points.at(p).y)};
Shinya Kitaoka 120a6e
      pointsTable[p].z = sqrtf(vec.x * vec.x + vec.y * vec.y);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*- wにはシャッター時間のオフセットを格納 -*/
Shinya Kitaoka 120a6e
    pointsTable[p].w = -(float)shutterStart + (float)p * dt;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  doCompute_CPU(tile, frame, settings, pointsTable, pointAmount, hardness,
Shinya Kitaoka 120a6e
                shutterStart, shutterEnd, traceResolution, startValue,
Shinya Kitaoka 120a6e
                startCurve, endValue, endCurve, marginLeft, marginRight,
Shinya Kitaoka 120a6e
                marginTop, marginBottom, enlargedDimIn, enlarge_tile, dimOut,
Shinya Kitaoka 120a6e
                filterDim, back_Tile);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_MotionBlurCompFx::doCompute_CPU(
Shinya Kitaoka 120a6e
    TTile &tile, double frame, const TRenderSettings &settings,
Shinya Kitaoka 120a6e
    float4 *pointsTable, int pointAmount, double hardness, double shutterStart,
Shinya Kitaoka 120a6e
    double shutterEnd, int traceResolution, float startValue, float startCurve,
Shinya Kitaoka 120a6e
    float endValue, float endCurve, int marginLeft, int marginRight,
Shinya Kitaoka 120a6e
    int marginTop, int marginBottom, TDimensionI &enlargedDimIn,
Shinya Kitaoka 120a6e
    TTile &enlarge_tile, TDimensionI &dimOut, TDimensionI &filterDim,
Shinya Kitaoka 120a6e
    TTile &back_tile) {
Shinya Kitaoka 120a6e
  /*- 処理を行うメモリ -*/
Shinya Kitaoka 120a6e
  float4 *in_tile_p;  /*- マージンあり -*/
Shinya Kitaoka 120a6e
  float4 *out_tile_p; /*- マージンあり -*/
Shinya Kitaoka 120a6e
  /*- フィルタ -*/
Shinya Kitaoka 120a6e
  float *filter_p;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- メモリ確保 -*/
Shinya Kitaoka 120a6e
  TRasterGR8P in_tile_ras(sizeof(float4) * enlargedDimIn.lx, enlargedDimIn.ly);
Shinya Kitaoka 120a6e
  in_tile_ras->lock();
Shinya Kitaoka 120a6e
  in_tile_p = (float4 *)in_tile_ras->getRawData();
Shinya Kitaoka 120a6e
  TRasterGR8P out_tile_ras(sizeof(float4) * enlargedDimIn.lx, enlargedDimIn.ly);
Shinya Kitaoka 120a6e
  out_tile_ras->lock();
Shinya Kitaoka 120a6e
  out_tile_p = (float4 *)out_tile_ras->getRawData();
Shinya Kitaoka 120a6e
  TRasterGR8P filter_ras(sizeof(float) * filterDim.lx, filterDim.ly);
Shinya Kitaoka 120a6e
  filter_ras->lock();
Shinya Kitaoka 120a6e
  filter_p = (float *)filter_ras->getRawData();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool sourceIsPremultiplied;
Shinya Kitaoka 120a6e
  /*- ソース画像を0〜1に正規化してメモリに読み込む -*/
Shinya Kitaoka 120a6e
  TRaster32P ras32 = (TRaster32P)enlarge_tile.getRaster();
Shinya Kitaoka 120a6e
  TRaster64P ras64 = (TRaster64P)enlarge_tile.getRaster();
Shinya Kitaoka 120a6e
  if (ras32)
Shinya Kitaoka 120a6e
    sourceIsPremultiplied = setSourceRaster<traster32p, tpixel32="">(</traster32p,>
Shinya Kitaoka 120a6e
        ras32, in_tile_p, enlargedDimIn,
Shinya Kitaoka 120a6e
        (PremultiTypes)m_premultiType->getValue());
Shinya Kitaoka 120a6e
  else if (ras64)
Shinya Kitaoka 120a6e
    sourceIsPremultiplied = setSourceRaster<traster64p, tpixel64="">(</traster64p,>
Shinya Kitaoka 120a6e
        ras64, in_tile_p, enlargedDimIn,
Shinya Kitaoka 120a6e
        (PremultiTypes)m_premultiType->getValue());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 残像モードがオフのとき -*/
Shinya Kitaoka 120a6e
  if (!m_zanzoMode->getValue()) {
Shinya Kitaoka 120a6e
    /*- フィルタをつくり、正規化する -*/
Shinya Kitaoka 120a6e
    makeMotionBlurFilter_CPU(filter_p, filterDim, marginLeft, marginBottom,
Shinya Kitaoka 120a6e
                             pointsTable, pointAmount, startValue, startCurve,
Shinya Kitaoka 120a6e
                             endValue, endCurve);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*- 残像モードがオンのとき -*/
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    /*- 残像フィルタをつくる/正規化する -*/
Shinya Kitaoka 120a6e
    makeZanzoFilter_CPU(filter_p, filterDim, marginLeft, marginBottom,
Shinya Kitaoka 120a6e
                        pointsTable, pointAmount, startValue, startCurve,
Shinya Kitaoka 120a6e
                        endValue, endCurve);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delete[] pointsTable;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- RGB値(0〜1)をdepremultiply→露光値に変換→再びpremultiply -*/
Shinya Kitaoka 120a6e
  convertRGBtoExposure_CPU(in_tile_p, enlargedDimIn, hardness,
Shinya Kitaoka 120a6e
                           sourceIsPremultiplied);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 露光値をフィルタリングしてぼかす -*/
Shinya Kitaoka 120a6e
  applyBlurFilter_CPU(in_tile_p, out_tile_p, enlargedDimIn, filter_p, filterDim,
Shinya Kitaoka 120a6e
                      marginLeft, marginBottom, marginRight, marginTop, dimOut);
Shinya Kitaoka 120a6e
  /*- メモリ解放 -*/
Shinya Kitaoka 120a6e
  in_tile_ras->unlock();
Shinya Kitaoka 120a6e
  filter_ras->unlock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 背景がある場合、Exposureの乗算を行う -*/
Shinya Kitaoka 120a6e
  if (m_background.isConnected()) {
Shinya Kitaoka 120a6e
    composeBackgroundExposure_CPU(out_tile_p, enlargedDimIn, marginRight,
Shinya Kitaoka 120a6e
                                  marginTop, back_tile, dimOut,
Shinya Kitaoka 120a6e
                                  (float)hardness);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*- 露光値をdepremultipy→RGB値(0〜1)に戻す→premultiply -*/
Shinya Kitaoka 120a6e
  convertExposureToRGB_CPU(out_tile_p, enlargedDimIn, hardness);
Shinya Kitaoka 120a6e
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();
Shinya Kitaoka 120a6e
  int2 margin         = {marginRight, marginTop};
Shinya Kitaoka 120a6e
  if (outRas32)
Shinya Kitaoka 120a6e
    setOutputRaster<traster32p, tpixel32="">(out_tile_p, outRas32, enlargedDimIn,</traster32p,>
Shinya Kitaoka 120a6e
                                          margin);
Shinya Kitaoka 120a6e
  else if (outRas64)
Shinya Kitaoka 120a6e
    setOutputRaster<traster64p, tpixel64="">(out_tile_p, outRas64, enlargedDimIn,</traster64p,>
Shinya Kitaoka 120a6e
                                          margin);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- メモリ解放 -*/
Shinya Kitaoka 120a6e
  out_tile_ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Iwa_MotionBlurCompFx::doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 120a6e
                                     const TRenderSettings &info) {
Shinya Kitaoka 120a6e
  if (!m_input.isConnected() && !m_background.isConnected()) {
Shinya Kitaoka 120a6e
    bBox = TRectD();
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 取り急ぎ、背景が繋がっていたら無限サイズにする -*/
Shinya Kitaoka 120a6e
  if (m_background.isConnected()) {
Shinya Kitaoka 120a6e
    bool _ret = m_background->doGetBBox(frame, bBox, info);
Shinya Kitaoka 120a6e
    bBox      = TConsts::infiniteRectD;
Shinya Kitaoka 120a6e
    return _ret;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool ret = m_input->doGetBBox(frame, bBox, info);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (bBox == TConsts::infiniteRectD) return true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QList<tpointd> points = getAttributes()->getMotionPoints();</tpointd>
Shinya Kitaoka 120a6e
  /*- 移動した軌跡のバウンディングボックスからマージンを求める -*/
Shinya Kitaoka 120a6e
  /*- 各軌跡点の座標の絶対値の最大値を得る -*/
Shinya Kitaoka 120a6e
  /*- 上下左右のマージンを得る -*/
Shinya Kitaoka 120a6e
  double minX = 0.0;
Shinya Kitaoka 120a6e
  double maxX = 0.0;
Shinya Kitaoka 120a6e
  double minY = 0.0;
Shinya Kitaoka 120a6e
  double maxY = 0.0;
Shinya Kitaoka 120a6e
  for (int p = 0; p < points.size(); p++) {
Shinya Kitaoka 120a6e
    if (points.at(p).x > maxX) maxX = points.at(p).x;
Shinya Kitaoka 120a6e
    if (points.at(p).x < minX) minX = points.at(p).x;
Shinya Kitaoka 120a6e
    if (points.at(p).y > maxY) maxY = points.at(p).y;
Shinya Kitaoka 120a6e
    if (points.at(p).y < minY) minY = points.at(p).y;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int marginLeft   = (int)ceil(abs(minX));
Shinya Kitaoka 120a6e
  int marginRight  = (int)ceil(abs(maxX));
Shinya Kitaoka 120a6e
  int marginTop    = (int)ceil(abs(maxY));
Shinya Kitaoka 120a6e
  int marginBottom = (int)ceil(abs(minY));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD enlargedBBox(
Shinya Kitaoka 120a6e
      bBox.x0 - (double)marginLeft, bBox.y0 - (double)marginBottom,
Shinya Kitaoka 120a6e
      bBox.x1 + (double)marginRight, bBox.y1 + (double)marginTop);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bBox = enlargedBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool Iwa_MotionBlurCompFx::canHandle(const TRenderSettings &info,
Shinya Kitaoka 120a6e
                                     double frame) {
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*------------------------------------------------------------
Toshihiro Shimizu 890ddd
 参考にしているオブジェクトが動いている可能性があるので、
Toshihiro Shimizu 890ddd
 エイリアスは毎フレーム変える
Toshihiro Shimizu 890ddd
------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::string Iwa_MotionBlurCompFx::getAlias(double frame,
Shinya Kitaoka 120a6e
                                           const TRenderSettings &info) const {
Shinya Kitaoka 120a6e
  std::string alias = getFxType();
Shinya Kitaoka 120a6e
  alias += "[";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // alias degli effetti connessi alle porte di input separati da virgole
Shinya Kitaoka 120a6e
  // una porta non connessa da luogo a un alias vuoto (stringa vuota)
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < getInputPortCount(); i++) {
Shinya Kitaoka 120a6e
    TFxPort *port = getInputPort(i);
Shinya Kitaoka 120a6e
    if (port->isConnected()) {
Shinya Kitaoka 120a6e
      TRasterFxP ifx = port->getFx();
Shinya Kitaoka 120a6e
      assert(ifx);
Shinya Kitaoka 120a6e
      alias += ifx->getAlias(frame, info);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    alias += ",";
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string paramalias("");
Shinya Kitaoka 120a6e
  for (i = 0; i < getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
    TParam *param = getParams()->getParam(i);
Shinya Kitaoka 120a6e
    paramalias += param->getName() + "=" + param->getValueAlias(frame, 3);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  unsigned long id = getIdentifier();
Shinya Kitaoka 120a6e
  return alias + std::to_string(frame) + "," + std::to_string(id) + paramalias +
Shinya Kitaoka 120a6e
         "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(Iwa_MotionBlurCompFx, "iwa_MotionBlurCompFx")