Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// Iwa_TiledParticlesFx for Marnie
Toshihiro Shimizu 890ddd
// based on ParticlesFx by Digital Video
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
#include "tparamuiconcept.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzStdfx includes
Toshihiro Shimizu 890ddd
#include "iwa_particlesengine.h"
Toshihiro Shimizu 890ddd
#include "iwa_particlesmanager.h"
Toshihiro Shimizu 890ddd
#include "iwa_particlesfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************
Toshihiro Shimizu 890ddd
//	Iwa_TiledParticlesFx  implementation
Toshihiro Shimizu 890ddd
//**************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Iwa_TiledParticlesFx::Iwa_TiledParticlesFx()
Shinya Kitaoka 120a6e
    : m_source("Texture")
Shinya Kitaoka 120a6e
    , m_control("Control")
Shinya Kitaoka 120a6e
    , source_ctrl_val(0)
Shinya Kitaoka 120a6e
    , bright_thres_val(25)
Shinya Kitaoka 120a6e
    , center_val(TPointD(0.0, 0.0))
Shinya Kitaoka 120a6e
    , length_val(5.0)
Shinya Kitaoka 120a6e
    , height_val(4.0)
Shinya Kitaoka 120a6e
    , maxnum_val(10.0)
Shinya Kitaoka 120a6e
    , lifetime_val(DoublePair(100., 100.))
Shinya Kitaoka 120a6e
    , lifetime_ctrl_val(0)
Shinya Kitaoka 120a6e
    , column_lifetime_val(false)
Shinya Kitaoka 120a6e
    , startpos_val(1)
Shinya Kitaoka 120a6e
    , randseed_val(1)
Shinya Kitaoka 120a6e
    , gravity_val(0.0)
Shinya Kitaoka 120a6e
    , g_angle_val(0.0)
Shinya Kitaoka 120a6e
    , gravity_ctrl_val(0)
Shinya Kitaoka 120a6e
    , friction_val(0.0)
Shinya Kitaoka 120a6e
    , friction_ctrl_val(0)
Shinya Kitaoka 120a6e
    , windint_val(0.0)
Shinya Kitaoka 120a6e
    , windangle_val(0.0)
Shinya Kitaoka 120a6e
    , swingmode_val(new TIntEnumParam(SWING_RANDOM, "Random"))
Shinya Kitaoka 120a6e
    , randomx_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , randomy_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , randomx_ctrl_val(0)
Shinya Kitaoka 120a6e
    , randomy_ctrl_val(0)
Shinya Kitaoka 120a6e
    , swing_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , speed_val(DoublePair(0., 10.))
Shinya Kitaoka 120a6e
    , speed_ctrl_val(0)
Shinya Kitaoka 120a6e
    , speeda_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , speeda_ctrl_val(0)
Shinya Kitaoka 120a6e
    , speeda_use_gradient_val(false)
Shinya Kitaoka 120a6e
    , speedscale_val(false)
Shinya Kitaoka 120a6e
    , toplayer_val(new TIntEnumParam(TOP_YOUNGER, "Younger"))
Shinya Kitaoka 120a6e
    , mass_val(DoublePair(1., 1.))
Shinya Kitaoka 120a6e
    , scale_val(DoublePair(100., 100.))
Shinya Kitaoka 120a6e
    , scale_ctrl_val(0)
Shinya Kitaoka 120a6e
    , scale_ctrl_all_val(false)
Shinya Kitaoka 120a6e
    , rot_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , rot_ctrl_val(0)
Shinya Kitaoka 120a6e
    , trail_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , trailstep_val(0.0)
Shinya Kitaoka 120a6e
    , rotswingmode_val(new TIntEnumParam(SWING_RANDOM, "Random"))
Shinya Kitaoka 120a6e
    , rotspeed_val(0.0)
Shinya Kitaoka 120a6e
    , rotsca_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , rotswing_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , pathaim_val(false)
Shinya Kitaoka 120a6e
    , opacity_val(DoublePair(0., 100.))
Shinya Kitaoka 120a6e
    , opacity_ctrl_val(0)
Shinya Kitaoka 120a6e
    , trailopacity_val(DoublePair(0., 100.))
Shinya Kitaoka 120a6e
    , scalestep_val(DoublePair(0., 0.))
Shinya Kitaoka 120a6e
    , scalestep_ctrl_val(0)
Shinya Kitaoka 120a6e
    , fadein_val(0.0)
Shinya Kitaoka 120a6e
    , fadeout_val(0.0)
Shinya Kitaoka 120a6e
    , animation_val(new TIntEnumParam(ANIM_HOLD, "Hold Frame"))
Shinya Kitaoka 120a6e
    , step_val(1)
Shinya Kitaoka 120a6e
    , gencol_ctrl_val(0)
