/* render/renderext.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include "math/functions.h" #include "core/range.h" #include "model/model.h" #include "render/renderext.h" #include "render/render.h" #include "render/textures.h" #include "sys/sys.h" namespace render { RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Render, entity) { state_visible = false; state_detailvisible = false; state_fuzz = math::randomf(); //state_engine_trail_offset = 0; if (!entity->model() && entity->modelname().size()) { entity->set_modelname(entity->modelname()); if (!entity->model()) entity->set_modelname(""); } if (entity->model()) { model::Model *model = entity->model(); for (model::Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) { model::Light *light = (*lit); // load light texture std::stringstream flarename; flarename << "textures/fx/flare" << std::setfill('0') << std::setw(2) << light->flare(); light->set_texture(Textures::load(flarename.str())); } for (model::Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) { model::Flare *flare = (*flit); // load flare texture std::stringstream flarename; flarename << "textures/fx/flare" << std::setfill('0') << std::setw(2) << flare->flare(); flare->set_texture(Textures::load(flarename.str())); } for (model::Model::ParticleSystems::iterator pit = model->particles().begin(); pit != model->particles().end(); pit++) { model::Particles *particlesystem = (*pit); // load particle systems ParticleScript *script = ParticleScript::load(particlesystem->script()); if (script) { if (script->type() == render::ParticleScript::Trail) { Trail *trail = new Trail(script, entity, particlesystem); state_particles.push_back(trail); } else if (script->type() == render::ParticleScript::Jet) { Jet *jet = new Jet(script, entity, particlesystem); state_particles.push_back(jet); } else if (script->type() == render::ParticleScript::Spray) { Spray *spray = new Spray(script, entity, particlesystem); state_particles.push_back(spray); } else if (script->type() == render::ParticleScript::Flame) { Flame *flame = new Flame(script, entity, particlesystem); state_particles.push_back(flame); } } } } else if (entity->type() == core::Entity::Globe) { core::EntityGlobe *globe = static_cast(entity); // load globe textures if (!globe->render_texture && globe->texture().size()) { std::stringstream texname; texname << "textures/" << globe->texture(); globe->render_texture = Textures::load(texname.str()); if (!globe->render_texture) globe->entity_texture.clear(); } } } RenderExt::~RenderExt() { for (ParticleSystems::iterator it = state_particles.begin(); it != state_particles.end(); it++) { delete(*it); } state_particles.clear(); } void RenderExt::frame(float elapsed) { state_distance = math::distance(Camera::eye(), entity()->location()); state_visible = entity()->visible(); state_detailvisible = false; state_behind = false; if (!state_visible) return; if ((entity()->type() == core::Entity::Controlable)) { if (static_cast(entity())->state() == core::Entity::Docked) { state_visible = false; return; } } if (!entity()->model()) return; if (distance() < core::range::fxdistance) { // entity within detail range state_visible = true; state_detailvisible = true; } else if (distance() < core::range::maxdistance) { // funky radius factor float r = entity()->model()->radius(); math::clamp(r, entity()->model()->radius(), core::range::maxdistance / core::range::fxdistance); if (distance() < core::range::fxdistance * r) { // entity within drawing distance, outside detail range state_visible = true; state_detailvisible = false; } else { // entity within drawing distance, outside detail range state_visible = true; state_detailvisible = false; } } else { // entity out of range state_visible = false; state_detailvisible = false; return; } if (math::dotproduct(Camera::axis().forward(), entity()->location() + Camera::axis().forward() * entity()->radius() - Camera::eye()) < 0.0f) { state_behind = true; } } } // namespace render