Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// Iwa_Particles_Engine for Marnie
Toshihiro Shimizu 890ddd
// based on Particles_Engine by Digital Video
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tflash.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcolorfunctions.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "iwa_particlesmanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "iwa_particlesengine.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trenderer.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qmutex></qmutex>
Toshihiro Shimizu 890ddd
#include <qmutexlocker></qmutexlocker>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9eb50d
#include <strstream></strstream>
Shinya Kitaoka 9eb50d
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
QMutex mutex;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void printTime(TStopWatch &sw, std::string name) {
Shinya Kitaoka 120a6e
  std::ostrstream ss;
Shinya Kitaoka 120a6e
  ss << name << " : ";
Shinya Kitaoka 120a6e
  sw.print(ss);
Shinya Kitaoka 120a6e
  ss << '\n' << '\0';
Shinya Kitaoka 120a6e
  TSystem::outputDebug(ss.str());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
//----
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Iwa_Particles_Engine::Iwa_Particles_Engine(Iwa_TiledParticlesFx *parent,
Shinya Kitaoka 120a6e
                                           double frame)
Shinya Kitaoka 120a6e
    : m_parent(parent), m_frame(frame) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::fill_value_struct(struct particles_values &myvalues,
Shinya Kitaoka 120a6e
                                             double frame) {
Shinya Kitaoka 120a6e
  myvalues.source_ctrl_val     = m_parent->source_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.bright_thres_val    = m_parent->bright_thres_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.x_pos_val           = m_parent->center_val->getValue(frame).x;
Shinya Kitaoka 120a6e
  myvalues.y_pos_val           = m_parent->center_val->getValue(frame).y;
Shinya Kitaoka 120a6e
  myvalues.length_val          = m_parent->length_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.height_val          = m_parent->height_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.maxnum_val          = m_parent->maxnum_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.lifetime_val        = m_parent->lifetime_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.lifetime_ctrl_val   = m_parent->lifetime_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.column_lifetime_val = m_parent->column_lifetime_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.startpos_val        = m_parent->startpos_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.randseed_val        = m_parent->randseed_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.gravity_val         = m_parent->gravity_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.g_angle_val         = m_parent->g_angle_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.gravity_ctrl_val    = m_parent->gravity_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.friction_val        = m_parent->friction_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.friction_ctrl_val   = m_parent->friction_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.windint_val         = m_parent->windint_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.windangle_val       = m_parent->windangle_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.swingmode_val       = m_parent->swingmode_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.randomx_val         = m_parent->randomx_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.randomy_val         = m_parent->randomy_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.randomx_ctrl_val    = m_parent->randomx_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.randomy_ctrl_val    = m_parent->randomy_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.swing_val           = m_parent->swing_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.speed_val           = m_parent->speed_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.speed_ctrl_val      = m_parent->speed_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.speeda_val          = m_parent->speeda_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.speeda_ctrl_val     = m_parent->speeda_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.speeda_use_gradient_val =
Shinya Kitaoka 120a6e
      m_parent->speeda_use_gradient_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.speedscale_val     = m_parent->speedscale_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.toplayer_val       = m_parent->toplayer_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.mass_val           = m_parent->mass_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.scale_val          = m_parent->scale_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.scale_ctrl_val     = m_parent->scale_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.scale_ctrl_all_val = m_parent->scale_ctrl_all_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.rot_val            = m_parent->rot_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.rot_ctrl_val       = m_parent->rot_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.trail_val          = m_parent->trail_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.trailstep_val      = m_parent->trailstep_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.rotswingmode_val   = m_parent->rotswingmode_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.rotspeed_val       = m_parent->rotspeed_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.rotsca_val         = m_parent->rotsca_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.rotswing_val       = m_parent->rotswing_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.pathaim_val        = m_parent->pathaim_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.opacity_val        = m_parent->opacity_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.opacity_ctrl_val   = m_parent->opacity_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.trailopacity_val   = m_parent->trailopacity_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.scalestep_val      = m_parent->scalestep_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.scalestep_ctrl_val = m_parent->scalestep_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.fadein_val         = m_parent->fadein_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.fadeout_val        = m_parent->fadeout_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.animation_val      = m_parent->animation_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.step_val           = m_parent->step_val->getValue();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  myvalues.gencol_val         = m_parent->gencol_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.gencol_ctrl_val    = m_parent->gencol_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.gencol_spread_val  = m_parent->gencol_spread_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.genfadecol_val     = m_parent->genfadecol_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.fincol_val         = m_parent->fincol_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.fincol_ctrl_val    = m_parent->fincol_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.fincol_spread_val  = m_parent->fincol_spread_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.finrangecol_val    = m_parent->finrangecol_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.finfadecol_val     = m_parent->finfadecol_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.foutcol_val        = m_parent->foutcol_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.foutcol_ctrl_val   = m_parent->foutcol_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.foutcol_spread_val = m_parent->foutcol_spread_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.foutrangecol_val   = m_parent->foutrangecol_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.foutfadecol_val    = m_parent->foutfadecol_val->getValue(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  myvalues.source_gradation_val = m_parent->source_gradation_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.pick_color_for_every_frame_val =
Shinya Kitaoka 120a6e
      m_parent->pick_color_for_every_frame_val->getValue();
Shinya Kitaoka 120a6e
  /*- 計算モード (背景+粒子/粒子/背景/照明された粒子) -*/
Shinya Kitaoka 120a6e
  myvalues.iw_rendermode_val = m_parent->iw_rendermode_val->getValue();
Shinya Kitaoka 120a6e
  /*- 粒子に貼られる絵の素材 -*/
Shinya Kitaoka 120a6e
  myvalues.base_ctrl_val = m_parent->base_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  /*- カールノイズ的な動きを与える -*/
Shinya Kitaoka 120a6e
  myvalues.curl_val        = m_parent->curl_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.curl_ctrl_1_val = m_parent->curl_ctrl_1_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.curl_ctrl_2_val = m_parent->curl_ctrl_2_val->getValue();
Shinya Kitaoka 120a6e
  /*- 粒子敷き詰め。粒子を正三角形で敷き詰めたときの、
Shinya Kitaoka 120a6e
          正三角形の一辺の長さをインチで指定する -*/
Shinya Kitaoka 120a6e
  myvalues.iw_triangleSize = m_parent->iw_triangleSize->getValue(frame);
Shinya Kitaoka 120a6e
  /*- ひらひら回転 -*/
Shinya Kitaoka 120a6e
  myvalues.flap_ctrl_val = m_parent->flap_ctrl_val->getValue();
Shinya Kitaoka 120a6e
  myvalues.iw_flap_velocity_val =
Shinya Kitaoka 120a6e
      m_parent->iw_flap_velocity_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.iw_flap_dir_sensitivity_val =
Shinya Kitaoka 120a6e
      m_parent->iw_flap_dir_sensitivity_val->getValue(frame);
Shinya Kitaoka 120a6e
  /*- ひらひら粒子に照明を当てる normalize_values()内で Degree → Radian 化する
Shinya Kitaoka 120a6e
   * -*/
Shinya Kitaoka 120a6e
  myvalues.iw_light_theta_val = m_parent->iw_light_theta_val->getValue(frame);
Shinya Kitaoka 120a6e
  myvalues.iw_light_phi_val   = m_parent->iw_light_phi_val->getValue(frame);
Shinya Kitaoka 120a6e
  /*- 読み込みマージン -*/
Shinya Kitaoka 120a6e
  myvalues.margin_val = m_parent->margin_val->getValue(frame);
Shinya Kitaoka 120a6e
  /*- 重力を徐々に与えるためのフレーム長 -*/
Shinya Kitaoka 120a6e
  myvalues.iw_gravityBufferFrame_val =
Shinya Kitaoka 120a6e
      m_parent->iw_gravityBufferFrame_val->getValue();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particles_Engine::fill_range_struct(struct particles_values &values,
Shinya Kitaoka 120a6e
                                             struct particles_ranges &ranges) {
Shinya Kitaoka 120a6e
  ranges.swing_range = values.swing_val.second - values.swing_val.first;
Shinya Kitaoka 120a6e
  ranges.rotswing_range =
Shinya Kitaoka 120a6e
      values.rotswing_val.second - values.rotswing_val.first;
Shinya Kitaoka 120a6e
  ranges.randomx_range = values.randomx_val.second - values.randomx_val.first;
Shinya Kitaoka 120a6e
  ranges.randomy_range = values.randomy_val.second - values.randomy_val.first;
Shinya Kitaoka 120a6e
  ranges.rotsca_range  = values.rotsca_val.second - values.rotsca_val.first;
Shinya Kitaoka 120a6e
  ranges.rot_range     = values.rot_val.second - values.rot_val.first;
Shinya Kitaoka 120a6e
  ranges.speed_range   = values.speed_val.second - values.speed_val.first;
Shinya Kitaoka 120a6e
  ranges.speeda_range  = values.speeda_val.second - values.speeda_val.first;
Shinya Kitaoka 120a6e
  ranges.mass_range    = values.mass_val.second - values.mass_val.first;
Shinya Kitaoka 120a6e
  ranges.scale_range   = values.scale_val.second - values.scale_val.first;
Shinya Kitaoka 120a6e
  ranges.lifetime_range =
Shinya Kitaoka 120a6e
      values.lifetime_val.second - values.lifetime_val.first;
Shinya Kitaoka 120a6e
  ranges.scalestep_range =
Shinya Kitaoka 120a6e
      values.scalestep_val.second - values.scalestep_val.first;
Shinya Kitaoka 120a6e
  ranges.trail_range = (int)(values.trail_val.second - values.trail_val.first);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Iwa_Particles_Engine::port_is_used(int i,
Shinya Kitaoka 120a6e
                                        struct particles_values &values) {
Shinya Kitaoka 120a6e
  return values.fincol_ctrl_val == i || values.foutcol_ctrl_val == i ||
Shinya Kitaoka 120a6e
         values.friction_ctrl_val == i || values.gencol_ctrl_val == i ||
Shinya Kitaoka 120a6e
         values.gravity_ctrl_val == i || values.opacity_ctrl_val == i ||
Shinya Kitaoka 120a6e
         values.rot_ctrl_val == i || values.scale_ctrl_val == i ||
Shinya Kitaoka 120a6e
         values.scalestep_ctrl_val == i || values.source_ctrl_val == i ||
Shinya Kitaoka 120a6e
         values.speed_ctrl_val == i || values.speeda_ctrl_val == i ||
Shinya Kitaoka 120a6e
         values.lifetime_ctrl_val == i || values.randomx_ctrl_val == i ||
Shinya Kitaoka 120a6e
         values.randomy_ctrl_val == i || values.base_ctrl_val == i ||
Shinya Kitaoka 120a6e
         values.curl_ctrl_1_val == i || values.curl_ctrl_2_val == i ||
Shinya Kitaoka 120a6e
         values.flap_ctrl_val == i;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------
Toshihiro Shimizu 890ddd
/*-  Startフレームからカレントフレームまで順番に回す関数 生成もここで -*/
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::roll_particles(
Shinya Kitaoka 120a6e
    TTile *tile,                      /*-結果を格納するTile-*/
Shinya Kitaoka 120a6e
    std::map<int, *="" ttile=""> porttiles, /*-コントロール画像のポート番号/タイル-*/</int,>
Shinya Kitaoka 120a6e
    const TRenderSettings &ri, /*-現在のフレームの計算用RenderSettings-*/
Shinya Kitaoka 120a6e
    std::list<iwa_particle> &myParticles, /*-パーティクルのリスト-*/</iwa_particle>
Shinya Kitaoka 120a6e
    struct particles_values &values, /*-現在のフレームでのパラメータ-*/
Shinya Kitaoka 120a6e
    float cx,                        /*- 0 で入ってくる-*/
Shinya Kitaoka 120a6e
    float cy,                        /*- 0 で入ってくる-*/
Shinya Kitaoka 120a6e
    int frame,          /*-現在のフレーム値(forで回す値)-*/
Shinya Kitaoka 120a6e
    int curr_frame,     /*-カレントフレーム-*/
Shinya Kitaoka 120a6e
    int level_n,        /*-テクスチャ素材画像の数-*/
Shinya Kitaoka 120a6e
    bool *random_level, /*-ループの最初にfalseで入ってくる-*/
Shinya Kitaoka 120a6e
    float dpi,          /*- 1 で入ってくる-*/
Shinya Kitaoka 120a6e
    std::vector<int> lastframe, /*-テクスチャ素材のそれぞれのカラム長-*/</int>
Shinya Kitaoka 120a6e
    int &totalparticles, QList<particleorigin> &particleOrigins,</particleorigin>
Shinya Kitaoka 120a6e
    int genPartNum /*- 実際に生成したい粒子数 -*/
Shinya Kitaoka 120a6e
    ) {
Shinya Kitaoka 120a6e
  particles_ranges ranges;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  float xgravity, ygravity, windx, windy;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 風の強さ/重力の強さをX,Y成分に分ける -*/
Shinya Kitaoka 120a6e
  windx    = values.windint_val * sin(values.windangle_val);
Shinya Kitaoka 120a6e
  windy    = values.windint_val * cos(values.windangle_val);
Shinya Kitaoka 120a6e
  xgravity = values.gravity_val * sin(values.g_angle_val);
Shinya Kitaoka 120a6e
  ygravity = values.gravity_val * cos(values.g_angle_val);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fill_range_struct(values, ranges);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tpointd> myregions;</tpointd>
Shinya Kitaoka 120a6e
  QList<qlist<int>> myHistogram;</qlist<int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<int, *="" ttile="">::iterator it = porttiles.find(values.source_ctrl_val);</int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- ソース画像にコントロールが付いていた場合 -*/
Shinya Kitaoka 120a6e
  if (values.source_ctrl_val && (it != porttiles.end()) &&
Shinya Kitaoka 120a6e
      it->second->getRaster())
Shinya Kitaoka 120a6e
    /*- 入力画像のアルファ値に比例して発生濃度を変える -*/
Shinya Kitaoka 120a6e
    fill_single_region(myregions, it->second, values.bright_thres_val,
Shinya Kitaoka 120a6e
                       values.source_gradation_val, myHistogram,
Shinya Kitaoka 120a6e
                       particleOrigins);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 粒子が出きったらもう出さない -*/
Shinya Kitaoka 120a6e
  int actualBirthParticles = std::min(genPartNum, particleOrigins.size());
Shinya Kitaoka 120a6e
  /*- 出発する粒子のインデックス -*/
Shinya Kitaoka 120a6e
  QList<int> leavingPartIndex;</int>
Shinya Kitaoka 120a6e
  if (myregions.size() &&
Shinya Kitaoka 120a6e
      values.source_ctrl_val != Iwa_TiledParticlesFx::CTRL_NONE) {
Shinya Kitaoka 120a6e
    int partLeft = actualBirthParticles;
Shinya Kitaoka 120a6e
    while (partLeft > 0) {
Shinya Kitaoka 120a6e
      int PrePartLeft = partLeft;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      int potential_sum = 0;
Shinya Kitaoka 120a6e
      QList<int> myWeight;</int>
Shinya Kitaoka 120a6e
      /*- 各濃度のポテンシャルの大きさmyWeightと、合計ポテンシャルを計算 -*/
Shinya Kitaoka 120a6e
      for (int m = 0; m < 256; m++) {
Shinya Kitaoka 120a6e
        int pot = myHistogram[m].size() * m;
Shinya Kitaoka 120a6e
        myWeight.append(pot);
Shinya Kitaoka 120a6e
        potential_sum += pot;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /*- 各濃度について(濃い方から) -*/
Shinya Kitaoka 120a6e
      for (int m = 255; m > 0; m--) {
Shinya Kitaoka 120a6e
        /*- 割り当てを計算(切り上げ) -*/
Shinya Kitaoka 120a6e
        int wariate = tceil((float)(myWeight[m]) * (float)(partLeft) /
Shinya Kitaoka 120a6e
                            (float)potential_sum);
Shinya Kitaoka 120a6e
        /*- 実際にこのポテンシャルから出発する粒子数 -*/
Shinya Kitaoka 120a6e
        int leaveNum = std::min(myHistogram.at(m).size(), wariate);
Shinya Kitaoka 120a6e
        /*- 割り当てられた粒子を頭から登録 -*/
Shinya Kitaoka 120a6e
        for (int lp = 0; lp < leaveNum; lp++) {
Shinya Kitaoka 120a6e
          /*- Histogramから減らしながら追加 -*/
Shinya Kitaoka 120a6e
          leavingPartIndex.append(myHistogram[m].takeFirst());
Shinya Kitaoka 120a6e
          /*- 残数を減らす -*/
Shinya Kitaoka 120a6e
          partLeft--;
Shinya Kitaoka 120a6e
          if (partLeft == 0) break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (partLeft == 0) break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- ひとつも出発出来なければbreak -*/
Shinya Kitaoka 120a6e
      if (partLeft == PrePartLeft) break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*- 実際に飛び出せた粒子数 -*/
Shinya Kitaoka 120a6e
    actualBirthParticles = leavingPartIndex.size();
Shinya Kitaoka 120a6e
  } else /*- 何も刺さっていなければ、ランダムに発生させる -*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    for (int i = 0; i < actualBirthParticles; i++) leavingPartIndex.append(i);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 動かす粒子も生まれる粒子も無い -*/
Shinya Kitaoka 120a6e
  if (myParticles.empty() && actualBirthParticles == 0) {
Shinya Kitaoka 120a6e
    std::cout << "no particles generated nor alive. returning function"
Shinya Kitaoka 120a6e
              << std::endl;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 背景だけを描画するモードのときは、particlesOriginを更新するだけでOK -*/
Shinya Kitaoka 120a6e
  if (values.iw_rendermode_val == Iwa_TiledParticlesFx::REND_BG) {
Shinya Kitaoka 120a6e
    /*- インデックスを小さい順にならべる -*/
Shinya Kitaoka 120a6e
    qSort(leavingPartIndex.begin(), leavingPartIndex.end());
Shinya Kitaoka 120a6e
    /*- インデックス大きい方から消していく -*/
Shinya Kitaoka 120a6e
    for (int lp = leavingPartIndex.size() - 1; lp >= 0; lp--)
Shinya Kitaoka 120a6e
      particleOrigins.removeAt(leavingPartIndex.at(lp));
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 新規粒子の生成 -*/
Shinya Kitaoka 120a6e
  /*- 新規粒子しかない場合 -*/
Shinya Kitaoka 120a6e
  if (myParticles.empty() && actualBirthParticles)  // Initial creation
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    /*- 新たに作るパーティクルの数だけループ -*/
Shinya Kitaoka 120a6e
    for (i = 0; i < actualBirthParticles; i++) {
Shinya Kitaoka 120a6e
      /*- 出発する粒子 -*/
Shinya Kitaoka 120a6e
      ParticleOrigin po = particleOrigins.at(leavingPartIndex.at(i));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*-  どのTextureレベルを使うか -*/
Shinya Kitaoka 120a6e
      int seed = (int)((std::numeric_limits<int>::max)() *</int>
Shinya Kitaoka 120a6e
                       values.random_val->getFloat());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*-  Lifetimeを得る -*/
Shinya Kitaoka 120a6e
      int lifetime = 0;
Shinya Kitaoka 120a6e
      if (values.column_lifetime_val)
Shinya Kitaoka 120a6e
        lifetime = lastframe[po.level];
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        lifetime = (int)(values.lifetime_val.first +
Shinya Kitaoka 120a6e
                         ranges.lifetime_range * values.random_val->getFloat());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /*-
Shinya Kitaoka 120a6e
       * この粒子が、レンダリングするフレームでも生きているか判断し、生きているなら生成
Shinya Kitaoka 120a6e
       * -*/
Shinya Kitaoka 120a6e
      if (lifetime > curr_frame - frame) {
Shinya Kitaoka 120a6e
        myParticles.push_back(Iwa_Particle(
Shinya Kitaoka 120a6e
            lifetime, seed, porttiles, values, ranges, totalparticles, 0,
Shinya Kitaoka 120a6e
            (int)po.level, lastframe[po.level], po.pos[0],
Shinya Kitaoka 120a6e
            po.pos[1],               /*- 座標を指定して発生 -*/
Shinya Kitaoka 120a6e
            po.isUpward,             /*- orientation を追加 -*/
Shinya Kitaoka 120a6e
            (int)po.initSourceFrame) /*- 素材内の初期フレーム位置 -*/
Shinya Kitaoka 120a6e
                              );
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      totalparticles++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*- 既存粒子を動かし、かつ新規粒子を作る -*/
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    std::list<iwa_particle>::iterator it;</iwa_particle>
Shinya Kitaoka 120a6e
    for (it = myParticles.begin(); it != myParticles.end();) {
Shinya Kitaoka 120a6e
      std::list<iwa_particle>::iterator current = it;</iwa_particle>
Shinya Kitaoka 120a6e
      ++it;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      Iwa_Particle &part = (*current);
Shinya Kitaoka 120a6e
      if (part.scale <= 0.0) continue;
Shinya Kitaoka 120a6e
      if (part.lifetime <= 0)        // Note: This is in line with the above
Shinya Kitaoka 120a6e
                                     // "lifetime>curr_frame-frame"
Shinya Kitaoka 120a6e
        myParticles.erase(current);  // insertion counterpart
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        part.move(porttiles, values, ranges, windx, windy, xgravity, ygravity,
Shinya Kitaoka 120a6e
                  dpi, lastframe[part.level]);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    switch (values.toplayer_val) {
Shinya Kitaoka 120a6e
    case Iwa_TiledParticlesFx::TOP_YOUNGER:
Shinya Kitaoka 120a6e
      for (i = 0; i < actualBirthParticles; i++) {
Shinya Kitaoka 120a6e
        /*- 出発する粒子 -*/
Shinya Kitaoka 120a6e
        ParticleOrigin po = particleOrigins.at(leavingPartIndex.at(i));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        int seed = (int)((std::numeric_limits<int>::max)() *</int>
Shinya Kitaoka 120a6e
                         values.random_val->getFloat());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        int lifetime = 0;
Shinya Kitaoka 120a6e
        if (values.column_lifetime_val)
Shinya Kitaoka 120a6e
          lifetime = lastframe[po.level];
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          lifetime =
Shinya Kitaoka 120a6e
              (int)(values.lifetime_val.first +
Shinya Kitaoka 120a6e
                    ranges.lifetime_range * values.random_val->getFloat());
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (lifetime > curr_frame - frame) {
Shinya Kitaoka 120a6e
          myParticles.push_front(Iwa_Particle(
Shinya Kitaoka 120a6e
              lifetime, seed, porttiles, values, ranges, totalparticles, 0,
Shinya Kitaoka 120a6e
              (int)po.level, lastframe[po.level], po.pos[0], po.pos[1],
Shinya Kitaoka 120a6e
              po.isUpward,
Shinya Kitaoka 120a6e
              (int)po.initSourceFrame) /*- 素材内の初期フレーム位置 -*/
Shinya Kitaoka 120a6e
                                 );
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        totalparticles++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    case Iwa_TiledParticlesFx::TOP_RANDOM:
Shinya Kitaoka 120a6e
      for (i = 0; i < actualBirthParticles; i++) {
Shinya Kitaoka 120a6e
        double tmp = values.random_val->getFloat() * myParticles.size();
Shinya Kitaoka 120a6e
        std::list<iwa_particle>::iterator it = myParticles.begin();</iwa_particle>
Shinya Kitaoka 120a6e
        for (int j = 0; j < tmp; j++, it++)
Shinya Kitaoka 120a6e
          ;
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          /*- 出発する粒子 -*/
Shinya Kitaoka 120a6e
          ParticleOrigin po = particleOrigins.at(leavingPartIndex.at(i));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          int seed = (int)((std::numeric_limits<int>::max)() *</int>
Shinya Kitaoka 120a6e
                           values.random_val->getFloat());
Shinya Kitaoka 120a6e
          int lifetime = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (values.column_lifetime_val)
Shinya Kitaoka 120a6e
            lifetime = lastframe[po.level];
Shinya Kitaoka 120a6e
          else {
Shinya Kitaoka 120a6e
            lifetime =
Shinya Kitaoka 120a6e
                (int)(values.lifetime_val.first +
Shinya Kitaoka 120a6e
                      ranges.lifetime_range * values.random_val->getFloat());
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          if (lifetime > curr_frame - frame) {
Shinya Kitaoka 120a6e
            myParticles.insert(
Shinya Kitaoka 120a6e
                it,
Shinya Kitaoka 120a6e
                Iwa_Particle(
Shinya Kitaoka 120a6e
                    lifetime, seed, porttiles, values, ranges, totalparticles,
Shinya Kitaoka 120a6e
                    0, (int)po.level, lastframe[po.level], po.pos[0], po.pos[1],
Shinya Kitaoka 120a6e
                    po.isUpward,
Shinya Kitaoka 120a6e
                    (int)po.initSourceFrame) /*- 素材内の初期フレーム位置 -*/
Shinya Kitaoka 120a6e
                );
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          totalparticles++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      for (i = 0; i < actualBirthParticles; i++) {
Shinya Kitaoka 120a6e
        /*- 出発する粒子 -*/
Shinya Kitaoka 120a6e
        ParticleOrigin po = particleOrigins.at(leavingPartIndex.at(i));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        int seed = (int)((std::numeric_limits<int>::max)() *</int>
Shinya Kitaoka 120a6e
                         values.random_val->getFloat());
Shinya Kitaoka 120a6e
        int lifetime = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (values.column_lifetime_val)
Shinya Kitaoka 120a6e
          lifetime = lastframe[po.level];
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          lifetime =
Shinya Kitaoka 120a6e
              (int)(values.lifetime_val.first +
Shinya Kitaoka 120a6e
                    ranges.lifetime_range * values.random_val->getFloat());
Shinya Kitaoka 120a6e
        if (lifetime > curr_frame - frame) {
Shinya Kitaoka 120a6e
          myParticles.push_back(Iwa_Particle(
Shinya Kitaoka 120a6e
              lifetime, seed, porttiles, values, ranges, totalparticles, 0,
Shinya Kitaoka 120a6e
              (int)po.level, lastframe[po.level], po.pos[0], po.pos[1],
Shinya Kitaoka 120a6e
              po.isUpward,
Shinya Kitaoka 120a6e
              (int)po.initSourceFrame) /*-  素材内の初期フレーム位置  -*/
Shinya Kitaoka 120a6e
                                );
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        totalparticles++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- すでに発生したparticleOriginを消去する
Shinya Kitaoka 120a6e
          インデックスを小さい順にならべる -*/
Shinya Kitaoka 120a6e
  qSort(leavingPartIndex.begin(), leavingPartIndex.end());
Shinya Kitaoka 120a6e
  /*- インデックス大きい方から消していく -*/
Shinya Kitaoka 120a6e
  for (int lp = leavingPartIndex.size() - 1; lp >= 0; lp--)
Shinya Kitaoka 120a6e
    particleOrigins.removeAt(leavingPartIndex.at(lp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particles_Engine::normalize_values(struct particles_values &values,
Shinya Kitaoka 120a6e
                                            const TRenderSettings &ri) {
Shinya Kitaoka 120a6e
  double dpicorr = 1;
Shinya Kitaoka 120a6e
  TPointD pos(values.x_pos_val, values.y_pos_val);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  (values.x_pos_val)               = pos.x;
Shinya Kitaoka 120a6e
  (values.y_pos_val)               = pos.y;
Shinya Kitaoka 120a6e
  (values.length_val)              = (values.length_val) * dpicorr;
Shinya Kitaoka 120a6e
  (values.height_val)              = (values.height_val) * dpicorr;
Shinya Kitaoka 120a6e
  (values.gravity_val)             = (values.gravity_val) * dpicorr * 0.1;
Shinya Kitaoka 120a6e
  (values.windint_val)             = (values.windint_val) * dpicorr;
Shinya Kitaoka 120a6e
  (values.speed_val.first)         = (values.speed_val.first) * dpicorr;
Shinya Kitaoka 120a6e
  (values.speed_val.second)        = (values.speed_val.second) * dpicorr;
Shinya Kitaoka 120a6e
  (values.randomx_val.first)       = (values.randomx_val.first) * dpicorr;
Shinya Kitaoka 120a6e
  (values.randomx_val.second)      = (values.randomx_val.second) * dpicorr;
Shinya Kitaoka 120a6e
  (values.randomy_val.first)       = (values.randomy_val.first) * dpicorr;
Shinya Kitaoka 120a6e
  (values.randomy_val.second)      = (values.randomy_val.second) * dpicorr;
Shinya Kitaoka 120a6e
  (values.scale_val.first)         = (values.scale_val.first) * 0.01;
Shinya Kitaoka 120a6e
  (values.scale_val.second)        = (values.scale_val.second) * 0.01;
Shinya Kitaoka 120a6e
  (values.scalestep_val.first)     = (values.scalestep_val.first) * 0.01;
Shinya Kitaoka 120a6e
  (values.scalestep_val.second)    = (values.scalestep_val.second) * 0.01;
Shinya Kitaoka 120a6e
  (values.opacity_val.first)       = (values.opacity_val.first) * 0.01;
Shinya Kitaoka 120a6e
  (values.opacity_val.second)      = (values.opacity_val.second) * 0.01;
Shinya Kitaoka 120a6e
  (values.trailopacity_val.first)  = (values.trailopacity_val.first) * 0.01;
Shinya Kitaoka 120a6e
  (values.trailopacity_val.second) = (values.trailopacity_val.second) * 0.01;
Shinya Kitaoka 120a6e
  (values.mblur_val)               = (values.mblur_val) * 0.01;
Shinya Kitaoka 120a6e
  (values.friction_val)            = -(values.friction_val) * 0.01;
Shinya Kitaoka 120a6e
  (values.windangle_val)           = (values.windangle_val) * M_PI_180;
Shinya Kitaoka 120a6e
  (values.g_angle_val)             = (values.g_angle_val + 180) * M_PI_180;
Shinya Kitaoka 120a6e
  (values.speeda_val.first)        = (values.speeda_val.first) * M_PI_180;
Shinya Kitaoka 120a6e
  (values.speeda_val.second)       = (values.speeda_val.second) * M_PI_180;
Shinya Kitaoka 120a6e
  if (values.step_val < 1) values.step_val = 1;
Shinya Kitaoka 120a6e
  values.genfadecol_val                    = (values.genfadecol_val) * 0.01;
Shinya Kitaoka 120a6e
  values.finfadecol_val                    = (values.finfadecol_val) * 0.01;
Shinya Kitaoka 120a6e
  values.foutfadecol_val                   = (values.foutfadecol_val) * 0.01;
Shinya Kitaoka 120a6e
  (values.curl_val)                        = (values.curl_val) * dpicorr * 0.1;
Shinya Kitaoka 120a6e
  /*- ひらひら粒子に照明を当てる normalize_values()内で Degree → Radian 化する
Shinya Kitaoka 120a6e
   * -*/
Shinya Kitaoka 120a6e
  (values.iw_light_theta_val) = (values.iw_light_theta_val) * M_PI_180;
Shinya Kitaoka 120a6e
  (values.iw_light_phi_val)   = (values.iw_light_phi_val) * M_PI_180;
Shinya Kitaoka 120a6e
  /*- 読み込みマージン -*/
Shinya Kitaoka 120a6e
  (values.margin_val) = (values.margin_val) * dpicorr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::render_particles(
Shinya Kitaoka 120a6e
    TFlash *flash,                           /*-  0 が入ってくる -*/
Shinya Kitaoka 120a6e
    TTile *tile,                             /*- 結果を格納するTile -*/
Shinya Kitaoka 120a6e
    std::vector<trasterfxport *=""> part_ports, /*- テクスチャ素材画像のポート -*/</trasterfxport>
Shinya Kitaoka 120a6e
    const TRenderSettings &ri,
Shinya Kitaoka 38fd86
    TDimension
Shinya Kitaoka 38fd86
        &p_size,       /*- テクスチャ素材のバウンディングボックスの足し合わさったもの
Shinya Kitaoka 120a6e
                          -*/
Shinya Kitaoka 120a6e
    TPointD &p_offset, /*- バウンディングボックス左下の座標 -*/
Shinya Kitaoka 120a6e
    std::map<int, *="" trasterfxport=""></int,>
Shinya Kitaoka 120a6e
        ctrl_ports, /*- コントロール画像のポート番号/ポート -*/
Shinya Kitaoka 120a6e
    std::vector<tlevelp></tlevelp>
Shinya Kitaoka 120a6e
        partLevel, /*- テクスチャ素材のリスト -*/
Shinya Kitaoka 120a6e
    float dpi,     /*- 1 が入ってくる -*/
Shinya Kitaoka 120a6e
    int curr_frame,
Shinya Kitaoka 120a6e
    int shrink,                  /*- 1 が入ってくる -*/
Shinya Kitaoka 120a6e
    double startx,               /*- 0 が入ってくる -*/
Shinya Kitaoka 120a6e
    double starty,               /*- 0 が入ってくる -*/
Shinya Kitaoka 120a6e
    double endx,                 /*- 0 が入ってくる -*/
Shinya Kitaoka 120a6e
    double endy,                 /*- 0 が入ってくる -*/
Shinya Kitaoka 120a6e
    std::vector<int> last_frame, /*- テクスチャ素材のそれぞれのカラム長 -*/</int>
Shinya Kitaoka 120a6e
    unsigned long fxId) {
Shinya Kitaoka 120a6e
  /*- 各種パーティクルのパラメータ -*/
Shinya Kitaoka 120a6e
  struct particles_values values;
Shinya Kitaoka 120a6e
  memset(&values, 0, sizeof(values));
Shinya Kitaoka 120a6e
  /*- 現在のフレームでの各パラメータを得る -*/
Shinya Kitaoka 120a6e
  fill_value_struct(values, m_frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int frame, intpart = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int level_n = part_ports.size();
Shinya Kitaoka 120a6e
  /*- 開始フレーム -*/
Shinya Kitaoka 120a6e
  int startframe = (int)values.startpos_val;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float dpicorr = dpi * 0.01f, fractpart = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 不透明度の範囲(透明~不透明を 0~1 に正規化) -*/
Shinya Kitaoka 120a6e
  float opacity_range =
Shinya Kitaoka 120a6e
      (values.opacity_val.second - values.opacity_val.first) * 0.01f;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool random_level = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool isPrecomputingEnabled = false;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TRenderer renderer(TRenderer::instance());
Shinya Kitaoka 120a6e
    isPrecomputingEnabled =
Shinya Kitaoka 120a6e
        (renderer && renderer.isPrecomputingEnabled()) ? true : false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- シュリンクしている場合 -*/
Shinya Kitaoka 120a6e
  float dpicorr_shrinked;
Shinya Kitaoka 120a6e
  if (values.unit_val == Iwa_TiledParticlesFx::UNIT_SMALL_INCH)
Shinya Kitaoka 120a6e
    dpicorr_shrinked = dpicorr / shrink;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    dpicorr_shrinked = dpi / shrink;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::pair<int, int="">, float> partScales;</std::pair<int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 現在のフレームをステップ値にする -*/
Shinya Kitaoka 120a6e
  curr_frame = curr_frame / values.step_val;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  Iwa_ParticlesManager *pc = Iwa_ParticlesManager::instance();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool isFirstFrame = !(pc->isCached(fxId));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieve the last rolled frame
Shinya Kitaoka 120a6e
  Iwa_ParticlesManager::FrameData *particlesData = pc->data(fxId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::list<iwa_particle> myParticles;</iwa_particle>
Shinya Kitaoka 120a6e
  TRandom myRandom  = m_parent->randseed_val->getValue();
Shinya Kitaoka 120a6e
  values.random_val = &myRandom;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int totalparticles = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 規則正しく並んだ(まだ出発していない)粒子情報 -*/
Shinya Kitaoka 120a6e
  QList<particleorigin> particleOrigins;</particleorigin>
Shinya Kitaoka 120a6e
  /*- 出力画像のバウンディングボックス -*/
Shinya Kitaoka 120a6e
  TRectD outTileBBox(tile->m_pos, TDimensionD(tile->getRaster()->getLx(),
Shinya Kitaoka 120a6e
                                              tile->getRaster()->getLy()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 現在取っておいてあるデータのフレーム番号 -*/
Shinya Kitaoka 120a6e
  int pcFrame = particlesData->m_frame;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- マージンをピクセル単位に換算する -*/
Shinya Kitaoka 120a6e
  double pixelMargin;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TPointD vect(values.margin_val, 0.0);
Shinya Kitaoka 120a6e
    TAffine aff(ri.m_affine);
Shinya Kitaoka 120a6e
    aff.a13 = aff.a23 = 0;
Shinya Kitaoka 120a6e
    vect              = aff * vect;
Shinya Kitaoka 120a6e
    pixelMargin       = sqrt(vect.x * vect.x + vect.y * vect.y);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*- 外側にマージンを取って粒子を生成 -*/
Shinya Kitaoka 120a6e
  TRectD resourceTileBBox = outTileBBox.enlarge(pixelMargin);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 初期粒子量。これが変わっていなければ、BGはそのまま描く -*/
Shinya Kitaoka 120a6e
  int initialOriginsSize;
Shinya Kitaoka 120a6e
  if (pcFrame > curr_frame) {
Shinya Kitaoka 120a6e
    /*- データを初期化 -*/
Shinya Kitaoka 120a6e
    // Clear stored particlesData
Shinya Kitaoka 120a6e
    particlesData->clear();
Shinya Kitaoka 120a6e
    pcFrame = particlesData->m_frame;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- まだ出発していない粒子情報を初期化 -*/
Shinya Kitaoka 120a6e
    initParticleOrigins(resourceTileBBox, particleOrigins, curr_frame,
Shinya Kitaoka 120a6e
                        ri.m_affine, values, level_n, last_frame, pixelMargin);
Shinya Kitaoka 120a6e
    initialOriginsSize = particleOrigins.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  else if (pcFrame >= startframe - 1) {
Shinya Kitaoka 120a6e
    myParticles        = particlesData->m_particles;
Shinya Kitaoka 120a6e
    myRandom           = particlesData->m_random;
Shinya Kitaoka 120a6e
    totalparticles     = particlesData->m_totalParticles;
Shinya Kitaoka 120a6e
    particleOrigins    = particlesData->m_particleOrigins;
Shinya Kitaoka 120a6e
    initialOriginsSize = -1;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    /*- まだ出発していない粒子情報を初期化 -*/
Shinya Kitaoka 120a6e
    initParticleOrigins(resourceTileBBox, particleOrigins, curr_frame,
Shinya Kitaoka 120a6e
                        ri.m_affine, values, level_n, last_frame, pixelMargin);
Shinya Kitaoka 120a6e
    initialOriginsSize = particleOrigins.size();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- スタートからカレントフレームまでループ -*/
Shinya Kitaoka 120a6e
  for (frame = startframe - 1; frame <= curr_frame; ++frame) {
Shinya Kitaoka 120a6e
    /*-  参照画像はキャッシュされてるフレームでは必要ないのでは? -*/
Shinya Kitaoka 120a6e
    if (frame <= pcFrame) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int dist_frame = curr_frame - frame;
Shinya Kitaoka 120a6e
    /*-
Shinya Kitaoka 120a6e
     * ループ内の現在のフレームでのパラメータを取得。スタートが負ならフレーム=0のときの値を格納。
Shinya Kitaoka 120a6e
     * -*/
Shinya Kitaoka 120a6e
    fill_value_struct(values, frame < 0 ? 0 : frame * values.step_val);
Shinya Kitaoka 120a6e
    /*- パラメータの正規化 -*/
Shinya Kitaoka 120a6e
    normalize_values(values, ri);
Shinya Kitaoka 120a6e
    /*- maxnum_valは"birth_rate"のパラメータ -*/
Shinya Kitaoka 120a6e
    intpart = (int)values.maxnum_val;
Shinya Kitaoka 120a6e
    /*-
Shinya Kitaoka 120a6e
     * birth_rateが小数だったとき、各フレームの小数部分を足しこんだ結果の整数部分をintpartに渡す
Shinya Kitaoka 120a6e
     * -*/
Shinya Kitaoka 120a6e
    fractpart = fractpart + values.maxnum_val - intpart;
Shinya Kitaoka 120a6e
    if ((int)fractpart) {
Shinya Kitaoka 120a6e
      values.maxnum_val += (int)fractpart;
Shinya Kitaoka 120a6e
      fractpart = fractpart - (int)fractpart;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::map<int, *="" ttile=""> porttiles;</int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Perform the roll
Shinya Kitaoka 120a6e
    /*- RenderSettingsを複製して現在のフレームの計算用にする -*/
Shinya Kitaoka 120a6e
    TRenderSettings riAux(ri);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- 64bitにする -*/
Shinya Kitaoka 120a6e
    riAux.m_bpp = 64;
Shinya Kitaoka 120a6e
    // riAux.m_bpp = 32;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int r_frame;  // Useful in case of negative roll frames
Shinya Kitaoka 120a6e
    if (frame < 0)
Shinya Kitaoka 120a6e
      r_frame = 0;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      r_frame = frame;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- コントロールに刺さっている各ポートについて -*/
Shinya Kitaoka 120a6e
    for (std::map<int, *="" trasterfxport="">::iterator it = ctrl_ports.begin();</int,>
Shinya Kitaoka 120a6e
         it != ctrl_ports.end(); ++it) {
Shinya Kitaoka 120a6e
      TTile *tmp;
Shinya Kitaoka 120a6e
      /*- ポートが接続されていて、Fx内で実際に使用されていたら -*/
Shinya Kitaoka 120a6e
      if ((it->second)->isConnected() && port_is_used(it->first, values)) {
Shinya Kitaoka 120a6e
        TRectD bbox = resourceTileBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        /*- 素材が存在する場合、portTilesにコントロール画像タイルを格納 -*/
Shinya Kitaoka 120a6e
        if (!bbox.isEmpty()) {
Shinya Kitaoka 120a6e
          if (frame <= pcFrame) {
Shinya Kitaoka 120a6e
            // This frame will not actually be rolled. However, it was
Shinya Kitaoka 120a6e
            // dryComputed - so, declare the same here.
Shinya Kitaoka 120a6e
            (*it->second)->dryCompute(bbox, r_frame, riAux);
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            tmp = new TTile;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (isPrecomputingEnabled) {
Shinya Kitaoka 120a6e
              (*it->second)
Shinya Kitaoka 120a6e
                  ->allocateAndCompute(*tmp, bbox.getP00(),
Shinya Kitaoka 120a6e
                                       convert(bbox).getSize(), 0, r_frame,
Shinya Kitaoka 120a6e
                                       riAux);
Shinya Kitaoka 120a6e
            } else {
Shinya Kitaoka 120a6e
              std::string alias =
Shinya Kitaoka 120a6e
                  "CTRL: " + (*(it->second))->getAlias(r_frame, riAux);
Shinya Kitaoka 120a6e
              TRasterImageP rimg = TImageCache::instance()->get(alias, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              if (rimg) {
Shinya Kitaoka 120a6e
                tmp->m_pos = bbox.getP00();
Shinya Kitaoka 120a6e
                tmp->setRaster(rimg->getRaster());
Shinya Kitaoka 120a6e
              } else {
Shinya Kitaoka 120a6e
                (*it->second)
Shinya Kitaoka 120a6e
                    ->allocateAndCompute(*tmp, bbox.getP00(),
Shinya Kitaoka 120a6e
                                         convert(bbox).getSize(), 0, r_frame,
Shinya Kitaoka 120a6e
                                         riAux);
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            porttiles[it->first] = tmp;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTile baseImgTile;
Shinya Kitaoka 120a6e
    if (values.base_ctrl_val &&
Shinya Kitaoka 120a6e
        ctrl_ports.at(values.base_ctrl_val)->isConnected() &&
Shinya Kitaoka 120a6e
        port_is_used(values.base_ctrl_val, values) &&
Shinya Kitaoka 120a6e
        values.iw_rendermode_val !=
Shinya Kitaoka 120a6e
            Iwa_TiledParticlesFx::
Shinya Kitaoka 120a6e
                REND_ILLUMINATED) /*- 照明モードなら、BG素材は要らない -*/
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      std::string alias =
Shinya Kitaoka 120a6e
          "BG_CTRL: " +
Shinya Kitaoka 120a6e
          (*ctrl_ports.at(values.base_ctrl_val))->getAlias(r_frame, ri);
Shinya Kitaoka 120a6e
      TRasterImageP rimg = TImageCache::instance()->get(alias, false);
Shinya Kitaoka 120a6e
      if (rimg) {
Shinya Kitaoka 120a6e
        baseImgTile.m_pos = tile->m_pos;
Shinya Kitaoka 120a6e
        baseImgTile.setRaster(rimg->getRaster());
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        /*- 出力と同じbpcにする -*/
Shinya Kitaoka 120a6e
        (*ctrl_ports.at(values.base_ctrl_val))
Shinya Kitaoka 120a6e
            ->allocateAndCompute(baseImgTile, tile->m_pos,
Shinya Kitaoka 120a6e
                                 convert(resourceTileBBox).getSize(),
Shinya Kitaoka 120a6e
                                 tile->getRaster(), r_frame, ri);
Shinya Kitaoka 120a6e
        addRenderCache(alias, TRasterImageP(baseImgTile.getRaster()));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      baseImgTile.getRaster()->lock();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Invoke the actual rolling procedure
Shinya Kitaoka 120a6e
    roll_particles(tile, porttiles, riAux, myParticles, values, 0, 0, frame,
Shinya Kitaoka 120a6e
                   curr_frame, level_n, &random_level, 1, last_frame,
Shinya Kitaoka 120a6e
                   totalparticles, particleOrigins,
Shinya Kitaoka 120a6e
                   intpart /*- 実際に生成したい粒子数 -*/
Shinya Kitaoka 120a6e
                   );
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Store the rolled data in the particles manager
Shinya Kitaoka 120a6e
    if (!particlesData->m_calculated ||
Shinya Kitaoka 120a6e
        particlesData->m_frame + particlesData->m_maxTrail < frame) {
Shinya Kitaoka 120a6e
      particlesData->m_frame     = frame;
Shinya Kitaoka 120a6e
      particlesData->m_particles = myParticles;
Shinya Kitaoka 120a6e
      particlesData->m_random    = myRandom;
Shinya Kitaoka 120a6e
      particlesData->buildMaxTrail();
Shinya Kitaoka 120a6e
      particlesData->m_calculated      = true;
Shinya Kitaoka 120a6e
      particlesData->m_totalParticles  = totalparticles;
Shinya Kitaoka 120a6e
      particlesData->m_particleOrigins = particleOrigins;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Render the particles if the distance from current frame is a trail
Shinya Kitaoka 120a6e
    // multiple
Shinya Kitaoka 120a6e
    /*- さしあたり、trailは無視する -*/
Shinya Kitaoka 120a6e
    if (dist_frame == 0) {
Shinya Kitaoka 120a6e
      //--------
Shinya Kitaoka 120a6e
      // Store the maximum particle size before the do_render cycle
Shinya Kitaoka 120a6e
      /*- 表示されている粒子のうち、各素材について最大サイズのものを記録しておく
Shinya Kitaoka 120a6e
              条件にあわせ、飛んでいる粒子と飛び立つ前の粒子の両方で記録を行う
Shinya Kitaoka 120a6e
         -*/
Shinya Kitaoka 120a6e
      /*-	①飛んでいる粒子 -*/
Shinya Kitaoka 120a6e
      if (values.iw_rendermode_val != Iwa_TiledParticlesFx::REND_BG) {
Shinya Kitaoka 120a6e
        std::list<iwa_particle>::iterator pt;</iwa_particle>
Shinya Kitaoka 120a6e
        for (pt = myParticles.begin(); pt != myParticles.end(); ++pt) {
Shinya Kitaoka 120a6e
          Iwa_Particle &part = *pt;
Shinya Kitaoka 120a6e
          int ndx            = part.frame % last_frame[part.level];
Shinya Kitaoka 120a6e
          std::pair<int, int=""> ndxPair(part.level, ndx);</int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          std::map<std::pair<int, int="">, float>::iterator it =</std::pair<int,>
Shinya Kitaoka 120a6e
              partScales.find(ndxPair);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (it != partScales.end())
Shinya Kitaoka 120a6e
            it->second = std::max(part.scale, it->second);
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            partScales[ndxPair] = part.scale;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /*- ②飛び立つ前の粒子がひとつでもあった場合、最大値でおきかえる -*/
Shinya Kitaoka 120a6e
      if (values.iw_rendermode_val == Iwa_TiledParticlesFx::REND_ALL ||
Shinya Kitaoka 120a6e
          values.iw_rendermode_val == Iwa_TiledParticlesFx::REND_BG) {
Shinya Kitaoka 120a6e
        for (int lev = 0; lev < level_n; lev++) {
Shinya Kitaoka 120a6e
          std::pair<int, int=""> ndxPair(lev, 0);</int,>
Shinya Kitaoka 120a6e
          std::map<std::pair<int, int="">, float>::iterator it =</std::pair<int,>
Shinya Kitaoka 120a6e
              partScales.find(ndxPair);
Shinya Kitaoka 120a6e
          if (it != partScales.end())
Shinya Kitaoka 120a6e
            it->second = std::max((float)values.scale_val.second, it->second);
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            partScales[ndxPair] = values.scale_val.second;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      //--------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- ここで、出発した粒子の分、穴を開けた背景を描く -*/
Shinya Kitaoka 120a6e
      /*- スイッチがONなら -*/
Shinya Kitaoka 120a6e
      if (values.iw_rendermode_val == Iwa_TiledParticlesFx::REND_ALL ||
Shinya Kitaoka 120a6e
          values.iw_rendermode_val == Iwa_TiledParticlesFx::REND_BG) {
Shinya Kitaoka 120a6e
        /*- まだ粒子が飛び立っていない場合、そのまま背景を描く -*/
Shinya Kitaoka 120a6e
        if (initialOriginsSize == particleOrigins.size()) {
Shinya Kitaoka 120a6e
          TRop::resample(tile->getRaster(), baseImgTile.getRaster(), TAffine());
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          renderBackground(tile, particleOrigins, part_ports, ri, partLevel,
Shinya Kitaoka 120a6e
                           partScales, &baseImgTile);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /*- 粒子の描画。もし、背景モードなら描かない -*/
Shinya Kitaoka 120a6e
      if (values.iw_rendermode_val != Iwa_TiledParticlesFx::REND_BG) {
Shinya Kitaoka 120a6e
        if (values.toplayer_val == Iwa_TiledParticlesFx::TOP_SMALLER ||
Shinya Kitaoka 120a6e
            values.toplayer_val == Iwa_TiledParticlesFx::TOP_BIGGER)
Shinya Kitaoka 120a6e
          myParticles.sort(Iwa_ComparebySize());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (values.toplayer_val == Iwa_TiledParticlesFx::TOP_SMALLER) {
Shinya Kitaoka 120a6e
          int unit  = 1 + (int)myParticles.size() / 100;
Shinya Kitaoka 120a6e
          int count = 0;
Shinya Kitaoka 120a6e
          std::list<iwa_particle>::iterator pt;</iwa_particle>
Shinya Kitaoka 120a6e
          for (pt = myParticles.begin(); pt != myParticles.end(); ++pt) {
Shinya Kitaoka 120a6e
            count++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            Iwa_Particle &part = *pt;
Shinya Kitaoka 120a6e
            if (dist_frame <= part.trail && part.scale > 0.0f &&
Shinya Kitaoka 120a6e
                part.lifetime > 0 &&
Shinya Kitaoka 120a6e
                part.lifetime <=
Shinya Kitaoka 120a6e
                    part.genlifetime)  // This last... shouldn't always be?
Shinya Kitaoka 120a6e
            {
Shinya Kitaoka 120a6e
              do_render(flash, &part, tile, part_ports, porttiles, ri, p_size,
Shinya Kitaoka 120a6e
                        p_offset, last_frame[part.level], partLevel, values,
Shinya Kitaoka 120a6e
                        opacity_range, dist_frame, partScales, &baseImgTile);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          int unit  = 1 + (int)myParticles.size() / 100;
Shinya Kitaoka 120a6e
          int count = 0;
Shinya Kitaoka 120a6e
          std::list<iwa_particle>::reverse_iterator pt;</iwa_particle>
Shinya Kitaoka 120a6e
          for (pt = myParticles.rbegin(); pt != myParticles.rend(); ++pt) {
Shinya Kitaoka 120a6e
            count++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            Iwa_Particle &part = *pt;
Shinya Kitaoka 120a6e
            if (dist_frame <= part.trail && part.scale > 0.0f &&
Shinya Kitaoka 120a6e
                part.lifetime > 0 &&
Shinya Kitaoka 120a6e
                part.lifetime <= part.genlifetime)  // Same here..?
Shinya Kitaoka 120a6e
            {
Shinya Kitaoka 120a6e
              do_render(flash, &part, tile, part_ports, porttiles, ri, p_size,
Shinya Kitaoka 120a6e
                        p_offset, last_frame[part.level], partLevel, values,
Shinya Kitaoka 120a6e
                        opacity_range, dist_frame, partScales, &baseImgTile);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /*- 粒子の描画 ここまで -*/
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::map<int, *="" ttile="">::iterator it;</int,>
Shinya Kitaoka 120a6e
    for (it = porttiles.begin(); it != porttiles.end(); ++it) delete it->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (values.base_ctrl_val &&
Shinya Kitaoka 120a6e
        ctrl_ports.at(values.base_ctrl_val)->isConnected() &&
Shinya Kitaoka 120a6e
        port_is_used(values.base_ctrl_val, values) &&
Shinya Kitaoka 120a6e
        values.iw_rendermode_val != Iwa_TiledParticlesFx::REND_ILLUMINATED)
Shinya Kitaoka 120a6e
      baseImgTile.getRaster()->unlock();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
 render_particles から来る
Toshihiro Shimizu 890ddd
 粒子の数だけ繰り返し
Toshihiro Shimizu 890ddd
-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::do_render(
Shinya Kitaoka 120a6e
    TFlash *flash, Iwa_Particle *part, TTile *tile,
Shinya Kitaoka 120a6e
    std::vector<trasterfxport *=""> part_ports, std::map<int, *="" ttile=""> porttiles,</int,></trasterfxport>
Shinya Kitaoka 120a6e
    const TRenderSettings &ri, TDimension &p_size, TPointD &p_offset,
Shinya Kitaoka 120a6e
    int lastframe, std::vector<tlevelp> partLevel,</tlevelp>
Shinya Kitaoka 120a6e
    struct particles_values &values, float opacity_range, int dist_frame,
Shinya Kitaoka 120a6e
    std::map<std::pair<int, int="">, float> &partScales, TTile *baseImgTile) {</std::pair<int,>
Shinya Kitaoka 120a6e
  /*- カメラに対してタテになっている粒子を描かずに飛ばす -*/
Shinya Kitaoka 120a6e
  if (abs(cosf(part->flap_phi * 3.14159f / 180.0f)) < 0.03f) {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Retrieve the particle frame - that is, the *column frame* from which we are
Shinya Kitaoka 120a6e
  // picking
Shinya Kitaoka 120a6e
  // the particle to be rendered.
Shinya Kitaoka 120a6e
  int ndx = part->frame % lastframe;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterP tileRas(tile->getRaster());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string levelid;
Shinya Kitaoka 120a6e
  double aim_angle = 0;
Shinya Kitaoka 120a6e
  if (values.pathaim_val) {
Shinya Kitaoka 120a6e
    float arctan = atan2f(part->vy, part->vx);
Shinya Kitaoka 120a6e
    aim_angle    = arctan * M_180_PI;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 粒子の回転、スケールをアフィン行列に入れる -*/
Shinya Kitaoka 120a6e
  // Calculate the rotational and scale components we have to apply on the
Shinya Kitaoka 120a6e
  // particle
Shinya Kitaoka 120a6e
  TRotation rotM(part->angle + aim_angle);
Shinya Kitaoka 120a6e
  TScale scaleM(part->scale);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- ひらひら -*/
Shinya Kitaoka 120a6e
  TAffine testAff;
Shinya Kitaoka 120a6e
  float illuminant;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    float theta = part->flap_theta * 3.14159f / 180.0f;
Shinya Kitaoka 120a6e
    float phi   = part->flap_phi * 3.14159f / 180.0f;
Shinya Kitaoka 120a6e
    float cosT  = cosf(theta);
Shinya Kitaoka 120a6e
    float sinT  = sinf(theta);
Shinya Kitaoka 120a6e
    float k     = 1.0f - cosf(phi);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    testAff.a11 = 1.0f - k * cosT * cosT;
Shinya Kitaoka 120a6e
    testAff.a21 = -k * cosT * sinT;
Shinya Kitaoka 120a6e
    testAff.a12 = -k * cosT * sinT;
Shinya Kitaoka 120a6e
    testAff.a22 = 1.0f - k * sinT * sinT;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- ここで、照明モードのとき、その明るさを計算する -*/
Shinya Kitaoka 120a6e
    if (values.iw_rendermode_val == Iwa_TiledParticlesFx::REND_ILLUMINATED) {
Shinya Kitaoka 120a6e
      float liTheta  = values.iw_light_theta_val;
Shinya Kitaoka 120a6e
      float liPhi    = values.iw_light_phi_val;
Shinya Kitaoka 120a6e
      float3 normVec = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi),
Shinya Kitaoka 120a6e
                        cosf(phi)};
Shinya Kitaoka 120a6e
      float3 lightVec = {sinf(liTheta) * sinf(liPhi),
Shinya Kitaoka 120a6e
                         cosf(liTheta) * sinf(liPhi), cosf(liPhi)};
Shinya Kitaoka 120a6e
      /*- 法線ベクトルと光源ベクトルの内積の絶対値 -*/
Shinya Kitaoka 120a6e
      illuminant = abs(normVec.x * lightVec.x + normVec.y * lightVec.y +
Shinya Kitaoka 120a6e
                       normVec.z * lightVec.z);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TAffine M(rotM * scaleM * testAff);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Particles deal with dpi affines on their own
Shinya Kitaoka 120a6e
  TAffine scaleAff(m_parent->handledAffine(ri, m_frame));
Shinya Kitaoka 120a6e
  float partScale =
Shinya Kitaoka 120a6e
      scaleAff.a11 * partScales[std::pair<int, int="">(part->level, ndx)];</int,>
Shinya Kitaoka 120a6e
  TDimensionD partResolution(0, 0);
Shinya Kitaoka 120a6e
  TRenderSettings riNew(ri);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieve the bounding box in the standard reference
Shinya Kitaoka 120a6e
  TRectD bbox(-5.0, -5.0, 5.0, 5.0), standardRefBBox;
Shinya Kitaoka 120a6e
  if (part->level <
Shinya Kitaoka 120a6e
          (int)part_ports.size() &&  // Not the default levelless cases
Shinya Kitaoka 120a6e
      part_ports[part->level]->isConnected()) {
Shinya Kitaoka 120a6e
    TRenderSettings riIdentity(ri);
Shinya Kitaoka 120a6e
    riIdentity.m_affine = TAffine();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    (*part_ports[part->level])->getBBox(ndx, bbox, riIdentity);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // A particle's bbox MUST be finite. Gradients and such which have an
Shinya Kitaoka 120a6e
    // infinite bbox
Shinya Kitaoka 120a6e
    // are just NOT rendered.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // NOTE: No fx returns half-planes or similar (ie if any coordinate is
Shinya Kitaoka 120a6e
    // either
Shinya Kitaoka 120a6e
    // (std::numeric_limits<double>::max)() or its opposite, then the rect IS</double>
Shinya Kitaoka 120a6e
    // THE infiniteRectD)
Shinya Kitaoka 120a6e
    if (bbox == TConsts::infiniteRectD) return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Now, these are the particle rendering specifications
Shinya Kitaoka 120a6e
  bbox            = bbox.enlarge(3);
Shinya Kitaoka 120a6e
  standardRefBBox = bbox;
Shinya Kitaoka 120a6e
  riNew.m_affine  = TScale(partScale);
Shinya Kitaoka 120a6e
  bbox            = riNew.m_affine * bbox;
Shinya Kitaoka 120a6e
  /*- 縮小済みのParticleのサイズ -*/
Shinya Kitaoka 120a6e
  partResolution = TDimensionD(tceil(bbox.getLx()), tceil(bbox.getLy()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (flash) {
Shinya Kitaoka 120a6e
    if (!partLevel[part->level]->frame(ndx)) {
Shinya Kitaoka 120a6e
      if (part_ports[0]->isConnected()) {
Shinya Kitaoka 120a6e
        TTile auxTile;
Shinya Kitaoka 120a6e
        /*- テクスチャは出力タイルと同じbpcにする -*/
Shinya Kitaoka 120a6e
        (*part_ports[0])
Shinya Kitaoka 120a6e
            ->allocateAndCompute(auxTile, p_offset, p_size, tile->getRaster(),
Shinya Kitaoka 120a6e
                                 ndx, ri);
Shinya Kitaoka 120a6e
        partLevel[part->level]->setFrame(ndx,
Shinya Kitaoka 120a6e
                                         TRasterImageP(auxTile.getRaster()));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    flash->pushMatrix();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const TAffine aff;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    flash->multMatrix(scaleM * aff.place(0, 0, part->x, part->y));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      TColorFader cf(TPixel32::Red, .5);
Shinya Kitaoka 120a6e
      flash->draw(partLevel[part->level]->frame(ndx), &cf);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    flash->popMatrix();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    TRasterP ras;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::string alias;
Shinya Kitaoka 120a6e
    TRasterImageP rimg;
Shinya Kitaoka 120a6e
    if (rimg = partLevel[part->level]->frame(ndx)) {
Shinya Kitaoka 120a6e
      ras = rimg->getRaster();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      alias = "PART: " + (*part_ports[part->level])->getAlias(ndx, riNew);
Shinya Kitaoka 120a6e
      if (rimg = TImageCache::instance()->get(alias, false)) {
Shinya Kitaoka 120a6e
        ras = rimg->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // Check that the raster resolution is sufficient for our purposes
Shinya Kitaoka 120a6e
        if (ras->getLx() < partResolution.lx ||
Shinya Kitaoka 120a6e
            ras->getLy() < partResolution.ly)
Shinya Kitaoka 120a6e
          ras = 0;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          partResolution = TDimensionD(ras->getLx(), ras->getLy());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // We are interested in making the relation between scale and (integer)
Shinya Kitaoka 120a6e
    // resolution
Shinya Kitaoka 120a6e
    // bijective - since we shall cache by using resolution as a partial
Shinya Kitaoka 120a6e
    // identification parameter.
Shinya Kitaoka 120a6e
    // Therefore, we find the current bbox Lx and take a unique scale out of it.
Shinya Kitaoka 120a6e
    partScale      = partResolution.lx / standardRefBBox.getLx();
Shinya Kitaoka 120a6e
    riNew.m_affine = TScale(partScale);
Shinya Kitaoka 120a6e
    bbox           = riNew.m_affine * standardRefBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // If no image was retrieved from the cache (or it was not scaled enough),
Shinya Kitaoka 120a6e
    // calculate it
Shinya Kitaoka 120a6e
    if (!ras) {
Shinya Kitaoka 120a6e
      TTile auxTile;
Shinya Kitaoka 120a6e
      (*part_ports[part->level])
Shinya Kitaoka 120a6e
          ->allocateAndCompute(auxTile, bbox.getP00(),
Shinya Kitaoka 120a6e
                               TDimension(partResolution.lx, partResolution.ly),
Shinya Kitaoka 120a6e
                               tile->getRaster(), ndx, riNew);
Shinya Kitaoka 120a6e
      ras = auxTile.getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Finally, cache the particle
Shinya Kitaoka 120a6e
      addRenderCache(alias, TRasterImageP(ras));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!ras) return;  // At this point, it should never happen anyway...
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Deal with particle colors/opacity
Shinya Kitaoka 120a6e
    TRasterP rfinalpart;
Shinya Kitaoka 120a6e
    // TRaster32P rfinalpart;
Shinya Kitaoka 120a6e
    double curr_opacity =
Shinya Kitaoka 120a6e
        part->set_Opacity(porttiles, values, opacity_range, dist_frame);
Shinya Kitaoka 120a6e
    if (curr_opacity != 1.0 || part->gencol.fadecol || part->fincol.fadecol ||
Shinya Kitaoka 120a6e
        part->foutcol.fadecol) {
Shinya Kitaoka 120a6e
      if (values.pick_color_for_every_frame_val && values.gencol_ctrl_val &&
Shinya Kitaoka 120a6e
          (porttiles.find(values.gencol_ctrl_val) != porttiles.end()))
Shinya Kitaoka 120a6e
        part->get_image_reference(porttiles[values.gencol_ctrl_val], values,
Shinya Kitaoka 120a6e
                                  part->gencol.col);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      rfinalpart = ras->clone();
Shinya Kitaoka 120a6e
      part->modify_colors_and_opacity(values, curr_opacity, dist_frame,
Shinya Kitaoka 120a6e
                                      rfinalpart);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      rfinalpart = ras;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRasterP rfinalpart2;
Shinya Kitaoka 120a6e
    /*- 照明モードのとき、その明るさを色に格納 -*/
Shinya Kitaoka 120a6e
    if (values.iw_rendermode_val == Iwa_TiledParticlesFx::REND_ILLUMINATED) {
Shinya Kitaoka 120a6e
      rfinalpart2 = rfinalpart->clone();
Shinya Kitaoka 120a6e
      part->set_illuminated_colors(illuminant, rfinalpart2);
Shinya Kitaoka 120a6e
    } else if (baseImgTile->getRaster() &&
Shinya Kitaoka 120a6e
               !baseImgTile->getRaster()->isEmpty()) {
Shinya Kitaoka 120a6e
      rfinalpart2 = rfinalpart->clone();
Shinya Kitaoka 120a6e
      /*- サイズが小さい場合は、単に色を拾う -*/
Shinya Kitaoka 120a6e
      if (partResolution.lx <= 4.0 && partResolution.ly <= 4.0)
Shinya Kitaoka 120a6e
        part->get_base_image_color(baseImgTile, values, rfinalpart2, bbox, ri);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        part->get_base_image_texture(baseImgTile, values, rfinalpart2, bbox,
Shinya Kitaoka 120a6e
                                     ri);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      rfinalpart2 = rfinalpart;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Now, let's build the particle transform before it is overed on the output
Shinya Kitaoka 120a6e
    // tile
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // First, complete the transform by adding the rotational and scale
Shinya Kitaoka 120a6e
    // components from
Shinya Kitaoka 120a6e
    // Particles parameters
Shinya Kitaoka 120a6e
    M = ri.m_affine * M * TScale(1.0 / partScale);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Then, retrieve the particle position in current reference.
Shinya Kitaoka 120a6e
    TPointD pos(part->x, part->y);
Shinya Kitaoka 120a6e
    pos = ri.m_affine * pos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Finally, add the translational component to the particle
Shinya Kitaoka 120a6e
    // NOTE: p_offset is added to account for the particle relative position
Shinya Kitaoka 120a6e
    // inside its level's bbox
Shinya Kitaoka 120a6e
    M = TTranslation(pos - tile->m_pos) * M * TTranslation(bbox.getP00());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (TRaster32P myras32 = tile->getRaster())
Shinya Kitaoka 120a6e
      TRop::over(tileRas, rfinalpart2, M);
Shinya Kitaoka 120a6e
    else if (TRaster64P myras64 = tile->getRaster())
Shinya Kitaoka 120a6e
      TRop::over(tileRas, rfinalpart2, M);
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      throw TException("ParticlesFx: unsupported Pixel Type");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::fill_array(
Shinya Kitaoka 120a6e
    TTile *ctrl1,     /*- ソース画像のTile -*/
Shinya Kitaoka 120a6e
    int ®ioncount, /*- 領域数を返す -*/
Shinya Kitaoka 120a6e
    std::vector<int></int>
Shinya Kitaoka 120a6e
        &myarray, /*- インデックスを返すと思われる。サイズはソースTileの縦横 -*/
Shinya Kitaoka 120a6e
    std::vector<int> &lista,</int>
Shinya Kitaoka 120a6e
    std::vector<int> &listb, int threshold) {</int>
Shinya Kitaoka 120a6e
  int pr = 0;
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  int lx, ly;
Shinya Kitaoka 120a6e
  lx = ctrl1->getRaster()->getLx();
Shinya Kitaoka 120a6e
  ly = ctrl1->getRaster()->getLy();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*prima riga*/
Shinya Kitaoka 120a6e
  TRaster32P raster32 = ctrl1->getRaster();
Shinya Kitaoka 120a6e
  raster32->lock();
Shinya Kitaoka 120a6e
  TPixel32 *pix = raster32->pixels(0);
Shinya Kitaoka 120a6e
  for (i = 0; i < lx; i++) {
Shinya Kitaoka 120a6e
    if (pix->m > threshold) {
Shinya Kitaoka 120a6e
      pr++;
Shinya Kitaoka 120a6e
      if (!i) {
Shinya Kitaoka 120a6e
        (regioncount)++;
Shinya Kitaoka 120a6e
        myarray[i] = (regioncount);
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        if (myarray[i - 1]) myarray[i] = myarray[i - 1];
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    *pix++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (j = 1; j < ly; j++) {
Shinya Kitaoka 120a6e
    for (i = 0, pix = raster32->pixels(j); i < lx; i++, pix++) {
Shinya Kitaoka 120a6e
      /*TMSG_INFO("j=%d i=%d\n", j, i);*/
Shinya Kitaoka 120a6e
      if (pix->m > threshold) {
Shinya Kitaoka 120a6e
        std::vector<int> mask(4);</int>
Shinya Kitaoka 120a6e
        pr++;
Shinya Kitaoka 120a6e
        /* l,ul,u,ur;*/
Shinya Kitaoka 120a6e
        if (i) {
Shinya Kitaoka 120a6e
          mask[0] = myarray[i - 1 + lx * j];
Shinya Kitaoka 120a6e
          mask[1] = myarray[i - 1 + lx * (j - 1)];
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (i != lx - 1) mask[3] = myarray[i + 1 + lx * (j - 1)];
Shinya Kitaoka 120a6e
        mask[2]                  = myarray[i + lx * (j - 1)];
Shinya Kitaoka 120a6e
        if (!mask[0] && !mask[1] && !mask[2] && !mask[3]) {
Shinya Kitaoka 120a6e
          (regioncount)++;
Shinya Kitaoka 120a6e
          myarray[i + lx * j] = (regioncount);
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          int mc, firsttime = 1;
Shinya Kitaoka 120a6e
          for (mc = 0; mc < 4; mc++) {
Shinya Kitaoka 120a6e
            if (mask[mc]) {
Shinya Kitaoka 120a6e
              if (firsttime) {
Shinya Kitaoka 120a6e
                myarray[i + lx * j] = mask[mc];
Shinya Kitaoka 120a6e
                firsttime           = 0;
Shinya Kitaoka 120a6e
              } else {
Shinya Kitaoka 120a6e
                if (myarray[i + lx * j] != mask[mc]) {
Shinya Kitaoka 120a6e
                  lista.push_back(myarray[i + lx * j]);
Shinya Kitaoka 120a6e
                  listb.push_back(mask[mc]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                  /*TMSG_INFO("j=%d i=%d mc=%d, mask=%d\n", j, i, mc,
Shinya Kitaoka 120a6e
                   * mask[mc]);*/
Shinya Kitaoka 120a6e
                }
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  raster32->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::normalize_array(
Shinya Kitaoka 120a6e
    std::vector<std::vector<tpointd>> &myregions, TPointD pos, int lx, int ly,</std::vector<tpointd>
Shinya Kitaoka 120a6e
    int regioncounter, std::vector<int> &myarray, std::vector<int> &lista,</int></int>
Shinya Kitaoka 120a6e
    std::vector<int> &listb, std::vector<int> & final) {</int></int>
Shinya Kitaoka 120a6e
  int i, j, k, l;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<int> tmp;</int>
Shinya Kitaoka 120a6e
  int maxregioncounter = 0;
Shinya Kitaoka 120a6e
  int listsize         = (int)lista.size();
Shinya Kitaoka 120a6e
  // TMSG_INFO("regioncounter %d, eqcount=%d\n", regioncounter, eqcount);
Shinya Kitaoka 120a6e
  for (k = 1; k <= regioncounter; k++) final[k] = k;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (l = 0; l < listsize; l++) {
Shinya Kitaoka 120a6e
    j = lista[l];
Shinya Kitaoka 120a6e
    /*TMSG_INFO("j vale %d\n", j);*/
Shinya Kitaoka 120a6e
    while (final[j] != j) j = final[j];
Shinya Kitaoka 120a6e
    k                       = listb[l];
Shinya Kitaoka 120a6e
    /*TMSG_INFO("k vale %d\n", k);*/
Shinya Kitaoka 120a6e
    while (final[k] != k) k = final[k];
Shinya Kitaoka 120a6e
    if (j != k) final[j]    = k;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // TMSG_INFO("esco dal for\n");
Shinya Kitaoka 120a6e
  for (j                                         = 1; j <= regioncounter; j++)
Shinya Kitaoka 120a6e
    while (final[j] != final[final[j]]) final[j] = final[final[j]];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*conto quante cavolo di regioni sono*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  tmp.push_back(final[1]);
Shinya Kitaoka 120a6e
  maxregioncounter = 1;
Shinya Kitaoka 120a6e
  for (i = 2; i <= regioncounter; i++) {
Shinya Kitaoka 120a6e
    int diff = 1;
Shinya Kitaoka 120a6e
    for (j = 0; j < maxregioncounter; j++) {
Shinya Kitaoka 120a6e
      if (tmp[j] == final[i]) {
Shinya Kitaoka 120a6e
        diff = 0;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (diff) {
Shinya Kitaoka 120a6e
      tmp.push_back(final[i]);
Shinya Kitaoka 120a6e
      maxregioncounter++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  myregions.resize(maxregioncounter);
Shinya Kitaoka 120a6e
  for (j = 0; j < ly; j++) {
Shinya Kitaoka 120a6e
    for (i = 0; i < lx; i++) {
Shinya Kitaoka 120a6e
      int tmpindex;
Shinya Kitaoka 120a6e
      if (myarray[i + lx * j]) {
Shinya Kitaoka 120a6e
        tmpindex = final[myarray[i + lx * j]];
Shinya Kitaoka 120a6e
        /*TMSG_INFO("tmpindex=%d\n", tmpindex);*/
Shinya Kitaoka 120a6e
        for (k = 0; k < maxregioncounter; k++) {
Shinya Kitaoka 120a6e
          if (tmp[k] == tmpindex) break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        /*TMSG_INFO("k=%d\n", k);*/
Shinya Kitaoka 120a6e
        TPointD tmppoint;
Shinya Kitaoka 120a6e
        tmppoint.x = i;
Shinya Kitaoka 120a6e
        tmppoint.y = j;
Shinya Kitaoka 120a6e
        tmppoint += pos;
Shinya Kitaoka 120a6e
        myregions[k].push_back(tmppoint);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- multiがONのときのSource画像(ctrl1)の領域を分析 -*/
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::fill_subregions(
Shinya Kitaoka 120a6e
    int cont_index, std::vector<std::vector<tpointd>> &myregions, TTile *ctrl1,</std::vector<tpointd>
Shinya Kitaoka 120a6e
    int thres) {
Shinya Kitaoka 120a6e
  int regioncounter = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int lx = ctrl1->getRaster()->getLx();
Shinya Kitaoka 120a6e
  int ly = ctrl1->getRaster()->getLy();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<int> myarray(lx * ly);</int>
Shinya Kitaoka 120a6e
  std::vector<int> lista;</int>
Shinya Kitaoka 120a6e
  std::vector<int> listb;</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  fill_array(ctrl1, regioncounter, myarray, lista, listb, thres);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (regioncounter) {
Shinya Kitaoka 120a6e
    std::vector<int> final(regioncounter + 1);</int>
Shinya Kitaoka 120a6e
    normalize_array(myregions, ctrl1->m_pos, lx, ly, regioncounter, myarray,
Shinya Kitaoka 120a6e
                    lista, listb, final);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
/*- 入力画像のアルファ値に比例して発生濃度を変える 各Pointにウェイトを持たせる
Shinya Kitaoka 120a6e
 * -*/
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::fill_single_region(
Shinya Kitaoka 120a6e
    std::vector<tpointd> &myregions, TTile *ctrl1, int threshold,</tpointd>
Shinya Kitaoka 120a6e
    bool do_source_gradation, QList<qlist<int>> &myHistogram,</qlist<int>
Shinya Kitaoka 120a6e
    QList<particleorigin> &particleOrigins) {</particleorigin>
Shinya Kitaoka 120a6e
  assert(ctrl1->getRaster());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P raster32(ctrl1->getRaster()->getSize());
Shinya Kitaoka 120a6e
  TRop::convert(raster32, ctrl1->getRaster());
Shinya Kitaoka 120a6e
  assert(raster32);  // per ora gestisco solo i Raster32
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  myregions.clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  raster32->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 初期化 -*/
Shinya Kitaoka 120a6e
  for (int i = 0; i < 256; i++) {
Shinya Kitaoka 120a6e
    QList<int> tmpVec;</int>
Shinya Kitaoka 120a6e
    myHistogram.push_back(tmpVec);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!do_source_gradation) /*- 1階調の場合 -*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    for (int po = 0; po < particleOrigins.size(); po++) {
Shinya Kitaoka 120a6e
      int index_x = (int)particleOrigins.at(po).pixPos[0];
Shinya Kitaoka 120a6e
      int index_y = (int)particleOrigins.at(po).pixPos[1];
Shinya Kitaoka 120a6e
      if (index_x < 0)
Shinya Kitaoka 120a6e
        index_x = 0;
Shinya Kitaoka 120a6e
      else if (index_x >= raster32->getLx())
Shinya Kitaoka 120a6e
        index_x = raster32->getLx() - 1;
Shinya Kitaoka 120a6e
      if (index_y < 0) {
Shinya Kitaoka 120a6e
        index_y = 0;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      } else if (index_y >= raster32->getLy()) {
Shinya Kitaoka 120a6e
        index_y = raster32->getLy() - 1;
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      TPixel32 *pix = raster32->pixels(index_y);
Shinya Kitaoka 120a6e
      pix += index_x;
Shinya Kitaoka 120a6e
      if (pix->m > threshold) {
Shinya Kitaoka 120a6e
        myHistogram[1].push_back(po);
Shinya Kitaoka 120a6e
        myregions.push_back(TPointD(particleOrigins.at(po).pos[0],
Shinya Kitaoka 120a6e
                                    particleOrigins.at(po).pos[1]));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TRandom rand = TRandom(1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (int po = 0; po < particleOrigins.size(); po++) {
Shinya Kitaoka 120a6e
      int index_x = (int)particleOrigins.at(po).pixPos[0];
Shinya Kitaoka 120a6e
      int index_y = (int)particleOrigins.at(po).pixPos[1];
Shinya Kitaoka 120a6e
      if (index_x < 0)
Shinya Kitaoka 120a6e
        index_x = 0;
Shinya Kitaoka 120a6e
      else if (index_x >= raster32->getLx())
Shinya Kitaoka 120a6e
        index_x = raster32->getLx() - 1;
Shinya Kitaoka 120a6e
      if (index_y < 0)
Shinya Kitaoka 120a6e
        index_y = 0;
Shinya Kitaoka 120a6e
      else if (index_y >= raster32->getLy())
Shinya Kitaoka 120a6e
        index_y = raster32->getLy() - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TPixel32 *pix = raster32->pixels(index_y);
Shinya Kitaoka 120a6e
      pix += index_x;
Shinya Kitaoka 120a6e
      if (pix->m > 0) {
Shinya Kitaoka 120a6e
        /*-  Histogramの登録 -*/
Shinya Kitaoka 120a6e
        myHistogram[(int)pix->m].push_back(po);
Shinya Kitaoka 120a6e
        myregions.push_back(TPointD(particleOrigins.at(po).pos[0],
Shinya Kitaoka 120a6e
                                    particleOrigins.at(po).pos[1]));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  raster32->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*----------------------------------------------------------------
Toshihiro Shimizu 890ddd
 まだ出発していない粒子情報を初期化
Toshihiro Shimizu 890ddd
----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
shun-iwasawa 27b0cf
static bool potentialLessThan(const ParticleOrigin &po1,
shun-iwasawa 27b0cf
                              const ParticleOrigin &po2) {
Shinya Kitaoka 120a6e
  return po1.potential < po2.potential;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::initParticleOrigins(
Shinya Kitaoka 120a6e
    TRectD &resourceTileBBox, QList<particleorigin> &particleOrigins,</particleorigin>
Shinya Kitaoka 120a6e
    const double frame, const TAffine affine, struct particles_values &values,
Shinya Kitaoka 120a6e
    int level_n, std::vector<int> &lastframe, /*- 素材カラムのフレーム長 -*/</int>
Shinya Kitaoka 120a6e
    double pixelMargin) {
Shinya Kitaoka 120a6e
  /*- 敷き詰め三角形の一辺の長さをピクセル単位に換算する -*/
Shinya Kitaoka 120a6e
  TPointD vect(values.iw_triangleSize, 0.0);
Shinya Kitaoka 120a6e
  TAffine aff(affine);
Shinya Kitaoka 120a6e
  aff.a13 = aff.a23 = 0;
Shinya Kitaoka 120a6e
  vect              = aff * vect;
Shinya Kitaoka 120a6e
  double triPixSize = sqrt(vect.x * vect.x + vect.y * vect.y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double pix2Inch = values.iw_triangleSize / triPixSize;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 横方向の移動距離 -*/
Shinya Kitaoka 120a6e
  double d_hori = values.iw_triangleSize * 0.5;
Shinya Kitaoka 120a6e
  /*- 縦方向の移動距離 -*/
Shinya Kitaoka 120a6e
  double d_vert = values.iw_triangleSize * 0.8660254;
Shinya Kitaoka 120a6e
  /*- 正三角形を横に上下交互に並べたときの、中心位置のオフセット -*/
Shinya Kitaoka 120a6e
  double vOffset = values.iw_triangleSize * 0.14433758;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- ピクセル位置の方も格納する -*/
Shinya Kitaoka 120a6e
  double d_hori_pix  = triPixSize * 0.5;
Shinya Kitaoka 120a6e
  double d_vert_pix  = triPixSize * 0.8660254;
Shinya Kitaoka 120a6e
  double vOffset_pix = triPixSize * 0.14433758;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD inchBBox(
Shinya Kitaoka 120a6e
      resourceTileBBox.x0 * pix2Inch, resourceTileBBox.y0 * pix2Inch,
Shinya Kitaoka 120a6e
      resourceTileBBox.x1 * pix2Inch, resourceTileBBox.y1 * pix2Inch);
Shinya Kitaoka 120a6e
  /*- インチ位置のスタート -*/
Shinya Kitaoka 120a6e
  double curr_y = inchBBox.y0;
Shinya Kitaoka 120a6e
  /*- 行の1列目のタテのオフセット値 -*/
Shinya Kitaoka 120a6e
  double startOff = -vOffset;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- ピクセル位置のスタート -*/
Shinya Kitaoka 120a6e
  double curr_y_pix   = 0.0;
Shinya Kitaoka 120a6e
  double startOff_pix = -vOffset_pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- メモリの見積もり -*/
Shinya Kitaoka 120a6e
  int gridSize;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    int ySize = 0;
Shinya Kitaoka 120a6e
    while (curr_y <= inchBBox.y1 + d_vert * 0.5) {
Shinya Kitaoka 120a6e
      curr_y += d_vert;
Shinya Kitaoka 120a6e
      ySize++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    int xSize     = 0;
Shinya Kitaoka 120a6e
    double curr_x = inchBBox.x0;
Shinya Kitaoka 120a6e
    while (curr_x <= inchBBox.x1 + d_hori * 0.5) {
Shinya Kitaoka 120a6e
      curr_x += d_hori;
Shinya Kitaoka 120a6e
      xSize++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    gridSize = xSize * ySize;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  curr_y = inchBBox.y0;
Shinya Kitaoka 120a6e
  particleOrigins.reserve(gridSize);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- タテでループ -*/
Shinya Kitaoka 120a6e
  while (curr_y <=
Shinya Kitaoka 120a6e
         inchBBox.y1 +
Shinya Kitaoka 120a6e
             d_vert *
Shinya Kitaoka 120a6e
                 0.5) /* ←d_vert * 0.5 は最後の一行を敷き詰めるための追加分 -*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    double curr_x = inchBBox.x0;
Shinya Kitaoka 120a6e
    double off    = startOff;
Shinya Kitaoka 120a6e
    /*- 三角形が上下どっちを向いているかのフラグ -*/
Shinya Kitaoka 120a6e
    bool isUp = (off < 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- ピクセル位置のスタート -*/
Shinya Kitaoka 120a6e
    double curr_x_pix = 0.0;
Shinya Kitaoka 120a6e
    double off_pix    = startOff_pix;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- ヨコでループ -*/
Shinya Kitaoka 120a6e
    while (curr_x <= inchBBox.x1 + d_hori * 0.5) {
Shinya Kitaoka 120a6e
      unsigned char level =
Shinya Kitaoka 120a6e
          (unsigned char)(values.random_val->getFloat() * level_n);
Shinya Kitaoka 120a6e
      particleOrigins.append(ParticleOrigin(
Shinya Kitaoka 120a6e
          curr_x, curr_y + off, values.random_val->getFloat(), isUp, level,
Shinya Kitaoka 120a6e
          getInitSourceFrame(values, 0, lastframe[level]),
Shinya Kitaoka 120a6e
          (short int)tround(curr_x_pix),
Shinya Kitaoka 120a6e
          (short int)tround(curr_y_pix + off_pix)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      off = -off;
Shinya Kitaoka 120a6e
      curr_x += d_hori;
Shinya Kitaoka 120a6e
      isUp = !isUp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      off_pix = -off_pix;
Shinya Kitaoka 120a6e
      curr_x_pix += d_hori_pix;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    startOff = -startOff;
Shinya Kitaoka 120a6e
    curr_y += d_vert;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    startOff_pix = -startOff_pix;
Shinya Kitaoka 120a6e
    curr_y_pix += d_vert_pix;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- 粒子をランダム値の大きい順に並べる -*/
Shinya Kitaoka 120a6e
  qSort(particleOrigins.begin(), particleOrigins.end(), potentialLessThan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
unsigned char Iwa_Particles_Engine::getInitSourceFrame(
Shinya Kitaoka 120a6e
    const particles_values &values, int first, int last) {
Shinya Kitaoka 120a6e
  switch (values.animation_val) {
Shinya Kitaoka 120a6e
  case Iwa_TiledParticlesFx::ANIM_CYCLE:
Shinya Kitaoka 120a6e
  case Iwa_TiledParticlesFx::ANIM_S_CYCLE:
Shinya Kitaoka 120a6e
    return (unsigned char)first;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case Iwa_TiledParticlesFx::ANIM_SR_CYCLE:
Shinya Kitaoka 120a6e
    return (unsigned char)(first +
Shinya Kitaoka 120a6e
                           (values.random_val->getFloat()) * (last - first));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    return (unsigned char)(first +
Shinya Kitaoka 120a6e
                           (values.random_val->getFloat()) * (last - first));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*--------------------------------------------------
Toshihiro Shimizu 890ddd
 ここで、出発した粒子の分、穴を開けた背景を描く
Toshihiro Shimizu 890ddd
--------------------------------------------------*/
Shinya Kitaoka 120a6e
void Iwa_Particles_Engine::renderBackground(
Shinya Kitaoka 120a6e
    TTile *tile, QList<particleorigin> &origins,</particleorigin>
Shinya Kitaoka 120a6e
    std::vector<trasterfxport *=""> part_ports, const TRenderSettings &ri,</trasterfxport>
Shinya Kitaoka 120a6e
    std::vector<tlevelp> partLevel,</tlevelp>
Shinya Kitaoka 120a6e
    std::map<std::pair<int, int="">, float> &partScales, TTile *baseImgTile) {</std::pair<int,>
Shinya Kitaoka 120a6e
  TRasterP tileRas(tile->getRaster());
Shinya Kitaoka 120a6e
  int unit = 1 + (int)origins.size() / 100;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*- まだ残っている粒子源について -*/
Shinya Kitaoka 120a6e
  for (int po = 0; po < origins.size(); po++) {
Shinya Kitaoka 120a6e
    ParticleOrigin origin = origins.at(po);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int ndx = origin.initSourceFrame;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*- 粒子の回転、スケール -*/
Shinya Kitaoka 120a6e
    TRotation rotM((origin.isUpward) ? 0.0 : 180.0);
Shinya Kitaoka 120a6e
    TAffine M(rotM);
Shinya Kitaoka 120a6e
    // Particles deal with dpi affines on their own
Shinya Kitaoka 120a6e
    TAffine scaleAff(m_parent->handledAffine(ri, m_frame));
Shinya Kitaoka 120a6e
    float partScale =
Shinya Kitaoka 120a6e
        scaleAff.a11 * partScales[std::pair<int, int="">(origin.level, ndx)];</int,>
Shinya Kitaoka 120a6e
    TDimensionD partResolution(0, 0);
Shinya Kitaoka 120a6e
    TRenderSettings riNew(ri);
Shinya Kitaoka 120a6e
    // Retrieve the bounding box in the standard reference
Shinya Kitaoka 120a6e
    TRectD bbox(-5.0, -5.0, 5.0, 5.0), standardRefBBox;
Shinya Kitaoka 120a6e
    if (origin.level <
Shinya Kitaoka 120a6e
            (int)part_ports.size() &&  // Not the default levelless cases
Shinya Kitaoka 120a6e
        part_ports[origin.level]->isConnected()) {
Shinya Kitaoka 120a6e
      TRenderSettings riIdentity(ri);
Shinya Kitaoka 120a6e
      riIdentity.m_affine = TAffine();
Shinya Kitaoka 120a6e
      (*part_ports[origin.level])->getBBox(ndx, bbox, riIdentity);
Shinya Kitaoka 120a6e
      if (bbox == TConsts::infiniteRectD) return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Now, these are the particle rendering specifications
Shinya Kitaoka 120a6e
    bbox            = bbox.enlarge(3);
Shinya Kitaoka 120a6e
    standardRefBBox = bbox;
Shinya Kitaoka 120a6e
    riNew.m_affine  = TScale(partScale);
Shinya Kitaoka 120a6e
    bbox            = riNew.m_affine * bbox;
Shinya Kitaoka 120a6e
    /*- 縮小済みのParticleのサイズ -*/
Shinya Kitaoka 120a6e
    partResolution = TDimensionD(tceil(bbox.getLx()), tceil(bbox.getLy()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRasterP ras;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::string alias;
Shinya Kitaoka 120a6e
    TRasterImageP rimg;
Shinya Kitaoka 120a6e
    if (rimg = partLevel[origin.level]->frame(ndx)) {
Shinya Kitaoka 120a6e
      ras = rimg->getRaster();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      alias = "PART: " + (*part_ports[origin.level])->getAlias(ndx, riNew);
Shinya Kitaoka 120a6e
      if (rimg = TImageCache::instance()->get(alias, false)) {
Shinya Kitaoka 120a6e
        ras = rimg->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // Check that the raster resolution is sufficient for our purposes
Shinya Kitaoka 120a6e
        if (ras->getLx() < partResolution.lx ||
Shinya Kitaoka 120a6e
            ras->getLy() < partResolution.ly)
Shinya Kitaoka 120a6e
          ras = 0;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          partResolution = TDimensionD(ras->getLx(), ras->getLy());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // We are interested in making the relation between scale and (integer)
Shinya Kitaoka 120a6e
    // resolution
Shinya Kitaoka 120a6e
    // bijective - since we shall cache by using resolution as a partial
Shinya Kitaoka 120a6e
    // identification parameter.
Shinya Kitaoka 120a6e
    // Therefore, we find the current bbox Lx and take a unique scale out of it.
Shinya Kitaoka 120a6e
    partScale      = partResolution.lx / standardRefBBox.getLx();
Shinya Kitaoka 120a6e
    riNew.m_affine = TScale(partScale);
Shinya Kitaoka 120a6e
    bbox           = riNew.m_affine * standardRefBBox;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // If no image was retrieved from the cache (or it was not scaled enough),
Shinya Kitaoka 120a6e
    // calculate it
Shinya Kitaoka 120a6e
    if (!ras) {
Shinya Kitaoka 120a6e
      TTile auxTile;
Shinya Kitaoka 120a6e
      (*part_ports[origin.level])
Shinya Kitaoka 120a6e
          ->allocateAndCompute(auxTile, bbox.getP00(),
Shinya Kitaoka 120a6e
                               TDimension(partResolution.lx, partResolution.ly),
Shinya Kitaoka 120a6e
                               tile->getRaster(), ndx, riNew);
Shinya Kitaoka 120a6e
      ras = auxTile.getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Finally, cache the particle
Shinya Kitaoka 120a6e
      addRenderCache(alias, TRasterImageP(ras));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!ras) return;  // At this point, it should never happen anyway...
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    M = ri.m_affine * M * TScale(1.0 / partScale);
Shinya Kitaoka 120a6e
    TPointD pos(origin.pos[0], origin.pos[1]);
Shinya Kitaoka 120a6e
    pos = ri.m_affine * pos;
Shinya Kitaoka 120a6e
    M   = TTranslation(pos - tile->m_pos) * M * TTranslation(bbox.getP00());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (TRaster32P myras32 = tile->getRaster())
Shinya Kitaoka 120a6e
      TRop::over(tileRas, ras, M);
Shinya Kitaoka 120a6e
    else if (TRaster64P myras64 = tile->getRaster())
Shinya Kitaoka 120a6e
      TRop::over(tileRas, ras, M);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*- サイズ縮める操作をいれる -*/
Shinya Kitaoka 120a6e
  TRasterP resizedBGRas;
Shinya Kitaoka 120a6e
  if (TRaster32P myBgRas32 = baseImgTile->getRaster())
Shinya Kitaoka 120a6e
    resizedBGRas = TRaster32P(tileRas->getSize());
Shinya Kitaoka 120a6e
  else if (TRaster64P myBgRas64 = baseImgTile->getRaster())
Shinya Kitaoka 120a6e
    resizedBGRas = TRaster64P(tileRas->getSize());
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  TAffine aff;
Shinya Kitaoka 120a6e
  /*- リサンプル -*/
Shinya Kitaoka 120a6e
  TRop::resample(resizedBGRas, baseImgTile->getRaster(), aff);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRop::ropin(resizedBGRas, tileRas, tileRas);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::cout << std::endl;
Toshihiro Shimizu 890ddd
}