|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "warp.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterfx.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "timage_io.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class WarpFx : public TStandardRasterFx
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_DECLARATION(WarpFx)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Toshihiro Shimizu |
890ddd |
TRasterFxPort m_warped, m_warper;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_intensity;
|
|
Toshihiro Shimizu |
890ddd |
TDoubleParamP m_gridStep;
|
|
Toshihiro Shimizu |
890ddd |
TBoolParamP m_sharpen;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
WarpFx()
|
|
Toshihiro Shimizu |
890ddd |
: m_intensity(20), m_gridStep(2), m_sharpen(true)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
addInputPort("Source", m_warped);
|
|
Toshihiro Shimizu |
890ddd |
addInputPort("warper", m_warper);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "intensity", m_intensity);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "sensitivity", m_gridStep);
|
|
Toshihiro Shimizu |
890ddd |
bindParam(this, "sharpen", m_sharpen);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_intensity->setValueRange(-1000, 1000);
|
|
Toshihiro Shimizu |
890ddd |
m_gridStep->setValueRange(2, 20);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
virtual ~WarpFx() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool canHandle(const TRenderSettings &info, double frame)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return isAlmostIsotropic(info.m_affine);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_warped.isConnected()) {
|
|
Toshihiro Shimizu |
890ddd |
int ret = m_warped->doGetBBox(frame, bBox, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (ret && !bBox.isEmpty()) {
|
|
Toshihiro Shimizu |
890ddd |
if (bBox != TConsts::infiniteRectD) {
|
|
Toshihiro Shimizu |
890ddd |
WarpParams params;
|
|
Toshihiro Shimizu |
890ddd |
params.m_intensity = m_intensity->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bBox = bBox.enlarge(getWarpRadius(params));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bBox = TRectD();
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void doDryCompute(TRectD &rect,
|
|
Toshihiro Shimizu |
890ddd |
double frame,
|
|
Toshihiro Shimizu |
890ddd |
const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool isWarped = m_warped.isConnected();
|
|
Toshihiro Shimizu |
890ddd |
bool isWarper = m_warper.isConnected();
|
|
Toshihiro Shimizu |
890ddd |
if (!isWarped)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
if (!isWarper || fabs(m_intensity->getValue(frame)) < 0.01) {
|
|
Toshihiro Shimizu |
890ddd |
m_warped->dryCompute(rect, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
|
|
Toshihiro Shimizu |
890ddd |
double scale = sqrt(fabs(info.m_affine.det()));
|
|
Toshihiro Shimizu |
890ddd |
double gridStep = 1.5 * m_gridStep->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
WarpParams params;
|
|
Toshihiro Shimizu |
890ddd |
params.m_intensity = m_intensity->getValue(frame) / gridStep;
|
|
Toshihiro Shimizu |
890ddd |
params.m_warperScale = scale * gridStep;
|
|
Toshihiro Shimizu |
890ddd |
params.m_sharpen = m_sharpen->getValue();
|
|
Toshihiro Shimizu |
890ddd |
params.m_shrink = shrink;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRenderSettings warperInfo(info);
|
|
Toshihiro Shimizu |
890ddd |
double warperScaleFactor = 1.0 / params.m_warperScale;
|
|
Toshihiro Shimizu |
890ddd |
warperInfo.m_affine = TScale(warperScaleFactor) * info.m_affine;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD warpedBox, warpedComputeRect, tileComputeRect;
|
|
Toshihiro Shimizu |
890ddd |
m_warped->getBBox(frame, warpedBox, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, rect, params);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD db;
|
|
Toshihiro Shimizu |
890ddd |
TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
|
|
Toshihiro Shimizu |
890ddd |
double warperEnlargement = getWarperEnlargement(params);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect.x0 = tfloor(warperComputeRect.x0);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect.y0 = tfloor(warperComputeRect.y0);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect.x1 = tceil(warperComputeRect.x1);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect.y1 = tceil(warperComputeRect.y1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_warped->dryCompute(warpedComputeRect, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
m_warper->dryCompute(warperComputeRect, frame, warperInfo);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void doCompute(TTile &tile, double frame, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool isWarped = m_warped.isConnected();
|
|
Toshihiro Shimizu |
890ddd |
bool isWarper = m_warper.isConnected();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isWarped)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!isWarper) {
|
|
Toshihiro Shimizu |
890ddd |
m_warped->compute(tile, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (fabs(m_intensity->getValue(frame)) < 0.01) {
|
|
Toshihiro Shimizu |
890ddd |
m_warped->compute(tile, frame, info);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
|
|
Toshihiro Shimizu |
890ddd |
double scale = sqrt(fabs(info.m_affine.det()));
|
|
Toshihiro Shimizu |
890ddd |
double gridStep = 1.5 * m_gridStep->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//NOTE: The gridStep is absorbed by the warper scale and the intensity - the former
|
|
Toshihiro Shimizu |
890ddd |
//balancing the latter.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
WarpParams params;
|
|
Toshihiro Shimizu |
890ddd |
params.m_intensity = m_intensity->getValue(frame) / gridStep;
|
|
Toshihiro Shimizu |
890ddd |
params.m_warperScale = scale * gridStep;
|
|
Toshihiro Shimizu |
890ddd |
params.m_sharpen = m_sharpen->getValue();
|
|
Toshihiro Shimizu |
890ddd |
params.m_shrink = shrink;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//The warper is calculated with a fixed dpi. This makes sure that the lattice
|
|
Toshihiro Shimizu |
890ddd |
//created for the warp does not depend on camera resolutions / affine scales.
|
|
Toshihiro Shimizu |
890ddd |
TRenderSettings warperInfo(info);
|
|
Toshihiro Shimizu |
890ddd |
double warperScaleFactor = 1.0 / params.m_warperScale;
|
|
Toshihiro Shimizu |
890ddd |
warperInfo.m_affine = TScale(warperScaleFactor) * info.m_affine;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Retrieve tile's geometry
|
|
Toshihiro Shimizu |
890ddd |
TRectD tileRect;
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRasterP tileRas = tile.getRaster();
|
|
Toshihiro Shimizu |
890ddd |
tileRect = TRectD(tile.m_pos, TDimensionD(tileRas->getLx(), tileRas->getLy()));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Build the compute rect
|
|
Toshihiro Shimizu |
890ddd |
TRectD warpedBox, warpedComputeRect, tileComputeRect;
|
|
Toshihiro Shimizu |
890ddd |
m_warped->getBBox(frame, warpedBox, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, tileRect, params);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
|
|
Toshihiro Shimizu |
890ddd |
double warperEnlargement = getWarperEnlargement(params);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect.x0 = tfloor(warperComputeRect.x0);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect.y0 = tfloor(warperComputeRect.y0);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect.x1 = tceil(warperComputeRect.x1);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect.y1 = tceil(warperComputeRect.y1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Compute the warped tile
|
|
Toshihiro Shimizu |
890ddd |
TTile tileIn;
|
|
Toshihiro Shimizu |
890ddd |
m_warped->allocateAndCompute(tileIn, warpedComputeRect.getP00(),
|
|
Toshihiro Shimizu |
890ddd |
TDimension(warpedComputeRect.getLx(), warpedComputeRect.getLy()),
|
|
Toshihiro Shimizu |
890ddd |
tile.getRaster(), frame, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Compute the warper tile
|
|
Toshihiro Shimizu |
890ddd |
TTile tileWarper;
|
|
Toshihiro Shimizu |
890ddd |
m_warper->allocateAndCompute(tileWarper, warperComputeRect.getP00(),
|
|
Toshihiro Shimizu |
890ddd |
TDimension(warperComputeRect.getLx(), warperComputeRect.getLy()),
|
|
Toshihiro Shimizu |
890ddd |
tile.getRaster(), frame, warperInfo);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Warp
|
|
Toshihiro Shimizu |
890ddd |
TRasterP rasIn = tileIn.getRaster();
|
|
Toshihiro Shimizu |
890ddd |
TRasterP rasWarper = tileWarper.getRaster();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD db;
|
|
Toshihiro Shimizu |
890ddd |
TRect rasComputeRectI(convert(tileComputeRect - tileRect.getP00(), db));
|
|
Toshihiro Shimizu |
890ddd |
TRasterP tileRas = tile.getRaster()->extract(rasComputeRectI);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD rasInPos(warpedComputeRect.getP00() - tileComputeRect.getP00());
|
|
Toshihiro Shimizu |
890ddd |
TPointD warperPos((TScale(params.m_warperScale) * warperComputeRect.getP00()) - tileComputeRect.getP00());
|
|
Toshihiro Shimizu |
890ddd |
warp(tileRas, rasIn, rasWarper, rasInPos, warperPos, params);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int getMemoryRequirement(const TRectD &rect, double frame, const TRenderSettings &info)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//return 0; //For debug purpose
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
|
|
Toshihiro Shimizu |
890ddd |
double scale = sqrt(fabs(info.m_affine.det()));
|
|
Toshihiro Shimizu |
890ddd |
double gridStep = 1.5 * m_gridStep->getValue(frame);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
WarpParams params;
|
|
Toshihiro Shimizu |
890ddd |
params.m_intensity = m_intensity->getValue(frame) / gridStep;
|
|
Toshihiro Shimizu |
890ddd |
params.m_warperScale = scale * gridStep;
|
|
Toshihiro Shimizu |
890ddd |
params.m_sharpen = m_sharpen->getValue();
|
|
Toshihiro Shimizu |
890ddd |
params.m_shrink = shrink;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double warperScaleFactor = 1.0 / params.m_warperScale;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD warpedBox, warpedComputeRect, tileComputeRect;
|
|
Toshihiro Shimizu |
890ddd |
m_warped->getBBox(frame, warpedBox, info);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, rect, params);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
|
|
Toshihiro Shimizu |
890ddd |
double warperEnlargement = getWarperEnlargement(params);
|
|
Toshihiro Shimizu |
890ddd |
warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
12c444 |
return std::max(
|
|
Toshihiro Shimizu |
890ddd |
TRasterFx::memorySize(warpedComputeRect, info.m_bpp),
|
|
Toshihiro Shimizu |
890ddd |
TRasterFx::memorySize(warperComputeRect, info.m_bpp));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(WarpFx, "warpFx")
|