|
Toshihiro Shimizu |
890ddd |
/*------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
Iwa_DirectionalBlurFx
|
|
Toshihiro Shimizu |
890ddd |
ボケ足の伸ばし方を選択でき、参照画像を追加した DirectionalBlur
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "iwa_directionalblurfx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamuiconcept.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
enum FILTER_TYPE { Linear = 0, Gaussian, Flat };
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
参照画像の輝度を0〜1に正規化してホストメモリに読み込む
|
|
Toshihiro Shimizu |
890ddd |
------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pixel="" raster,="" typename=""></typename>
|
|
Toshihiro Shimizu |
890ddd |
void Iwa_DirectionalBlurFx::setReferenceRaster(const RASTER srcRas,
|
|
Shinya Kitaoka |
120a6e |
float *dstMem, TDimensionI dim) {
|
|
Shinya Kitaoka |
120a6e |
float *dst_p = dstMem;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < dim.ly; j++) {
|
|
Shinya Kitaoka |
120a6e |
PIXEL *pix = srcRas->pixels(j);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < dim.lx; i++, pix++, dst_p++) {
|
|
Shinya Kitaoka |
120a6e |
(*dst_p) = ((float)pix->r * 0.3f + (float)pix->g * 0.59f +
|
|
Shinya Kitaoka |
120a6e |
(float)pix->b * 0.11f) /
|
|
Shinya Kitaoka |
120a6e |
(float)PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
ソース画像を0〜1に正規化してホストメモリに読み込む
|
|
Toshihiro Shimizu |
890ddd |
------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pixel="" raster,="" typename=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void Iwa_DirectionalBlurFx::setSourceRaster(const RASTER srcRas, float4 *dstMem,
|
|
Shinya Kitaoka |
120a6e |
TDimensionI dim) {
|
|
Shinya Kitaoka |
120a6e |
float4 *chann_p = dstMem;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < dim.ly; j++) {
|
|
Shinya Kitaoka |
120a6e |
PIXEL *pix = srcRas->pixels(j);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < dim.lx; i++, pix++, chann_p++) {
|
|
Shinya Kitaoka |
120a6e |
(*chann_p).x = (float)pix->r / (float)PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
(*chann_p).y = (float)pix->g / (float)PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
(*chann_p).z = (float)pix->b / (float)PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
(*chann_p).w = (float)pix->m / (float)PIXEL::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
出力結果をChannel値に変換してタイルに格納
|
|
Toshihiro Shimizu |
890ddd |
------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
template <typename pixel="" raster,="" typename=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void Iwa_DirectionalBlurFx::setOutputRaster(float4 *srcMem, const RASTER dstRas,
|
|
Shinya Kitaoka |
120a6e |
TDimensionI dim, int2 margin) {
|
|
Shinya Kitaoka |
120a6e |
int out_j = 0;
|
|
Shinya Kitaoka |
120a6e |
for (int j = margin.y; j < dstRas->getLy() + margin.y; j++, out_j++) {
|
|
Shinya Kitaoka |
120a6e |
PIXEL *pix = dstRas->pixels(out_j);
|
|
Shinya Kitaoka |
120a6e |
float4 *chan_p = srcMem;
|
|
Shinya Kitaoka |
120a6e |
chan_p += j * dim.lx + margin.x;
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < dstRas->getLx(); i++, pix++, chan_p++) {
|
|
Shinya Kitaoka |
120a6e |
float val;
|
|
Shinya Kitaoka |
120a6e |
val = (*chan_p).x * (float)PIXEL::maxChannelValue + 0.5f;
|
|
Shinya Kitaoka |
120a6e |
pix->r = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? (float)PIXEL::maxChannelValue
|
|
Shinya Kitaoka |
120a6e |
: val);
|
|
Shinya Kitaoka |
120a6e |
val = (*chan_p).y * (float)PIXEL::maxChannelValue + 0.5f;
|
|
Shinya Kitaoka |
120a6e |
pix->g = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? (float)PIXEL::maxChannelValue
|
|
Shinya Kitaoka |
120a6e |
: val);
|
|
Shinya Kitaoka |
120a6e |
val = (*chan_p).z * (float)PIXEL::maxChannelValue + 0.5f;
|
|
Shinya Kitaoka |
120a6e |
pix->b = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? (float)PIXEL::maxChannelValue
|
|
Shinya Kitaoka |
120a6e |
: val);
|
|
Shinya Kitaoka |
120a6e |
val = (*chan_p).w * (float)PIXEL::maxChannelValue + 0.5f;
|
|
Shinya Kitaoka |
120a6e |
pix->m = (typename PIXEL::Channel)((val > (float)PIXEL::maxChannelValue)
|
|
Shinya Kitaoka |
120a6e |
? (float)PIXEL::maxChannelValue
|
|
Shinya Kitaoka |
120a6e |
: val);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Iwa_DirectionalBlurFx::Iwa_DirectionalBlurFx()
|
|
Shinya Kitaoka |
120a6e |
: m_angle(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_intensity(10.0)
|
|
Shinya Kitaoka |
120a6e |
, m_bidirectional(false)
|
|
Shinya Kitaoka |
120a6e |
, m_filterType(new TIntEnumParam(Linear, "Linear")) {
|
|
Shinya Kitaoka |
120a6e |
m_intensity->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_angle->setMeasureName("angle");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "angle", m_angle);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "intensity", m_intensity);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "bidirectional", m_bidirectional);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "filterType", m_filterType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
addInputPort("Source", m_input);
|
|
Shinya Kitaoka |
120a6e |
addInputPort("Reference", m_reference);
|
|
Shinya Kitaoka |
120a6e |
m_intensity->setValueRange(0, (std::numeric_limits<double>::max)());</double>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_filterType->addItem(Gaussian, "Gaussian");
|
|
Shinya Kitaoka |
120a6e |
m_filterType->addItem(Flat, "Flat");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Iwa_DirectionalBlurFx::doCompute(TTile &tile, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &settings) {
|
|
Shinya Kitaoka |
120a6e |
/*- 接続していない場合は処理しない -*/
|
|
Shinya Kitaoka |
120a6e |
if (!m_input.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->clear();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD blurVector;
|
|
Shinya Kitaoka |
120a6e |
double angle = m_angle->getValue(frame) * M_PI_180;
|
|
Shinya Kitaoka |
120a6e |
double intensity = m_intensity->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
bool bidirectional = m_bidirectional->getValue();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
blurVector.x = intensity * cos(angle);
|
|
Shinya Kitaoka |
120a6e |
blurVector.y = intensity * sin(angle);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double shrink = (settings.m_shrinkX + settings.m_shrinkY) / 2.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 平行移動成分を消したアフィン変換をかけ、ボケベクトルを変形 -*/
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = settings.m_affine;
|
|
Shinya Kitaoka |
120a6e |
aff.a13 = aff.a23 = 0;
|
|
Shinya Kitaoka |
120a6e |
TPointD blur = (1.0 / shrink) * (aff * blurVector);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- ボケの実際の長さを求める -*/
|
|
Shinya Kitaoka |
120a6e |
double blurValue = norm(blur);
|
|
Shinya Kitaoka |
120a6e |
/*- ボケの実際の長さがほぼ0なら入力画像をそのまま return -*/
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(blurValue, 0, 1e-3)) {
|
|
Shinya Kitaoka |
120a6e |
m_input->compute(tile, frame, settings);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
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 |
double minX, maxX, minY, maxY;
|
|
Shinya Kitaoka |
120a6e |
if (blur.x > 0.0) /*- X成分が正の場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
maxX = blur.x;
|
|
Shinya Kitaoka |
120a6e |
minX = (bidirectional) ? -blur.x : 0.0;
|
|
Shinya Kitaoka |
120a6e |
} else /*- X成分が負の場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
maxX = (bidirectional) ? -blur.x : 0.0;
|
|
Shinya Kitaoka |
120a6e |
minX = blur.x;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (blur.y > 0.0) /*- Y成分が正の場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
maxY = blur.y;
|
|
Shinya Kitaoka |
120a6e |
minY = (bidirectional) ? -blur.y : 0.0;
|
|
Shinya Kitaoka |
120a6e |
} else /*- Y成分が負の場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
maxY = (bidirectional) ? -blur.y : 0.0;
|
|
Shinya Kitaoka |
120a6e |
minY = blur.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 |
/*- マージンは、フィルタの上下左右を反転した寸法になる -*/
|
|
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:" << marginLeft << " Right:" << marginRight
|
|
Shinya Kitaoka |
120a6e |
<< " Bottom:" << marginBottom << " Top:" << marginTop << std::endl;
|
|
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 |
float *reference_host = 0;
|
|
Shinya Kitaoka |
120a6e |
TRasterGR8P reference_host_ras;
|
|
Shinya Kitaoka |
120a6e |
if (m_reference.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
TTile reference_tile;
|
|
Shinya Kitaoka |
120a6e |
m_reference->allocateAndCompute(reference_tile, enlargedBBox.getP00(),
|
|
Shinya Kitaoka |
120a6e |
enlargedDimIn, tile.getRaster(), frame,
|
|
Shinya Kitaoka |
120a6e |
settings);
|
|
Shinya Kitaoka |
120a6e |
/*- ホストのメモリ確保 -*/
|
|
Shinya Kitaoka |
120a6e |
reference_host_ras =
|
|
Shinya Kitaoka |
120a6e |
TRasterGR8P(sizeof(float) * enlargedDimIn.lx, enlargedDimIn.ly);
|
|
Shinya Kitaoka |
120a6e |
reference_host_ras->lock();
|
|
Shinya Kitaoka |
120a6e |
reference_host = (float *)reference_host_ras->getRawData();
|
|
Shinya Kitaoka |
120a6e |
/*- 参照画像の輝度を0〜1に正規化してホストメモリに読み込む -*/
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras32 = (TRaster32P)reference_tile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
TRaster64P ras64 = (TRaster64P)reference_tile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (ras32)
|
|
Shinya Kitaoka |
120a6e |
setReferenceRaster<traster32p, tpixel32="">(ras32, reference_host,</traster32p,>
|
|
Shinya Kitaoka |
120a6e |
enlargedDimIn);
|
|
Shinya Kitaoka |
120a6e |
else if (ras64)
|
|
Shinya Kitaoka |
120a6e |
setReferenceRaster<traster64p, tpixel64="">(ras64, reference_host,</traster64p,>
|
|
Shinya Kitaoka |
120a6e |
enlargedDimIn);
|
|
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 |
doCompute_CPU(tile, frame, settings, blur, bidirectional, marginLeft,
|
|
Shinya Kitaoka |
120a6e |
marginRight, marginTop, marginBottom, enlargedDimIn,
|
|
Shinya Kitaoka |
120a6e |
enlarge_tile, dimOut, filterDim, reference_host);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 参照画像が刺さっている場合、メモリを解放する -*/
|
|
Shinya Kitaoka |
120a6e |
if (reference_host) {
|
|
Shinya Kitaoka |
120a6e |
reference_host_ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
reference_host = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Iwa_DirectionalBlurFx::doCompute_CPU(
|
|
Shinya Kitaoka |
120a6e |
TTile &tile, double frame, const TRenderSettings &settings, TPointD &blur,
|
|
Shinya Kitaoka |
120a6e |
bool bidirectional, int marginLeft, int marginRight, int marginTop,
|
|
Shinya Kitaoka |
120a6e |
int marginBottom, TDimensionI &enlargedDimIn, TTile &enlarge_tile,
|
|
Shinya Kitaoka |
120a6e |
TDimensionI &dimOut, TDimensionI &filterDim, float *reference_host) {
|
|
Shinya Kitaoka |
120a6e |
/*- メモリ確保 -*/
|
|
Shinya Kitaoka |
120a6e |
TRasterGR8P in_ras(sizeof(float4) * enlargedDimIn.lx, enlargedDimIn.ly);
|
|
Shinya Kitaoka |
120a6e |
in_ras->lock();
|
|
Shinya Kitaoka |
120a6e |
float4 *in = (float4 *)in_ras->getRawData();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRasterGR8P out_ras(sizeof(float4) * enlargedDimIn.lx, enlargedDimIn.ly);
|
|
Shinya Kitaoka |
120a6e |
out_ras->lock();
|
|
Shinya Kitaoka |
120a6e |
float4 *out = (float4 *)out_ras->getRawData();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRasterGR8P filter_ras(sizeof(float) * filterDim.lx, filterDim.ly);
|
|
Shinya Kitaoka |
120a6e |
filter_ras->lock();
|
|
Shinya Kitaoka |
120a6e |
float *filter = (float *)filter_ras->getRawData();
|
|
Shinya Kitaoka |
120a6e |
|
|
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 |
setSourceRaster<traster32p, tpixel32="">(ras32, in, enlargedDimIn);</traster32p,>
|
|
Shinya Kitaoka |
120a6e |
else if (ras64)
|
|
Shinya Kitaoka |
120a6e |
setSourceRaster<traster64p, tpixel64="">(ras64, in, enlargedDimIn);</traster64p,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- フィルタ作る -*/
|
|
Shinya Kitaoka |
120a6e |
makeDirectionalBlurFilter_CPU(filter, blur, bidirectional, marginLeft,
|
|
Shinya Kitaoka |
120a6e |
marginRight, marginTop, marginBottom,
|
|
Shinya Kitaoka |
120a6e |
filterDim);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (reference_host) /*- 参照画像がある場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
float4 *out_p = out + marginTop * enlargedDimIn.lx;
|
|
Shinya Kitaoka |
120a6e |
float *ref_p = reference_host + marginTop * enlargedDimIn.lx;
|
|
Shinya Kitaoka |
120a6e |
/*- フィルタリング -*/
|
|
Shinya Kitaoka |
120a6e |
for (int y = marginTop; y < dimOut.ly + marginTop; y++) {
|
|
Shinya Kitaoka |
120a6e |
out_p += marginRight;
|
|
Shinya Kitaoka |
120a6e |
ref_p += marginRight;
|
|
Shinya Kitaoka |
120a6e |
for (int x = marginRight; x < dimOut.lx + marginRight;
|
|
Shinya Kitaoka |
120a6e |
x++, out_p++, ref_p++) {
|
|
Shinya Kitaoka |
120a6e |
/*- 参照画像が黒ならソースをそのまま返す -*/
|
|
Shinya Kitaoka |
120a6e |
if ((*ref_p) == 0.0f) {
|
|
Shinya Kitaoka |
120a6e |
(*out_p) = in[y * enlargedDimIn.lx + x];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
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 |
float *filter_p = filter;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((*ref_p) == 1.0f) {
|
|
Shinya Kitaoka |
120a6e |
/*- フィルタのサイズでループ
|
|
Shinya Kitaoka |
120a6e |
ただし、フィルタはサンプル点の画像を収集するように
|
|
Shinya Kitaoka |
120a6e |
用いるため、上下左右反転してサンプルする -*/
|
|
Shinya Kitaoka |
120a6e |
for (int fily = -marginBottom; fily < filterDim.ly - marginBottom;
|
|
Shinya Kitaoka |
120a6e |
fily++) {
|
|
Shinya Kitaoka |
120a6e |
/*- サンプル座標 と インデックス の このスキャンラインのうしろ -*/
|
|
Shinya Kitaoka |
120a6e |
int2 samplePos = {x + marginLeft, y - fily};
|
|
Shinya Kitaoka |
120a6e |
int sampleIndex = samplePos.y * enlargedDimIn.lx + samplePos.x;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int filx = -marginLeft; filx < filterDim.lx - marginLeft;
|
|
Shinya Kitaoka |
120a6e |
filx++, filter_p++, sampleIndex--) {
|
|
Shinya Kitaoka |
120a6e |
/*- フィルター値が0またはサンプルピクセルが透明ならcontinue -*/
|
|
Shinya Kitaoka |
120a6e |
if ((*filter_p) == 0.0f || in[sampleIndex].w == 0.0f) continue;
|
|
Shinya Kitaoka |
120a6e |
/*- サンプル点の値にフィルタ値を掛けて積算する -*/
|
|
Shinya Kitaoka |
120a6e |
value.x += in[sampleIndex].x * (*filter_p);
|
|
Shinya Kitaoka |
120a6e |
value.y += in[sampleIndex].y * (*filter_p);
|
|
Shinya Kitaoka |
120a6e |
value.z += in[sampleIndex].z * (*filter_p);
|
|
Shinya Kitaoka |
120a6e |
value.w += in[sampleIndex].w * (*filter_p);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
for (int fily = -marginBottom; fily < filterDim.ly - marginBottom;
|
|
Shinya Kitaoka |
120a6e |
fily++) {
|
|
Shinya Kitaoka |
120a6e |
for (int filx = -marginLeft; filx < filterDim.lx - marginLeft;
|
|
Shinya Kitaoka |
120a6e |
filx++, filter_p++) {
|
|
Shinya Kitaoka |
120a6e |
/*- フィルター値が0ならcontinue -*/
|
|
Shinya Kitaoka |
120a6e |
if ((*filter_p) == 0.0f) continue;
|
|
Shinya Kitaoka |
120a6e |
/*- サンプル座標 -*/
|
|
Shinya Kitaoka |
120a6e |
int2 samplePos = {tround((float)x - (float)filx * (*ref_p)),
|
|
Shinya Kitaoka |
120a6e |
tround((float)y - (float)fily * (*ref_p))};
|
|
Shinya Kitaoka |
120a6e |
int sampleIndex = samplePos.y * enlargedDimIn.lx + samplePos.x;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- サンプルピクセルが透明ならcontinue -*/
|
|
Shinya Kitaoka |
120a6e |
if (in[sampleIndex].w == 0.0f) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- サンプル点の値にフィルタ値を掛けて積算する -*/
|
|
Shinya Kitaoka |
120a6e |
value.x += in[sampleIndex].x * (*filter_p);
|
|
Shinya Kitaoka |
120a6e |
value.y += in[sampleIndex].y * (*filter_p);
|
|
Shinya Kitaoka |
120a6e |
value.z += in[sampleIndex].z * (*filter_p);
|
|
Shinya Kitaoka |
120a6e |
value.w += in[sampleIndex].w * (*filter_p);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 値を格納 -*/
|
|
Shinya Kitaoka |
120a6e |
(*out_p) = value;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
out_p += marginLeft;
|
|
Shinya Kitaoka |
120a6e |
ref_p += marginLeft;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
} else /*- 参照画像が無い場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
float4 *out_p = out + marginTop * enlargedDimIn.lx;
|
|
Shinya Kitaoka |
120a6e |
/*- フィルタリング -*/
|
|
Shinya Kitaoka |
120a6e |
for (int y = marginTop; y < dimOut.ly + marginTop; y++) {
|
|
Shinya Kitaoka |
120a6e |
out_p += marginRight;
|
|
Shinya Kitaoka |
120a6e |
for (int x = marginRight; x < dimOut.lx + marginRight; x++, out_p++) {
|
|
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 |
int filterIndex = 0;
|
|
Shinya Kitaoka |
120a6e |
for (int fily = -marginBottom; fily < filterDim.ly - marginBottom;
|
|
Shinya Kitaoka |
120a6e |
fily++) {
|
|
Shinya Kitaoka |
120a6e |
/*- サンプル座標 と インデックス の このスキャンラインのうしろ -*/
|
|
Shinya Kitaoka |
120a6e |
int2 samplePos = {x + marginLeft, y - fily};
|
|
Shinya Kitaoka |
120a6e |
int sampleIndex = samplePos.y * enlargedDimIn.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[filterIndex] == 0.0f || in[sampleIndex].w == 0.0f)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
/*- サンプル点の値にフィルタ値を掛けて積算する -*/
|
|
Shinya Kitaoka |
120a6e |
value.x += in[sampleIndex].x * filter[filterIndex];
|
|
Shinya Kitaoka |
120a6e |
value.y += in[sampleIndex].y * filter[filterIndex];
|
|
Shinya Kitaoka |
120a6e |
value.z += in[sampleIndex].z * filter[filterIndex];
|
|
Shinya Kitaoka |
120a6e |
value.w += in[sampleIndex].w * filter[filterIndex];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 値を格納 -*/
|
|
Shinya Kitaoka |
120a6e |
(*out_p) = value;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
out_p += marginLeft;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
in_ras->unlock();
|
|
Shinya Kitaoka |
120a6e |
filter_ras->unlock();
|
|
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, outRas32, enlargedDimIn, margin);</traster32p,>
|
|
Shinya Kitaoka |
120a6e |
else if (outRas64)
|
|
Shinya Kitaoka |
120a6e |
setOutputRaster<traster64p, tpixel64="">(out, outRas64, enlargedDimIn, margin);</traster64p,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
out_ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void Iwa_DirectionalBlurFx::makeDirectionalBlurFilter_CPU(
|
|
Shinya Kitaoka |
120a6e |
float *filter, TPointD &blur, bool bidirectional, int marginLeft,
|
|
Shinya Kitaoka |
120a6e |
int marginRight, int marginTop, int marginBottom, TDimensionI &filterDim) {
|
|
Shinya Kitaoka |
120a6e |
/*- 必要なら、ガウスフィルタを前計算 -*/
|
|
Shinya Kitaoka |
120a6e |
FILTER_TYPE filterType = (FILTER_TYPE)m_filterType->getValue();
|
|
Shinya Kitaoka |
120a6e |
std::vector<float> gaussian;</float>
|
|
Shinya Kitaoka |
120a6e |
if (filterType == Gaussian) {
|
|
Shinya Kitaoka |
120a6e |
gaussian.reserve(101);
|
|
Shinya Kitaoka |
120a6e |
for (int g = 0; g < 101; g++) {
|
|
Shinya Kitaoka |
120a6e |
float x = (float)g / 100.0f;
|
|
Shinya Kitaoka |
120a6e |
// sigma == 0.25
|
|
Shinya Kitaoka |
120a6e |
gaussian.push_back(exp(-x * x / 0.125f));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- フィルタを作る -*/
|
|
Shinya Kitaoka |
120a6e |
TPointD p0 =
|
|
Shinya Kitaoka |
120a6e |
(bidirectional) ? TPointD(-blur.x, -blur.y) : TPointD(0.0f, 0.0f);
|
|
Shinya Kitaoka |
120a6e |
TPointD p1 = blur;
|
|
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 |
|
|
Shinya Kitaoka |
120a6e |
float *fil_p = filter;
|
|
Shinya Kitaoka |
120a6e |
float intensity_sum = 0.0f;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int fy = -marginBottom; fy <= marginTop; fy++) {
|
|
Shinya Kitaoka |
120a6e |
for (int fx = -marginLeft; fx <= marginRight; fx++, fil_p++) {
|
|
Shinya Kitaoka |
120a6e |
/*- 現在の座標とブラー直線の距離を求める -*/
|
|
Shinya Kitaoka |
120a6e |
/*- P0->サンプル点とP0->P1の内積を求める -*/
|
|
Shinya Kitaoka |
120a6e |
float2 vec_p0_sample = {static_cast<float>(fx - p0.x),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(fy - p0.y)};</float>
|
|
Shinya Kitaoka |
120a6e |
float dot = vec_p0_sample.x * vec_p0_p1.x + vec_p0_sample.y * vec_p0_p1.y;
|
|
Shinya Kitaoka |
120a6e |
/*- 軌跡ベクトルの長さの2乗を計算する -*/
|
|
Shinya Kitaoka |
120a6e |
float length2 = vec_p0_p1.x * vec_p0_p1.x + vec_p0_p1.y * vec_p0_p1.y;
|
|
Shinya Kitaoka |
120a6e |
|
|
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 |
/*- P0〜P1間にある場合 -*/
|
|
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 = {static_cast<float>(fx - p1.x),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(fy - p1.y)};</float>
|
|
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より遠かったらreturn dist2との比較だから2乗している
|
|
Shinya Kitaoka |
120a6e |
* -*/
|
|
Shinya Kitaoka |
120a6e |
if (dist2 > 1.4571f) {
|
|
Shinya Kitaoka |
120a6e |
(*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 |
|
|
Shinya Kitaoka |
120a6e |
for (int yy = 0; yy < 16; yy++) {
|
|
Shinya Kitaoka |
120a6e |
/*- サブピクセルのY座標 -*/
|
|
Shinya Kitaoka |
120a6e |
float subPosY = (float)fy + ((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 = (float)fx + ((float)xx - 7.5f) / 16.0f;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
float2 vec_p0_sub = {static_cast<float>(subPosX - p0.x),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(subPosY - p0.y)};</float>
|
|
Shinya Kitaoka |
120a6e |
float sub_dot =
|
|
Shinya Kitaoka |
120a6e |
vec_p0_sub.x * vec_p0_p1.x + vec_p0_sub.y * vec_p0_p1.y;
|
|
Shinya Kitaoka |
120a6e |
/*- 距離の2乗を求める -*/
|
|
Shinya Kitaoka |
120a6e |
float dist2;
|
|
Shinya Kitaoka |
120a6e |
/*- P0より手前にある場合 -*/
|
|
Shinya Kitaoka |
120a6e |
if (sub_dot <= 0.0f)
|
|
Shinya Kitaoka |
120a6e |
dist2 = vec_p0_sub.x * vec_p0_sub.x + vec_p0_sub.y * vec_p0_sub.y;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
/*- P0〜P1間にある場合 -*/
|
|
Shinya Kitaoka |
120a6e |
if (sub_dot < length2) {
|
|
Shinya Kitaoka |
120a6e |
float p0_sub_dist2 =
|
|
Shinya Kitaoka |
120a6e |
vec_p0_sub.x * vec_p0_sub.x + vec_p0_sub.y * vec_p0_sub.y;
|
|
Shinya Kitaoka |
120a6e |
dist2 = p0_sub_dist2 - sub_dot * sub_dot / length2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*- P1より先にある場合 -*/
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
float2 vec_p1_sub = {static_cast<float>(subPosX - p1.x),</float>
|
|
Shinya Kitaoka |
120a6e |
static_cast<float>(subPosY - p1.y)};</float>
|
|
Shinya Kitaoka |
120a6e |
dist2 = vec_p1_sub.x * vec_p1_sub.x + vec_p1_sub.y * vec_p1_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 |
(*fil_p) = 0.0f;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*- countは Max256 -*/
|
|
Shinya Kitaoka |
120a6e |
float countRatio = (float)count / 256.0f;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- オフセット値を求める -*/
|
|
Shinya Kitaoka |
120a6e |
float offset =
|
|
Shinya Kitaoka |
120a6e |
(bidirectional) ? abs(framePosRatio * 2.0 - 1.0) : framePosRatio;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- フィルタごとに分ける -*/
|
|
Shinya Kitaoka |
120a6e |
float bokeAsiVal;
|
|
Shinya Kitaoka |
120a6e |
switch (filterType) {
|
|
Shinya Kitaoka |
120a6e |
case Linear:
|
|
Shinya Kitaoka |
120a6e |
bokeAsiVal = 1.0f - offset;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case Gaussian: {
|
|
Shinya Kitaoka |
120a6e |
int index = (int)floor(offset * 100.0f);
|
|
Shinya Kitaoka |
120a6e |
float ratio = offset * 100.0f - (float)index;
|
|
Shinya Kitaoka |
120a6e |
bokeAsiVal =
|
|
Shinya Kitaoka |
120a6e |
gaussian[index] * (1.0f - ratio) + gaussian[index + 1] * ratio;
|
|
Shinya Kitaoka |
120a6e |
} break;
|
|
Shinya Kitaoka |
120a6e |
case Flat:
|
|
Shinya Kitaoka |
120a6e |
bokeAsiVal = 1.0f;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
bokeAsiVal = 1.0f - offset;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- フィールド値の格納 -*/
|
|
Shinya Kitaoka |
120a6e |
(*fil_p) = bokeAsiVal * countRatio;
|
|
Shinya Kitaoka |
120a6e |
intensity_sum += (*fil_p);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 正規化 -*/
|
|
Shinya Kitaoka |
120a6e |
fil_p = filter;
|
|
Shinya Kitaoka |
120a6e |
for (int f = 0; f < filterDim.lx * filterDim.ly; f++, fil_p++) {
|
|
Shinya Kitaoka |
120a6e |
if ((*fil_p) == 0.0f) continue;
|
|
Shinya Kitaoka |
120a6e |
(*fil_p) /= intensity_sum;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool Iwa_DirectionalBlurFx::doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (false == this->m_input.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
bBox = TRectD();
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
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 ret;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD blur;
|
|
Shinya Kitaoka |
120a6e |
double angle = m_angle->getValue(frame) * M_PI_180;
|
|
Shinya Kitaoka |
120a6e |
double intensity = m_intensity->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
bool bidirectional = m_bidirectional->getValue();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
blur.x = intensity * cos(angle);
|
|
Shinya Kitaoka |
120a6e |
blur.y = intensity * sin(angle);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*- 上下左右のマージンを得る -*/
|
|
Shinya Kitaoka |
120a6e |
double minX, maxX, minY, maxY;
|
|
Shinya Kitaoka |
120a6e |
if (blur.x > 0.0) /*- X成分が正の場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
maxX = blur.x;
|
|
Shinya Kitaoka |
120a6e |
minX = (bidirectional) ? -blur.x : 0.0;
|
|
Shinya Kitaoka |
120a6e |
} else /*- X成分が負の場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
maxX = (bidirectional) ? -blur.x : 0.0;
|
|
Shinya Kitaoka |
120a6e |
minX = blur.x;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (blur.y > 0.0) /*- Y成分が正の場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
maxY = blur.y;
|
|
Shinya Kitaoka |
120a6e |
minY = (bidirectional) ? -blur.y : 0.0;
|
|
Shinya Kitaoka |
120a6e |
} else /*- Y成分が負の場合 -*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
maxY = (bidirectional) ? -blur.y : 0.0;
|
|
Shinya Kitaoka |
120a6e |
minY = blur.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_DirectionalBlurFx::canHandle(const TRenderSettings &info,
|
|
Shinya Kitaoka |
120a6e |
double frame) {
|
|
Shinya Kitaoka |
120a6e |
return isAlmostIsotropic(info.m_affine) || m_intensity->getValue(frame) == 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void Iwa_DirectionalBlurFx::getParamUIs(TParamUIConcept *&concepts,
|
|
Shinya Kitaoka |
120a6e |
int &length) {
|
|
Shinya Kitaoka |
120a6e |
concepts = new TParamUIConcept[length = 1];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_type = TParamUIConcept::POLAR;
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_label = "Angle and Intensity";
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_params.push_back(m_angle);
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_params.push_back(m_intensity);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(Iwa_DirectionalBlurFx, "iwa_DirectionalBlurFx")
|