Shinya Kitaoka 120a6e
    , gencol_spread_val(0.0)
Shinya Kitaoka 120a6e
    , genfadecol_val(0.0)
Shinya Kitaoka 120a6e
    , fincol_ctrl_val(0)
Shinya Kitaoka 120a6e
    , fincol_spread_val(0.0)
Shinya Kitaoka 120a6e
    , finrangecol_val(0.0)
Shinya Kitaoka 120a6e
    , finfadecol_val(0.0)
Shinya Kitaoka 120a6e
    , foutcol_ctrl_val(0)
Shinya Kitaoka 120a6e
    , foutcol_spread_val(0.0)
Shinya Kitaoka 120a6e
    , foutrangecol_val(0.0)
Shinya Kitaoka 120a6e
    , foutfadecol_val(0.0)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    , source_gradation_val(false)
Shinya Kitaoka 120a6e
    , pick_color_for_every_frame_val(false)
Shinya Kitaoka 120a6e
    /*- 計算モード (背景+粒子/粒子/背景/照明された粒子 -*/
Shinya Kitaoka 120a6e
    , iw_rendermode_val(new TIntEnumParam(REND_ALL, "All"))
Shinya Kitaoka 120a6e
    /*- 粒子に貼られる絵の素材 -*/
Shinya Kitaoka 120a6e
    , base_ctrl_val(0)
Shinya Kitaoka 120a6e
    /*- カールノイズ的な動きを与える -*/
Shinya Kitaoka 120a6e
    , curl_val(0.0)
Shinya Kitaoka 120a6e
    /*- 手前奥でコントロールを立体化してみる -*/
Shinya Kitaoka 120a6e
    , curl_ctrl_1_val(0)
Shinya Kitaoka 120a6e
    , curl_ctrl_2_val(0)
Shinya Kitaoka 120a6e
    /*- 粒子敷き詰め作戦。粒子を正三角形で敷き詰めたときの、
Shinya Kitaoka 120a6e
          正三角形の一辺の長さをインチで指定する -*/
Shinya Kitaoka 120a6e
    , iw_triangleSize(15.0)
Shinya Kitaoka 120a6e
    /*- ひらひら回転 -*/
Shinya Kitaoka 120a6e
    , flap_ctrl_val(0)
Shinya Kitaoka 120a6e
    , iw_flap_velocity_val(0.0)        /*- 回転角速度 -*/
Shinya Kitaoka 120a6e
    , iw_flap_dir_sensitivity_val(1.0) /*- 回転軸感度 -*/
Shinya Kitaoka 120a6e
    /*- ひらひら粒子に照明を当てる -*/
Shinya Kitaoka 120a6e
    , iw_light_theta_val(60.0) /*- 光源の方向(Degree)-*/
Shinya Kitaoka 120a6e
    , iw_light_phi_val(45.0)   /*- 光源の傾き(Degree)-*/
Shinya Kitaoka 120a6e
    /*- 読み込みマージン -*/
Shinya Kitaoka 120a6e
    , margin_val(0.0)
Shinya Kitaoka 120a6e
    /*- 重力を徐々に与えるためのフレーム長 -*/
