diff options
Diffstat (limited to 'src/render/particlesystem.cc')
-rw-r--r-- | src/render/particlesystem.cc | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/render/particlesystem.cc b/src/render/particlesystem.cc new file mode 100644 index 0000000..ff9c720 --- /dev/null +++ b/src/render/particlesystem.cc @@ -0,0 +1,144 @@ +/* + render/particlesystem.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "render/particlesystem.h" + +namespace render { + +ParticleSystem::ParticleSystem(const ParticleSystemScript *script, const core::Entity *entity, const model::Particles *modelclass) +{ + // constructor asserts that modelclass->parent == entity->model + + particlesystem_modelscale = 1.0f; + + particlesystem_entity = entity; + + if (modelclass) { + particlesystem_location.assign(modelclass->location()); + particlesystem_axis.assign(modelclass->axis()); + } + + if (entity && entity->model() && entity->model()->radius()) { + particlesystem_modelscale = entity->radius() / entity->model()->radius(); + particlesystem_location *= particlesystem_modelscale; + + } + + // add ParticleEjectors as defined by the ParticleSystemScript + for (ParticleSystemScript::Ejectors::const_iterator it = script->ejectors().begin(); it != script->ejectors().end(); ++it) { + ParticleEjector *ejector = 0; + switch ((*it)->type()) { + case ParticleEjector::Spray: + ejector = new ParticleEjectorSpray(*(*it)); + break; + + case ParticleEjector::Trail: + ejector = new ParticleEjectorTrail(*(*it)); + break; + default: + break; + } + + if (ejector) { + ejectors().push_back(ejector); + + if (entity) { + if (ejector->entity()) { + if (ejector->entity_second()) { + for (size_t i = 0; i < 3; i++) { + ejector->get_color()[i] = (entity->color()[i] + entity->color_second()[i]) * 0.5f; + } + } else { + ejector->set_color(entity->color()); + } + } else if (ejector->entity_second()) { + ejector->set_color(entity->color_second()); + } else if (ejector->engine()) { + if (entity->model()) { + ejector->set_color(entity->model()->enginecolor()); + } + } + } + + if (modelclass) { + // modelclass overrides script parameters + if (modelclass->has_color()) { + ejector->set_color(modelclass->color()); + } + if (entity) { + if (modelclass->entity()) { + if (modelclass->entity_second()) { + for (size_t i = 0; i < 3; i++) { + ejector->get_color()[i] = (entity->color()[i] + entity->color_second()[i]) * 0.5f; + } + } else { + ejector->set_color(entity->color()); + } + } else if (modelclass->entity_second()) { + ejector->set_color(entity->color_second()); + } else if (modelclass->engine()) { + if (entity->model()) { + ejector->set_color(entity->model()->enginecolor()); + } + } + } + } + } + } +} + +ParticleSystem::~ParticleSystem() +{ + for (Ejectors::iterator it = ejectors().begin(); it != ejectors().end(); ++it) { + delete (*it); + (*it) = 0; + } + ejectors().clear(); + +} + +void ParticleSystem::clear() +{ + for (Ejectors::iterator it = ejectors().begin(); it != ejectors().end(); ++it) { + (*it)->clear(); + } +} +void ParticleSystem::draw(const float seconds) +{ + // clear particles for docked entities + if ( entity() && (entity()->type() == core::Entity::Controlable)) { + const core::EntityControlable *controlable = static_cast<const core::EntityControlable *>(entity()); + if (controlable->state() == core::Entity::Docked) { + clear(); + return; + } + } + + math::Vector3f current_location(entity() ? entity()->location() + (entity()->axis() * location()) : location()); + math::Axis current_axis(entity() ? entity()->axis() * axis() : axis()); + + for (Ejectors::iterator it = ejectors().begin(); it != ejectors().end(); ++it) { + + if (entity()) { + bool ejector_active = true; + if (entity()->type() == core::Entity::Controlable) { + + if ((*it)->thrust()) { + // thrust activated + const core::EntityControlable *controlable = static_cast<const core::EntityControlable *>(entity()); + if ( controlable->thrust() == 0.0f ) { + ejector_active = false; + } + (*it)->enable(ejector_active); + } + } + } + + (*it)->frame(seconds, current_location, current_axis); + } +} + +}
\ No newline at end of file |