Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// Iwa_Particle for Marnie
Toshihiro Shimizu 890ddd
// based on ParticlesFx by Digital Video
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfxparam.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "iwa_particles.h"
Toshihiro Shimizu 890ddd
#include "iwa_particlesengine.h"
Toshihiro Shimizu 890ddd
#include "hsvutil.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particle::create_Animation(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:
Shinya Kitaoka d4642c
	case Iwa_TiledParticlesFx::ANIM_S_CYCLE:
Shinya Kitaoka d4642c
		animswing = 0; /*frame <0 perche' c'e' il preroll dialmeno un frame*/
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case Iwa_TiledParticlesFx::ANIM_SR_CYCLE:
Shinya Kitaoka d4642c
		animswing = random.getFloat() > 0.5 ? 1 : 0;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Iwa_Particle::Iwa_Particle(int g_lifetime,
Toshihiro Shimizu 890ddd
						   int seed,
Shinya Kitaoka 3bfa54
							 std::map<int, TTile *> porttiles,
Toshihiro Shimizu 890ddd
						   const particles_values &values,
Toshihiro Shimizu 890ddd
						   const particles_ranges &ranges,
Toshihiro Shimizu 890ddd
						   int howmany,
Toshihiro Shimizu 890ddd
						   int first,
Toshihiro Shimizu 890ddd
						   int level,
Toshihiro Shimizu 890ddd
						   int last,
Toshihiro Shimizu 890ddd
						   float posx, float posy,
Toshihiro Shimizu 890ddd
						   bool isUpward,		/*- 初期向き -*/
Toshihiro Shimizu 890ddd
						   int initSourceFrame) /*- Level内の初期フレーム位置 -*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double random_s_a_range, random_speed;
Shinya Kitaoka 3bfa54
	std::map<int, float> imagereferences;
Toshihiro Shimizu 890ddd
	random = TRandom(seed);
Toshihiro Shimizu 890ddd
	float randomxreference = 0.0;
Toshihiro Shimizu 890ddd
	float randomyreference = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- ここで、出発時の素材フレームが決定するので、ParticleOriginに渡す -*/
Toshihiro Shimizu 890ddd
	create_Animation(values, 0, last);
Toshihiro Shimizu 890ddd
	frame = initSourceFrame;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	this->level = level;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	x = posx;
Toshihiro Shimizu 890ddd
	y = posy;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 粒子パラメータに参照画像が使われている場合、
Toshihiro Shimizu 890ddd
		参照画像のとる値を先にまとめて得ておく -*/