Shinya Kitaoka 120a6e
    , iw_gravityBufferFrame_val(0) {
Shinya Kitaoka 120a6e
  addInputPort("Texture1", new TRasterFxPort, 0);
Shinya Kitaoka 120a6e
  addInputPort("Control1", new TRasterFxPort, 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  length_val->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  height_val->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  center_val->getX()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  center_val->getY()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "source_ctrl", source_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "bright_thres", bright_thres_val);
Shinya Kitaoka 120a6e
  bright_thres_val->setValueRange(0, 255);
Shinya Kitaoka 120a6e
  bindParam(this, "center", center_val);
Shinya Kitaoka 120a6e
  bindParam(this, "length", length_val);
Shinya Kitaoka 120a6e
  length_val->setValueRange(1.0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "height", height_val);
Shinya Kitaoka 120a6e
  height_val->setValueRange(1.0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "birth_rate", maxnum_val);
Shinya Kitaoka 120a6e
  maxnum_val->setValueRange(0.0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "lifetime", lifetime_val);
Shinya Kitaoka 120a6e
  lifetime_val->getMin()->setValueRange(0., +3000.);
Shinya Kitaoka 120a6e
  lifetime_val->getMax()->setValueRange(0., +3000.);
Shinya Kitaoka 120a6e
  bindParam(this, "lifetime_ctrl", lifetime_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "column_lifetime", column_lifetime_val);
Shinya Kitaoka 120a6e
  bindParam(this, "starting_frame", startpos_val);
Shinya Kitaoka 120a6e
  bindParam(this, "random_seed", randseed_val);
Shinya Kitaoka 120a6e
  bindParam(this, "gravity", gravity_val);
Shinya Kitaoka 120a6e
  gravity_val->setValueRange(0.0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "gravity_angle", g_angle_val);
Shinya Kitaoka 120a6e
  g_angle_val->setMeasureName("angle");
Shinya Kitaoka 120a6e
  bindParam(this, "gravity_ctrl", gravity_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "friction", friction_val);
Shinya Kitaoka 120a6e
  bindParam(this, "friction_ctrl", friction_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "wind", windint_val);
Shinya Kitaoka 120a6e
  bindParam(this, "wind_angle", windangle_val);
Shinya Kitaoka 120a6e
  windangle_val->setMeasureName("angle");
Shinya Kitaoka 120a6e
  bindParam(this, "swing_mode", swingmode_val);
Shinya Kitaoka 120a6e
  swingmode_val->addItem(SWING_SMOOTH, "Smooth");
Shinya Kitaoka 120a6e
  bindParam(this, "scattering_x", randomx_val);
Shinya Kitaoka 120a6e
  randomx_val->getMin()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  randomx_val->getMax()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  randomx_val->getMin()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  randomx_val->getMax()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  bindParam(this, "scattering_y", randomy_val);
Shinya Kitaoka 120a6e
  randomy_val->getMin()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  randomy_val->getMax()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  randomy_val->getMin()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  randomy_val->getMax()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  bindParam(this, "scattering_x_ctrl", randomx_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "scattering_y_ctrl", randomy_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "swing", swing_val);
Shinya Kitaoka 120a6e
  swing_val->getMin()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  swing_val->getMax()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  speed_val->getMin()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  speed_val->getMax()->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  bindParam(this, "speed", speed_val);
Shinya Kitaoka 120a6e
  speed_val->getMin()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  speed_val->getMax()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  bindParam(this, "speed_ctrl", speed_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "speed_angle", speeda_val);
Shinya Kitaoka 120a6e
  speeda_val->getMin()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  speeda_val->getMax()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  speeda_val->getMin()->setMeasureName("angle");
Shinya Kitaoka 120a6e
  speeda_val->getMax()->setMeasureName("angle");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "speeda_ctrl", speeda_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "speeda_use_gradient", speeda_use_gradient_val);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "speed_size", speedscale_val);
Shinya Kitaoka 120a6e
  bindParam(this, "top_layer", toplayer_val);
Shinya Kitaoka 120a6e
  toplayer_val->addItem(TOP_OLDER, "Older");
Shinya Kitaoka 120a6e
  toplayer_val->addItem(TOP_SMALLER, "Smaller");
Shinya Kitaoka 120a6e
  toplayer_val->addItem(TOP_BIGGER, "Bigger");
Shinya Kitaoka 120a6e
  toplayer_val->addItem(TOP_RANDOM, "Random");
Shinya Kitaoka 120a6e
  bindParam(this, "mass", mass_val);
Shinya Kitaoka 120a6e
  mass_val->getMin()->setValueRange(0., +1000.);
Shinya Kitaoka 120a6e
  mass_val->getMax()->setValueRange(0., +1000.);
Shinya Kitaoka 120a6e
  bindParam(this, "scale", scale_val);
Shinya Kitaoka 120a6e
  scale_val->getMin()->setValueRange(0., +1000.);
Shinya Kitaoka 120a6e
  scale_val->getMax()->setValueRange(0., +1000.);
Shinya Kitaoka 120a6e
  bindParam(this, "scale_ctrl", scale_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "scale_ctrl_all", scale_ctrl_all_val);
Shinya Kitaoka 120a6e
  bindParam(this, "rot", rot_val);
Shinya Kitaoka 120a6e
  rot_val->getMin()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  rot_val->getMax()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  rot_val->getMin()->setMeasureName("angle");
Shinya Kitaoka 120a6e
  rot_val->getMax()->setMeasureName("angle");
Shinya Kitaoka 120a6e
  bindParam(this, "rot_ctrl", rot_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "trail", trail_val);
Shinya Kitaoka 120a6e
  trail_val->getMin()->setValueRange(0., +1000.);
Shinya Kitaoka 120a6e
  trail_val->getMax()->setValueRange(0., +1000.);
Shinya Kitaoka 120a6e
  bindParam(this, "trail_step", trailstep_val);
Shinya Kitaoka 120a6e
  trailstep_val->setValueRange(1.0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "spin_swing_mode", rotswingmode_val);
Shinya Kitaoka 120a6e
  rotswingmode_val->addItem(SWING_SMOOTH, "Smooth");
Shinya Kitaoka 120a6e
  bindParam(this, "spin_speed", rotspeed_val);
