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