Toshihiro Shimizu 890ddd
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 "tstroke.h"
Toshihiro Shimizu 890ddd
//#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
//#include "tpalette.h"
Toshihiro Shimizu 890ddd
//#include "tvectorrenderdata.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 "particlesmanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "particlesengine.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trenderer.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Particles_Engine::Particles_Engine(ParticlesFx *parent, double frame)
Toshihiro Shimizu 890ddd
	: m_parent(parent), m_frame(frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void printTime(TStopWatch &sw, string name)
Toshihiro Shimizu 890ddd
{
kogaki 5bbc3c
	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
void Particles_Engine::scramble_particles(std::list <particle*> &myParticles)</particle*>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
double size=myParticles.size()
Toshihiro Shimizu 890ddd
for(i=0; i
Toshihiro Shimizu 890ddd
 {
Toshihiro Shimizu 890ddd
  j=(int)((size)*tnz_random_float());
Toshihiro Shimizu 890ddd
  k=(int)((size)*tnz_random_float());
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
 } 
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void 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.multi_source_val = m_parent->multi_source_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.unit_val=m_parent->unit_val->getValue(frame);
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.mblur_val=m_parent->mblur_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
	myvalues.perspective_distribution_val = m_parent->perspective_distribution_val->getValue();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void 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 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
}
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*-- Startフレームからカレントフレームまで順番に回す関数 --*/
Toshihiro Shimizu 890ddd
void Particles_Engine::roll_particles(
Toshihiro Shimizu 890ddd
	TTile *tile, std::map<int, *="" ttile=""> porttiles,</int,>
Toshihiro Shimizu 890ddd
	const TRenderSettings &ri, std::list<particle> &myParticles, struct particles_values &values,</particle>
Toshihiro Shimizu 890ddd
	float cx, float cy, int frame, int curr_frame, int level_n, bool *random_level,
Toshihiro Shimizu 890ddd
	float dpi, vector<int> lastframe, int &totalparticles)</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	particles_ranges ranges;
Toshihiro Shimizu 890ddd
	int i, newparticles;
Toshihiro Shimizu 890ddd
	float xgravity, ygravity, windx, windy;
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<vector<tpointd>> myregions;</vector<tpointd>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*-- [1〜255] そのIndexに対応するアルファ値を持つピクセルのインデックス値を保存。 [0] 使用せず --*/
Toshihiro Shimizu 890ddd
	vector<vector<int>> myHistogram;</vector<int>
Toshihiro Shimizu 890ddd
	/*-- アルファ値255から下がっていき、ピクセル数×重み又はアルファ値を次々足した値を格納 --*/
Toshihiro Shimizu 890ddd
	vector<float> myWeight;</float>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<int, *="" ttile="">::iterator it = porttiles.find(values.source_ctrl_val);</int,>
Toshihiro Shimizu 890ddd
	/*-- Perspective DistributionがONのとき、Sizeに刺さったControlImageが粒子の発生分布を決める --*/
Toshihiro Shimizu 890ddd
	std::map<int, *="" ttile="">::iterator sizeIt = porttiles.find(values.scale_ctrl_val);</int,>
Toshihiro Shimizu 890ddd
	if (values.perspective_distribution_val && (sizeIt != porttiles.end())) {
Toshihiro Shimizu 890ddd
		/*-- ソース画像にコントロールが付いていた場合、そのアルファ値をマスクに使う --*/
Toshihiro Shimizu 890ddd
		if (values.source_ctrl_val && (it != porttiles.end()))
Toshihiro Shimizu 890ddd
			fill_regions_with_size_map(myregions, myHistogram, sizeIt->second, it->second, values.bright_thres_val);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			fill_regions_with_size_map(myregions, myHistogram, sizeIt->second, 0, values.bright_thres_val);
Toshihiro Shimizu 890ddd
		/*- パーティクルを作る前に myregion内の候補数を合計する--*/
Toshihiro Shimizu 890ddd
		if ((int)myHistogram.size() == 256) {
Toshihiro Shimizu 890ddd
			for (int m = 255; m >= 0; m--) {
Toshihiro Shimizu 890ddd
				/*-- 明度からサイズ サイズから重みを出す --*/
Toshihiro Shimizu 890ddd
				float scale = values.scale_val.first + ranges.scale_range * (float)m / 255.0f;
Toshihiro Shimizu 890ddd
				float weight = 1.0f / (scale * scale);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				float tmpSum = weight * (float)myHistogram[m].size();
Toshihiro Shimizu 890ddd
				int index = 255 - m;
Toshihiro Shimizu 890ddd
				if (index > 0) /*-- これまでの合計に追加する --*/
Toshihiro Shimizu 890ddd
					tmpSum += myWeight[index - 1];
Toshihiro Shimizu 890ddd
				myWeight.push_back(tmpSum);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		/*- ソース画像にコントロールが付いていた場合 -*/
Toshihiro Shimizu 890ddd
		if (values.source_ctrl_val && (it != porttiles.end()))
Toshihiro Shimizu 890ddd
			/*-- 入力画像のアルファ値に比例して発生濃度を変える --*/
Toshihiro Shimizu 890ddd
			fill_regions(1, myregions, it->second, values.multi_source_val, values.bright_thres_val, values.source_gradation_val, myHistogram);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- パーティクルを作る前に myregion内の候補数を合計する--*/
Toshihiro Shimizu 890ddd
		/*-- myWeight の中には、アルファ255から0まで、各アルファ値×ポイント数を足しこんでいったものが格納される。--*/
Toshihiro Shimizu 890ddd
		if ((int)myHistogram.size() == 256) {
Toshihiro Shimizu 890ddd
			for (int m = 255; m > 0; m--) {
Toshihiro Shimizu 890ddd
				float tmpSum = (float)(m * (int)myHistogram[m].size());
Toshihiro Shimizu 890ddd
				int index = 255 - m;
Toshihiro Shimizu 890ddd
				if (index > 0)
Toshihiro Shimizu 890ddd
					tmpSum += myWeight[index - 1];
Toshihiro Shimizu 890ddd
				myWeight.push_back(tmpSum);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- birth rate を格納 -*/
Toshihiro Shimizu 890ddd
	newparticles = (int)values.maxnum_val;
Toshihiro Shimizu 890ddd
	if (myParticles.empty() && newparticles) // Initial creation
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		/*- 新たに作るパーティクルの数だけ繰り返す -*/
Toshihiro Shimizu 890ddd
		for (i = 0; i < newparticles; i++) {
Toshihiro Shimizu 890ddd
			int seed = (int)((std::numeric_limits<int>::max)() * values.random_val->getFloat());</int>
Toshihiro Shimizu 890ddd
			int level = (int)(values.random_val->getFloat() * level_n);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			int lifetime = 0;
Toshihiro Shimizu 890ddd
			if (values.column_lifetime_val)
Toshihiro Shimizu 890ddd
				lifetime = lastframe[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(Particle(lifetime, seed, porttiles, values, ranges, myregions, totalparticles, 0, level, lastframe[level], myHistogram, myWeight));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			totalparticles++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		std::list<particle>::iterator it;</particle>
Toshihiro Shimizu 890ddd
		for (it = myParticles.begin(); it != myParticles.end();) {
Toshihiro Shimizu 890ddd
			std::list<particle>::iterator current = it;</particle>
Toshihiro Shimizu 890ddd
			++it;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			Particle &part = (*current);
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, values, ranges, windx, windy, xgravity, ygravity, dpi, lastframe[part.level]);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int oldparticles = myParticles.size();
Toshihiro Shimizu 890ddd
		switch (values.toplayer_val) {
Toshihiro Shimizu 890ddd
		case ParticlesFx::TOP_YOUNGER: {
Toshihiro Shimizu 890ddd
			for (i = 0; i < newparticles; i++) {
Toshihiro Shimizu 890ddd
				int seed = (int)((std::numeric_limits<int>::max)() * values.random_val->getFloat());</int>
Toshihiro Shimizu 890ddd
				int level = (int)(values.random_val->getFloat() * level_n);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				int lifetime = 0;
Toshihiro Shimizu 890ddd
				if (values.column_lifetime_val)
Toshihiro Shimizu 890ddd
					lifetime = lastframe[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(Particle(lifetime, seed, porttiles, values, ranges, myregions, totalparticles, 0, level, lastframe[level], myHistogram, myWeight));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				totalparticles++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
			CASE ParticlesFx::TOP_RANDOM:
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				for (i = 0; i < newparticles; i++) {
Toshihiro Shimizu 890ddd
					double tmp = values.random_val->getFloat() * myParticles.size();
Toshihiro Shimizu 890ddd
					std::list<particle>::iterator it = myParticles.begin();</particle>
Toshihiro Shimizu 890ddd
					for (int j = 0; j < tmp; j++, it++)
Toshihiro Shimizu 890ddd
						;
Toshihiro Shimizu 890ddd
					{
Toshihiro Shimizu 890ddd
						int seed = (int)((std::numeric_limits<int>::max)() * values.random_val->getFloat());</int>
Toshihiro Shimizu 890ddd
						int level = (int)(values.random_val->getFloat() * level_n);
Toshihiro Shimizu 890ddd
						int lifetime = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (values.column_lifetime_val)
Toshihiro Shimizu 890ddd
							lifetime = lastframe[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.insert(it, Particle(lifetime, seed, porttiles, values, ranges, myregions, totalparticles, 0, level, lastframe[level], myHistogram, myWeight));
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 < newparticles; i++) {
Toshihiro Shimizu 890ddd
				int seed = (int)((std::numeric_limits<int>::max)() * values.random_val->getFloat());</int>
Toshihiro Shimizu 890ddd
				int level = (int)(values.random_val->getFloat() * level_n);
Toshihiro Shimizu 890ddd
				int lifetime = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (values.column_lifetime_val)
Toshihiro Shimizu 890ddd
					lifetime = lastframe[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(Particle(lifetime, seed, porttiles, values, ranges, myregions, totalparticles, 0, level, lastframe[level], myHistogram, myWeight));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				totalparticles++;
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
void 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
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Particles_Engine::render_particles(
Toshihiro Shimizu 890ddd
	TFlash *flash, TTile *tile, std::vector<trasterfxport *=""> part_ports,</trasterfxport>
Toshihiro Shimizu 890ddd
	const TRenderSettings &ri, 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,
Toshihiro Shimizu 890ddd
	int curr_frame, int shrink, double startx, double starty,
Toshihiro Shimizu 890ddd
	double endx, double endy, vector<int> last_frame,</int>
Toshihiro Shimizu 890ddd
	unsigned long fxId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int frame, startframe, intpart = 0, level_n = 0;
Toshihiro Shimizu 890ddd
	struct particles_values values;
Toshihiro Shimizu 890ddd
	double dpicorr = dpi * 0.01, fractpart = 0, dpicorr_shrinked = 0, opacity_range = 0;
Toshihiro Shimizu 890ddd
	bool random_level = false;
Toshihiro Shimizu 890ddd
	level_n = part_ports.size();
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
	memset(&values, 0, sizeof(values));
Toshihiro Shimizu 890ddd
	/*- 現在のフレームでの各種パラメータを得る -*/
Toshihiro Shimizu 890ddd
	fill_value_struct(values, m_frame);
Toshihiro Shimizu 890ddd
	/*- 不透明度の範囲(透明〜不透明を 0〜1 に正規化)-*/
Toshihiro Shimizu 890ddd
	opacity_range = (values.opacity_val.second - values.opacity_val.first) * 0.01;
Toshihiro Shimizu 890ddd
	/*- 開始フレーム -*/
Toshihiro Shimizu 890ddd
	startframe = (int)values.startpos_val;
Toshihiro Shimizu 890ddd
	if (values.unit_val == ParticlesFx::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="">, double> partScales;</std::pair<int,>
Toshihiro Shimizu 890ddd
	curr_frame = curr_frame / values.step_val;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ParticlesManager *pc = ParticlesManager::instance();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Retrieve the last rolled frame
Toshihiro Shimizu 890ddd
	ParticlesManager::FrameData *particlesData = pc->data(fxId);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::list<particle> myParticles;</particle>
Toshihiro Shimizu 890ddd
	TRandom myRandom;
Toshihiro Shimizu 890ddd
	values.random_val = &myRandom;
Toshihiro Shimizu 890ddd
	myRandom = m_parent->randseed_val->getValue();
Toshihiro Shimizu 890ddd
	int totalparticles = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int pcFrame = particlesData->m_frame;
Toshihiro Shimizu 890ddd
	if (pcFrame > curr_frame) {
Toshihiro Shimizu 890ddd
		// Clear stored particlesData
Toshihiro Shimizu 890ddd
		particlesData->clear();
Toshihiro Shimizu 890ddd
		pcFrame = particlesData->m_frame;
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
	}
Toshihiro Shimizu 890ddd
	/*- スタートからカレントフレームまでループ -*/
Toshihiro Shimizu 890ddd
	for (frame = startframe - 1; frame <= curr_frame; ++frame) {
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
		riAux.m_affine = TAffine();
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
		TRectD outTileBBox(tile->m_pos, TDimensionD(tile->getRaster()->getLx(), tile->getRaster()->getLy()));
Toshihiro Shimizu 890ddd
		/*- Controlに刺さっている各ポートについて -*/
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;
Toshihiro Shimizu 890ddd
				(*(it->second))->getBBox(r_frame, bbox, riAux);
Toshihiro Shimizu 890ddd
				/*- 素材が存在する場合、portTilesにコントロール画像タイルを格納 -*/
Toshihiro Shimizu 890ddd
				if (!bbox.isEmpty()) {
Toshihiro Shimizu 890ddd
					if (bbox == TConsts::infiniteRectD) // There could be an infinite bbox - deal with it
Toshihiro Shimizu 890ddd
						bbox = ri.m_affine.inv() * outTileBBox;
Toshihiro Shimizu 890ddd
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
								addRenderCache(alias, TRasterImageP(tmp->getRaster()));
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
		if (frame > pcFrame) {
Toshihiro Shimizu 890ddd
			// Invoke the actual rolling procedure
Toshihiro Shimizu 890ddd
			roll_particles(tile, porttiles, riAux, myParticles, values, 0, 0, frame, curr_frame, level_n, &random_level, 1, last_frame, totalparticles);
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
			}
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
		if (frame >= startframe - 1 &&
Toshihiro Shimizu 890ddd
			!(dist_frame % (values.trailstep_val > 1.0 ? (int)values.trailstep_val : 1))) {
Toshihiro Shimizu 890ddd
			// Store the maximum particle size before the do_render cycle
Toshihiro Shimizu 890ddd
			std::list<particle>::iterator pt;</particle>
Toshihiro Shimizu 890ddd
			for (pt = myParticles.begin(); pt != myParticles.end(); ++pt) {
Toshihiro Shimizu 890ddd
				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="">, double>::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
			if (values.toplayer_val == ParticlesFx::TOP_SMALLER || values.toplayer_val == ParticlesFx::TOP_BIGGER)
Toshihiro Shimizu 890ddd
				myParticles.sort(ComparebySize());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (values.toplayer_val == ParticlesFx::TOP_SMALLER) {
Toshihiro Shimizu 890ddd
				std::list<particle>::iterator pt;</particle>
Toshihiro Shimizu 890ddd
				for (pt = myParticles.begin(); pt != myParticles.end(); ++pt) {
Toshihiro Shimizu 890ddd
					Particle &part = *pt;
Toshihiro Shimizu 890ddd
					if (dist_frame <= part.trail && part.scale && 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, &part, tile, part_ports, porttiles, ri, p_size, p_offset, last_frame[part.level], partLevel, values, opacity_range, dist_frame, partScales);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				std::list<particle>::reverse_iterator pt;</particle>
Toshihiro Shimizu 890ddd
				for (pt = myParticles.rbegin(); pt != myParticles.rend(); ++pt) {
Toshihiro Shimizu 890ddd
					Particle &part = *pt;
Toshihiro Shimizu 890ddd
					if (dist_frame <= part.trail && part.scale && part.lifetime > 0 &&
Toshihiro Shimizu 890ddd
						part.lifetime <= part.genlifetime) // Same here..?
Toshihiro Shimizu 890ddd
					{
Toshihiro Shimizu 890ddd
						do_render(flash, &part, tile, part_ports, porttiles, ri, p_size, p_offset, last_frame[part.level], partLevel, values, opacity_range, dist_frame, partScales);
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
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*- render_particles から呼ばれる。粒子の数だけ繰り返し -*/
Toshihiro Shimizu 890ddd
void Particles_Engine::do_render(TFlash *flash, Particle *part, 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, TPointD &p_offset, int lastframe, vector<tlevelp> partLevel,</tlevelp>
Toshihiro Shimizu 890ddd
								 struct particles_values &values, double opacity_range, int dist_frame,
Toshihiro Shimizu 890ddd
								 std::map<std::pair<int, int="">, double> &partScales)</std::pair<int,>
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
		double arctan = atan2(part->vy, part->vx);
Toshihiro Shimizu 890ddd
		aim_angle = (180 / TConsts::pi) * arctan;
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
	TAffine M(rotM * scaleM);
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
	double 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
				TRaster32P tmp;
Toshihiro Shimizu 890ddd
				tmp = TRaster32P(p_size);
Toshihiro Shimizu 890ddd
				(*part_ports[0])->allocateAndCompute(auxTile, p_offset, p_size, tmp, 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
		//if(curr_opacity!=1.0 || part->gencol.fadecol || part->fincol.fadecol || part->foutcol.fadecol)
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
		//flash->draw(partLevel->frame(ndx), 0);
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
			// For now, we'll just use 32 bit particles
Toshihiro Shimizu 890ddd
			TRaster32P rcachepart;
Toshihiro Shimizu 890ddd
			rcachepart = ras;
Toshihiro Shimizu 890ddd
			if (!rcachepart) {
Toshihiro Shimizu 890ddd
				rcachepart = TRaster32P(ras->getSize());
Toshihiro Shimizu 890ddd
				TRop::convert(rcachepart, ras);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			ras = rcachepart;
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
		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 || part->gencol.fadecol || part->fincol.fadecol || part->foutcol.fadecol) {
Toshihiro Shimizu 890ddd
			/*- 毎フレーム現在位置のピクセル色を参照 -*/
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
		// 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, rfinalpart, M);
Toshihiro Shimizu 890ddd
		else if (TRaster64P myras64 = tile->getRaster())
Toshihiro Shimizu 890ddd
			TRop::over(tileRas, rfinalpart, 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
void Particles_Engine::fill_array(TTile *ctrl1, int ®ioncount,
Toshihiro Shimizu 890ddd
								  vector<int> &myarray, vector<int> &lista, vector<int> &listb, int threshold)</int></int></int>
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 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
/*- multiがONのときのSource画像(ctrl1)の領域を分析 -*/
Toshihiro Shimizu 890ddd
void 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
/*- 入力画像のアルファ値に比例して発生濃度を変える。各Pointにウェイトを持たせる -*/
Toshihiro Shimizu 890ddd
void Particles_Engine::fill_single_region(vector<vector<tpointd>> &myregions, TTile *ctrl1, int threshold,</vector<tpointd>
Toshihiro Shimizu 890ddd
										  bool do_source_gradation, vector<vector<int>> &myHistogram)</vector<int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P raster32 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	assert(raster32); // per ora gestisco solo i Raster32
Toshihiro Shimizu 890ddd
					  //  int lx=raster32->getLx();
Toshihiro Shimizu 890ddd
					  //  int ly=raster32->getLy();
Toshihiro Shimizu 890ddd
	int j;
Toshihiro Shimizu 890ddd
	myregions.resize(1);
Toshihiro Shimizu 890ddd
	myregions[0].clear();
Toshihiro Shimizu 890ddd
	int cc = 0;
Toshihiro Shimizu 890ddd
	int icc = 0;
Toshihiro Shimizu 890ddd
	raster32->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!do_source_gradation) /*- 2階調の場合 -*/
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		for (j = 0; j < raster32->getLy(); j++) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TPixel32 *pix = raster32->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel32 *endPix = pix + raster32->getLx();
Toshihiro Shimizu 890ddd
			int i = 0;
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				cc++;
Toshihiro Shimizu 890ddd
				if (pix->m > threshold) {
Toshihiro Shimizu 890ddd
					icc++;
Toshihiro Shimizu 890ddd
					TPointD tmp;
Toshihiro Shimizu 890ddd
					tmp.y = j;
Toshihiro Shimizu 890ddd
					tmp.x = i;
Toshihiro Shimizu 890ddd
					tmp += ctrl1->m_pos;
Toshihiro Shimizu 890ddd
					myregions[0].push_back(tmp);
Toshihiro Shimizu 890ddd
					/*TMSG_INFO("total=%d\n", Region[0].total);*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					//           int a=0;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				i++;
Toshihiro Shimizu 890ddd
				*pix++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		for (int i = 0; i < 256; i++)
Toshihiro Shimizu 890ddd
			myHistogram.push_back(vector<int>());</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TRandom rand = TRandom(1);
Toshihiro Shimizu 890ddd
		for (j = 0; j < raster32->getLy(); j++) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TPixel32 *pix = raster32->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel32 *endPix = pix + raster32->getLx();
Toshihiro Shimizu 890ddd
			int i = 0;
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				cc++;
Toshihiro Shimizu 890ddd
				/*-- アルファの濃度に比例してパーティクルを発生させるための、
Toshihiro Shimizu 890ddd
					シンプルな方法。そのピクセルのアルファ値の数だけ「立候補」させる。
Toshihiro Shimizu 890ddd
				--*/
Toshihiro Shimizu 890ddd
				if (pix->m > 0) {
Toshihiro Shimizu 890ddd
					icc++;
Toshihiro Shimizu 890ddd
					TPointD tmp;
Toshihiro Shimizu 890ddd
					tmp.y = j;
Toshihiro Shimizu 890ddd
					tmp.x = i;
Toshihiro Shimizu 890ddd
					tmp += ctrl1->m_pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					/*- Histogramの登録 -*/
Toshihiro Shimizu 890ddd
					myHistogram[(int)pix->m].push_back((int)myregions[0].size());
Toshihiro Shimizu 890ddd
					/*-  各Pointにウェイトを持たせる -*/
Toshihiro Shimizu 890ddd
					myregions[0].push_back(tmp);
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				i++;
Toshihiro Shimizu 890ddd
				*pix++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (myregions[0].size() == 0)
Toshihiro Shimizu 890ddd
		myregions.resize(0);
Toshihiro Shimizu 890ddd
	raster32->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*- 入力画像のアルファ値に比例して発生濃度を変える。Histogramを格納しながら領域を登録 -*/
Toshihiro Shimizu 890ddd
void Particles_Engine::fill_regions(int frame, vector<vector<tpointd>> &myregions, TTile *ctrl1, bool multi, int thres,</vector<tpointd>
Toshihiro Shimizu 890ddd
									bool do_source_gradation, vector<vector<int>> &myHistogram)</vector<int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P ctrl1ras = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	if (!ctrl1ras)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	if (frame <= 0)
Toshihiro Shimizu 890ddd
		i = 0;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		i = frame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (multi) {
Toshihiro Shimizu 890ddd
		fill_subregions(i, myregions, ctrl1, thres);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		fill_single_region(myregions, ctrl1, thres, do_source_gradation, myHistogram);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*-- Perspective DistributionがONのとき、Sizeに刺さったControlImageが粒子の発生分布を決める。
Toshihiro Shimizu 890ddd
	そのとき、SourceのControlが刺さっている場合は、マスクとして用いられる
Toshihiro Shimizu 890ddd
--*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Particles_Engine::fill_regions_with_size_map(vector<vector<tpointd>> &myregions,</vector<tpointd>
Toshihiro Shimizu 890ddd
												  vector<vector<int>> &myHistogram,</vector<int>
Toshihiro Shimizu 890ddd
												  TTile *sizeTile,
Toshihiro Shimizu 890ddd
												  TTile *sourceTile,
Toshihiro Shimizu 890ddd
												  int thres)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P sizeRas = sizeTile->getRaster();
Toshihiro Shimizu 890ddd
	if (!sizeRas)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P sourceRas;
Toshihiro Shimizu 890ddd
	if (sourceTile)
Toshihiro Shimizu 890ddd
		sourceRas = sourceTile->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	sizeRas->lock();
Toshihiro Shimizu 890ddd
	if (sourceRas)
Toshihiro Shimizu 890ddd
		sourceRas->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	myregions.resize(1);
Toshihiro Shimizu 890ddd
	myregions[0].clear();
Toshihiro Shimizu 890ddd
	for (int i = 0; i < 256; i++)
Toshihiro Shimizu 890ddd
		myHistogram.push_back(vector<int>());</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int j = 0; j < sizeRas->getLy(); j++) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPixel32 *pix = sizeRas->pixels(j);
Toshihiro Shimizu 890ddd
		TPixel32 *endPix = pix + sizeRas->getLx();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPixel32 *sourcePixHead = 0;
Toshihiro Shimizu 890ddd
		if (sourceRas) {
Toshihiro Shimizu 890ddd
			int sourceYPos = troundp(j + sizeTile->m_pos.y - sourceTile->m_pos.y);
Toshihiro Shimizu 890ddd
			if (sourceYPos >= 0 && sourceYPos < sourceRas->getLy())
Toshihiro Shimizu 890ddd
				sourcePixHead = sourceRas->pixels(sourceYPos);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int i = 0;
Toshihiro Shimizu 890ddd
		TPixel32 *sourcePix = 0;
Toshihiro Shimizu 890ddd
		while (pix < endPix) {
Toshihiro Shimizu 890ddd
			if (sourceRas) {
Toshihiro Shimizu 890ddd
				int sourceXPos = (int)(i + sizeTile->m_pos.x - sourceTile->m_pos.x);
Toshihiro Shimizu 890ddd
				if (sourcePixHead && sourceXPos >= 0 && sourceXPos < sourceRas->getLx())
Toshihiro Shimizu 890ddd
					sourcePix = sourcePixHead + sourceXPos;
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					sourcePix = 0;
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				sourcePix = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- Source画像があって、ピクセルがバウンディング外またはアルファが0なら抜かす。 -*/
Toshihiro Shimizu 890ddd
			if (sourceRas && (!sourcePix || sourcePix->m <= thres)) {
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			/*- 明度に比例してパーティクルを発生させる。そのピクセルのアルファ値の数だけ「立候補」させる。-*/
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				TPointD tmp;
Toshihiro Shimizu 890ddd
				tmp.y = j;
Toshihiro Shimizu 890ddd
				tmp.x = i;
Toshihiro Shimizu 890ddd
				tmp += sizeTile->m_pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				int val = (int)TPixelGR8::from(*pix).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				/*- Histogramの登録 -*/
Toshihiro Shimizu 890ddd
				myHistogram[val].push_back((int)myregions[0].size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				/*- 各Pointにウェイトを持たせる -*/
Toshihiro Shimizu 890ddd
				myregions[0].push_back(tmp);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			i++;
Toshihiro Shimizu 890ddd
			pix++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (myregions[0].size() == 0)
Toshihiro Shimizu 890ddd
		myregions.resize(0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	sizeRas->unlock();
Toshihiro Shimizu 890ddd
	if (sourceRas)
Toshihiro Shimizu 890ddd
		sourceRas->unlock();
Toshihiro Shimizu 890ddd
}