Shinya Kitaoka 120a6e
  rotspeed_val->setMeasureName("angle");
Shinya Kitaoka 120a6e
  bindParam(this, "spin_random", rotsca_val);
Shinya Kitaoka 120a6e
  rotsca_val->getMin()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  rotsca_val->getMax()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  rotsca_val->getMin()->setMeasureName("angle");
Shinya Kitaoka 120a6e
  rotsca_val->getMax()->setMeasureName("angle");
Shinya Kitaoka 120a6e
  bindParam(this, "spin_swing", rotswing_val);
Shinya Kitaoka 120a6e
  rotswing_val->getMin()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  rotswing_val->getMax()->setValueRange(-1000., +1000.);
Shinya Kitaoka 120a6e
  rotswing_val->getMin()->setMeasureName("angle");
Shinya Kitaoka 120a6e
  rotswing_val->getMax()->setMeasureName("angle");
Shinya Kitaoka 120a6e
  bindParam(this, "path_aim", pathaim_val);
Shinya Kitaoka 120a6e
  bindParam(this, "opacity", opacity_val);
Shinya Kitaoka 120a6e
  opacity_val->getMin()->setValueRange(0., +100.);
Shinya Kitaoka 120a6e
  opacity_val->getMax()->setValueRange(0., +100.);
Shinya Kitaoka 120a6e
  bindParam(this, "opacity_ctrl", opacity_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "trail_opacity", trailopacity_val);
Shinya Kitaoka 120a6e
  trailopacity_val->getMin()->setValueRange(0., +100.);
Shinya Kitaoka 120a6e
  trailopacity_val->getMax()->setValueRange(0., +100.);
Shinya Kitaoka 120a6e
  bindParam(this, "scale_step", scalestep_val);
Shinya Kitaoka 120a6e
  bindParam(this, "scale_step_ctrl", scalestep_ctrl_val);
Shinya Kitaoka 120a6e
  scalestep_val->getMin()->setValueRange(-100., +100.);
Shinya Kitaoka 120a6e
  scalestep_val->getMax()->setValueRange(-100., +100.);
Shinya Kitaoka 120a6e
  bindParam(this, "fade_in", fadein_val);
Shinya Kitaoka 120a6e
  bindParam(this, "fade_out", fadeout_val);
Shinya Kitaoka 120a6e
  bindParam(this, "animation", animation_val);
Shinya Kitaoka 120a6e
  animation_val->addItem(ANIM_RANDOM, "Random Frame");
Shinya Kitaoka 120a6e
  animation_val->addItem(ANIM_CYCLE, "Column");
Shinya Kitaoka 120a6e
  animation_val->addItem(ANIM_R_CYCLE, "Column - Random Start");
Shinya Kitaoka 120a6e
  animation_val->addItem(ANIM_SR_CYCLE, "Column Swing - Random Start");
Shinya Kitaoka 120a6e
  bindParam(this, "step", step_val);
Shinya Kitaoka 120a6e
  step_val->setValueRange(1, (std::numeric_limits<int>::max)());</int>
Tact Yoshida 1d7cf9
  std::vector<tspectrum::colorkey> colors = {</tspectrum::colorkey>
Tact Yoshida 1d7cf9
      TSpectrum::ColorKey(0, TPixel32::Red),
Tact Yoshida 1d7cf9
      TSpectrum::ColorKey(1, TPixel32::Red)};
Tact Yoshida 1d7cf9
  gencol_val = TSpectrumParamP(colors);
Shinya Kitaoka 120a6e
  bindParam(this, "birth_color", gencol_val);
Shinya Kitaoka 120a6e
  bindParam(this, "birth_color_ctrl", gencol_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "birth_color_spread", gencol_spread_val);
Shinya Kitaoka 120a6e
  gencol_spread_val->setValueRange(0.0, (std::numeric_limits<int>::max)());</int>
Shinya Kitaoka 120a6e
  bindParam(this, "birth_color_fade", genfadecol_val);
Shinya Kitaoka 120a6e
  genfadecol_val->setValueRange(0.0, 100.0);
Tact Yoshida 1d7cf9
  std::vector<tspectrum::colorkey> colors1 = {</tspectrum::colorkey>
Tact Yoshida 1d7cf9
      TSpectrum::ColorKey(0, TPixel32::Green),
Tact Yoshida 1d7cf9
      TSpectrum::ColorKey(1, TPixel32::Green)};
Tact Yoshida 1d7cf9
  fincol_val = TSpectrumParamP(colors1);
Shinya Kitaoka 120a6e
  bindParam(this, "fadein_color", fincol_val);
Shinya Kitaoka 120a6e
  bindParam(this, "fadein_color_ctrl", fincol_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "fadein_color_spread", fincol_spread_val);