Toshihiro Shimizu 890ddd
	for (std::map<int, TTile *>::iterator it = porttiles.begin(); it != porttiles.end(); ++it) {
Toshihiro Shimizu 890ddd
		if ((values.lifetime_ctrl_val == it->first ||
Toshihiro Shimizu 890ddd
			 values.speed_ctrl_val == it->first ||
Toshihiro Shimizu 890ddd
			 values.scale_ctrl_val == it->first ||
Toshihiro Shimizu 890ddd
			 values.rot_ctrl_val == it->first
Toshihiro Shimizu 890ddd
			 /*- Speed Angleを明るさでコントロールする場合 -*/
Toshihiro Shimizu 890ddd
			 || (values.speeda_ctrl_val == it->first && !values.speeda_use_gradient_val)) &&
Toshihiro Shimizu 890ddd
			it->second->getRaster()) {
Toshihiro Shimizu 890ddd
			float tmpvalue;
Toshihiro Shimizu 890ddd
			get_image_reference(it->second, values, tmpvalue, Iwa_TiledParticlesFx::GRAY_REF);
Toshihiro Shimizu 890ddd
			imagereferences[it->first] = tmpvalue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 寿命にControlが刺さっている場合は、その値に合わせて寿命を減ずる -*/
Toshihiro Shimizu 890ddd
	if (values.lifetime_ctrl_val) {
Toshihiro Shimizu 890ddd
		float lifetimereference = 0.0;
Toshihiro Shimizu 890ddd
		lifetimereference = imagereferences[values.lifetime_ctrl_val];
Toshihiro Shimizu 890ddd
		lifetime = g_lifetime * lifetimereference;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		lifetime = g_lifetime;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	genlifetime = lifetime;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 粒子の初期速度を得る -*/
Toshihiro Shimizu 890ddd
	if (values.speed_ctrl_val && (porttiles.find(values.speed_ctrl_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		float speedreference = 0.0;
Toshihiro Shimizu 890ddd
		speedreference = imagereferences[values.speed_ctrl_val];
Toshihiro Shimizu 890ddd
		random_speed = values.speed_val.first + (ranges.speed_range) * speedreference;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		random_speed = values.speed_val.first + (ranges.speed_range) * random.getFloat();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 粒子の初期移動方向を得る -*/
Toshihiro Shimizu 890ddd
	if (values.speeda_ctrl_val && (porttiles.find(values.speeda_ctrl_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		if (values.speeda_use_gradient_val) {
Toshihiro Shimizu 890ddd
			/*- 参照画像のGradientを得る関数を利用して角度を得るモード -*/
Toshihiro Shimizu 890ddd
			float dir_x, dir_y;
Toshihiro Shimizu 890ddd
			get_image_gravity(porttiles[values.speeda_ctrl_val], values, dir_x, dir_y);
Toshihiro Shimizu 890ddd
			if (dir_x == 0.0f && dir_y == 0.0f)
Toshihiro Shimizu 890ddd
				random_s_a_range = values.speed_val.first;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				random_s_a_range = atan2f(dir_x, -dir_y);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			float speedareference = 0.0;
Toshihiro Shimizu 890ddd
			speedareference = imagereferences[values.speeda_ctrl_val];
Toshihiro Shimizu 890ddd
			random_s_a_range = values.speeda_val.first + (ranges.speeda_range) * speedareference;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else /*- Controlが無ければランダム -*/
Toshihiro Shimizu 890ddd
		random_s_a_range = values.speeda_val.first + (ranges.speeda_range) * random.getFloat();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 移動方向から速度のX,Y成分を得る -*/
Toshihiro Shimizu 890ddd
	vx = random_speed * sin(random_s_a_range);
Toshihiro Shimizu 890ddd
	vy = -random_speed * cos(random_s_a_range);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	trail = (int)(values.trail_val.first + (ranges.trail_range) * random.getFloat());
Toshihiro Shimizu 890ddd
	oldx = 0;
Toshihiro Shimizu 890ddd
	oldy = 0;
Toshihiro Shimizu 890ddd
	/*- 質量を指定(動きにくさ) -*/
Toshihiro Shimizu 890ddd
	mass = values.mass_val.first + (ranges.mass_range) * random.getFloat();
Toshihiro Shimizu 890ddd
	/*- サイズを得る -*/
Toshihiro Shimizu 890ddd
	if (values.scale_ctrl_val && (porttiles.find(values.scale_ctrl_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		float scalereference = 0.0f;
Toshihiro Shimizu 890ddd
		scalereference = imagereferences[values.scale_ctrl_val];
Toshihiro Shimizu 890ddd
		scale = values.scale_val.first + (ranges.scale_range) * scalereference;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		/*- ONのとき、かつ、ScaleにControlが無い場合、
Toshihiro Shimizu 890ddd
			粒子サイズが小さいほど(遠くにあるので)多く分布するようになる。 -*/
Toshihiro Shimizu 890ddd
		if (values.perspective_distribution_val) {
Toshihiro Shimizu 890ddd
			scale = (values.scale_val.first * values.scale_val.second) /
Toshihiro Shimizu 890ddd
					(values.scale_val.second - (ranges.scale_range) * random.getFloat());
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			scale = values.scale_val.first + (ranges.scale_range) * random.getFloat();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 向きを得る -*/
Toshihiro Shimizu 890ddd
	if (values.rot_ctrl_val && (porttiles.find(values.rot_ctrl_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		float anglereference = 0.0f;
Toshihiro Shimizu 890ddd
		anglereference = imagereferences[values.rot_ctrl_val];
Toshihiro Shimizu 890ddd
		angle = -(values.rot_val.first) - (ranges.rot_range) * anglereference;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		angle = -(values.rot_val.first) - (ranges.rot_range) * random.getFloat();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//140212 初期粒子向き
Toshihiro Shimizu 890ddd
	if (!isUpward)
Toshihiro Shimizu 890ddd
		angle += 180.0f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- ランダムな動きのふれはば -*/
Toshihiro Shimizu 890ddd
	if (values.randomx_ctrl_val)
Toshihiro Shimizu 890ddd
		randomxreference = imagereferences[values.randomx_ctrl_val];
Toshihiro Shimizu 890ddd
	if (values.randomy_ctrl_val)
Toshihiro Shimizu 890ddd
		randomyreference = imagereferences[values.randomy_ctrl_val];
Toshihiro Shimizu 890ddd
	create_Swing(values, ranges, randomxreference, randomyreference);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	create_Colors(values, ranges, porttiles);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (scale < 0.001f)
Toshihiro Shimizu 890ddd
		scale = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- ひらひらした動き -*/
Toshihiro Shimizu 890ddd
	if (values.flap_ctrl_val && (porttiles.find(values.flap_ctrl_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		//*- 参照画像のGradientを得る関数を利用して角度を得る -*/
Toshihiro Shimizu 890ddd
		float dir_x, dir_y;
Toshihiro Shimizu 890ddd
		float norm;
Toshihiro Shimizu 890ddd
		norm = get_image_gravity(porttiles[values.flap_ctrl_val], values, dir_x, dir_y);
Toshihiro Shimizu 890ddd
		if (dir_x == 0.0f && dir_y == 0.0f) {
Toshihiro Shimizu 890ddd
			flap_theta = 0.0f;
Toshihiro Shimizu 890ddd
			flap_phi = 0.0f;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			flap_theta = atan2f(dir_y, dir_x) * 180.0f / 3.14159f;
Toshihiro Shimizu 890ddd
			flap_phi = values.iw_flap_velocity_val * norm / mass;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		flap_theta = 0.0f;
Toshihiro Shimizu 890ddd
		flap_phi = 0.0f;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	initial_x = x;
Toshihiro Shimizu 890ddd
	initial_y = y;
Toshihiro Shimizu 890ddd
	initial_angle = angle;
Toshihiro Shimizu 890ddd
	initial_scale = scale;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	curlx = 0.0f;
Toshihiro Shimizu 890ddd
	curly = 0.0f;
Toshihiro Shimizu 890ddd
	curlz = random.getFloat();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int Iwa_Particle::check_Swing(const particles_values &values)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (values.randomx_val.first || values.randomx_val.second ||
Toshihiro Shimizu 890ddd
			values.randomy_val.first || values.randomy_val.second ||
Toshihiro Shimizu 890ddd
			values.rotsca_val.first || values.rotsca_val.second);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particle::create_Swing(const particles_values &values,
Toshihiro Shimizu 890ddd
								const particles_ranges &ranges,
Toshihiro Shimizu 890ddd
								double randomxreference, double randomyreference)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	changesignx = (int)(values.swing_val.first + random.getFloat() * (ranges.swing_range));
Toshihiro Shimizu 890ddd
	changesigny = (int)(values.swing_val.first + random.getFloat() * (ranges.swing_range));
Toshihiro Shimizu 890ddd
	changesigna = (int)(values.rotswing_val.first + random.getFloat() * (ranges.rotswing_range));
Toshihiro Shimizu 890ddd
	if (values.swingmode_val == Iwa_TiledParticlesFx::SWING_SMOOTH) {
Toshihiro Shimizu 890ddd
		if (values.randomx_ctrl_val)
Toshihiro Shimizu 890ddd
			smswingx = abs((int)values.randomx_val.first) + randomxreference * (ranges.randomx_range);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			smswingx = abs((int)values.randomx_val.first) + random.getFloat() * (ranges.randomx_range);
Toshihiro Shimizu 890ddd
		if (values.randomy_ctrl_val)
Toshihiro Shimizu 890ddd
			smswingy = abs((int)values.randomy_val.first) + randomyreference * (ranges.randomy_range);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			smswingy = abs((int)values.randomy_val.first) + random.getFloat() * (ranges.randomy_range);
Toshihiro Shimizu 890ddd
		smperiodx = changesignx;
Toshihiro Shimizu 890ddd
		smperiody = changesigny;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (values.rotswingmode_val == Iwa_TiledParticlesFx::SWING_SMOOTH) {
Toshihiro Shimizu 890ddd
		smswinga = abs((int)(values.rotsca_val.first + random.getFloat() * (ranges.rotsca_range)));
Toshihiro Shimizu 890ddd
		smperioda = changesigna;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	signx = random.getInt(0, 1) > 0 ? 1 : -1;
Toshihiro Shimizu 890ddd
	signy = random.getInt(0, 1) > 0 ? 1 : -1;
Toshihiro Shimizu 890ddd
	signa = random.getInt(0, 1) > 0 ? 1 : -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particle::create_Colors(const particles_values &values,
Toshihiro Shimizu 890ddd
								 const particles_ranges &ranges,
Shinya Kitaoka 3bfa54
								 std::map<int, TTile *> porttiles)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (values.genfadecol_val) {
Toshihiro Shimizu 890ddd
		TPixel32 color;
Toshihiro Shimizu 890ddd
		if (values.gencol_ctrl_val && (porttiles.find(values.gencol_ctrl_val) != porttiles.end()))
Toshihiro Shimizu 890ddd
			get_image_reference(porttiles[values.gencol_ctrl_val], values, color);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			color = values.gencol_val.getPremultipliedValue(random.getFloat());
Toshihiro Shimizu 890ddd
		gencol.fadecol = values.genfadecol_val;
Toshihiro Shimizu 890ddd
		if (values.gencol_spread_val)
Toshihiro Shimizu 890ddd
			spread_color(color, values.gencol_spread_val);
Toshihiro Shimizu 890ddd
		gencol.col = color;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		gencol.col = TPixel32::Transparent;
Toshihiro Shimizu 890ddd
		gencol.fadecol = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.finfadecol_val) {
Toshihiro Shimizu 890ddd
		TPixel32 color;
Toshihiro Shimizu 890ddd
		if (values.fincol_ctrl_val && (porttiles.find(values.fincol_ctrl_val) != porttiles.end()))
Toshihiro Shimizu 890ddd
			get_image_reference(porttiles[values.fincol_ctrl_val], values, color);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			color = values.fincol_val.getPremultipliedValue(random.getFloat());
Toshihiro Shimizu 890ddd
		fincol.rangecol = (int)values.finrangecol_val;
Toshihiro Shimizu 890ddd
		fincol.fadecol = values.finfadecol_val;
Toshihiro Shimizu 890ddd
		if (values.fincol_spread_val)
Toshihiro Shimizu 890ddd
			spread_color(color, values.fincol_spread_val);
Toshihiro Shimizu 890ddd
		fincol.col = color;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		fincol.col = TPixel32::Transparent;
Toshihiro Shimizu 890ddd
		fincol.rangecol = 0;
Toshihiro Shimizu 890ddd
		fincol.fadecol = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.foutfadecol_val) {
Toshihiro Shimizu 890ddd
		TPixel32 color;
Toshihiro Shimizu 890ddd
		if (values.foutcol_ctrl_val && (porttiles.find(values.foutcol_ctrl_val) != porttiles.end()))
Toshihiro Shimizu 890ddd
			get_image_reference(porttiles[values.foutcol_ctrl_val], values, color);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			color = values.foutcol_val.getPremultipliedValue(random.getFloat());
Toshihiro Shimizu 890ddd
		;
Toshihiro Shimizu 890ddd
		foutcol.rangecol = (int)values.foutrangecol_val;
Toshihiro Shimizu 890ddd
		foutcol.fadecol = values.foutfadecol_val;
Toshihiro Shimizu 890ddd
		if (values.foutcol_spread_val)
Toshihiro Shimizu 890ddd
			spread_color(color, values.foutcol_spread_val);
Toshihiro Shimizu 890ddd
		foutcol.col = color;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		foutcol.col = TPixel32::Transparent;
Toshihiro Shimizu 890ddd
		foutcol.rangecol = 0;
Toshihiro Shimizu 890ddd
		foutcol.fadecol = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- modify_colors_and_opacityから呼ばれる。
Toshihiro Shimizu 890ddd
	lifetimeが粒子の現在の年齢。 gencol/fincol/foutcolから色を決める -*/
Toshihiro Shimizu 890ddd
void Iwa_Particle::modify_colors(TPixel32 &color, double &intensity)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	float percent = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((gencol.fadecol || fincol.fadecol) &&
Toshihiro Shimizu 890ddd
		(genlifetime - lifetime) <= fincol.rangecol) {
Toshihiro Shimizu 890ddd
		if (fincol.rangecol)
Toshihiro Shimizu 890ddd
			percent = (genlifetime - lifetime) / (float)(fincol.rangecol);
Toshihiro Shimizu 890ddd
		color = blend(gencol.col, fincol.col, percent);
Toshihiro Shimizu 890ddd
		intensity = gencol.fadecol + percent * (fincol.fadecol - gencol.fadecol);
Toshihiro Shimizu 890ddd
	} else if (foutcol.fadecol && lifetime <= foutcol.rangecol) {
Toshihiro Shimizu 890ddd
		if (foutcol.rangecol)
Toshihiro Shimizu 890ddd
			percent = 1 - (lifetime - 1) / (float)(foutcol.rangecol);
Toshihiro Shimizu 890ddd
		if (fincol.rangecol && fincol.fadecol) {
Toshihiro Shimizu 890ddd
			color = blend(fincol.col, foutcol.col, percent);
Toshihiro Shimizu 890ddd
			intensity = fincol.fadecol + percent * (foutcol.fadecol - fincol.fadecol);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			color = blend(gencol.col, foutcol.col, percent);
Toshihiro Shimizu 890ddd
			intensity = gencol.fadecol + percent * (foutcol.fadecol - gencol.fadecol);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		if (fincol.fadecol && fincol.rangecol) {
Toshihiro Shimizu 890ddd
			color = fincol.col;
Toshihiro Shimizu 890ddd
			intensity = fincol.fadecol;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			color = gencol.col;
Toshihiro Shimizu 890ddd
			intensity = gencol.fadecol;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*- do_render から呼ばれる。各粒子の描画の直前に色を決めるところ -*/
Toshihiro Shimizu 890ddd
void Iwa_Particle::modify_colors_and_opacity(const particles_values &values,
Toshihiro Shimizu 890ddd
											 float curr_opacity,
Toshihiro Shimizu 890ddd
											 int dist_frame,
Toshihiro Shimizu 890ddd
											 TRaster32P raster32)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double intensity = 0;
Toshihiro Shimizu 890ddd
	TPixel32 col;
Toshihiro Shimizu 890ddd
	if (gencol.fadecol || fincol.fadecol || foutcol.fadecol) {
Toshihiro Shimizu 890ddd
		modify_colors(col, intensity);
Toshihiro Shimizu 890ddd
		int j;
Toshihiro Shimizu 890ddd
		raster32->lock();
Toshihiro Shimizu 890ddd
		for (j = 0; j < raster32->getLy(); j++) {
Toshihiro Shimizu 890ddd
			TPixel32 *pix = raster32->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel32 *endPix = pix + raster32->getLx();
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				double factor = pix->m / 255.0;
Toshihiro Shimizu 890ddd
				pix->r = (UCHAR)(pix->r + intensity * (factor * col.r - pix->r));
Toshihiro Shimizu 890ddd
				pix->g = (UCHAR)(pix->g + intensity * (factor * col.g - pix->g));
Toshihiro Shimizu 890ddd
				pix->b = (UCHAR)(pix->b + intensity * (factor * col.b - pix->b));
Toshihiro Shimizu 890ddd
				pix->m = (UCHAR)(pix->m + intensity * (factor * col.m - pix->m));
Toshihiro Shimizu 890ddd
				++pix;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		raster32->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (curr_opacity != 1.0)
Toshihiro Shimizu 890ddd
		TRop::rgbmScale(raster32, raster32, 1, 1, 1, curr_opacity);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
void Iwa_Particle::update_Animation(const particles_values &values,
Toshihiro Shimizu 890ddd
									int first, int last, int keep)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	switch (values.animation_val) {
Toshihiro Shimizu 890ddd
	case Iwa_TiledParticlesFx::ANIM_RANDOM:
Toshihiro Shimizu 890ddd
		frame = (int)(first + random.getFloat() * (last - first));
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case Iwa_TiledParticlesFx::ANIM_R_CYCLE:
Shinya Kitaoka d4642c
	case Iwa_TiledParticlesFx::ANIM_CYCLE:
Shinya Kitaoka d4642c
		if (!keep || frame != keep - 1)
Shinya Kitaoka d4642c
			frame = first + (frame + 1) % (last - first);
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case Iwa_TiledParticlesFx::ANIM_S_CYCLE:
Shinya Kitaoka d4642c
	case Iwa_TiledParticlesFx::ANIM_SR_CYCLE:
Shinya Kitaoka d4642c
		if (!keep || frame != keep - 1) {
Shinya Kitaoka d4642c
			if (!animswing && frame < last - 1) {
Shinya Kitaoka d4642c
				frame = (frame + 1);
Shinya Kitaoka d4642c
				if (frame == last - 1)
Shinya Kitaoka d4642c
					animswing = 1;
Shinya Kitaoka d4642c
			} else
Shinya Kitaoka d4642c
				frame = (frame - 1);
Shinya Kitaoka d4642c
			if (frame <= first) {
Shinya Kitaoka d4642c
				animswing = 0;
Shinya Kitaoka d4642c
				frame = first;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
void Iwa_Particle::update_Swing(const particles_values &values,
Toshihiro Shimizu 890ddd
								const particles_ranges &ranges,
Toshihiro Shimizu 890ddd
								struct pos_dummy &dummy,
Toshihiro Shimizu 890ddd
								double randomxreference, double randomyreference)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.swingmode_val == Iwa_TiledParticlesFx::SWING_SMOOTH) {
Toshihiro Shimizu 890ddd
		if (smperiodx)
Shinya Kitaoka ee259f
			dummy.x = smswingx * randomxreference * sin((M_PI * changesignx) / smperiodx);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			dummy.x = 0;
Toshihiro Shimizu 890ddd
		if (smperiody)
Shinya Kitaoka ee259f
			dummy.y = smswingy * randomyreference * sin((M_PI * changesigny) / smperiody);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			dummy.y = 0;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		if (values.randomx_ctrl_val)
Toshihiro Shimizu 890ddd
			dummy.x = (values.randomx_val.first + (ranges.randomx_range) * randomxreference);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			dummy.x = (values.randomx_val.first + (ranges.randomx_range) * random.getFloat());
Toshihiro Shimizu 890ddd
		if (values.randomy_ctrl_val)
Toshihiro Shimizu 890ddd
			dummy.y = (values.randomy_val.first + (ranges.randomy_range) * randomyreference);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			dummy.y = (values.randomy_val.first + (ranges.randomy_range) * random.getFloat());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.rotswingmode_val == Iwa_TiledParticlesFx::SWING_SMOOTH) {
Toshihiro Shimizu 890ddd
		if (smperioda)
Shinya Kitaoka ee259f
			dummy.a = smswinga * sin((M_PI * changesigna) / smperioda);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			dummy.a = 0;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		dummy.a = (values.rotsca_val.first + (ranges.rotsca_range) * random.getFloat());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(genlifetime - lifetime)) {
Toshihiro Shimizu 890ddd
		signx = dummy.x > 0 ? 1 : -1;
Toshihiro Shimizu 890ddd
		signy = dummy.y > 0 ? 1 : -1;
Toshihiro Shimizu 890ddd
		signa = dummy.a > 0 ? 1 : -1;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		dummy.x = (fabs(dummy.x)) * signx;
Toshihiro Shimizu 890ddd
		dummy.y = (fabs(dummy.y)) * signy;
Toshihiro Shimizu 890ddd
		dummy.a = (fabs(dummy.a)) * signa;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	changesignx--;
Toshihiro Shimizu 890ddd
	changesigny--;
Toshihiro Shimizu 890ddd
	changesigna--;
Toshihiro Shimizu 890ddd
	if (changesignx <= 0) {
Toshihiro Shimizu 890ddd
		//  if(random->getFloat()<0.5);
Toshihiro Shimizu 890ddd
		signx *= -1;
Toshihiro Shimizu 890ddd
		changesignx = abs((int)(values.swing_val.first) + (int)(random.getFloat() * (ranges.swing_range)));
Toshihiro Shimizu 890ddd
		if (values.swingmode_val == Iwa_TiledParticlesFx::SWING_SMOOTH) {
Toshihiro Shimizu 890ddd
			smperiodx = changesignx;
Toshihiro Shimizu 890ddd
			if (values.randomx_ctrl_val)
Toshihiro Shimizu 890ddd
				smswingx = values.randomx_val.first + randomxreference * (ranges.randomx_range);
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				smswingx = values.randomx_val.first + random.getFloat() * (ranges.randomx_range);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (changesigny <= 0) {
Toshihiro Shimizu 890ddd
		//  if(random->getFloat()<0.5);
Toshihiro Shimizu 890ddd
		signy *= -1;
Toshihiro Shimizu 890ddd
		changesigny = abs((int)(values.swing_val.first) + (int)(random.getFloat() * (ranges.swing_range)));
Toshihiro Shimizu 890ddd
		if (values.swingmode_val == Iwa_TiledParticlesFx::SWING_SMOOTH) {
Toshihiro Shimizu 890ddd
			smperiody = changesigny;
Toshihiro Shimizu 890ddd
			if (values.randomy_ctrl_val)
Toshihiro Shimizu 890ddd
				smswingy = values.randomy_val.first + randomyreference * (ranges.randomy_range);
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				smswingy = values.randomy_val.first + random.getFloat() * (ranges.randomy_range);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (changesigna <= 0) {
Toshihiro Shimizu 890ddd
		signa *= -1;
Toshihiro Shimizu 890ddd
		changesigna = abs((int)(values.rotswing_val.first) + (int)(random.getFloat() * (ranges.rotswing_range)));
Toshihiro Shimizu 890ddd
		if (values.rotswingmode_val == Iwa_TiledParticlesFx::SWING_SMOOTH) {
Toshihiro Shimizu 890ddd
			smperioda = changesigna;
Toshihiro Shimizu 890ddd
			smswinga = values.rotsca_val.first + random.getFloat() * (ranges.rotsca_range);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
void Iwa_Particle::update_Scale(const particles_values &values,
Toshihiro Shimizu 890ddd
								const particles_ranges &ranges, double scalereference,
Toshihiro Shimizu 890ddd
								double scalestepreference)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double scalestep;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.scale_ctrl_val && values.scale_ctrl_all_val)
Toshihiro Shimizu 890ddd
		scale = values.scale_val.first + (ranges.scale_range) * scalereference;
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		if (values.scalestep_ctrl_val)
Toshihiro Shimizu 890ddd
			scalestep = values.scalestep_val.first + (ranges.scalestep_range) * scalestepreference;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			scalestep = values.scalestep_val.first + (ranges.scalestep_range) * random.getFloat();
Toshihiro Shimizu 890ddd
		if (scalestep)
Toshihiro Shimizu 890ddd
			scale += scalestep;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (scale < 0.001)
Toshihiro Shimizu 890ddd
		scale = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
void Iwa_Particle::get_image_reference(TTile *ctrl, const particles_values &values,
Toshihiro Shimizu 890ddd
									   float &imagereference, int type)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P raster32 = ctrl->getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P raster64 = ctrl->getRaster();
Toshihiro Shimizu 890ddd
	TPointD tmp(x, y);
Toshihiro Shimizu 890ddd
	tmp -= ctrl->m_pos;
Toshihiro Shimizu 890ddd
	imagereference = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (raster32)
Toshihiro Shimizu 890ddd
		raster32->lock();
Toshihiro Shimizu 890ddd
	else if (raster64)
Toshihiro Shimizu 890ddd
		raster64->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (type) {
Toshihiro Shimizu 890ddd
	case Iwa_TiledParticlesFx::GRAY_REF:
Toshihiro Shimizu 890ddd
		if (raster32 &&
Toshihiro Shimizu 890ddd
			tmp.x >= 0 && tmp.x < raster32->getLx() &&
Toshihiro Shimizu 890ddd
			tmp.y >= 0 && troundp(tmp.y) < raster32->getLy()) {
Toshihiro Shimizu 890ddd
			TPixel32 pix = raster32->pixels(troundp(tmp.y))[(int)tmp.x];
Toshihiro Shimizu 890ddd
			imagereference = TPixelGR8::from(pix).value / (float)TPixelGR8::maxChannelValue;
Toshihiro Shimizu 890ddd
		} else if (raster64 && tmp.x >= 0 &&
Toshihiro Shimizu 890ddd
				   tmp.x < raster64->getLx() &&
Toshihiro Shimizu 890ddd
				   tmp.y >= 0 &&
Toshihiro Shimizu 890ddd
				   troundp(tmp.y) < raster64->getLy()) {
Toshihiro Shimizu 890ddd
			TPixel64 pix = raster64->pixels(troundp(tmp.y))[(int)tmp.x];
Toshihiro Shimizu 890ddd
			imagereference = TPixelGR16::from(pix).value / (float)TPixelGR16::maxChannelValue;
Toshihiro Shimizu 890ddd
		}
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	case Iwa_TiledParticlesFx::H_REF:
Shinya Kitaoka d4642c
		if (raster32 &&
Shinya Kitaoka d4642c
			tmp.x >= 0 && tmp.x < raster32->getLx() &&
Shinya Kitaoka d4642c
			tmp.y >= 0 && tround(tmp.y) < raster32->getLy())
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			float aux = (float)TPixel32::maxChannelValue;
Toshihiro Shimizu 890ddd
			double h, s, v;
Toshihiro Shimizu 890ddd
			TPixel32 pix = raster32->pixels(troundp(tmp.y))[(int)tmp.x];
Toshihiro Shimizu 890ddd
			OLDRGB2HSV(pix.r / aux, pix.g / aux, pix.b / aux, &h, &s, &v);
Toshihiro Shimizu 890ddd
			imagereference = (float)h / 360.0f;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		else if (raster64 &&
Toshihiro Shimizu 890ddd
				 tmp.x >= 0 && tmp.x < raster64->getLx() &&
Toshihiro Shimizu 890ddd
				 tmp.y >= 0 && tround(tmp.y) < raster64->getLy())
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			float aux = (float)TPixel64::maxChannelValue;
Toshihiro Shimizu 890ddd
			double h, s, v;
Toshihiro Shimizu 890ddd
			TPixel64 pix = raster64->pixels(troundp(tmp.y))[(int)tmp.x];
Toshihiro Shimizu 890ddd
			OLDRGB2HSV(pix.r / aux, pix.g / aux, pix.b / aux, &h, &s, &v);
Toshihiro Shimizu 890ddd
			imagereference = (float)h / 360.0f;
Toshihiro Shimizu 890ddd
		}
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (raster32)
Toshihiro Shimizu 890ddd
		raster32->unlock();
Toshihiro Shimizu 890ddd
	else if (raster64)
Toshihiro Shimizu 890ddd
		raster64->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*- ベクタ長を返す -*/
Toshihiro Shimizu 890ddd
float Iwa_Particle::get_image_gravity(TTile *ctrl1, const particles_values &values,
Toshihiro Shimizu 890ddd
									  float &gx, float &gy)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P raster32 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P raster64 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	TPointD tmp(x, y);
Toshihiro Shimizu 890ddd
	tmp -= ctrl1->m_pos;
Toshihiro Shimizu 890ddd
	int radius = 2;
Toshihiro Shimizu 890ddd
	gx = 0;
Toshihiro Shimizu 890ddd
	gy = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float norm = 1.0f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (raster32) {
Toshihiro Shimizu 890ddd
		raster32->lock();
Toshihiro Shimizu 890ddd
		if (raster32 &&
Toshihiro Shimizu 890ddd
			tmp.x >= radius && tmp.x < raster32->getLx() - radius &&
Toshihiro Shimizu 890ddd
			tmp.y >= radius && tmp.y < raster32->getLy() - radius) {
Toshihiro Shimizu 890ddd
			TPixel32 *pix = &(raster32->pixels(troundp(tmp.y))[(int)tmp.x]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gx += 2 * TPixelGR8::from(*(pix + 1)).value;
Toshihiro Shimizu 890ddd
			gx += TPixelGR8::from(*(pix + 1 + raster32->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
			gx += TPixelGR8::from(*(pix + 1 - raster32->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gx -= 2 * TPixelGR8::from(*(pix - 1)).value;
Toshihiro Shimizu 890ddd
			gx -= TPixelGR8::from(*(pix - 1 + raster32->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
			gx -= TPixelGR8::from(*(pix - 1 - raster32->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gy += 2 * TPixelGR8::from(*(pix + raster32->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
			gy += TPixelGR8::from(*(pix + raster32->getWrap() * 1 + 1)).value;
Toshihiro Shimizu 890ddd
			gy += TPixelGR8::from(*(pix + raster32->getWrap() * 1 - 1)).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gy -= 2 * TPixelGR8::from(*(pix - raster32->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
			gy -= TPixelGR8::from(*(pix - raster32->getWrap() * 1 + 1)).value;
Toshihiro Shimizu 890ddd
			gy -= TPixelGR8::from(*(pix - raster32->getWrap() * 1 - 1)).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			norm = sqrtf(gx * gx + gy * gy);
Toshihiro Shimizu 890ddd
			if (norm) {
Toshihiro Shimizu 890ddd
				float inorm = 0.1f / norm;
Toshihiro Shimizu 890ddd
				gx = gx * inorm;
Toshihiro Shimizu 890ddd
				gy = gy * inorm;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		raster32->unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		norm /= (float)(TPixelGR8::maxChannelValue);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	} else if (raster64) {
Toshihiro Shimizu 890ddd
		raster64->lock();
Toshihiro Shimizu 890ddd
		if (raster64 &&
Toshihiro Shimizu 890ddd
			tmp.x >= radius && tmp.x < raster64->getLx() - radius &&
Toshihiro Shimizu 890ddd
			tmp.y >= radius && tmp.y < raster64->getLy() - radius) {
Toshihiro Shimizu 890ddd
			TPixel64 *pix = &(raster64->pixels(troundp(tmp.y))[(int)tmp.x]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gx += 2 * TPixelGR16::from(*(pix + 1)).value;
Toshihiro Shimizu 890ddd
			gx += TPixelGR16::from(*(pix + 1 + raster64->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
			gx += TPixelGR16::from(*(pix + 1 - raster64->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gx -= 2 * TPixelGR16::from(*(pix - 1)).value;
Toshihiro Shimizu 890ddd
			gx -= TPixelGR16::from(*(pix - 1 + raster64->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
			gx -= TPixelGR16::from(*(pix - 1 - raster64->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gy += 2 * TPixelGR16::from(*(pix + raster64->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
			gy += TPixelGR16::from(*(pix + raster64->getWrap() * 1 + 1)).value;
Toshihiro Shimizu 890ddd
			gy += TPixelGR16::from(*(pix + raster64->getWrap() * 1 - 1)).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			gy -= 2 * TPixelGR16::from(*(pix - raster64->getWrap() * 1)).value;
Toshihiro Shimizu 890ddd
			gy -= TPixelGR16::from(*(pix - raster64->getWrap() * 1 + 1)).value;
Toshihiro Shimizu 890ddd
			gy -= TPixelGR16::from(*(pix - raster64->getWrap() * 1 - 1)).value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			norm = sqrtf(gx * gx + gy * gy);
Toshihiro Shimizu 890ddd
			if (norm) {
Toshihiro Shimizu 890ddd
				float inorm = 0.1 / norm;
Toshihiro Shimizu 890ddd
				gx = gx * inorm;
Toshihiro Shimizu 890ddd
				gy = gy * inorm;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		raster64->unlock();
Toshihiro Shimizu 890ddd
		norm /= (float)(TPixelGR16::maxChannelValue);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return norm;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool Iwa_Particle::get_image_curl(TTile *ctrl1,
Toshihiro Shimizu 890ddd
								  const particles_values &values,
Toshihiro Shimizu 890ddd
								  float &cx, float &cy)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P raster32 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P raster64 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	TPointD tmp(x, y);
Toshihiro Shimizu 890ddd
	tmp -= ctrl1->m_pos;
Toshihiro Shimizu 890ddd
	int radius = 4;
Toshihiro Shimizu 890ddd
	cx = 0;
Toshihiro Shimizu 890ddd
	cy = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool ret;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (raster32) {
Toshihiro Shimizu 890ddd
		raster32->lock();
Toshihiro Shimizu 890ddd
		if (raster32 &&
Toshihiro Shimizu 890ddd
			tmp.x >= radius + 1 && tmp.x < raster32->getLx() - radius - 1 &&
Toshihiro Shimizu 890ddd
			tmp.y >= radius + 1 && tmp.y < raster32->getLy() - radius - 1) {
Toshihiro Shimizu 890ddd
			TPixel32 *pix = &(raster32->pixels(troundp(tmp.y))[(int)tmp.x]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			cx = -TPixelGR8::from(*(pix + radius * raster32->getWrap())).value + TPixelGR8::from(*(pix - radius * raster32->getWrap())).value;
Toshihiro Shimizu 890ddd
			cy = TPixelGR8::from(*(pix + radius)).value - TPixelGR8::from(*(pix - radius)).value;
Toshihiro Shimizu 890ddd
			ret = true;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			ret = false;
Toshihiro Shimizu 890ddd
		raster32->unlock();
Toshihiro Shimizu 890ddd
	} else if (raster64) {
Toshihiro Shimizu 890ddd
		raster64->lock();
Toshihiro Shimizu 890ddd
		if (raster64 &&
Toshihiro Shimizu 890ddd
			tmp.x >= radius + 1 && tmp.x < raster64->getLx() - radius - 1 &&
Toshihiro Shimizu 890ddd
			tmp.y >= radius + 1 && tmp.y < raster64->getLy() - radius - 1) {
Toshihiro Shimizu 890ddd
			TPixel64 *pix = &(raster64->pixels(troundp(tmp.y))[(int)tmp.x]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			cx = -TPixelGR16::from(*(pix + radius * raster64->getWrap())).value + TPixelGR16::from(*(pix - radius * raster64->getWrap())).value;
Toshihiro Shimizu 890ddd
			cy = TPixelGR16::from(*(pix + radius)).value - TPixelGR16::from(*(pix - radius)).value;
Toshihiro Shimizu 890ddd
			cx /= 256.0f;
Toshihiro Shimizu 890ddd
			cy /= 256.0f;
Toshihiro Shimizu 890ddd
			ret = true;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			ret = false;
Toshihiro Shimizu 890ddd
		raster64->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particle::get_image_reference(TTile *ctrl1,
Toshihiro Shimizu 890ddd
									   const particles_values &values,
Toshihiro Shimizu 890ddd
									   TPixel32 &color)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P raster32 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P raster64 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD tmp(x, y);
Toshihiro Shimizu 890ddd
	tmp -= ctrl1->m_pos;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (raster32 &&
Toshihiro Shimizu 890ddd
		tmp.x >= 0 && tmp.x < raster32->getLx() &&
Toshihiro Shimizu 890ddd
		tmp.y >= 0 && troundp(tmp.y) < raster32->getLy()) {
Toshihiro Shimizu 890ddd
		color = raster32->pixels(troundp(tmp.y))[(int)tmp.x];
Toshihiro Shimizu 890ddd
	} else if (raster64 &&
Toshihiro Shimizu 890ddd
			   tmp.x >= 0 && tmp.x < raster64->getLx() &&
Toshihiro Shimizu 890ddd
			   tmp.y >= 0 && troundp(tmp.y) < raster64->getLy()) {
Toshihiro Shimizu 890ddd
		TPixel64 pix64 = raster64->pixels(troundp(tmp.y))[(int)tmp.x];
Toshihiro Shimizu 890ddd
		color = TPixel32((int)pix64.r / 256, (int)pix64.g / 256, (int)pix64.b / 256, (int)pix64.m / 256);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/*- 参照画像のBBoxの外側で、粒子の色を透明にする -*/
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		color = TPixel32::Transparent;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particle::get_base_image_texture(TTile *ctrl1,
Toshihiro Shimizu 890ddd
										  const particles_values &values,
Toshihiro Shimizu 890ddd
										  TRasterP texRaster,
Toshihiro Shimizu 890ddd
										  const TRectD &texBBox,
Toshihiro Shimizu 890ddd
										  const TRenderSettings &ri)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*- ベースの絵を粒子の初期位置にあわせ移動させる -*/
Toshihiro Shimizu 890ddd
	TPointD pos(initial_x, initial_y);
Toshihiro Shimizu 890ddd
	pos = ri.m_affine * pos;
Toshihiro Shimizu 890ddd
	TRotation rotM(-initial_angle);
Toshihiro Shimizu 890ddd
	TScale scaleM(1.0);
Toshihiro Shimizu 890ddd
	TAffine M = TTranslation(-texBBox.getP00()) * scaleM * rotM * TTranslation(-pos + ctrl1->m_pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P baseRas32 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P baseRas64 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	if (baseRas32) {
Toshihiro Shimizu 890ddd
		baseRas32->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- 粒子と同サイズのラスタを用意 -*/
Toshihiro Shimizu 890ddd
		TRaster32P kirinukiBaseRas(texRaster->getSize());
Toshihiro Shimizu 890ddd
		kirinukiBaseRas->lock();
Toshihiro Shimizu 890ddd
		TRaster32P texRas32 = texRaster;
Toshihiro Shimizu 890ddd
		texRas32->lock();
Toshihiro Shimizu 890ddd
		/*- そこにquickput -*/
Toshihiro Shimizu 890ddd
		TRop::quickPut(kirinukiBaseRas, baseRas32, M);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- 粒子のRGBをベース絵で置換していく -*/
Toshihiro Shimizu 890ddd
		for (int j = 0; j < texRaster->getLy(); j++) {
Toshihiro Shimizu 890ddd
			TPixel32 *pix = texRas32->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel32 *endPix = pix + texRas32->getLx();
Toshihiro Shimizu 890ddd
			TPixel32 *basePix = kirinukiBaseRas->pixels(j);
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				double factor = pix->m / 255.0;
Toshihiro Shimizu 890ddd
				pix->r = (UCHAR)(factor * basePix->r);
Toshihiro Shimizu 890ddd
				pix->g = (UCHAR)(factor * basePix->g);
Toshihiro Shimizu 890ddd
				pix->b = (UCHAR)(factor * basePix->b);
Toshihiro Shimizu 890ddd
				pix->m = (UCHAR)(factor * basePix->m);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				++pix;
Toshihiro Shimizu 890ddd
				++basePix;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		kirinukiBaseRas->unlock();
Toshihiro Shimizu 890ddd
		baseRas32->unlock();
Toshihiro Shimizu 890ddd
		texRas32->unlock();
Toshihiro Shimizu 890ddd
	} else if (baseRas64) {
Toshihiro Shimizu 890ddd
		baseRas64->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- 粒子と同サイズのラスタを用意 -*/
Toshihiro Shimizu 890ddd
		TRaster64P kirinukiBaseRas(texRaster->getSize());
Toshihiro Shimizu 890ddd
		kirinukiBaseRas->lock();
Toshihiro Shimizu 890ddd
		TRaster64P texRas64 = texRaster;
Toshihiro Shimizu 890ddd
		texRas64->lock();
Toshihiro Shimizu 890ddd
		/*- そこにquickput -*/
Toshihiro Shimizu 890ddd
		TRop::quickPut(kirinukiBaseRas, baseRas64, M);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*- 粒子のRGBをベース絵で置換していく -*/
Toshihiro Shimizu 890ddd
		for (int j = 0; j < texRaster->getLy(); j++) {
Toshihiro Shimizu 890ddd
			TPixel64 *pix = texRas64->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel64 *endPix = pix + texRas64->getLx();
Toshihiro Shimizu 890ddd
			TPixel64 *basePix = kirinukiBaseRas->pixels(j);
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				double factor = (double)pix->m / (double)TPixel64::maxChannelValue;
Toshihiro Shimizu 890ddd
				pix->r = (TPixel64::Channel)(factor * basePix->r);
Toshihiro Shimizu 890ddd
				pix->g = (TPixel64::Channel)(factor * basePix->g);
Toshihiro Shimizu 890ddd
				pix->b = (TPixel64::Channel)(factor * basePix->b);
Toshihiro Shimizu 890ddd
				pix->m = (TPixel64::Channel)(factor * basePix->m);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				++pix;
Toshihiro Shimizu 890ddd
				++basePix;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		kirinukiBaseRas->unlock();
Toshihiro Shimizu 890ddd
		baseRas64->unlock();
Toshihiro Shimizu 890ddd
		texRas64->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particle::get_base_image_color(TTile *ctrl1,
Toshihiro Shimizu 890ddd
										const particles_values &values,
Toshihiro Shimizu 890ddd
										TRasterP texRaster,
Toshihiro Shimizu 890ddd
										const TRectD &texBBox,
Toshihiro Shimizu 890ddd
										const TRenderSettings &ri)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*- まず、色を拾う -*/
Toshihiro Shimizu 890ddd
	TPixel32 color;
Toshihiro Shimizu 890ddd
	TRaster32P baseRas32 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
	TRaster64P baseRas64 = ctrl1->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPointD tmp(initial_x, initial_y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tmp = ri.m_affine * tmp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tmp -= ctrl1->m_pos;
Toshihiro Shimizu 890ddd
	if (baseRas32 &&
Toshihiro Shimizu 890ddd
		tmp.x >= 0 && tmp.x < baseRas32->getLx() &&
Toshihiro Shimizu 890ddd
		tmp.y >= 0 && troundp(tmp.y) < baseRas32->getLy()) {
Toshihiro Shimizu 890ddd
		color = baseRas32->pixels(troundp(tmp.y))[(int)tmp.x];
Toshihiro Shimizu 890ddd
	} else if (baseRas64 &&
Toshihiro Shimizu 890ddd
			   tmp.x >= 0 && tmp.x < baseRas64->getLx() &&
Toshihiro Shimizu 890ddd
			   tmp.y >= 0 && troundp(tmp.y) < baseRas64->getLy()) {
Toshihiro Shimizu 890ddd
		TPixel64 pix64 = baseRas64->pixels(troundp(tmp.y))[(int)tmp.x];
Toshihiro Shimizu 890ddd
		color = TPixel32((int)pix64.r / 256, (int)pix64.g / 256, (int)pix64.b / 256, (int)pix64.m / 256);
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		color = TPixel32::Transparent;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P texRas32 = texRaster;
Toshihiro Shimizu 890ddd
	TRaster64P texRas64 = texRaster;
Toshihiro Shimizu 890ddd
	if (texRas32) {
Toshihiro Shimizu 890ddd
		texRas32->lock();
Toshihiro Shimizu 890ddd
		for (int j = 0; j < texRas32->getLy(); j++) {
Toshihiro Shimizu 890ddd
			TPixel32 *pix = texRas32->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel32 *endPix = pix + texRas32->getLx();
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				double factor = pix->m / (double)TPixel32::maxChannelValue;
Toshihiro Shimizu 890ddd
				pix->r = (UCHAR)(factor * color.r);
Toshihiro Shimizu 890ddd
				pix->g = (UCHAR)(factor * color.g);
Toshihiro Shimizu 890ddd
				pix->b = (UCHAR)(factor * color.b);
Toshihiro Shimizu 890ddd
				pix->m = (UCHAR)(factor * color.m);
Toshihiro Shimizu 890ddd
				++pix;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		texRas32->unlock();
Toshihiro Shimizu 890ddd
	} else if (texRas64) {
Toshihiro Shimizu 890ddd
		texRas64->lock();
Toshihiro Shimizu 890ddd
		TPixel64 color64(color.r * 256, color.g * 256, color.b * 256, color.m * 256);
Toshihiro Shimizu 890ddd
		for (int j = 0; j < texRas64->getLy(); j++) {
Toshihiro Shimizu 890ddd
			TPixel64 *pix = texRas64->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel64 *endPix = pix + texRas64->getLx();
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				double factor = pix->m / (double)TPixel64::maxChannelValue;
Toshihiro Shimizu 890ddd
				pix->r = (USHORT)(factor * color64.r);
Toshihiro Shimizu 890ddd
				pix->g = (USHORT)(factor * color64.g);
Toshihiro Shimizu 890ddd
				pix->b = (USHORT)(factor * color64.b);
Toshihiro Shimizu 890ddd
				pix->m = (USHORT)(factor * color64.m);
Toshihiro Shimizu 890ddd
				++pix;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		texRas64->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
/*- 照明モードのとき、その明るさを色に格納 -*/
Toshihiro Shimizu 890ddd
void Iwa_Particle::set_illuminated_colors(float illuminant,
Toshihiro Shimizu 890ddd
										  TRasterP texRaster)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRaster32P texRas32 = texRaster;
Toshihiro Shimizu 890ddd
	TRaster64P texRas64 = texRaster;
Toshihiro Shimizu 890ddd
	if (texRas32) {
Toshihiro Shimizu 890ddd
		texRas32->lock();
Toshihiro Shimizu 890ddd
		TPixel32::Channel val = (TPixel32::Channel)(illuminant * TPixel32::maxChannelValue);
Toshihiro Shimizu 890ddd
		for (int j = 0; j < texRas32->getLy(); j++) {
Toshihiro Shimizu 890ddd
			TPixel32 *pix = texRas32->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel32 *endPix = pix + texRas32->getLx();
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				double factor = pix->m / (double)TPixel32::maxChannelValue;
Toshihiro Shimizu 890ddd
				pix->r = (UCHAR)(factor * val);
Toshihiro Shimizu 890ddd
				pix->g = (UCHAR)(factor * val);
Toshihiro Shimizu 890ddd
				pix->b = (UCHAR)(factor * val);
Toshihiro Shimizu 890ddd
				++pix;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		texRas32->unlock();
Toshihiro Shimizu 890ddd
	} else if (texRas64) {
Toshihiro Shimizu 890ddd
		texRas64->lock();
Toshihiro Shimizu 890ddd
		TPixel64::Channel val = (TPixel64::Channel)(illuminant * TPixel64::maxChannelValue);
Toshihiro Shimizu 890ddd
		for (int j = 0; j < texRas64->getLy(); j++) {
Toshihiro Shimizu 890ddd
			TPixel64 *pix = texRas64->pixels(j);
Toshihiro Shimizu 890ddd
			TPixel64 *endPix = pix + texRas64->getLx();
Toshihiro Shimizu 890ddd
			while (pix < endPix) {
Toshihiro Shimizu 890ddd
				double factor = pix->m / (double)TPixel64::maxChannelValue;
Toshihiro Shimizu 890ddd
				pix->r = (USHORT)(factor * val);
Toshihiro Shimizu 890ddd
				pix->g = (USHORT)(factor * val);
Toshihiro Shimizu 890ddd
				pix->b = (USHORT)(factor * val);
Toshihiro Shimizu 890ddd
				++pix;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		texRas64->unlock();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void Iwa_Particle::spread_color(TPixel32 &color, double range)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int randcol = (int)((random.getFloat() - 0.5) * range);
Toshihiro Shimizu 890ddd
	int r = color.r + randcol;
Toshihiro Shimizu 890ddd
	int g = color.g + randcol;
Toshihiro Shimizu 890ddd
	int b = color.b + randcol;
Toshihiro Shimizu 890ddd
	color.r = (UCHAR)tcrop<TINT32>(r, (TINT32)0, (TINT32)255);
Toshihiro Shimizu 890ddd
	color.g = (UCHAR)tcrop<TINT32>(g, (TINT32)0, (TINT32)255);
Toshihiro Shimizu 890ddd
	color.b = (UCHAR)tcrop<TINT32>(b, (TINT32)0, (TINT32)255);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------
Toshihiro Shimizu 890ddd
 Iwa_Particles_Engine::roll_particles から呼ばれる
Toshihiro Shimizu 890ddd
 粒子の移動
Toshihiro Shimizu 890ddd
-----------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
void Iwa_Particle::move(std::map<int, TTile *> porttiles,
Toshihiro Shimizu 890ddd
						const particles_values &values,
Toshihiro Shimizu 890ddd
						const particles_ranges &ranges,
Toshihiro Shimizu 890ddd
						float windx, float windy,
Toshihiro Shimizu 890ddd
						float xgravity, float ygravity,
Toshihiro Shimizu 890ddd
						float dpicorr,
Toshihiro Shimizu 890ddd
						int lastframe)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct pos_dummy dummy;
Toshihiro Shimizu 890ddd
	float frictx, fricty;
Shinya Kitaoka 3bfa54
	std::map<int, float> imagereferences;
Toshihiro Shimizu 890ddd
	dummy.x = dummy.y = dummy.a = 0.0;
Toshihiro Shimizu 890ddd
	frictx = fricty = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float frictreference = 1;
Toshihiro Shimizu 890ddd
	float scalereference = 0;
Toshihiro Shimizu 890ddd
	float scalestepreference = 0;
Toshihiro Shimizu 890ddd
	float randomxreference = 1;
Toshihiro Shimizu 890ddd
	float randomyreference = 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*-  移動に用いるパラメータに参照画像が刺さっている場合は、あらかじめ取得しておく -*/
Toshihiro Shimizu 890ddd
	for (std::map<int, TTile *>::iterator it = porttiles.begin(); it != porttiles.end(); ++it) {
Toshihiro Shimizu 890ddd
		if ((values.friction_ctrl_val == it->first ||
Toshihiro Shimizu 890ddd
			 values.scale_ctrl_val == it->first ||
Toshihiro Shimizu 890ddd
			 values.scalestep_ctrl_val == it->first ||
Toshihiro Shimizu 890ddd
			 values.randomx_ctrl_val == it->first ||
Toshihiro Shimizu 890ddd
			 values.randomy_ctrl_val == it->first) &&
Toshihiro Shimizu 890ddd
			it->second->getRaster()) {
Toshihiro Shimizu 890ddd
			float tmpvalue;
Toshihiro Shimizu 890ddd
			get_image_reference(it->second, values, tmpvalue, Iwa_TiledParticlesFx::GRAY_REF);
Toshihiro Shimizu 890ddd
			imagereferences[it->first] = tmpvalue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.randomx_ctrl_val)
Toshihiro Shimizu 890ddd
		randomxreference = imagereferences[values.randomx_ctrl_val];
Toshihiro Shimizu 890ddd
	if (values.randomy_ctrl_val)
Toshihiro Shimizu 890ddd
		randomyreference = imagereferences[values.randomy_ctrl_val];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (check_Swing(values))
Toshihiro Shimizu 890ddd
		update_Swing(values, ranges, dummy, randomxreference, randomyreference);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.friction_ctrl_val)
Toshihiro Shimizu 890ddd
		frictreference = imagereferences[values.friction_ctrl_val];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.scale_ctrl_val)
Toshihiro Shimizu 890ddd
		scalereference = imagereferences[values.scale_ctrl_val];
Toshihiro Shimizu 890ddd
	if (values.scalestep_ctrl_val)
Toshihiro Shimizu 890ddd
		scalestepreference = imagereferences[values.scalestep_ctrl_val];
Toshihiro Shimizu 890ddd
	lifetime--;
Toshihiro Shimizu 890ddd
	oldx = x;
Toshihiro Shimizu 890ddd
	oldy = y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.gravity_ctrl_val && (porttiles.find(values.gravity_ctrl_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		get_image_gravity(porttiles[values.gravity_ctrl_val], values, xgravity, ygravity);
Toshihiro Shimizu 890ddd
		xgravity *= values.gravity_val;
Toshihiro Shimizu 890ddd
		ygravity *= values.gravity_val;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.friction_val * frictreference) {
Toshihiro Shimizu 890ddd
		if (vx) {
Toshihiro Shimizu 890ddd
			frictx = vx * (1.0f + values.friction_val * frictreference) + (10.0f / vx) * values.friction_val * frictreference;
Toshihiro Shimizu 890ddd
			if ((frictx / vx) < 0.0f)
Toshihiro Shimizu 890ddd
				frictx = 0.0f;
Toshihiro Shimizu 890ddd
			vx = frictx;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (!frictx && fabs(values.friction_val * frictreference * 10.0f) > fabs(xgravity)) {
Toshihiro Shimizu 890ddd
			xgravity = 0.0f;
Toshihiro Shimizu 890ddd
			dummy.x = 0.0f;
Toshihiro Shimizu 890ddd
			dummy.a = 0.0f;
Toshihiro Shimizu 890ddd
			windx = 0.0f;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (vy) {
Toshihiro Shimizu 890ddd
			fricty = vy * (1.0f + values.friction_val * frictreference) + (10.0f / vy) * values.friction_val * frictreference;
Toshihiro Shimizu 890ddd
			if ((fricty / vy) < 0.0f)
Toshihiro Shimizu 890ddd
				fricty = 0.0f;
Toshihiro Shimizu 890ddd
			vy = fricty;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (!fricty && fabs(values.friction_val * frictreference * 10.0f) > fabs(ygravity)) {
Toshihiro Shimizu 890ddd
			ygravity = 0.0f;
Toshihiro Shimizu 890ddd
			dummy.y = 0.0f;
Toshihiro Shimizu 890ddd
			dummy.a = 0.0f;
Toshihiro Shimizu 890ddd
			windy = 0.0f;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 重力を徐々に付けていく処理を入れる -*/
Toshihiro Shimizu 890ddd
	if (genlifetime - lifetime < values.iw_gravityBufferFrame_val) {
Toshihiro Shimizu 890ddd
		float ratio = (float)(genlifetime - lifetime) / (float)values.iw_gravityBufferFrame_val;
Toshihiro Shimizu 890ddd
		xgravity *= ratio;
Toshihiro Shimizu 890ddd
		ygravity *= ratio;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 重力の寄与 -*/
Toshihiro Shimizu 890ddd
	vx += xgravity * mass;
Toshihiro Shimizu 890ddd
	vy += ygravity * mass;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- カールノイズ的動き 奥行き持たせる -*/
Toshihiro Shimizu 890ddd
	if (values.curl_ctrl_1_val &&
Toshihiro Shimizu 890ddd
		(porttiles.find(values.curl_ctrl_1_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		float tmpCurlx, tmpCurly;
Toshihiro Shimizu 890ddd
		if (get_image_curl(porttiles[values.curl_ctrl_1_val], values, tmpCurlx, tmpCurly)) {
Toshihiro Shimizu 890ddd
			if (values.curl_ctrl_2_val && (porttiles.find(values.curl_ctrl_2_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
				float tmpCurlx2, tmpCurly2;
Toshihiro Shimizu 890ddd
				if (get_image_curl(porttiles[values.curl_ctrl_2_val], values, tmpCurlx2, tmpCurly2)) {
Toshihiro Shimizu 890ddd
					float length1 = sqrtf(tmpCurlx * tmpCurlx + tmpCurly * tmpCurly);
Toshihiro Shimizu 890ddd
					float length2 = sqrtf(tmpCurlx2 * tmpCurlx2 + tmpCurly2 * tmpCurly2);
Toshihiro Shimizu 890ddd
					float length = length1 * curlz + length2 * (1.0f - curlz);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					tmpCurlx = tmpCurlx * curlz + tmpCurlx2 * (1.0f - curlz);
Toshihiro Shimizu 890ddd
					tmpCurly = tmpCurly * curlz + tmpCurly2 * (1.0f - curlz);
Toshihiro Shimizu 890ddd
					float tmpLen = tmpCurlx * tmpCurlx + tmpCurly * tmpCurly;
Toshihiro Shimizu 890ddd
					if (tmpLen > 0.0f) {
Toshihiro Shimizu 890ddd
						tmpLen = sqrtf(tmpLen);
Toshihiro Shimizu 890ddd
						tmpCurlx *= length / tmpLen;
Toshihiro Shimizu 890ddd
						tmpCurly *= length / tmpLen;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			tmpCurlx *= values.curl_val * mass;
Toshihiro Shimizu 890ddd
			tmpCurly *= values.curl_val * mass;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- ローパスフィルタをかます -*/
Toshihiro Shimizu 890ddd
			curlx = 0.5f * curlx + 0.5f * tmpCurlx;
Toshihiro Shimizu 890ddd
			curly = 0.5f * curly + 0.5f * tmpCurly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			vx = vx * 0.5 + curlx;
Toshihiro Shimizu 890ddd
			vy = vy * 0.5 + curly;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*- 現在位置に速度を足す -*/
Toshihiro Shimizu 890ddd
	if (values.speedscale_val) {
Toshihiro Shimizu 890ddd
		float scalecorr = scale / dpicorr;
Toshihiro Shimizu 890ddd
		x += (vx + windx + dummy.x) * scalecorr;
Toshihiro Shimizu 890ddd
		y += (vy + windy + dummy.y) * scalecorr;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		x += vx + windx + dummy.x;
Toshihiro Shimizu 890ddd
		y += vy + windy + dummy.y;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/*- 粒子の向きを計算 -*/
Toshihiro Shimizu 890ddd
	angle -= values.rotspeed_val + dummy.a;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(lifetime % values.step_val) || (frame < 0)) {
Toshihiro Shimizu 890ddd
		update_Animation(values, 0, lastframe, 0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	update_Scale(values, ranges, scalereference, scalestepreference);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*-  ひらひら -*/
Toshihiro Shimizu 890ddd
	if (values.flap_ctrl_val && (porttiles.find(values.flap_ctrl_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		/*- 参照画像のGradientを得る関数を利用して角度を得る -*/
Toshihiro Shimizu 890ddd
		float dir_x, dir_y;
Toshihiro Shimizu 890ddd
		double norm;
Toshihiro Shimizu 890ddd
		norm = get_image_gravity(porttiles[values.flap_ctrl_val], values, dir_x, dir_y);
Toshihiro Shimizu 890ddd
		if (dir_x == 0.0f && dir_y == 0.0f) {
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			float newTheta = atan2f(dir_y, dir_x) * 180.0f / 3.14159f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*- Thetaを補間する。右回り/左回りで近いほうを選ぶ -*/
Toshihiro Shimizu 890ddd
			if (newTheta > flap_theta && newTheta - flap_theta > 180.0f)
Toshihiro Shimizu 890ddd
				newTheta -= 360.0f;
Toshihiro Shimizu 890ddd
			else if (newTheta < flap_theta && flap_theta - newTheta > 180.0f)
Toshihiro Shimizu 890ddd
				newTheta += 360.0f;
Toshihiro Shimizu 890ddd
			flap_theta = flap_theta * (1.0f - values.iw_flap_dir_sensitivity_val) +
Toshihiro Shimizu 890ddd
						 newTheta * values.iw_flap_dir_sensitivity_val;
Toshihiro Shimizu 890ddd
			if (flap_theta < 0.0f)
Toshihiro Shimizu 890ddd
				flap_theta += 360.0f;
Toshihiro Shimizu 890ddd
			else if (flap_theta > 360.0f)
Toshihiro Shimizu 890ddd
				flap_theta -= 360.0f;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			flap_phi += values.iw_flap_velocity_val * norm / mass;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			while (flap_phi > 360.0f)
Toshihiro Shimizu 890ddd
				flap_phi -= 360.0f;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*-----------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double Iwa_Particle::set_Opacity(std::map<int, TTile *> porttiles,
Toshihiro Shimizu 890ddd
								 const particles_values &values, float opacity_range, double dist_frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double opacity = 1.0, trailcorr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (values.fadein_val && (genlifetime - lifetime) < values.fadein_val)
Toshihiro Shimizu 890ddd
		opacity *= (genlifetime - lifetime - 1) / (values.fadein_val);
Toshihiro Shimizu 890ddd
	if (values.fadeout_val && lifetime < values.fadeout_val)
Toshihiro Shimizu 890ddd
		opacity *= (lifetime) / values.fadeout_val;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (trail) {
Toshihiro Shimizu 890ddd
		trailcorr = values.trailopacity_val.first + (values.trailopacity_val.second - values.trailopacity_val.first) * (1 - (dist_frame) / trail);
Toshihiro Shimizu 890ddd
		opacity *= trailcorr;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (values.opacity_ctrl_val && (porttiles.find(values.opacity_ctrl_val) != porttiles.end())) {
Toshihiro Shimizu 890ddd
		float opacityreference = 0.0f;
Toshihiro Shimizu 890ddd
		get_image_reference(porttiles[values.opacity_ctrl_val], values, opacityreference, Iwa_TiledParticlesFx::GRAY_REF);
Toshihiro Shimizu 890ddd
		opacity = values.opacity_val.first + (opacity_range)*opacityreference * opacity;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		opacity = values.opacity_val.first + opacity_range * opacity;
Toshihiro Shimizu 890ddd
	return opacity;
Toshihiro Shimizu 890ddd
}