#ifdef EYE_CANDY // I N C L U D E S //////////////////////////////////////////////////////////// #include "eye_candy.h" #include "math_cache.h" #include "effect_bag.h" namespace ec { // C L A S S F U N C T I O N S ////////////////////////////////////////////// BagParticle::BagParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const coord_t _size) : Particle(_effect, _mover, _pos, _velocity) { color[0] = randcolor(0.3) + 0.7; color[1] = randcolor(0.3) + 0.5; color[2] = randcolor(0.3) + 0.3; size = _size; alpha = 0.75; flare_max = 1.0; flare_exp = 1.0; flare_frequency = 1.0; state = 0; } void BagParticle::draw(const Uint64 usec) { glEnable(GL_LIGHTING); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Vec3 shifted_pos = pos - ((BagEffect*)effect)->effect_center; #if 0 // Clear, but slow. Consider this a comment. Vec3 velocity2 = velocity; // velocity2.normalize(); shifted_pos.normalize(); Vec3 cross = velocity2.cross(shifted_pos).cross(velocity2); glNormal3f(cross.x, cross.y, cross.z); #else // Faster, but obfuscated. NOTE: For some reason, it's not producing the same output! However, I like the new output better. const coord_t vel_mag_squared = velocity.magnitude_squared(); const coord_t sp_mag = shifted_pos.magnitude(); const coord_t scalar = vel_mag_squared * sp_mag; const coord_t vx_squared = velocity.x * velocity.x; const coord_t vy_squared = velocity.y * velocity.y; const coord_t vz_squared = velocity.z * velocity.z; const coord_t x = (shifted_pos.x * (vz_squared - vy_squared) - velocity.x * (shifted_pos.z * velocity.z + shifted_pos.y * velocity.y)) / scalar; const coord_t y = (shifted_pos.y * (vx_squared - vz_squared) - velocity.y * (shifted_pos.x * velocity.x + shifted_pos.z * velocity.z)) / scalar; const coord_t z = (shifted_pos.z * (vy_squared - vx_squared) - velocity.z * (shifted_pos.y * velocity.y + shifted_pos.x * velocity.x)) / scalar; glNormal3f(-x, -y, -z); #endif Particle::draw(usec); glDisable(GL_LIGHTING); glBlendFunc(GL_SRC_ALPHA, GL_ONE); } bool BagParticle::idle(const Uint64 delta_t) { if (effect->recall) return false; const Uint64 age = get_time() - born; const interval_t float_time = delta_t / 1000000.0; if (age > 220000) { const alpha_t alpha_scalar = math_cache.powf_05_close(float_time * 3.0); alpha *= alpha_scalar; if (alpha < 0.01) return false; } return true; } GLuint BagParticle::get_texture(const Uint16 res_index) { return base->TexFlare.get_texture(res_index); } BagEffect::BagEffect(EyeCandy* _base, bool* _dead, Vec3* _pos, const bool _picked_up, const Uint16 _LOD) { if (EC_DEBUG) std::cout << "BagEffect (" << this << ") created." << std::endl; base = _base; dead = _dead; pos = _pos; picked_up = _picked_up; effect_center = *pos; if (!picked_up) effect_center.y += 0.2; LOD = base->last_forced_LOD; desired_LOD = _LOD; bounds = NULL; mover = new GravityMover(this, &effect_center, 4e9); spawner = new HollowSphereSpawner(0.14 + 0.02 * (float)picked_up); const coord_t size = 40 / (LOD + 10); for (int i = 0; i < LOD * (30 + 30 * (int)picked_up); i++) { Vec3 coords = spawner->get_new_coords(); Vec3 velocity = coords * 1.3; coords += effect_center; Particle* p = new BagParticle(this, mover, coords, velocity, size); if (!base->push_back_particle(p)) break; } } BagEffect::~BagEffect() { delete mover; delete spawner; if (EC_DEBUG) std::cout << "BagEffect (" << this << ") destroyed." << std::endl; } bool BagEffect::idle(const Uint64 usec) { if (particles.size() == 0) return false; effect_center.x = pos->x; if (picked_up) effect_center.y += usec / 2000000.0; else effect_center.y -= usec / 2000000.0; effect_center.z = pos->z; return true; } /////////////////////////////////////////////////////////////////////////////// }; #endif // #ifdef EYE_CANDY