Shinya Kitaoka 120a6e
  fincol_spread_val->setValueRange(0.0, (std::numeric_limits<int>::max)());</int>
Shinya Kitaoka 120a6e
  bindParam(this, "fadein_color_range", finrangecol_val);
Shinya Kitaoka 120a6e
  finrangecol_val->setValueRange(0.0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "fadein_color_fade", finfadecol_val);
Shinya Kitaoka 120a6e
  finfadecol_val->setValueRange(0.0, 100.0);
Tact Yoshida 1d7cf9
  std::vector<tspectrum::colorkey> colors2 = {</tspectrum::colorkey>
Tact Yoshida 1d7cf9
      TSpectrum::ColorKey(0, TPixel32::Blue),
Tact Yoshida 1d7cf9
      TSpectrum::ColorKey(1, TPixel32::Blue)};
Tact Yoshida 1d7cf9
  foutcol_val = TSpectrumParamP(colors2);
Shinya Kitaoka 120a6e
  bindParam(this, "fadeout_color", foutcol_val);
Shinya Kitaoka 120a6e
  bindParam(this, "fadeout_color_ctrl", foutcol_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "fadeout_color_spread", foutcol_spread_val);
Shinya Kitaoka 120a6e
  foutcol_spread_val->setValueRange(0.0, (std::numeric_limits<int>::max)());</int>
Shinya Kitaoka 120a6e
  bindParam(this, "fadeout_color_range", foutrangecol_val);
Shinya Kitaoka 120a6e
  foutrangecol_val->setValueRange(0.0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "fadeout_color_fade", foutfadecol_val);
