|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "stdfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tfxparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "warp.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterfx.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tspectrumparam.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "gradients.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "timage_io.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tparamuiconcept.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class RippleFx : public TStandardRasterFx {
|
|
Shinya Kitaoka |
120a6e |
FX_PLUGIN_DECLARATION(RippleFx)
|
|
Toshihiro Shimizu |
890ddd |
protected:
|
|
Shinya Kitaoka |
120a6e |
TRasterFxPort m_warped;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_intensity;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_gridStep;
|
|
Shinya Kitaoka |
120a6e |
TPointParamP m_center;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_period;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_count;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_cycle;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_scaleX;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_scaleY;
|
|
Shinya Kitaoka |
120a6e |
TDoubleParamP m_angle;
|
|
Shinya Kitaoka |
120a6e |
TBoolParamP m_sharpen;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
RippleFx()
|
|
Shinya Kitaoka |
120a6e |
: m_intensity(20)
|
|
Shinya Kitaoka |
120a6e |
, m_gridStep(2)
|
|
Shinya Kitaoka |
120a6e |
, m_center(TPointD(0.0, 0.0))
|
|
Shinya Kitaoka |
120a6e |
, m_period(100) // args, "Period")
|
|
Shinya Kitaoka |
120a6e |
, m_count(2) // args, "Count")
|
|
Shinya Kitaoka |
120a6e |
, m_cycle(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_scaleX(100.0)
|
|
Shinya Kitaoka |
120a6e |
, m_scaleY(100.0)
|
|
Shinya Kitaoka |
120a6e |
, m_angle(0.0)
|
|
Shinya Kitaoka |
120a6e |
, m_sharpen(false) {
|
|
Shinya Kitaoka |
120a6e |
m_center->getX()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_center->getY()->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
m_period->setMeasureName("fxLength");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
addInputPort("Source", m_warped);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "period", m_period);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "count", m_count);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "cycle", m_cycle);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "center", m_center);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "scalex", m_scaleX);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "scaley", m_scaleY);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "angle", m_angle);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "intensity", m_intensity);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "sensitivity", m_gridStep);
|
|
Shinya Kitaoka |
120a6e |
bindParam(this, "sharpen", m_sharpen);
|
|
Shinya Kitaoka |
120a6e |
m_intensity->setValueRange(-1000, 1000);
|
|
Shinya Kitaoka |
120a6e |
m_gridStep->setValueRange(2, 20);
|
|
Shinya Kitaoka |
120a6e |
m_period->setValueRange(0, (std::numeric_limits<double>::max)());</double>
|
|
Shinya Kitaoka |
120a6e |
m_cycle->setValueRange(0, (std::numeric_limits<double>::max)());</double>
|
|
Shinya Kitaoka |
120a6e |
m_count->setValueRange(0, (std::numeric_limits<double>::max)());</double>
|
|
Shinya Kitaoka |
120a6e |
m_angle->setMeasureName("angle");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
virtual ~RippleFx() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
bool canHandle(const TRenderSettings &info, double frame) override {
|
|
Shinya Kitaoka |
120a6e |
return isAlmostIsotropic(info.m_affine);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
bool doGetBBox(double frame, TRectD &bBox, const TRenderSettings &info) override {
|
|
Shinya Kitaoka |
120a6e |
if (m_warped.isConnected()) {
|
|
Shinya Kitaoka |
120a6e |
int ret = m_warped->doGetBBox(frame, bBox, info);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ret && !bBox.isEmpty()) {
|
|
Shinya Kitaoka |
120a6e |
if (bBox != TConsts::infiniteRectD) {
|
|
Shinya Kitaoka |
120a6e |
WarpParams params;
|
|
Shinya Kitaoka |
120a6e |
params.m_intensity = m_intensity->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bBox = bBox.enlarge(getWarpRadius(params));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bBox = TRectD();
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void doDryCompute(TRectD &rect, double frame, const TRenderSettings &info) override {
|
|
Shinya Kitaoka |
120a6e |
bool isWarped = m_warped.isConnected();
|
|
Shinya Kitaoka |
120a6e |
if (!isWarped) return;
|
|
Shinya Kitaoka |
120a6e |
if (fabs(m_intensity->getValue(frame)) < 0.01) {
|
|
Shinya Kitaoka |
120a6e |
m_warped->dryCompute(rect, frame, info);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double scale = sqrt(fabs(info.m_affine.det()));
|
|
Shinya Kitaoka |
120a6e |
double gridStep = 1.5 * m_gridStep->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
WarpParams params;
|
|
Shinya Kitaoka |
120a6e |
params.m_intensity = m_intensity->getValue(frame) / gridStep;
|
|
Shinya Kitaoka |
120a6e |
params.m_warperScale = scale * gridStep;
|
|
Shinya Kitaoka |
120a6e |
params.m_sharpen = m_sharpen->getValue();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD warpedBox, warpedComputeRect, tileComputeRect;
|
|
Shinya Kitaoka |
120a6e |
m_warped->getBBox(frame, warpedBox, info);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, rect,
|
|
Shinya Kitaoka |
120a6e |
params);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0) return;
|
|
Shinya Kitaoka |
120a6e |
if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0)
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_warped->dryCompute(warpedComputeRect, frame, info);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void doCompute(TTile &tile, double frame, const TRenderSettings &info) override {
|
|
Shinya Kitaoka |
120a6e |
bool isWarped = m_warped.isConnected();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!isWarped) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (fabs(m_intensity->getValue(frame)) < 0.01) {
|
|
Shinya Kitaoka |
120a6e |
m_warped->compute(tile, frame, info);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
|
|
Shinya Kitaoka |
120a6e |
double scale = sqrt(fabs(info.m_affine.det()));
|
|
Shinya Kitaoka |
120a6e |
double gridStep = 1.5 * m_gridStep->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
WarpParams params;
|
|
Shinya Kitaoka |
120a6e |
params.m_intensity = m_intensity->getValue(frame) / gridStep;
|
|
Shinya Kitaoka |
120a6e |
params.m_warperScale = scale * gridStep;
|
|
Shinya Kitaoka |
120a6e |
params.m_sharpen = m_sharpen->getValue();
|
|
Shinya Kitaoka |
120a6e |
params.m_shrink = shrink;
|
|
Shinya Kitaoka |
120a6e |
double period = m_period->getValue(frame) / info.m_shrinkX;
|
|
Shinya Kitaoka |
120a6e |
double count = m_count->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
double cycle = m_cycle->getValue(frame) / info.m_shrinkX;
|
|
Shinya Kitaoka |
120a6e |
double scaleX = m_scaleX->getValue(frame) / 100.0;
|
|
Shinya Kitaoka |
120a6e |
double scaleY = m_scaleY->getValue(frame) / 100.0;
|
|
Shinya Kitaoka |
120a6e |
double angle = -m_angle->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
TPointD center = m_center->getValue(frame) * (1.0 / info.m_shrinkX);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// The warper is calculated on a standard reference, with fixed dpi. This
|
|
Shinya Kitaoka |
120a6e |
// makes sure
|
|
Shinya Kitaoka |
120a6e |
// that the lattice created for the warp does not depend on camera
|
|
Shinya Kitaoka |
120a6e |
// transforms and resolution.
|
|
Shinya Kitaoka |
120a6e |
TRenderSettings warperInfo(info);
|
|
Shinya Kitaoka |
120a6e |
double warperScaleFactor = 1.0 / params.m_warperScale;
|
|
Shinya Kitaoka |
120a6e |
warperInfo.m_affine = TScale(warperScaleFactor) * info.m_affine;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Retrieve tile's geometry
|
|
Shinya Kitaoka |
120a6e |
TRectD tileRect;
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TRasterP tileRas = tile.getRaster();
|
|
Shinya Kitaoka |
120a6e |
tileRect =
|
|
Shinya Kitaoka |
120a6e |
TRectD(tile.m_pos, TDimensionD(tileRas->getLx(), tileRas->getLy()));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build the compute rect
|
|
Shinya Kitaoka |
120a6e |
TRectD warpedBox, warpedComputeRect, tileComputeRect;
|
|
Shinya Kitaoka |
120a6e |
m_warped->getBBox(frame, warpedBox, info);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, tileRect,
|
|
Shinya Kitaoka |
120a6e |
params);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (tileComputeRect.getLx() <= 0 || tileComputeRect.getLy() <= 0) return;
|
|
Shinya Kitaoka |
120a6e |
if (warpedComputeRect.getLx() <= 0 || warpedComputeRect.getLy() <= 0)
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
|
|
Shinya Kitaoka |
120a6e |
double warperEnlargement = getWarperEnlargement(params);
|
|
Shinya Kitaoka |
120a6e |
warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
|
|
Shinya Kitaoka |
120a6e |
warperComputeRect.x0 = tfloor(warperComputeRect.x0);
|
|
Shinya Kitaoka |
120a6e |
warperComputeRect.y0 = tfloor(warperComputeRect.y0);
|
|
Shinya Kitaoka |
120a6e |
warperComputeRect.x1 = tceil(warperComputeRect.x1);
|
|
Shinya Kitaoka |
120a6e |
warperComputeRect.y1 = tceil(warperComputeRect.y1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Compute the warped tile
|
|
Shinya Kitaoka |
120a6e |
TTile tileIn;
|
|
Shinya Kitaoka |
120a6e |
m_warped->allocateAndCompute(
|
|
Shinya Kitaoka |
120a6e |
tileIn, warpedComputeRect.getP00(),
|
|
Shinya Kitaoka |
120a6e |
TDimension(warpedComputeRect.getLx(), warpedComputeRect.getLy()),
|
|
Shinya Kitaoka |
120a6e |
tile.getRaster(), frame, info);
|
|
Shinya Kitaoka |
120a6e |
TRasterP rasIn = tileIn.getRaster();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Compute the warper tile
|
|
Shinya Kitaoka |
120a6e |
TSpectrum::ColorKey colors[] = {TSpectrum::ColorKey(0, TPixel32::White),
|
|
Shinya Kitaoka |
120a6e |
TSpectrum::ColorKey(0.5, TPixel32::Black),
|
|
Shinya Kitaoka |
120a6e |
TSpectrum::ColorKey(1, TPixel32::White)};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSpectrumParamP ripplecolors = TSpectrumParamP(tArrayCount(colors), colors);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Build the multiradial
|
|
Shinya Kitaoka |
120a6e |
warperInfo.m_affine = warperInfo.m_affine * TTranslation(center) *
|
|
Shinya Kitaoka |
120a6e |
TRotation(angle) * TScale(scaleX, scaleY);
|
|
Shinya Kitaoka |
120a6e |
TAffine aff = warperInfo.m_affine.inv();
|
|
Shinya Kitaoka |
120a6e |
TPointD posTrasf = aff * (warperComputeRect.getP00());
|
|
Shinya Kitaoka |
120a6e |
TRasterP rasWarper =
|
|
Shinya Kitaoka |
120a6e |
rasIn->create(warperComputeRect.getLx(), warperComputeRect.getLy());
|
|
Shinya Kitaoka |
120a6e |
multiRadial(rasWarper, posTrasf, ripplecolors, period, count, cycle, aff,
|
|
Shinya Kitaoka |
120a6e |
frame);
|
|
Shinya Kitaoka |
120a6e |
// TImageWriter::save(TFilePath("C:\\ripple.tif"), rasWarper);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Warp
|
|
Shinya Kitaoka |
120a6e |
TPointD db;
|
|
Shinya Kitaoka |
120a6e |
TRect rasComputeRectI(convert(tileComputeRect - tileRect.getP00(), db));
|
|
Shinya Kitaoka |
120a6e |
TRasterP tileRas = tile.getRaster()->extract(rasComputeRectI);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD rasInPos(warpedComputeRect.getP00() - tileComputeRect.getP00());
|
|
Shinya Kitaoka |
120a6e |
TPointD warperPos(
|
|
Shinya Kitaoka |
120a6e |
(TScale(params.m_warperScale) * warperComputeRect.getP00()) -
|
|
Shinya Kitaoka |
120a6e |
tileComputeRect.getP00());
|
|
Shinya Kitaoka |
120a6e |
warp(tileRas, rasIn, rasWarper, rasInPos, warperPos, params);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void getParamUIs(TParamUIConcept *&concepts, int &length) override {
|
|
Shinya Kitaoka |
120a6e |
concepts = new TParamUIConcept[length = 2];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_type = TParamUIConcept::POINT;
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_label = "Center";
|
|
Shinya Kitaoka |
120a6e |
concepts[0].m_params.push_back(m_center);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
concepts[1].m_type = TParamUIConcept::RADIUS;
|
|
Shinya Kitaoka |
120a6e |
concepts[1].m_label = "Period";
|
|
Shinya Kitaoka |
120a6e |
concepts[1].m_params.push_back(m_period);
|
|
Shinya Kitaoka |
120a6e |
concepts[1].m_params.push_back(m_center);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int getMemoryRequirement(const TRectD &rect, double frame,
|
|
Shinya Kitaoka |
473e70 |
const TRenderSettings &info) override {
|
|
Shinya Kitaoka |
120a6e |
// return -1; //Deactivated. This fx is currently very inefficient if
|
|
Shinya Kitaoka |
120a6e |
// subdivided!
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int shrink = (info.m_shrinkX + info.m_shrinkY) / 2;
|
|
Shinya Kitaoka |
120a6e |
double scale = sqrt(fabs(info.m_affine.det()));
|
|
Shinya Kitaoka |
120a6e |
double gridStep = 1.5 * m_gridStep->getValue(frame);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
WarpParams params;
|
|
Shinya Kitaoka |
120a6e |
params.m_intensity = m_intensity->getValue(frame) / gridStep;
|
|
Shinya Kitaoka |
120a6e |
params.m_warperScale = scale * gridStep;
|
|
Shinya Kitaoka |
120a6e |
params.m_sharpen = m_sharpen->getValue();
|
|
Shinya Kitaoka |
120a6e |
params.m_shrink = shrink;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double warperScaleFactor = 1.0 / params.m_warperScale;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD warpedBox, warpedComputeRect, tileComputeRect;
|
|
Shinya Kitaoka |
120a6e |
m_warped->getBBox(frame, warpedBox, info);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
getWarpComputeRects(tileComputeRect, warpedComputeRect, warpedBox, rect,
|
|
Shinya Kitaoka |
120a6e |
params);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD warperComputeRect(TScale(warperScaleFactor) * tileComputeRect);
|
|
Shinya Kitaoka |
120a6e |
double warperEnlargement = getWarperEnlargement(params);
|
|
Shinya Kitaoka |
120a6e |
warperComputeRect = warperComputeRect.enlarge(warperEnlargement);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return std::max(TRasterFx::memorySize(warpedComputeRect, info.m_bpp),
|
|
Shinya Kitaoka |
120a6e |
TRasterFx::memorySize(warperComputeRect, info.m_bpp));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FX_PLUGIN_IDENTIFIER(RippleFx, "rippleFx")
|