/* render/dust.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/dust.h" #include "render/gl.h" #include "core/cvar.h" #include "core/core.h" #include "math/functions.h" #include "sys/sys.h" namespace render { core::Cvar *r_dust; core::Cvar *r_dustsize; const float LOWSPEEDLIMIT = 5.0f; const float TRAILLENGHT = 0.25f; const float DUSTMAXALPHA = 0.8f; const float DUSTDISTANCE = 8.0f; float *dust; size_t dustsize; void Dust::init() { r_dust = core::Cvar::get("r_dust", "1", core::Cvar::Archive); r_dust->set_info("[bool] render dust"); r_dustsize = core::Cvar::get("r_dustsize", "128", core::Cvar::Archive); r_dustsize->set_info("[int] number of dust particles"); dust = 0; dustsize = (size_t) r_dustsize->value(); } void Dust::shutdown() { if (dust) { delete dust; dust = 0; dustsize = 0; } } void Dust::reset() { delete dust; dust = 0; } void Dust::draw() { if (!r_dust->value()) { if (dust) { delete dust; dust = 0; } return; } if (!core::localcontrol()) { return; } if ((size_t) r_dustsize->value() != dustsize) { con_debug << " changing dust size..." << std::endl; if (dust) { delete dust; dust = 0; } } dustsize = (size_t) r_dustsize->value(); if (!dustsize) { if (dust) { delete dust; dust = 0; } return; } if (!dust) { con_debug << " generating dust..." << std::endl; dust = new float[dustsize*3]; for (size_t i = 0; i < dustsize; i++) { dust[i*3] = core::localcontrol()->location().x + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius()); dust[i*3+1] = core::localcontrol()->location().y + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius()); dust[i*3+2] = core::localcontrol()->location().z + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius()); } } if (!core::localcontrol()->speed()) return; math::Color color; if (core::localcontrol()->speed() < LOWSPEEDLIMIT) { color.a = core::localcontrol()->speed() / LOWSPEEDLIMIT; } color.a *= DUSTMAXALPHA; gl::color(color); gl::begin(gl::Lines); math::Vector3f v; for (size_t i = 0; i < dustsize; i++) { v.assign(core::localcontrol()->location()); for (size_t j = 0; j < 3; j++) v[j] -= dust[i*3+j]; if (v.lengthsquared() > (core::localcontrol()->radius() + DUSTDISTANCE)*(core::localcontrol()->radius() + DUSTDISTANCE)) { dust[i*3] = core::localcontrol()->location().x + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius()); dust[i*3+1] = core::localcontrol()->location().y + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius()); dust[i*3+2] = core::localcontrol()->location().z + (math::randomf(2) - 1) * (DUSTDISTANCE + core::localcontrol()->radius()); } glVertex3fv(dust+3*i); for (size_t j = 0; j < 3; j++) v[j] = dust[i*3+j]; v -= core::localcontrol()->state()->axis().forward() * color.a * TRAILLENGHT; gl::vertex(v); } gl::end(); } }