Shinya Kitaoka 120a6e
  foutfadecol_val->setValueRange(0.0, 100.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bindParam(this, "source_gradation", source_gradation_val);
Shinya Kitaoka 120a6e
  bindParam(this, "pick_color_for_every_frame", pick_color_for_every_frame_val);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 計算モード (背景+粒子/粒子/背景/照明された粒子) -*/
Shinya Kitaoka 120a6e
  bindParam(this, "rendermode", iw_rendermode_val);
Shinya Kitaoka 120a6e
  iw_rendermode_val->addItem(REND_PARTICLES, "Particles");
Shinya Kitaoka 120a6e
  iw_rendermode_val->addItem(REND_BG, "Background");
Shinya Kitaoka 120a6e
  iw_rendermode_val->addItem(REND_ILLUMINATED, "Illuminated");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 粒子に貼られる絵の素材 -*/
Shinya Kitaoka 120a6e
  bindParam(this, "base_ctrl", base_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "curl", curl_val);
Shinya Kitaoka 120a6e
  curl_val->setValueRange(0.0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "curl_ctrl", curl_ctrl_1_val);
Shinya Kitaoka 120a6e
  bindParam(this, "curl_ctrl_2", curl_ctrl_2_val);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 粒子敷き詰め作戦。粒子を正三角形で敷き詰めたときの、
Shinya Kitaoka 120a6e
          正三角形の一辺の長さをインチで指定する -*/
Shinya Kitaoka 120a6e
  bindParam(this, "triangleSize", iw_triangleSize);
Shinya Kitaoka 120a6e
  iw_triangleSize->setValueRange(0.1, 100);
Shinya Kitaoka 120a6e
  iw_triangleSize->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- ひらひら回転 -*/
Shinya Kitaoka 120a6e
  bindParam(this, "flap_ctrl", flap_ctrl_val);
Shinya Kitaoka 120a6e
  bindParam(this, "flap_velocity", iw_flap_velocity_val);
Shinya Kitaoka 120a6e
  iw_flap_velocity_val->setValueRange(0.0,
Shinya Kitaoka 120a6e
                                      (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
  bindParam(this, "flap_dir_sensitivity", iw_flap_dir_sensitivity_val);
Shinya Kitaoka 120a6e
  iw_flap_dir_sensitivity_val->setValueRange(0.0, 1.0);
Shinya Kitaoka 120a6e
  /*- ひらひら粒子に照明を当てる -*/
Shinya Kitaoka 120a6e
  bindParam(this, "light_theta", iw_light_theta_val);
Shinya Kitaoka 120a6e
  iw_light_theta_val->setValueRange(-1000.0, 1000.0);
Shinya Kitaoka 120a6e
  bindParam(this, "light_phi", iw_light_phi_val);
Shinya Kitaoka 120a6e
  iw_light_phi_val->setValueRange(-1000.0, 1000.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 読み込みマージン -*/
Shinya Kitaoka 120a6e
  margin_val->setMeasureName("fxLength");
Shinya Kitaoka 120a6e
  bindParam(this, "margin", margin_val);
Shinya Kitaoka 120a6e
  margin_val->setValueRange(0, (std::numeric_limits<double>::max)());</double>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 重力を徐々に与えるためのフレーム長 -*/
Shinya Kitaoka 120a6e
  bindParam(this, "gravityBufferFrame", iw_gravityBufferFrame_val);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Iwa_TiledParticlesFx::~Iwa_TiledParticlesFx() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_TiledParticlesFx::getParamUIs(TParamUIConcept *&concepts,
Shinya Kitaoka 120a6e
                                       int &length) {
Shinya Kitaoka 120a6e
  concepts = new TParamUIConcept[length = 2];
Toshihiro Shimizu 890ddd
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(center_val);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  concepts[1].m_type = TParamUIConcept::RECT;
Shinya Kitaoka 120a6e
  concepts[1].m_params.push_back(length_val);
Shinya Kitaoka 120a6e
  concepts[1].m_params.push_back(height_val);
Shinya Kitaoka 120a6e
  concepts[1].m_params.push_back(center_val);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Iwa_TiledParticlesFx::doGetBBox(double frame, TRectD &bBox,
Shinya Kitaoka 120a6e
                                     const TRenderSettings &info) {
Shinya Kitaoka 120a6e
  // Returning an infinite rect. This is necessary since building the actual
Shinya Kitaoka 120a6e
  // bbox
Shinya Kitaoka 120a6e
  // is a very complicate task.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bBox = TConsts::infiniteRectD;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::string Iwa_TiledParticlesFx::getAlias(double frame,
Shinya Kitaoka 120a6e
                                           const TRenderSettings &info) const {
Shinya Kitaoka 120a6e
  std::string alias = getFxType();
Shinya Kitaoka 120a6e
  alias += "[";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // alias degli effetti connessi alle porte di input separati da virgole
Shinya Kitaoka 120a6e
  // una porta non connessa da luogo a un alias vuoto (stringa vuota)
Shinya Kitaoka 120a6e
  for (int i = 0; i < getInputPortCount(); ++i) {
Shinya Kitaoka 120a6e
    TFxPort *port = getInputPort(i);
Shinya Kitaoka 120a6e
    if (port->isConnected()) {
Shinya Kitaoka 120a6e
      TRasterFxP ifx = port->getFx();
Shinya Kitaoka 120a6e
      assert(ifx);
Shinya Kitaoka 120a6e
      alias += ifx->getAlias(frame, info);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    alias += ",";
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string paramalias("");
Shinya Kitaoka 120a6e
  for (int i = 0; i < getParams()->getParamCount(); ++i) {
Shinya Kitaoka 120a6e
    TParam *param = getParams()->getParam(i);
Shinya Kitaoka 120a6e
    paramalias += param->getName() + "=" + param->getValueAlias(frame, 3);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return alias + std::to_string(frame) + "," + std::to_string(getIdentifier()) +
Shinya Kitaoka 120a6e
         paramalias + "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Iwa_TiledParticlesFx::allowUserCacheOnPort(int portNum) {
Shinya Kitaoka 120a6e
  // Only control port are currently allowed to cache upon explicit user's
Shinya Kitaoka 120a6e
  // request
Shinya Kitaoka 120a6e
  std::string tmpName = getInputPortName(portNum);
Shinya Kitaoka 120a6e
  return tmpName.find("Control") != std::string::npos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_TiledParticlesFx::doDryCompute(TRectD &rect, double frame,
Shinya Kitaoka 120a6e
                                        const TRenderSettings &info) {
Shinya Kitaoka 120a6e
  Iwa_ParticlesManager *pc = Iwa_ParticlesManager::instance();
Shinya Kitaoka 120a6e
  unsigned long fxId       = getIdentifier();
Shinya Kitaoka 120a6e
  int inputPortCount       = getInputPortCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i, j, curr_frame = frame,              /*- 現在のフレーム -*/
Shinya Kitaoka 120a6e
      startframe = startpos_val->getValue(); /*- Particesの開始フレーム -*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRenderSettings infoOnInput(info);
Shinya Kitaoka 120a6e
  infoOnInput.m_affine =
Shinya Kitaoka 120a6e
      TAffine();  // Using the standard reference - indep. from cameras.
Shinya Kitaoka 120a6e
  infoOnInput.m_bpp =
Shinya Kitaoka 120a6e
      64;  // Control ports rendered at 32 bit - since not visible.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = startframe - 1; i <= curr_frame; ++i) {
Shinya Kitaoka 120a6e
    double frame = std::max(0, i);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (j = 0; j < inputPortCount; ++j) {
Shinya Kitaoka 120a6e
      TFxPort *port       = getInputPort(j);
Shinya Kitaoka 120a6e
      std::string tmpName = getInputPortName(j);
Shinya Kitaoka 120a6e
      if (port->isConnected()) {
Shinya Kitaoka 120a6e
        TRasterFxP fx = port->getFx();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // Now, consider that source ports work different than control ones
Shinya Kitaoka 120a6e
        QString portName = QString::fromStdString(tmpName);
Shinya Kitaoka 120a6e
        if (portName.startsWith("C")) {
Shinya Kitaoka 120a6e
          // Control ports are calculated from start to current frame, since
Shinya Kitaoka 120a6e
          // particle mechanics at current frame is influenced by previous ones
Shinya Kitaoka 120a6e
          // (and therefore by all previous control images).
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          TRectD bbox;
Shinya Kitaoka 120a6e
          fx->getBBox(frame, bbox, infoOnInput);
Shinya Kitaoka 120a6e
          if (bbox == TConsts::infiniteRectD) bbox = info.m_affine.inv() * rect;
Shinya Kitaoka 120a6e
          fx->dryCompute(bbox, frame, infoOnInput);
Shinya Kitaoka 120a6e
        } else if (portName.startsWith("T")) {
Shinya Kitaoka 120a6e
          // Particles handle source ports caching procedures on its own.
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_TiledParticlesFx::doCompute(TTile &tile, double frame,
Shinya Kitaoka 120a6e
                                     const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  std::vector<int> lastframe;</int>
Shinya Kitaoka 120a6e
  std::vector<tlevelp> partLevel;</tlevelp>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD p_offset;
Shinya Kitaoka 120a6e
  TDimension p_size(0, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 参照画像ポートの取得 -*/
Shinya Kitaoka 120a6e
  std::vector<trasterfxport *=""> part_ports; /*- テクスチャ素材画像のポート -*/</trasterfxport>
Shinya Kitaoka 120a6e
  std::map<int, *="" trasterfxport=""></int,>
Shinya Kitaoka 120a6e
      ctrl_ports; /*- コントロール画像のポート番号/ポート -*/
Shinya Kitaoka 120a6e
  int portsCount = this->getInputPortCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < portsCount; ++i) {
Shinya Kitaoka 120a6e
    std::string tmpName = this->getInputPortName(i);
Shinya Kitaoka 120a6e
    QString portName    = QString::fromStdString(tmpName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (portName.startsWith("T")) {
Shinya Kitaoka 120a6e
      TRasterFxPort *tmpPart = (TRasterFxPort *)this->getInputPort(tmpName);
Shinya Kitaoka 120a6e
      if (tmpPart->isConnected())
Shinya Kitaoka 120a6e
        part_ports.push_back((TRasterFxPort *)this->getInputPort(tmpName));
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      portName.replace(QString("Control"), QString(""));
Shinya Kitaoka 120a6e
      TRasterFxPort *tmpCtrl = (TRasterFxPort *)this->getInputPort(tmpName);
Shinya Kitaoka 120a6e
      if (tmpCtrl->isConnected())
Shinya Kitaoka 120a6e
        ctrl_ports[portName.toInt()] =
Shinya Kitaoka 120a6e
            (TRasterFxPort *)this->getInputPort(tmpName);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- テクスチャ素材のバウンディングボックスを足し合わせる
Shinya Kitaoka 120a6e
   * ←この工程、いらないかも?-*/
Shinya Kitaoka 120a6e
  if (!part_ports.empty()) {
Shinya Kitaoka 120a6e
    TRectD outTileBBox(tile.m_pos, TDimensionD(tile.getRaster()->getLx(),
Shinya Kitaoka 120a6e
                                               tile.getRaster()->getLy()));
Shinya Kitaoka 120a6e
    TRectD bbox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (unsigned int i = 0; i < (int)part_ports.size(); ++i) {
Shinya Kitaoka 120a6e
      const TFxTimeRegion &tr = (*part_ports[i])->getTimeRegion();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      lastframe.push_back(tr.getLastFrame() + 1);
Shinya Kitaoka 120a6e
      partLevel.push_back(new TLevel());
Shinya Kitaoka 120a6e
      partLevel[i]->setName((*part_ports[i])->getAlias(0, ri));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // The particles offset must be calculated without considering the
Shinya Kitaoka 120a6e
      // affine's translational
Shinya Kitaoka 120a6e
      // component
Shinya Kitaoka 120a6e
      TRenderSettings riZero(ri);
Shinya Kitaoka 120a6e
      riZero.m_affine.a13 = riZero.m_affine.a23 = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Calculate the bboxes union
Shinya Kitaoka 120a6e
      for (int t = 0; t <= tr.getLastFrame(); ++t) {
Shinya Kitaoka 120a6e
        TRectD inputBox;
Shinya Kitaoka 120a6e
        (*part_ports[i])->getBBox(t, inputBox, riZero);
Shinya Kitaoka 120a6e
        bbox += inputBox;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (bbox == TConsts::infiniteRectD) bbox *= outTileBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    p_size.lx = (int)bbox.getLx() + 1;
Shinya Kitaoka 120a6e
    p_size.ly = (int)bbox.getLy() + 1;
Shinya Kitaoka 120a6e
    p_offset  = TPointD(0.5 * (bbox.x0 + bbox.x1), 0.5 * (bbox.y0 + bbox.y1));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    partLevel.push_back(new TLevel());
Shinya Kitaoka 120a6e
    partLevel[0]->setName("particles");
Shinya Kitaoka 120a6e
    TDimension vecsize(10, 10);
Shinya Kitaoka 120a6e
    TOfflineGL *offlineGlContext = new TOfflineGL(vecsize);
Shinya Kitaoka 120a6e
    offlineGlContext->clear(TPixel32(0, 0, 0, 0));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStroke *stroke;
Shinya Kitaoka 120a6e
    stroke = makeEllipticStroke(
Shinya Kitaoka 120a6e
        0.07, TPointD((vecsize.lx - 1) * .5, (vecsize.ly - 1) * .5), 2.0, 2.0);
Shinya Kitaoka 120a6e
    TVectorImageP vectmp = new TVectorImage();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TPalette *plt = new TPalette();
Shinya Kitaoka 120a6e
    vectmp->setPalette(plt);
Shinya Kitaoka 120a6e
    vectmp->addStroke(stroke);
Shinya Kitaoka 120a6e
    TVectorRenderData rd(AffI, TRect(vecsize), plt, 0, true, true);
Shinya Kitaoka 120a6e
    offlineGlContext->makeCurrent();
Shinya Kitaoka 120a6e
    offlineGlContext->draw(vectmp, rd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    partLevel[0]->setFrame(
Shinya Kitaoka 120a6e
        0, TRasterImageP(offlineGlContext->getRaster()->clone()));
Shinya Kitaoka 120a6e
    p_size.lx = vecsize.lx + 1;
Shinya Kitaoka 120a6e
    p_size.ly = vecsize.ly + 1;
Shinya Kitaoka 120a6e
    lastframe.push_back(1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    delete offlineGlContext;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Iwa_Particles_Engine myEngine(this, frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieving the dpi multiplier from the accumulated affine (which is
Shinya Kitaoka 120a6e
  // isotropic). That is,
Shinya Kitaoka 120a6e
  // the affine will be applied *before* this effect - and we'll multiply
Shinya Kitaoka 120a6e
  // geometrical parameters
Shinya Kitaoka 120a6e
  // by this dpi mult. in order to compensate.
Shinya Kitaoka 120a6e
  float dpi = sqrt(fabs(ri.m_affine.det())) * 100;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TTile tileIn;
Shinya Kitaoka 120a6e
  if (TRaster32P raster32 = tile.getRaster()) {
Jeremy Bullock 175c6b
    myEngine.render_particles(&tile, part_ports, ri, p_size, p_offset,
Shinya Kitaoka 120a6e
                              ctrl_ports, partLevel, 1, (int)frame, 1, 0, 0, 0,
Shinya Kitaoka 120a6e
                              0, lastframe, getIdentifier());
Shinya Kitaoka 120a6e
  } else if (TRaster64P raster64 = tile.getRaster()) {
Jeremy Bullock 175c6b
    myEngine.render_particles(&tile, part_ports, ri, p_size, p_offset,
Shinya Kitaoka 120a6e
                              ctrl_ports, partLevel, 1, (int)frame, 1, 0, 0, 0,
Shinya Kitaoka 120a6e
                              0, lastframe, getIdentifier());
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    throw TException("ParticlesFx: unsupported Pixel Type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_TiledParticlesFx::compatibilityTranslatePort(int major, int minor,
Shinya Kitaoka 120a6e
                                                      std::string &portName) {
Shinya Kitaoka 120a6e
  VersionNumber version(major, minor);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (version < VersionNumber(1, 16)) {
Shinya Kitaoka 120a6e
    if (portName == "Texture") portName = "Texture1";
Shinya Kitaoka 120a6e
  } else if (version < VersionNumber(1, 20)) {
Shinya Kitaoka 120a6e
    int idx;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    bool chop =
Shinya Kitaoka 120a6e
        ((idx = portName.find("Texture")) != std::string::npos && idx > 0) ||
Shinya Kitaoka 120a6e
        ((idx = portName.find("Control")) != std::string::npos && idx > 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (chop) portName.erase(portName.begin(), portName.begin() + idx);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FX_PLUGIN_IDENTIFIER(Iwa_TiledParticlesFx, "iwa_TiledParticlesFx");