1 // I N C L U D E S ////////////////////////////////////////////////////////////
2 
3 #include "eye_candy.h"
4 #include "math_cache.h"
5 
6 #include "effect_fountain.h"
7 
8 namespace ec
9 {
10 
11 	// C L A S S   F U N C T I O N S //////////////////////////////////////////////
12 
FountainParticle(Effect * _effect,ParticleMover * _mover,const Vec3 _pos,const Vec3 _velocity,const color_t hue_adjust,const color_t saturation_adjust,const coord_t _base_height,const bool _backlight,const float _sqrt_scale,const coord_t _max_size,const coord_t size_scalar)13 	FountainParticle::FountainParticle(Effect* _effect, ParticleMover* _mover,
14 		const Vec3 _pos, const Vec3 _velocity, const color_t hue_adjust,
15 		const color_t saturation_adjust, const coord_t _base_height,
16 		const bool _backlight, const float _sqrt_scale,
17 		const coord_t _max_size, const coord_t size_scalar) :
18 		Particle(_effect, _mover, _pos, _velocity,
19 			size_scalar * (0.5 + 5 * randcoord()))
20 	{
21 		base_height = _base_height;
22 		backlight = _backlight;
23 		sqrt_scale = _sqrt_scale;
24 		max_size = _max_size;
25 		color_t hue, saturation, value;
26 		hue = 0.6;
27 		saturation = 0.3;
28 		value = 0.85;
29 		hue += hue_adjust;
30 		if (hue > 1.0)
31 			hue -= 1.0;
32 		saturation = std::min(1.0f, saturation * saturation_adjust);
33 		hsv_to_rgb(hue, saturation, value, color[0], color[1], color[2]);
34 		color[0] *= 2.0;
35 		color[1] *= 2.0;
36 		color[2] *= 2.0;
37 		alpha = sqrt_scale * 3.5 / size;
38 		if (backlight)
39 			alpha /= 9;
40 		alpha = std::min(1.0f, alpha);
41 		flare_max = 1.5;
42 		flare_exp = 0.3;
43 		flare_frequency = 5.0;
44 		state = 0;
45 	}
46 
get_burn() const47 	float FountainParticle::get_burn() const
48 	{
49 		if (backlight)
50 		{
51 			return 1.0f;
52 		}
53 		else
54 		{
55 			return 0.0f;
56 		}
57 	}
58 
idle(const Uint64 delta_t)59 	bool FountainParticle::idle(const Uint64 delta_t)
60 	{
61 		if (effect->recall)
62 			return false;
63 
64 		if (state == 0)
65 		{
66 			const float scalar = std::pow(0.5f, (float)delta_t
67 				/ 2500000);
68 			alpha *= scalar;
69 			size = std::min(max_size, size / scalar * 0.25f + size * 0.75f);
70 
71 			if (pos.y < base_height)
72 			{
73 				state = 1;
74 				velocity.randomize(sqrt_scale);
75 				velocity.y = -velocity.y / 10;
76 				pos.y = base_height;
77 			}
78 		}
79 		else
80 		{
81 			if (alpha < 0.02)
82 				return false;
83 
84 			const float scalar = std::pow(0.5f, (float)delta_t
85 				/ 200000);
86 			alpha *= scalar;
87 			size = std::min(max_size, size / scalar * 0.25f + size * 0.75f);
88 		}
89 
90 		return true;
91 	}
92 
get_texture()93 	Uint32 FountainParticle::get_texture()
94 	{
95 		if (state == 1)
96 		{
97 			return base->get_texture(EC_WATER);
98 		}
99 		else
100 		{
101 			return base->get_texture(EC_FLARE);
102 		}
103 	}
104 
FountainEffect(EyeCandy * _base,bool * _dead,Vec3 * _pos,const color_t _hue_adjust,const color_t _saturation_adjust,const bool _backlight,const coord_t _base_height,const float _scale,const Uint16 _LOD)105 	FountainEffect::FountainEffect(EyeCandy* _base, bool* _dead, Vec3* _pos,
106 		const color_t _hue_adjust, const color_t _saturation_adjust,
107 		const bool _backlight, const coord_t _base_height, const float _scale,
108 		const Uint16 _LOD)
109 	{
110 		if (EC_DEBUG)
111 			std::cout << "FountainEffect (" << this << ") created."
112 				<< std::endl;
113 		base = _base;
114 		dead = _dead;
115 		pos = _pos;
116 		count = 0;
117 		hue_adjust = _hue_adjust;
118 		saturation_adjust = _saturation_adjust;
119 		backlight = _backlight;
120 		scale = _scale;
121 		sqrt_scale = std::sqrt(scale);
122 		max_size = 3 * scale * 90 / (_LOD + 10);
123 		size_scalar = sqrt_scale * 4.5 / (_LOD + 5);
124 		base_height = _base_height + 0.1;
125 		count_scalar = 15000 / _LOD;
126 		LOD = base->last_forced_LOD;
127 		desired_LOD = _LOD;
128 		bounds = NULL;
129 		mover = new SimpleGravityMover(this);
130 		basic_mover = new ParticleMover(this);
131 		spawner = new FilledSphereSpawner(0.05 * sqrt_scale);
132 
133 		/*
134 		 for (int i = 0; i < LOD * 4; i++)
135 		 {
136 		 const Vec3 coords = spawner->get_new_coords() + *pos + Vec3(0.0, 0.1 * sqrt_scale, 0.0);
137 		 Vec3 velocity;
138 		 velocity.randomize(0.1 * sqrt_scale);
139 		 velocity += Vec3(0.0, 0.8 * scale, 0.0);
140 		 Particle* p = new FountainParticle(this, mover, coords, velocity, hue_adjust, saturation_adjust, pos->y, backlight, sqrt_scale, max_size, size_scalar);
141 		 if (!base->push_back_particle(p))
142 		 break;
143 		 }
144 		 */
145 	}
146 
~FountainEffect()147 	FountainEffect::~FountainEffect()
148 	{
149 		delete mover;
150 		delete basic_mover;
151 		delete spawner;
152 		if (EC_DEBUG)
153 			std::cout << "FountainEffect (" << this << ") destroyed."
154 				<< std::endl;
155 	}
156 
idle(const Uint64 usec)157 	bool FountainEffect::idle(const Uint64 usec)
158 	{
159 		if ((recall) && (particles.size() == 0))
160 			return false;
161 
162 		if (recall)
163 			return true;
164 
165 		count += usec;
166 
167 		while (count > 0)
168 		{
169 			const Vec3 coords = spawner->get_new_coords() + *pos + Vec3(0.0,
170 				0.1 * sqrt_scale, 0.0);
171 			Vec3 velocity;
172 			velocity.randomize(0.2 * sqrt_scale);
173 			velocity.y = 0.0;
174 			velocity.normalize((0.15 + randfloat(0.1)) * sqrt_scale);
175 			velocity += Vec3(0.0, 1.2 * scale, 0.0);
176 			Particle
177 				* p =
178 					new FountainParticle(this, mover, coords, velocity, hue_adjust, saturation_adjust, base_height, backlight, sqrt_scale, max_size, size_scalar);
179 			if (!base->push_back_particle(p))
180 			{
181 				count = 0;
182 				break;
183 			}
184 			count -= count_scalar * std::max(3.0f, 10.0f - LOD);
185 		}
186 
187 		return true;
188 	}
189 
190 ///////////////////////////////////////////////////////////////////////////////
191 
192 }
193 ;
194 
195