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