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