Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2013-01-20 21:37:11 +0000
committerStijn Buys <ingar@osirion.org>2013-01-20 21:37:11 +0000
commitd4f9da2f3c19511b028da2569d7b6a8d1371e135 (patch)
treee1bba0d8dd3b15169612f865612d3fca6475639a /src/render/particlesystem.cc
parent4feff2411d1b703a3b93d8a342112bd998b1ffed (diff)
Major overhaul of the particle system back-end, support multiple ejectors per particle system.
Diffstat (limited to 'src/render/particlesystem.cc')
-rw-r--r--src/render/particlesystem.cc144
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