|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfx.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamset.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "time.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixelutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamuiconcept.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "timage_io.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tdistort.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
inline bool myIsEmpty(const TRectD &r) { return r.x0 >= r.x1 || r.y0 >= r.y1; }
|
|
shun-iwasawa |
6817df |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class FreeDistortBaseFx : public TStandardRasterFx {
|
|
Shinya Kitaoka |
120a6e |
enum { PERSPECTIVE, BILINEAR };
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
FreeDistortBaseFx(bool isCastShadow);
|
|
Shinya Kitaoka |
120a6e |
~FreeDistortBaseFx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
38fd86 |
bool doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &info) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void doCompute(TTile &tile, double frame, const TRenderSettings &ri) override;
|
|
Shinya Kitaoka |
38fd86 |
void doDryCompute(TRectD &rect, double frame,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &ri) override;
|
|
Shinya Kitaoka |
120a6e |
void onPortConnected(TFxPort *port);
|
|
Shinya Kitaoka |
473e70 |
bool canHandle(const TRenderSettings &info, double frame) override;
|
|
Shinya Kitaoka |
120a6e |
int getMemoryRequirement(const TRectD &rect, double frame,
|
|
Shinya Kitaoka |
473e70 |
const TRenderSettings &info) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void transform(double frame, int port, const TRectD &rectOnOutput,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &infoOnOutput, TRectD &rectOnInput,
|
|
Shinya Kitaoka |
473e70 |
TRenderSettings &infoOnInput) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void safeTransform(double frame, int port, const TRectD &rectOnOutput,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &infoOnOutput, TRectD &rectOnInput,
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings &infoOnInput, TRectD &inBBox);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void getParamUIs(TParamUIConcept *&concepts, int &length) override;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
bool m_isCastShadow;
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort m_input;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TIntEnumParamP m_distortType;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_p00_a;
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_p00_b;
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_p01_a;
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_p01_b;
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_p11_a;
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_p11_b;
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_p10_a;
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_p10_b;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TBoolParamP m_deactivate;
|
|
Shinya Kitaoka |
120a6e |
TPixelParamP m_color;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_fade;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_upTransp;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_downTransp;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_upBlur;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_downBlur;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class FreeDistortFx final : public FreeDistortBaseFx {
|
|
Shinya Kitaoka |
120a6e |
FX_PLUGIN_DECLARATION(FreeDistortFx)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
FreeDistortFx() : FreeDistortBaseFx(false) {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class CastShadowFx final : public FreeDistortBaseFx {
|
|
Shinya Kitaoka |
120a6e |
FX_PLUGIN_DECLARATION(CastShadowFx)
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
CastShadowFx() : FreeDistortBaseFx(true) {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FreeDistortBaseFx::FreeDistortBaseFx(bool isCastShadow)
|
|
Shinya Kitaoka |
120a6e |
: m_deactivate(false)
|
|
Shinya Kitaoka |
120a6e |
, m_color(TPixel32::Black)
|
|
Shinya Kitaoka |
120a6e |
, m_fade(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_upTransp(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_downTransp(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_upBlur(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_downBlur(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_isCastShadow(isCastShadow)
|
|
Shinya Kitaoka |
120a6e |
, m_distortType(new TIntEnumParam(PERSPECTIVE, "Perspective")) {
|
|
Shinya Kitaoka |
120a6e |
m_upBlur->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_downBlur->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
double ext = 400.;
|
|
Shinya Kitaoka |
120a6e |
double inn = 400.;
|
|
Shinya Kitaoka |
120a6e |
m_p00_a = TPointD(-ext, -ext);
|
|
Shinya Kitaoka |
120a6e |
m_p00_b = TPointD(-inn, -inn);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p01_a = TPointD(-ext, ext);
|
|
Shinya Kitaoka |
120a6e |
m_p01_b = TPointD(-inn, inn);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p11_a = TPointD(ext, ext);
|
|
Shinya Kitaoka |
120a6e |
m_p11_b = TPointD(inn, inn);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p10_a = TPointD(ext, -ext);
|
|
Shinya Kitaoka |
120a6e |
m_p10_b = TPointD(inn, -inn);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p00_b->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p00_b->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p10_b->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p10_b->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p01_b->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p01_b->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p11_b->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p11_b->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p00_a->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p00_a->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p10_a->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p10_a->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p01_a->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p01_a->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p11_a->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_p11_a->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "distort_type", m_distortType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "bottom_left_b", m_p00_b);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "bottom_right_b", m_p10_b);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "top_left_b", m_p01_b);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "top_right_b", m_p11_b);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "bottom_left_a", m_p00_a);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "bottom_right_a", m_p10_a);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "top_left_a", m_p01_a);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "top_right_a", m_p11_a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isCastShadow) {
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "color", m_color);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "fade", m_fade);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "up_transp", m_upTransp);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "down_transp", m_downTransp);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "up_blur", m_upBlur);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "down_blur", m_downBlur);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_color->enableMatte(false);
|
|
Shinya Kitaoka |
120a6e |
m_fade->setValueRange(0.0, 100.0);
|
|
Shinya Kitaoka |
120a6e |
m_upTransp->setValueRange(0.0, 100.0);
|
|
Shinya Kitaoka |
120a6e |
m_downTransp->setValueRange(0.0, 100.0);
|
|
Shinya Kitaoka |
120a6e |
m_upBlur->setValueRange(0.0, (std::numeric_limits<double>::max)());</double>
|
|
Shinya Kitaoka |
120a6e |
m_downBlur->setValueRange(0.0, (std::numeric_limits<double>::max)());</double>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "deactivate", m_deactivate);
|
|
Shinya Kitaoka |
120a6e |
addInputPort("source", m_input);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p00_a->getX()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_p00_b->getX()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p00_a->getY()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_p00_b->getY()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p01_a->getX()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_p01_b->getX()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p01_a->getY()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_p01_b->getY()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p11_a->getX()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_p11_b->getX()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p11_a->getY()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_p11_b->getY()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p10_a->getX()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_p10_b->getX()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_p10_a->getY()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_p10_b->getY()->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_distortType->addItem(BILINEAR, "Bilinear");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
FreeDistortBaseFx::~FreeDistortBaseFx() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool FreeDistortBaseFx::canHandle(const TRenderSettings &info, double frame) {
|
|
Shinya Kitaoka |
120a6e |
// Blurs cant deal with anisotropic affines, so these are retained above
|
|
Shinya Kitaoka |
120a6e |
return m_upBlur->getValue(frame) == 0 && m_downBlur->getValue(frame) == 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool FreeDistortBaseFx::doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (m_input.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
// We'll treat this fx like a zerary one. The idea is, since
|
|
Shinya Kitaoka |
120a6e |
// the task of taking images and pre-images of rects through
|
|
Shinya Kitaoka |
120a6e |
// these kind of distortions is definitely non-trivial, we'll
|
|
Shinya Kitaoka |
120a6e |
// simply avoid doing so...
|
|
Shinya Kitaoka |
120a6e |
bBox = TConsts::infiniteRectD;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
bool ret = m_input->doGetBBox(frame, bBox);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if(m_deactivate->getValue())
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD p00_a = m_p00_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p00_b = m_p00_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p10_a = m_p10_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p10_b = m_p10_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p01_a = m_p01_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p01_b = m_p01_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p11_a = m_p11_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p11_b = m_p11_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_isCastShadow)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
otakuto |
ed7dcd |
std::swap(p00_a, p01_a);
|
|
otakuto |
ed7dcd |
std::swap(p10_a, p11_a);
|
|
Shinya Kitaoka |
120a6e |
}*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*TRectD source;
|
|
Shinya Kitaoka |
120a6e |
source.x0 = std::min(p00_b.x, p10_b.x, p01_b.x, p11_b.x);
|
|
Shinya Kitaoka |
120a6e |
source.y0 = std::min(p00_b.y, p10_b.y, p01_b.y, p11_b.y);
|
|
Shinya Kitaoka |
120a6e |
source.x1 = std::max(p00_b.x, p10_b.x, p01_b.x, p11_b.x);
|
|
Shinya Kitaoka |
120a6e |
source.y1 = std::max(p00_b.y, p10_b.y, p01_b.y, p11_b.y);
|
|
Shinya Kitaoka |
120a6e |
bBox *= source;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int distortType = m_distortType->getValue();
|
|
Shinya Kitaoka |
120a6e |
if(distortType == PERSPECTIVE)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
PerspectiveDistorter distorter(
|
|
Shinya Kitaoka |
120a6e |
p00_b, p10_b, p01_b, p11_b,
|
|
Shinya Kitaoka |
120a6e |
p00_a, p10_a, p01_a, p11_a
|
|
Shinya Kitaoka |
120a6e |
);
|
|
Shinya Kitaoka |
120a6e |
bBox = distorter.map(bBox);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else if(distortType == BILINEAR)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
BilinearDistorter distorter(
|
|
Shinya Kitaoka |
120a6e |
p00_b, p10_b, p01_b, p11_b,
|
|
Shinya Kitaoka |
120a6e |
p00_a, p10_a, p01_a, p11_a
|
|
Shinya Kitaoka |
120a6e |
);
|
|
Shinya Kitaoka |
120a6e |
bBox = distorter.map(bBox);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else assert(0);*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Further, we will also avoid the assumption that the bbox
|
|
Shinya Kitaoka |
120a6e |
// is defined by that of destination points...
|
|
Shinya Kitaoka |
120a6e |
/*TRectD result;
|
|
Shinya Kitaoka |
120a6e |
result.x0 = std::min(p00_a.x, p10_a.x, p01_a.x, p11_a.x);
|
|
Shinya Kitaoka |
120a6e |
result.y0 = std::min(p00_a.y, p10_a.y, p01_a.y, p11_a.y);
|
|
Shinya Kitaoka |
120a6e |
result.x1 = std::max(p00_a.x, p10_a.x, p01_a.x, p11_a.x);
|
|
Shinya Kitaoka |
120a6e |
result.y1 = std::max(p00_a.y, p10_a.y, p01_a.y, p11_a.y);
|
|
Shinya Kitaoka |
120a6e |
bBox = result; //bBox *= result;*/
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
bBox = TRectD();
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_upBlur->getValue(frame) > 0 || m_downBlur->getValue(frame) > 0) {
|
|
Shinya Kitaoka |
120a6e |
int brad = std::max((int)m_upBlur->getValue(frame),
|
|
Shinya Kitaoka |
120a6e |
(int)m_downBlur->getValue(frame));
|
|
Shinya Kitaoka |
120a6e |
bBox.x0 -= brad;
|
|
Shinya Kitaoka |
120a6e |
bBox.x1 += brad;
|
|
Shinya Kitaoka |
120a6e |
bBox.y0 -= brad;
|
|
Shinya Kitaoka |
120a6e |
bBox.y1 += brad;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FreeDistortBaseFx::transform(double frame, int port,
|
|
Shinya Kitaoka |
120a6e |
const TRectD &rectOnOutput,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &infoOnOutput,
|
|
Shinya Kitaoka |
120a6e |
TRectD &rectOnInput,
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings &infoOnInput) {
|
|
Shinya Kitaoka |
120a6e |
TPointD p00_b = m_p00_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p10_b = m_p10_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p01_b = m_p01_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p11_b = m_p11_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD p00_a = m_p00_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p10_a = m_p10_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p01_a = m_p01_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p11_a = m_p11_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_isCastShadow) {
|
|
Shinya Kitaoka |
120a6e |
// Shadows are mirrored
|
|
otakuto |
ed7dcd |
std::swap(p00_a, p01_a);
|
|
otakuto |
ed7dcd |
std::swap(p10_a, p11_a);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build the input affine
|
|
Shinya Kitaoka |
120a6e |
infoOnInput = infoOnOutput;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double scale = 0;
|
|
Shinya Kitaoka |
120a6e |
scale = std::max(scale, norm(p10_a - p00_a) / norm(p10_b - p00_b));
|
|
Shinya Kitaoka |
120a6e |
scale = std::max(scale, norm(p01_a - p00_a) / norm(p01_b - p00_b));
|
|
Shinya Kitaoka |
120a6e |
scale = std::max(scale, norm(p11_a - p10_a) / norm(p11_b - p10_b));
|
|
Shinya Kitaoka |
120a6e |
scale = std::max(scale, norm(p11_a - p01_a) / norm(p11_b - p01_b));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
scale *= sqrt(fabs(infoOnInput.m_affine.det()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (infoOnOutput.m_isSwatch) {
|
|
Shinya Kitaoka |
120a6e |
// Swatch viewers work out a lite version of the distort: only contractions
|
|
Shinya Kitaoka |
120a6e |
// are passed below in the schematic - so that input memory load is always
|
|
Shinya Kitaoka |
120a6e |
// at minimum.
|
|
Shinya Kitaoka |
120a6e |
// This is allowed in order to make fx adjusts the less frustrating as
|
|
Shinya Kitaoka |
120a6e |
// possible.
|
|
Shinya Kitaoka |
120a6e |
if (scale > 1) scale = 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
infoOnInput.m_affine = TScale(scale);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build rectOnInput
|
|
Shinya Kitaoka |
120a6e |
p00_a = infoOnOutput.m_affine * p00_a;
|
|
Shinya Kitaoka |
120a6e |
p10_a = infoOnOutput.m_affine * p10_a;
|
|
Shinya Kitaoka |
120a6e |
p01_a = infoOnOutput.m_affine * p01_a;
|
|
Shinya Kitaoka |
120a6e |
p11_a = infoOnOutput.m_affine * p11_a;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p00_b = infoOnInput.m_affine * p00_b;
|
|
Shinya Kitaoka |
120a6e |
p10_b = infoOnInput.m_affine * p10_b;
|
|
Shinya Kitaoka |
120a6e |
p01_b = infoOnInput.m_affine * p01_b;
|
|
Shinya Kitaoka |
120a6e |
p11_b = infoOnInput.m_affine * p11_b;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_distortType->getValue() == PERSPECTIVE) {
|
|
Shinya Kitaoka |
120a6e |
PerspectiveDistorter pd(p00_b, p10_b, p01_b, p11_b, p00_a, p10_a, p01_a,
|
|
Shinya Kitaoka |
120a6e |
p11_a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rectOnInput = ((TQuadDistorter *)&pd)->invMap(rectOnOutput);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
BilinearDistorter bd(p00_b, p10_b, p01_b, p11_b, p00_a, p10_a, p01_a,
|
|
Shinya Kitaoka |
120a6e |
p11_a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rectOnInput = ((TQuadDistorter *)&bd)->invMap(rectOnOutput);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (rectOnInput.x0 != TConsts::infiniteRectD.x0)
|
|
Shinya Kitaoka |
120a6e |
rectOnInput.x0 = tfloor(rectOnInput.x0);
|
|
Shinya Kitaoka |
120a6e |
if (rectOnInput.y0 != TConsts::infiniteRectD.y0)
|
|
Shinya Kitaoka |
120a6e |
rectOnInput.y0 = tfloor(rectOnInput.y0);
|
|
Shinya Kitaoka |
120a6e |
if (rectOnInput.x1 != TConsts::infiniteRectD.x1)
|
|
Shinya Kitaoka |
120a6e |
rectOnInput.x1 = tceil(rectOnInput.x1);
|
|
Shinya Kitaoka |
120a6e |
if (rectOnInput.y1 != TConsts::infiniteRectD.y1)
|
|
Shinya Kitaoka |
120a6e |
rectOnInput.y1 = tceil(rectOnInput.y1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FreeDistortBaseFx::safeTransform(double frame, int port,
|
|
Shinya Kitaoka |
120a6e |
const TRectD &rectOnOutput,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &infoOnOutput,
|
|
Shinya Kitaoka |
120a6e |
TRectD &rectOnInput,
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings &infoOnInput,
|
|
Shinya Kitaoka |
120a6e |
TRectD &inBBox) {
|
|
Shinya Kitaoka |
120a6e |
assert(port == 0 && m_input.isConnected());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_deactivate->getValue()) {
|
|
Shinya Kitaoka |
120a6e |
infoOnInput = infoOnOutput;
|
|
Shinya Kitaoka |
120a6e |
rectOnInput = rectOnOutput;
|
|
Shinya Kitaoka |
120a6e |
m_input->getBBox(frame, inBBox, infoOnInput);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Avoid the singular matrix cases
|
|
Shinya Kitaoka |
120a6e |
if (fabs(infoOnOutput.m_affine.det()) < 1.e-3) {
|
|
Shinya Kitaoka |
120a6e |
infoOnInput = infoOnOutput;
|
|
Shinya Kitaoka |
120a6e |
rectOnInput.empty();
|
|
Shinya Kitaoka |
120a6e |
m_input->getBBox(frame, inBBox, infoOnInput);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
transform(frame, port, rectOnOutput, infoOnOutput, rectOnInput, infoOnInput);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_input->getBBox(frame, inBBox, infoOnInput);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// In case inBBox is infinite, such as with gradients, also intersect with the
|
|
Shinya Kitaoka |
120a6e |
// input quadrilateral's bbox
|
|
Shinya Kitaoka |
120a6e |
if (inBBox == TConsts::infiniteRectD) {
|
|
Shinya Kitaoka |
120a6e |
TPointD affP00_b(infoOnInput.m_affine * m_p00_b->getValue(frame));
|
|
Shinya Kitaoka |
120a6e |
TPointD affP10_b(infoOnInput.m_affine * m_p10_b->getValue(frame));
|
|
Shinya Kitaoka |
120a6e |
TPointD affP01_b(infoOnInput.m_affine * m_p01_b->getValue(frame));
|
|
Shinya Kitaoka |
120a6e |
TPointD affP11_b(infoOnInput.m_affine * m_p11_b->getValue(frame));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD source;
|
|
Shinya Kitaoka |
120a6e |
source.x0 = std::min({affP00_b.x, affP10_b.x, affP01_b.x, affP11_b.x});
|
|
Shinya Kitaoka |
120a6e |
source.y0 = std::min({affP00_b.y, affP10_b.y, affP01_b.y, affP11_b.y});
|
|
Shinya Kitaoka |
120a6e |
source.x1 = std::max({affP00_b.x, affP10_b.x, affP01_b.x, affP11_b.x});
|
|
Shinya Kitaoka |
120a6e |
source.y1 = std::max({affP00_b.y, affP10_b.y, affP01_b.y, affP11_b.y});
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rectOnInput *= source;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FreeDistortBaseFx::getParamUIs(TParamUIConcept *&concepts, int &length) {
|
|
shun-iwasawa |
6817df |
concepts = new TParamUIConcept[length = 6];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_type = TParamUIConcept::QUAD;
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_params.push_back(m_p01_b);
|
|
shun-iwasawa |
6817df |
concepts[0].m_params.push_back(m_p11_b);
|
|
shun-iwasawa |
6817df |
concepts[0].m_params.push_back(m_p10_b);
|
|
shun-iwasawa |
6817df |
concepts[0].m_params.push_back(m_p00_b);
|
|
shun-iwasawa |
6817df |
concepts[0].m_label = " Src";
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[1].m_type = TParamUIConcept::QUAD;
|
|
Shinya Kitaoka |
120a6e |
concepts[1].m_params.push_back(m_p01_a);
|
|
shun-iwasawa |
6817df |
concepts[1].m_params.push_back(m_p11_a);
|
|
shun-iwasawa |
6817df |
concepts[1].m_params.push_back(m_p10_a);
|
|
shun-iwasawa |
6817df |
concepts[1].m_params.push_back(m_p00_a);
|
|
shun-iwasawa |
6817df |
concepts[1].m_label = " Dst";
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[2].m_type = TParamUIConcept::VECTOR;
|
|
Shinya Kitaoka |
120a6e |
concepts[2].m_params.push_back(m_p00_b);
|
|
Shinya Kitaoka |
120a6e |
concepts[2].m_params.push_back(m_p00_a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[3].m_type = TParamUIConcept::VECTOR;
|
|
Shinya Kitaoka |
120a6e |
concepts[3].m_params.push_back(m_p10_b);
|
|
Shinya Kitaoka |
120a6e |
concepts[3].m_params.push_back(m_p10_a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[4].m_type = TParamUIConcept::VECTOR;
|
|
Shinya Kitaoka |
120a6e |
concepts[4].m_params.push_back(m_p01_b);
|
|
Shinya Kitaoka |
120a6e |
concepts[4].m_params.push_back(m_p01_a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[5].m_type = TParamUIConcept::VECTOR;
|
|
Shinya Kitaoka |
120a6e |
concepts[5].m_params.push_back(m_p11_b);
|
|
Shinya Kitaoka |
120a6e |
concepts[5].m_params.push_back(m_p11_a);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pix=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void doFade(TRasterPT<pix> &ras, PIX col, double intensity) {</pix>
|
|
Shinya Kitaoka |
120a6e |
double maxChannelValueD = PIX::maxChannelValue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int j;
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < ras->getLy(); j++) {
|
|
Shinya Kitaoka |
120a6e |
PIX *pix = ras->pixels(j);
|
|
Shinya Kitaoka |
120a6e |
PIX *endPix = pix + ras->getLx();
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) {
|
|
Shinya Kitaoka |
120a6e |
if (pix->m > 0) {
|
|
Shinya Kitaoka |
120a6e |
double factor = pix->m / maxChannelValueD;
|
|
Shinya Kitaoka |
120a6e |
int val;
|
|
Shinya Kitaoka |
120a6e |
val = troundp(pix->r + intensity * (col.r * factor - pix->r));
|
|
Shinya Kitaoka |
120a6e |
pix->r = (val > PIX::maxChannelValue) ? PIX::maxChannelValue : val;
|
|
Shinya Kitaoka |
120a6e |
val = troundp(pix->g + intensity * (col.g * factor - pix->g));
|
|
Shinya Kitaoka |
120a6e |
pix->g = (val > PIX::maxChannelValue) ? PIX::maxChannelValue : val;
|
|
Shinya Kitaoka |
120a6e |
val = troundp(pix->b + intensity * (col.b * factor - pix->b));
|
|
Shinya Kitaoka |
120a6e |
pix->b = (val > PIX::maxChannelValue) ? PIX::maxChannelValue : val;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++pix;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pix=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void doTransparency(TRasterPT<pix> &ras, double downTransp, double upTransp,</pix>
|
|
Shinya Kitaoka |
120a6e |
double y0, double y1) {
|
|
Shinya Kitaoka |
120a6e |
assert(y0 <= 0.0 && y1 >= ras->getLy() - 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double den = y1 - y0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int j;
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < ras->getLy(); j++) {
|
|
Shinya Kitaoka |
120a6e |
double transp = (1 - downTransp) + (downTransp - upTransp) * (j - y0) / den;
|
|
Shinya Kitaoka |
120a6e |
PIX *pix = ras->pixels(j);
|
|
Shinya Kitaoka |
120a6e |
PIX *endPix = pix + ras->getLx();
|
|
Shinya Kitaoka |
120a6e |
while (pix < endPix) {
|
|
Shinya Kitaoka |
120a6e |
if (pix->m > 0) {
|
|
Shinya Kitaoka |
120a6e |
pix->r = troundp(pix->r * transp);
|
|
Shinya Kitaoka |
120a6e |
pix->g = troundp(pix->g * transp);
|
|
Shinya Kitaoka |
120a6e |
pix->b = troundp(pix->b * transp);
|
|
Shinya Kitaoka |
120a6e |
pix->m = troundp(pix->m * transp);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++pix;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pix=""></typename>
|
|
Shinya Kitaoka |
120a6e |
inline void filterPixel(PIX *bufin, int wrap, PIX *bufout, double blur,
|
|
Shinya Kitaoka |
120a6e |
int coord, int maxVal) {
|
|
Shinya Kitaoka |
120a6e |
int rad, k, index;
|
|
Shinya Kitaoka |
120a6e |
double coeff, weight;
|
|
Shinya Kitaoka |
120a6e |
double valr = 0.0, valg = 0.0, valb = 0.0, valm = 0.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rad = tceil(blur);
|
|
Shinya Kitaoka |
120a6e |
coeff = 1.0 / rad;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
valr = bufin[0].r;
|
|
Shinya Kitaoka |
120a6e |
valg = bufin[0].g;
|
|
Shinya Kitaoka |
120a6e |
valb = bufin[0].b;
|
|
Shinya Kitaoka |
120a6e |
valm = bufin[0].m;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (k = 1, index = wrap, weight = (1 - coeff); k < rad;
|
|
Shinya Kitaoka |
120a6e |
k++, index += wrap, weight -= coeff) {
|
|
Shinya Kitaoka |
120a6e |
if (k + coord < maxVal) {
|
|
Shinya Kitaoka |
120a6e |
if (-k + coord >= 0) {
|
|
Shinya Kitaoka |
120a6e |
valr += (bufin[index].r + bufin[-index].r) * weight;
|
|
Shinya Kitaoka |
120a6e |
valg += (bufin[index].g + bufin[-index].g) * weight;
|
|
Shinya Kitaoka |
120a6e |
valb += (bufin[index].b + bufin[-index].b) * weight;
|
|
Shinya Kitaoka |
120a6e |
valm += (bufin[index].m + bufin[-index].m) * weight;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
valr += bufin[index].r * weight;
|
|
Shinya Kitaoka |
120a6e |
valg += bufin[index].g * weight;
|
|
Shinya Kitaoka |
120a6e |
valb += bufin[index].b * weight;
|
|
Shinya Kitaoka |
120a6e |
valm += bufin[index].m * weight;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (-k + coord >= 0) {
|
|
Shinya Kitaoka |
120a6e |
if (k + coord < maxVal) {
|
|
Shinya Kitaoka |
120a6e |
valr += (bufin[index].r + bufin[-index].r) * weight;
|
|
Shinya Kitaoka |
120a6e |
valg += (bufin[index].g + bufin[-index].g) * weight;
|
|
Shinya Kitaoka |
120a6e |
valb += (bufin[index].b + bufin[-index].b) * weight;
|
|
Shinya Kitaoka |
120a6e |
valm += (bufin[index].m + bufin[-index].m) * weight;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
valr += bufin[-index].r * weight;
|
|
Shinya Kitaoka |
120a6e |
valg += bufin[-index].g * weight;
|
|
Shinya Kitaoka |
120a6e |
valb += bufin[-index].b * weight;
|
|
Shinya Kitaoka |
120a6e |
valm += bufin[-index].m * weight;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
valr *= coeff;
|
|
Shinya Kitaoka |
120a6e |
valg *= coeff;
|
|
Shinya Kitaoka |
120a6e |
valb *= coeff;
|
|
Shinya Kitaoka |
120a6e |
valm *= coeff;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bufout->r = troundp(valr);
|
|
Shinya Kitaoka |
120a6e |
bufout->g = troundp(valg);
|
|
Shinya Kitaoka |
120a6e |
bufout->b = troundp(valb);
|
|
Shinya Kitaoka |
120a6e |
bufout->m = troundp(valm);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*----------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename pix=""></typename>
|
|
Shinya Kitaoka |
120a6e |
void doBlur(TRasterPT<pix> &r, double blur0, double blur1, double transp0,</pix>
|
|
Shinya Kitaoka |
120a6e |
double transp1, double y0, double y1) {
|
|
Shinya Kitaoka |
120a6e |
int lx, ly, wrap;
|
|
Shinya Kitaoka |
120a6e |
int i, j, brad, blur_max;
|
|
Shinya Kitaoka |
120a6e |
PIX *bufin, *bufout, *pixin, *pixout, *row;
|
|
Shinya Kitaoka |
120a6e |
double cur_blur, actual_blur, blur_incr, cur_transp, actual_transp,
|
|
Shinya Kitaoka |
120a6e |
transp_incr;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
lx = r->getLx();
|
|
Shinya Kitaoka |
120a6e |
ly = r->getLy();
|
|
Shinya Kitaoka |
120a6e |
wrap = r->getWrap();
|
|
Shinya Kitaoka |
120a6e |
blur_max = (int)std::max(blur0, blur1);
|
|
Shinya Kitaoka |
120a6e |
brad = tceil(blur_max);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// assert(y0 <= brad && y1 >= r->getLy()-1 - 2 * brad + y0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double den = y1 - y0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
blur_incr = (blur1 - blur0) / den;
|
|
Shinya Kitaoka |
120a6e |
transp_incr = (transp0 - transp1) / den;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
row = new PIX[std::max(lx, ly)];
|
|
Shinya Kitaoka |
120a6e |
r->lock();
|
|
Shinya Kitaoka |
120a6e |
bufin = r->pixels(0);
|
|
Rozhuk Ivan |
823a31 |
for (i = 0, cur_blur = blur0 + (blur1 - blur0) * (i - y0) / den,
|
|
Shinya Kitaoka |
120a6e |
actual_blur = std::max(cur_blur, 0.0);
|
|
Shinya Kitaoka |
120a6e |
i < ly; i++, bufin += wrap, cur_blur += blur_incr,
|
|
Shinya Kitaoka |
120a6e |
actual_blur = std::max(cur_blur, 0.0)) {
|
|
Shinya Kitaoka |
120a6e |
pixin = bufin;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < lx; j++, pixin++) {
|
|
Shinya Kitaoka |
120a6e |
if (cur_blur > 1.0)
|
|
Shinya Kitaoka |
120a6e |
filterPixel(pixin, 1, row + j, actual_blur, j, lx);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
row[j] = *pixin;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < lx; j++) bufin[j] = row[j];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bufin = r->pixels(0);
|
|
Shinya Kitaoka |
120a6e |
bufout = r->pixels(0);
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < lx; i++, bufin++, bufout++) {
|
|
Shinya Kitaoka |
120a6e |
pixin = bufin;
|
|
Shinya Kitaoka |
120a6e |
pixout = bufout;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (j = 0, cur_blur = blur0 + (blur1 - blur0) * (j - y0) / den,
|
|
Shinya Kitaoka |
120a6e |
actual_blur = std::max(cur_blur, 0.0);
|
|
Shinya Kitaoka |
120a6e |
j < ly; j++, pixin += wrap, cur_blur += blur_incr,
|
|
Shinya Kitaoka |
120a6e |
actual_blur = std::max(cur_blur, 0.0)) {
|
|
Shinya Kitaoka |
120a6e |
if (cur_blur > 1.0)
|
|
Shinya Kitaoka |
120a6e |
filterPixel(pixin, wrap, row + j, actual_blur, j, ly);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
row[j] = *pixin;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (transp0 > 0 || transp1 > 0)
|
|
Shinya Kitaoka |
120a6e |
for (j = 0,
|
|
Shinya Kitaoka |
120a6e |
cur_transp = 1 - transp0 + (transp0 - transp1) * (j - y0) / den,
|
|
Shinya Kitaoka |
120a6e |
actual_transp = std::max(cur_transp, 0.0);
|
|
Shinya Kitaoka |
120a6e |
j < ly; j++, pixout += wrap, cur_transp += transp_incr,
|
|
Shinya Kitaoka |
120a6e |
actual_transp = std::max(cur_transp, 0.0)) {
|
|
Shinya Kitaoka |
120a6e |
pixout->r = troundp(row[j].r * actual_transp);
|
|
Shinya Kitaoka |
120a6e |
pixout->g = troundp(row[j].g * actual_transp);
|
|
Shinya Kitaoka |
120a6e |
pixout->b = troundp(row[j].b * actual_transp);
|
|
Shinya Kitaoka |
120a6e |
pixout->m = troundp(row[j].m * actual_transp);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < ly; j++, pixout += wrap) {
|
|
Shinya Kitaoka |
120a6e |
pixout->r = row[j].r;
|
|
Shinya Kitaoka |
120a6e |
pixout->g = row[j].g;
|
|
Shinya Kitaoka |
120a6e |
pixout->b = row[j].b;
|
|
Shinya Kitaoka |
120a6e |
pixout->m = row[j].m;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
r->unlock();
|
|
Shinya Kitaoka |
120a6e |
delete[] row;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
shun-iwasawa |
6817df |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FreeDistortBaseFx::doDryCompute(TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_input.isConnected()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_deactivate->getValue()) {
|
|
Shinya Kitaoka |
120a6e |
m_input->dryCompute(rect, frame, info);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRectD rectOnInput;
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings infoOnInput;
|
|
Shinya Kitaoka |
120a6e |
TRectD inBBox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
safeTransform(frame, 0, rect, info, rectOnInput, infoOnInput, inBBox);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
rectOnInput *= inBBox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!myIsEmpty(rectOnInput))
|
|
Shinya Kitaoka |
120a6e |
m_input->dryCompute(rectOnInput, frame, infoOnInput);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FreeDistortBaseFx::doCompute(TTile &tile, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &ri) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_input.isConnected()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Upon deactivation, this fx does nothing.
|
|
Shinya Kitaoka |
120a6e |
if (m_deactivate->getValue()) {
|
|
Shinya Kitaoka |
120a6e |
m_input->compute(tile, frame, ri);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Get the source quad
|
|
Shinya Kitaoka |
120a6e |
TPointD p00_b = m_p00_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p10_b = m_p10_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p01_b = m_p01_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p11_b = m_p11_b->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Get destination quad
|
|
Shinya Kitaoka |
120a6e |
TPointD p00_a = m_p00_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p10_a = m_p10_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p01_a = m_p01_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD p11_a = m_p11_a->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_isCastShadow) {
|
|
Shinya Kitaoka |
120a6e |
// Shadows are mirrored
|
|
otakuto |
ed7dcd |
std::swap(p00_a, p01_a);
|
|
otakuto |
ed7dcd |
std::swap(p10_a, p11_a);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Get requested tile's geometry
|
|
Shinya Kitaoka |
120a6e |
TRasterP tileRas(tile.getRaster());
|
|
Shinya Kitaoka |
120a6e |
TRectD tileRect(convert(tileRas->getBounds()) + tile.m_pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Call transform to get the minimal rectOnInput
|
|
Shinya Kitaoka |
120a6e |
TRectD inRect;
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings riNew;
|
|
Shinya Kitaoka |
120a6e |
TRectD inBBox;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
safeTransform(frame, 0, tileRect, ri, inRect, riNew, inBBox);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Intersect with the bbox
|
|
Shinya Kitaoka |
120a6e |
inRect *= inBBox;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (myIsEmpty(inRect)) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double scale = ri.m_affine.a11;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double downBlur = m_downBlur->getValue(frame) * scale;
|
|
Shinya Kitaoka |
120a6e |
double upBlur = m_upBlur->getValue(frame) * scale;
|
|
Shinya Kitaoka |
120a6e |
int brad = tceil(std::max(downBlur, upBlur));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inRect = inRect.enlarge(brad);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDimension inRectSize(tceil(inRect.getLx()), tceil(inRect.getLy()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TTile inTile;
|
|
Shinya Kitaoka |
120a6e |
m_input->allocateAndCompute(inTile, inRect.getP00(), inRectSize, tileRas,
|
|
Shinya Kitaoka |
120a6e |
frame, riNew);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD inTilePosRi = inTile.m_pos;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Update quads by the scale factors
|
|
Shinya Kitaoka |
120a6e |
p00_b = riNew.m_affine * p00_b;
|
|
Shinya Kitaoka |
120a6e |
p10_b = riNew.m_affine * p10_b;
|
|
Shinya Kitaoka |
120a6e |
p01_b = riNew.m_affine * p01_b;
|
|
Shinya Kitaoka |
120a6e |
p11_b = riNew.m_affine * p11_b;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p00_a = ri.m_affine * p00_a;
|
|
Shinya Kitaoka |
120a6e |
p10_a = ri.m_affine * p10_a;
|
|
Shinya Kitaoka |
120a6e |
p01_a = ri.m_affine * p01_a;
|
|
Shinya Kitaoka |
120a6e |
p11_a = ri.m_affine * p11_a;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PerspectiveDistorter perpDistorter(p00_b - inTile.m_pos, p10_b - inTile.m_pos,
|
|
Shinya Kitaoka |
120a6e |
p01_b - inTile.m_pos, p11_b - inTile.m_pos,
|
|
Shinya Kitaoka |
120a6e |
p00_a, p10_a, p01_a, p11_a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
BilinearDistorter bilDistorter(p00_b - inTile.m_pos, p10_b - inTile.m_pos,
|
|
Shinya Kitaoka |
120a6e |
p01_b - inTile.m_pos, p11_b - inTile.m_pos,
|
|
Shinya Kitaoka |
120a6e |
p00_a, p10_a, p01_a, p11_a);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TQuadDistorter *distorter;
|
|
Shinya Kitaoka |
120a6e |
if (m_distortType->getValue() == PERSPECTIVE)
|
|
Shinya Kitaoka |
120a6e |
distorter = &perpDistorter;
|
|
Shinya Kitaoka |
120a6e |
else if (m_distortType->getValue() == BILINEAR)
|
|
Shinya Kitaoka |
120a6e |
distorter = &bilDistorter;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
assert(0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_isCastShadow) {
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras32 = inTile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
TRaster64P ras64 = inTile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ras32) {
|
|
Shinya Kitaoka |
120a6e |
if (m_fade->getValue(frame) > 0)
|
|
Shinya Kitaoka |
120a6e |
doFade(ras32, m_color->getValue(frame),
|
|
Shinya Kitaoka |
120a6e |
m_fade->getValue(frame) / 100.0);
|
|
Shinya Kitaoka |
120a6e |
if (brad > 0)
|
|
Shinya Kitaoka |
120a6e |
doBlur(ras32, upBlur, downBlur, m_upTransp->getValue(frame) / 100.0,
|
|
Shinya Kitaoka |
120a6e |
m_downTransp->getValue(frame) / 100.0,
|
|
Shinya Kitaoka |
120a6e |
inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y);
|
|
Shinya Kitaoka |
120a6e |
else if (m_upTransp->getValue(frame) > 0 ||
|
|
Shinya Kitaoka |
120a6e |
m_downTransp->getValue(frame) > 0)
|
|
Shinya Kitaoka |
120a6e |
doTransparency(ras32, m_upTransp->getValue(frame) / 100.0,
|
|
Shinya Kitaoka |
120a6e |
m_downTransp->getValue(frame) / 100.0,
|
|
Shinya Kitaoka |
120a6e |
inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y);
|
|
Shinya Kitaoka |
120a6e |
} else if (ras64) {
|
|
Shinya Kitaoka |
120a6e |
if (m_fade->getValue(frame) > 0)
|
|
Shinya Kitaoka |
120a6e |
doFade(ras64, toPixel64(m_color->getValue(frame)),
|
|
Shinya Kitaoka |
120a6e |
m_fade->getValue(frame) / 100.0);
|
|
Shinya Kitaoka |
120a6e |
if (brad > 0)
|
|
Shinya Kitaoka |
120a6e |
doBlur(ras64, upBlur, downBlur, m_upTransp->getValue(frame) / 100.0,
|
|
Shinya Kitaoka |
120a6e |
m_downTransp->getValue(frame) / 100.0,
|
|
Shinya Kitaoka |
120a6e |
inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y);
|
|
Shinya Kitaoka |
120a6e |
else if (m_upTransp->getValue(frame) > 0 ||
|
|
Shinya Kitaoka |
120a6e |
m_downTransp->getValue(frame) > 0)
|
|
Shinya Kitaoka |
120a6e |
doTransparency(ras64, m_upTransp->getValue(frame) / 100.0,
|
|
Shinya Kitaoka |
120a6e |
m_downTransp->getValue(frame) / 100.0,
|
|
Shinya Kitaoka |
120a6e |
inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
distort(tileRas, inTile.getRaster(), *distorter, convert(tile.m_pos),
|
|
Shinya Kitaoka |
120a6e |
TRop::Bilinear);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int FreeDistortBaseFx::getMemoryRequirement(const TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_input.isConnected()) return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRectD inRect;
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings riNew;
|
|
Shinya Kitaoka |
120a6e |
TRectD inBBox;
|
|
Shinya Kitaoka |
120a6e |
safeTransform(frame, 0, rect, info, inRect, riNew, inBBox);
|
|
Shinya Kitaoka |
120a6e |
inRect *= inBBox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return TRasterFx::memorySize(inRect, riNew.m_bpp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(FreeDistortFx, "freeDistortFx");
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(CastShadowFx, "castShadowFx");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*----------------------------------------------------------------------------*/
|