Blob Blame Raw
#pragma once

/*------------------------------------
 Iwa_MotionBlurCompFx
 露光量/オブジェクトの軌跡を考慮したモーションブラー
 背景との露光値合成を可能にする
//------------------------------------*/

#ifndef IWA_MOTION_BLUR_COMP_H
#define IWA_MOTION_BLUR_COMP_H

#include "tfxparam.h"
#include "stdfx.h"

#include "motionawarebasefx.h"

class TStageObjectId;

struct float2 {
	float x, y;
};
struct float3 {
	float x, y, z;
};
struct float4 {
	float x, y, z, w;
};
struct int2 {
	int x, y;
};

/*- m_premultiTypeの取る値 -*/
enum PremultiTypes {
	AUTO = 0,
	SOURCE_IS_PREMULTIPLIED,
	SOURCE_IS_NOT_PREMUTIPLIED
};

class Iwa_MotionBlurCompFx : public MotionAwareBaseFx
{
	FX_PLUGIN_DECLARATION(Iwa_MotionBlurCompFx)

protected:
	TRasterFxPort m_input;
	TRasterFxPort m_background;

	TDoubleParamP m_hardness; /*- フィルムのガンマ値 -*/

	/*-- 左右をぼかすためのパラメータ --*/
	TDoubleParamP m_startValue; /*- シャッター開け時のフィルタ値 -*/
	/*- シャッター開け時〜現時点までのフィルタ値のガンマ補正値 -*/
	TDoubleParamP m_startCurve;
	TDoubleParamP m_endValue; /*- シャッター閉じ時のフィルタ値 -*/
	/*- 現時点〜シャッター閉じ時までのフィルタ値のガンマ補正値 -*/
	TDoubleParamP m_endCurve;

	/*- 残像モードのトグル -*/
	TBoolParamP m_zanzoMode;

	TIntEnumParamP m_premultiType;

	/*- ソース画像を0〜1に正規化してホストメモリに読み込む
		ソース画像がPremultipyされているか、コンボボックスで指定されていない場合は
		ここで判定する -*/
	template <typename RASTER, typename PIXEL>
	bool setSourceRaster(const RASTER srcRas,
						 float4 *dstMem,
						 TDimensionI dim,
						 PremultiTypes type = AUTO);
	/*- 出力結果をChannel値に変換して格納 -*/
	template <typename RASTER, typename PIXEL>
	void setOutputRaster(float4 *srcMem,
						 const RASTER dstRas,
						 TDimensionI dim,
						 int2 margin);

	/*-  フィルタをつくり、正規化する -*/
	void makeMotionBlurFilter_CPU(float *filter_p,
								  TDimensionI &filterDim,
								  int marginLeft, int marginBottom,
								  float4 *pointsTable,
								  int pointAmount,
								  float startValue, float startCurve,
								  float endValue, float endCurve);

	/*- 残像フィルタをつくり、正規化する -*/
	void makeZanzoFilter_CPU(float *filter_p,
							 TDimensionI &filterDim,
							 int marginLeft, int marginBottom,
							 float4 *pointsTable,
							 int pointAmount,
							 float startValue, float startCurve,
							 float endValue, float endCurve);

	/*- RGB値(0〜1)を露光値に変換 -*/
	void convertRGBtoExposure_CPU(float4 *in_tile_p,
								  TDimensionI &dim, float hardness,
								  bool sourceIsPremultiplied);

	/*- 露光値をフィルタリングしてぼかす -*/
	void applyBlurFilter_CPU(float4 *in_tile_p,
							 float4 *out_tile_p,
							 TDimensionI &dim,
							 float *filter_p,
							 TDimensionI &filterDim,
							 int marginLeft, int marginBottom,
							 int marginRight, int marginTop,
							 TDimensionI &outDim);

	/*- 露光値をdepremultipy→RGB値(0〜1)に戻す→premultiply -*/
	void convertExposureToRGB_CPU(float4 *out_tile_p,
								  TDimensionI &dim, float hardness);

	/*- 背景があり、前景が動かない場合、単純にOverする -*/
	void composeWithNoMotion(TTile &tile,
							 double frame,
							 const TRenderSettings &settings);

	/*- 背景を露光値にして通常合成 -*/
	void composeBackgroundExposure_CPU(float4 *out_tile_p,
									   TDimensionI &enlargedDimIn,
									   int marginRight, int marginTop,
									   TTile &back_tile,
									   TDimensionI &dimOut,
									   float hardness);

public:
	Iwa_MotionBlurCompFx();

	void doCompute(TTile &tile,
				   double frame,
				   const TRenderSettings &settings);

	void doCompute_CPU(TTile &tile,
					   double frame,
					   const TRenderSettings &settings,
					   float4 *pointsTable,
					   int pointAmount,
					   double hardness,
					   double shutterStart, double shutterEnd,
					   int traceResolution,
					   float startValue, float startCurve,
					   float endValue, float endCurve,
					   int marginLeft, int marginRight,
					   int marginTop, int marginBottom,
					   TDimensionI &enlargedDimIn,
					   TTile &enlarge_tile,
					   TDimensionI &dimOut,
					   TDimensionI &filterDim,
					   TTile &back_tile);

	bool doGetBBox(double frame,
				   TRectD &bBox,
				   const TRenderSettings &info);

	bool canHandle(const TRenderSettings &info,
				   double frame);
	/*- 参考にしているオブジェクトが動いている可能性があるので、
		エイリアスは毎フレーム変える -*/
	std::string getAlias(double frame, const TRenderSettings &info) const;
};

#endif