|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
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 "ttzpimagefx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tdistort.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "texturefxP.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; }
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class CornerPinFx final : public TStandardRasterFx {
|
|
Shinya Kitaoka |
120a6e |
FX_PLUGIN_DECLARATION(CornerPinFx)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
enum { PERSPECTIVE, BILINEAR };
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
CornerPinFx();
|
|
Shinya Kitaoka |
120a6e |
~CornerPinFx();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
bool doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
38fd86 |
const TRenderSettings &info) override;
|
|
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 &info) override;
|
|
Shinya Kitaoka |
120a6e |
int getMemoryRequirement(const TRectD &rect, double frame,
|
|
Shinya Kitaoka |
473e70 |
const TRenderSettings &info) override;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void onPortConnected(TFxPort *port);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
38fd86 |
bool canHandle(const TRenderSettings &info, double frame) override {
|
|
Shinya Kitaoka |
38fd86 |
return true;
|
|
Shinya Kitaoka |
38fd86 |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
bool allowUserCacheOnPort(int port) override { return port != 0; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
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;
|
|
Toshihiro Shimizu |
890ddd |
|
|
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);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort m_input;
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort m_texture;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TIntEnumParamP m_distortType;
|
|
Toshihiro Shimizu |
890ddd |
|
|
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;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TBoolParamP m_deactivate;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStringParamP m_string;
|
|
Shinya Kitaoka |
120a6e |
TIntEnumParamP m_mode;
|
|
Shinya Kitaoka |
120a6e |
TIntEnumParamP m_keep;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_value;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TAffine getPort1Affine(double frame) const;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
CornerPinFx::CornerPinFx()
|
|
Shinya Kitaoka |
120a6e |
: m_distortType(new TIntEnumParam(PERSPECTIVE, "Perspective"))
|
|
Shinya Kitaoka |
120a6e |
, m_deactivate(false)
|
|
Shinya Kitaoka |
120a6e |
, m_string(L"1,2,3")
|
|
Shinya Kitaoka |
120a6e |
, m_mode(new TIntEnumParam(SUBSTITUTE, "Texture"))
|
|
Shinya Kitaoka |
120a6e |
, m_keep(new TIntEnumParam(0, "Delete"))
|
|
Shinya Kitaoka |
120a6e |
, m_value(100) {
|
|
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 |
bindParam(this, "deactivate", m_deactivate);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "indexes", m_string);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "mode", m_mode);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "keep", m_keep);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "value", m_value);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
addInputPort("source", m_input);
|
|
Shinya Kitaoka |
120a6e |
addInputPort("Texture", m_texture);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_value->setValueRange(0, 100);
|
|
Shinya Kitaoka |
120a6e |
m_keep->addItem(1, "Keep");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_mode->addItem(PATTERNTYPE, "Pattern");
|
|
Shinya Kitaoka |
120a6e |
m_mode->addItem(ADD, "Add");
|
|
Shinya Kitaoka |
120a6e |
m_mode->addItem(SUBTRACT, "Subtract");
|
|
Shinya Kitaoka |
120a6e |
m_mode->addItem(MULTIPLY, "Multiply");
|
|
Shinya Kitaoka |
120a6e |
m_mode->addItem(LIGHTEN, "Lighten");
|
|
Shinya Kitaoka |
120a6e |
m_mode->addItem(DARKEN, "Darken");
|
|
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");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
CornerPinFx::~CornerPinFx() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool CornerPinFx::doGetBBox(double frame, TRectD &bBox,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (m_input.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
bool ret = m_input->doGetBBox(frame, bBox, info);
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
bBox = TRectD();
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TAffine CornerPinFx::getPort1Affine(double frame) const {
|
|
Shinya Kitaoka |
120a6e |
// Explanation: Fxs tree decomposition on n-ary fxs (n>1) works the following
|
|
Shinya Kitaoka |
120a6e |
// way.
|
|
Shinya Kitaoka |
120a6e |
// Fxs on port 0 are considered 'column representants' - so affines found on
|
|
Shinya Kitaoka |
120a6e |
// them
|
|
Shinya Kitaoka |
120a6e |
// must be passed throughout the tree hierarchy. Therefore, their inverses are
|
|
Shinya Kitaoka |
120a6e |
// multiplied
|
|
Shinya Kitaoka |
120a6e |
// just below the other input ports in order to push the former affine above.
|
|
Shinya Kitaoka |
120a6e |
// In other words:
|
|
Shinya Kitaoka |
120a6e |
// port 0: A -| ---|
|
|
Shinya Kitaoka |
120a6e |
// +-- => + A --
|
|
Shinya Kitaoka |
120a6e |
// port >0: B -| B - (Ainv) -|
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve the affine that lies just below texture's port.
|
|
Shinya Kitaoka |
120a6e |
TGeometryFx *AinvFx = dynamic_cast<tgeometryfx *="">(m_texture.getFx());</tgeometryfx>
|
|
Shinya Kitaoka |
120a6e |
if (!AinvFx) return TAffine();
|
|
Shinya Kitaoka |
120a6e |
TGeometryFx *BFx =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tgeometryfx *="">(AinvFx->getInputPort(0)->getFx());</tgeometryfx>
|
|
Shinya Kitaoka |
120a6e |
if (!BFx) return AinvFx->getPlacement(frame);
|
|
Shinya Kitaoka |
120a6e |
return AinvFx->getPlacement(frame) * BFx->getPlacement(frame);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CornerPinFx::transform(double frame, int port, const TRectD &rectOnOutput,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &infoOnOutput,
|
|
Shinya Kitaoka |
120a6e |
TRectD &rectOnInput, TRenderSettings &infoOnInput) {
|
|
Shinya Kitaoka |
120a6e |
// Build the input affine
|
|
Shinya Kitaoka |
120a6e |
infoOnInput = infoOnOutput;
|
|
Shinya Kitaoka |
120a6e |
|
|
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 |
// NOTE 1: An appropriate scale factor is sent below in the schematic,
|
|
Shinya Kitaoka |
120a6e |
// depending
|
|
Shinya Kitaoka |
120a6e |
// on the image distortion. For example, if the distortion brings a 2 scale
|
|
Shinya Kitaoka |
120a6e |
// factor,
|
|
Shinya Kitaoka |
120a6e |
// we want the same factor applied on image levels, so that their detail is
|
|
Shinya Kitaoka |
120a6e |
// appropriate
|
|
Shinya Kitaoka |
120a6e |
//(especially for vector images).
|
|
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 |
TAffine A_1B(getPort1Affine(frame));
|
|
Shinya Kitaoka |
120a6e |
TAffine B(infoOnOutput.m_affine * A_1B);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
scale *= sqrt(fabs(B.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 |
// NOTE 2: We further include A_1B.inv() to be applied on the level. This is
|
|
Shinya Kitaoka |
120a6e |
// done to
|
|
Shinya Kitaoka |
120a6e |
// counter the presence of A_1B just below this node - since it is preferable
|
|
Shinya Kitaoka |
120a6e |
// to place A_1B
|
|
Shinya Kitaoka |
120a6e |
// directly in the distort.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
infoOnInput.m_affine = TScale(scale) * A_1B.inv();
|
|
Shinya Kitaoka |
120a6e |
// rectOnInput = (TScale(scale) * B.inv()) * rectOnOutput;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// NOTE 3: The original distortion points are intended on the source port
|
|
Shinya Kitaoka |
120a6e |
// *before* applying A.
|
|
Shinya Kitaoka |
120a6e |
// But we want to have them on texture port *before* applying B; so, the
|
|
Shinya Kitaoka |
120a6e |
// following ref change arises:
|
|
Shinya Kitaoka |
120a6e |
// p_b = (TScale(scale) * A_1B.inv()) * p_b == infoOnInput.m_aff * p_b;
|
|
Shinya Kitaoka |
120a6e |
// p_a = (B * A_1B.inv()) * p_a == infoOnOutput.m_aff * p_a;
|
|
Shinya Kitaoka |
120a6e |
// Observe that scale and B are here due to NOTES 1 and 2.
|
|
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 CornerPinFx::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, TRectD &inBBox) {
|
|
Shinya Kitaoka |
120a6e |
assert(port == 1 && m_texture.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_texture->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_texture->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_texture->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 CornerPinFx::doDryCompute(TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &ri) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_input.isConnected()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::string> items;</std::string>
|
|
Shinya Kitaoka |
120a6e |
std::string indexes = ::to_string(m_string->getValue());
|
|
Shinya Kitaoka |
120a6e |
parseIndexes(indexes, items);
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings ri2(ri);
|
|
Shinya Kitaoka |
120a6e |
PaletteFilterFxRenderData *PaletteFilterData = new PaletteFilterFxRenderData;
|
|
Shinya Kitaoka |
120a6e |
TRasterFxRenderDataP smartP(PaletteFilterData);
|
|
Shinya Kitaoka |
120a6e |
insertIndexes(items, PaletteFilterData);
|
|
Shinya Kitaoka |
120a6e |
PaletteFilterData->m_keep = (m_keep->getValue() == 1);
|
|
Shinya Kitaoka |
120a6e |
ri2.m_data.push_back(PaletteFilterData);
|
|
Shinya Kitaoka |
120a6e |
ri2.m_userCachable = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// First child compute: part of output that IS NOT texturized
|
|
Shinya Kitaoka |
120a6e |
m_input->dryCompute(rect, frame, ri2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_texture.isConnected()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isSwatch = ri2.m_isSwatch;
|
|
Shinya Kitaoka |
120a6e |
if (isSwatch) ri2.m_isSwatch = false;
|
|
Shinya Kitaoka |
120a6e |
PaletteFilterData->m_keep = !(m_keep->getValue() == 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Second child compute: part of output that IS to be texturized
|
|
Shinya Kitaoka |
120a6e |
m_input->dryCompute(rect, frame, ri2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Deal with the texture
|
|
Shinya Kitaoka |
120a6e |
if (m_deactivate->getValue())
|
|
Shinya Kitaoka |
120a6e |
m_texture->dryCompute(rect, frame, ri);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TRectD inRect;
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings riNew;
|
|
Shinya Kitaoka |
120a6e |
TRectD inBBox;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
safeTransform(frame, 1, rect, ri, inRect, riNew, inBBox);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inRect *= inBBox;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (myIsEmpty(inRect)) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_texture->dryCompute(inRect, frame, riNew);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void CornerPinFx::doCompute(TTile &tile, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &ri) {
|
|
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 |
TTile invertMaskTile;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// carico il vettore items con gli indici dei colori
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::string> items;</std::string>
|
|
Shinya Kitaoka |
120a6e |
std::string indexes = ::to_string(m_string->getValue());
|
|
Shinya Kitaoka |
120a6e |
parseIndexes(indexes, items);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// genero il tile il cui raster contiene l'immagine in input a cui sono stati
|
|
Shinya Kitaoka |
120a6e |
// tolti i pixel
|
|
Shinya Kitaoka |
120a6e |
// colorati con gli indici contenuti nel vettore items
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings ri2(ri);
|
|
Shinya Kitaoka |
120a6e |
PaletteFilterFxRenderData *PaletteFilterData = new PaletteFilterFxRenderData;
|
|
Shinya Kitaoka |
120a6e |
TRasterFxRenderDataP smartP(PaletteFilterData);
|
|
Shinya Kitaoka |
120a6e |
insertIndexes(items, PaletteFilterData);
|
|
Shinya Kitaoka |
120a6e |
PaletteFilterData->m_keep = (m_keep->getValue() == 1);
|
|
Shinya Kitaoka |
120a6e |
ri2.m_data.push_back(PaletteFilterData);
|
|
Shinya Kitaoka |
120a6e |
ri2.m_userCachable = false;
|
|
Shinya Kitaoka |
120a6e |
m_input->allocateAndCompute(invertMaskTile, tile.m_pos,
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->getSize(), tile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
frame, ri2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_texture.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster()->copy(invertMaskTile.getRaster());
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// genero il tile il cui raster contiene l'immagine in input a cui sono stati
|
|
Shinya Kitaoka |
120a6e |
// tolti i pixel
|
|
Shinya Kitaoka |
120a6e |
// colorati con indici diversi da quelli contenuti nel vettore items
|
|
Shinya Kitaoka |
120a6e |
bool isSwatch = ri2.m_isSwatch;
|
|
Shinya Kitaoka |
120a6e |
if (isSwatch) ri2.m_isSwatch = false;
|
|
Shinya Kitaoka |
120a6e |
PaletteFilterData->m_keep = !(m_keep->getValue() == 1);
|
|
Shinya Kitaoka |
120a6e |
m_input->compute(tile, frame, ri2);
|
|
Shinya Kitaoka |
120a6e |
if (isSwatch) ri2.m_isSwatch = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// controllo se ho ottenuto quaclosa su cui si possa lavorare.
|
|
Shinya Kitaoka |
120a6e |
TRect saveBox;
|
|
Shinya Kitaoka |
120a6e |
TRop::computeBBox(tile.getRaster(), saveBox);
|
|
Shinya Kitaoka |
120a6e |
if (saveBox.isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
// I guess that this case should be wiped out...
|
|
Shinya Kitaoka |
120a6e |
m_input->compute(tile, frame, ri); // Could the invertMask be copied??
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Then, generate the texture tile and make its distortion
|
|
Shinya Kitaoka |
120a6e |
TTile textureTile;
|
|
Shinya Kitaoka |
120a6e |
if (m_deactivate->getValue()) {
|
|
Shinya Kitaoka |
120a6e |
TDimension size = tile.getRaster()->getSize();
|
|
Shinya Kitaoka |
120a6e |
TPointD pos = tile.m_pos;
|
|
Shinya Kitaoka |
120a6e |
m_texture->allocateAndCompute(textureTile, pos, size, tile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
frame, ri);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
// Build the interesting texture region
|
|
Shinya Kitaoka |
120a6e |
TRasterP tileRas(tile.getRaster());
|
|
Shinya Kitaoka |
120a6e |
TRectD tileRect(convert(tileRas->getBounds()) + tile.m_pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD inRect;
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings riNew;
|
|
Shinya Kitaoka |
120a6e |
TRectD inBBox;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
safeTransform(frame, 1, tileRect, ri, inRect, riNew, inBBox);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inRect *= inBBox;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (myIsEmpty(inRect)) return;
|
|
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_texture->allocateAndCompute(inTile, inRect.getP00(), inRectSize, tileRas,
|
|
Shinya Kitaoka |
120a6e |
frame, riNew);
|
|
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 |
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 |
TAffine A_1B(getPort1Affine(frame));
|
|
Shinya Kitaoka |
120a6e |
TAffine B(ri.m_affine * A_1B);
|
|
Shinya Kitaoka |
120a6e |
scale *= sqrt(fabs(B.det()));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ri.m_isSwatch)
|
|
Shinya Kitaoka |
120a6e |
if (scale > 1) scale = 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
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(
|
|
Shinya Kitaoka |
120a6e |
p00_b - inTile.m_pos, p10_b - inTile.m_pos, p01_b - inTile.m_pos,
|
|
Shinya Kitaoka |
120a6e |
p11_b - inTile.m_pos, 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 |
TDistorter *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 |
TRasterP textureRas(tileRas->create(tileRas->getLx(), tileRas->getLy()));
|
|
Shinya Kitaoka |
120a6e |
distort(textureRas, inTile.getRaster(), *distorter, convert(tile.m_pos),
|
|
Shinya Kitaoka |
120a6e |
TRop::Bilinear);
|
|
Shinya Kitaoka |
120a6e |
textureTile.m_pos = tile.m_pos;
|
|
Shinya Kitaoka |
120a6e |
textureTile.setRaster(textureRas);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Then, apply the texture
|
|
Shinya Kitaoka |
120a6e |
double v = m_value->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
if (ri.m_bpp == 32) {
|
|
Shinya Kitaoka |
120a6e |
TRaster32P witheCard;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myOver32(tile.getRaster(), invertMaskTile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
&makeOpaque<tpixel32>, v);</tpixel32>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode->getValue()) {
|
|
Shinya Kitaoka |
120a6e |
case SUBSTITUTE:
|
|
Shinya Kitaoka |
120a6e |
myOver32(tile.getRaster(), textureTile.getRaster(), &substitute<tpixel32>,</tpixel32>
|
|
Shinya Kitaoka |
120a6e |
v);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case PATTERNTYPE:
|
|
Shinya Kitaoka |
120a6e |
witheCard = TRaster32P(textureTile.getRaster()->getSize());
|
|
Shinya Kitaoka |
120a6e |
witheCard->fill(TPixel32::White);
|
|
Shinya Kitaoka |
120a6e |
TRop::over(textureTile.getRaster(), witheCard, textureTile.getRaster());
|
|
Shinya Kitaoka |
120a6e |
myOver32(tile.getRaster(), textureTile.getRaster(), &pattern32, v);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ADD:
|
|
Shinya Kitaoka |
120a6e |
myOver32(tile.getRaster(), textureTile.getRaster(), &textureAdd<tpixel32>,</tpixel32>
|
|
Shinya Kitaoka |
120a6e |
v / 100.0);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case SUBTRACT:
|
|
Shinya Kitaoka |
120a6e |
myOver32(tile.getRaster(), textureTile.getRaster(), &textureSub<tpixel32>,</tpixel32>
|
|
Shinya Kitaoka |
120a6e |
v / 100.0);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case MULTIPLY:
|
|
Shinya Kitaoka |
120a6e |
myOver32(tile.getRaster(), textureTile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
&textureMult<tpixel32>, v);</tpixel32>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case DARKEN:
|
|
Shinya Kitaoka |
120a6e |
myOver32(tile.getRaster(), textureTile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
&textureDarken<tpixel32>, v);</tpixel32>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case LIGHTEN:
|
|
Shinya Kitaoka |
120a6e |
myOver32(tile.getRaster(), textureTile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
&textureLighten<tpixel32>, v);</tpixel32>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
assert(0);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
TRaster64P witheCard;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
myOver64(tile.getRaster(), invertMaskTile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
&makeOpaque<tpixel64>, v);</tpixel64>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (m_mode->getValue()) {
|
|
Shinya Kitaoka |
120a6e |
case SUBSTITUTE:
|
|
Shinya Kitaoka |
120a6e |
myOver64(tile.getRaster(), textureTile.getRaster(), &substitute<tpixel64>,</tpixel64>
|
|
Shinya Kitaoka |
120a6e |
v);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case PATTERNTYPE:
|
|
Shinya Kitaoka |
120a6e |
witheCard = TRaster64P(textureTile.getRaster()->getSize());
|
|
Shinya Kitaoka |
120a6e |
witheCard->fill(TPixel64::White);
|
|
Shinya Kitaoka |
120a6e |
TRop::over(textureTile.getRaster(), witheCard, textureTile.getRaster());
|
|
Shinya Kitaoka |
120a6e |
myOver64(tile.getRaster(), textureTile.getRaster(), &pattern64, v);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case ADD:
|
|
Shinya Kitaoka |
120a6e |
myOver64(tile.getRaster(), textureTile.getRaster(), &textureAdd<tpixel64>,</tpixel64>
|
|
Shinya Kitaoka |
120a6e |
v / 100.0);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case SUBTRACT:
|
|
Shinya Kitaoka |
120a6e |
myOver64(tile.getRaster(), textureTile.getRaster(), &textureSub<tpixel64>,</tpixel64>
|
|
Shinya Kitaoka |
120a6e |
v / 100.0);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case MULTIPLY:
|
|
Shinya Kitaoka |
120a6e |
myOver64(tile.getRaster(), textureTile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
&textureMult<tpixel64>, v);</tpixel64>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case DARKEN:
|
|
Shinya Kitaoka |
120a6e |
myOver64(tile.getRaster(), textureTile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
&textureDarken<tpixel64>, v);</tpixel64>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case LIGHTEN:
|
|
Shinya Kitaoka |
120a6e |
myOver64(tile.getRaster(), textureTile.getRaster(),
|
|
Shinya Kitaoka |
120a6e |
&textureLighten<tpixel64>, v);</tpixel64>
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
assert(0);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRop::over(tile.getRaster(), invertMaskTile.getRaster());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int CornerPinFx::getMemoryRequirement(const TRectD &rect, double frame,
|
|
Shinya Kitaoka |
120a6e |
const TRenderSettings &info) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_texture.isConnected()) return TRasterFx::memorySize(rect, info.m_bpp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRectD inRect;
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings riNew;
|
|
Shinya Kitaoka |
120a6e |
TRectD inBBox;
|
|
Shinya Kitaoka |
120a6e |
safeTransform(frame, 1, rect, info, inRect, riNew, inBBox);
|
|
Shinya Kitaoka |
120a6e |
inRect *= inBBox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return std::max(TRasterFx::memorySize(rect, info.m_bpp),
|
|
Shinya Kitaoka |
120a6e |
TRasterFx::memorySize(inRect, riNew.m_bpp));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TRectD CornerPinFx::getContainingBox(const FourPoints &points)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
if(points.m_p00==points.m_p01 && points.m_p01==points.m_p10 &&
|
|
Shinya Kitaoka |
120a6e |
points.m_p10==points.m_p11)
|
|
Shinya Kitaoka |
120a6e |
return TRectD(points.m_p00,points.m_p00);
|
|
Shinya Kitaoka |
120a6e |
double
|
|
Shinya Kitaoka |
120a6e |
xMax=std::max(points.m_p00.x,points.m_p01.x,points.m_p10.x,points.m_p11.x);
|
|
Shinya Kitaoka |
120a6e |
double
|
|
Shinya Kitaoka |
120a6e |
yMax=std::max(points.m_p00.y,points.m_p01.y,points.m_p10.y,points.m_p11.y);
|
|
Shinya Kitaoka |
120a6e |
double
|
|
Shinya Kitaoka |
120a6e |
xMin=std::min(points.m_p00.x,points.m_p01.x,points.m_p10.x,points.m_p11.x);
|
|
Shinya Kitaoka |
120a6e |
double
|
|
Shinya Kitaoka |
120a6e |
yMin=std::min(points.m_p00.y,points.m_p01.y,points.m_p10.y,points.m_p11.y);
|
|
Shinya Kitaoka |
120a6e |
return TRectD(xMin,yMin,xMax, yMax);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
// ------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(CornerPinFx, "cornerPinFx");
|