From 4ca453e2272beed121b957244408a61b0b0d8b9b Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 15 Aug 2009 08:18:13 +0000 Subject: don't render entites behind the camera --- src/client/keyboard.cc | 2 +- src/client/targets.cc | 1 - src/core/range.h | 13 ++- src/model/asefile.cc | 1 - src/model/mapfile.cc | 235 +++++++++++++++++++++++++++--------------------- src/model/parts.cc | 2 +- src/model/parts.h | 103 ++++++++++++++------- src/render/draw.cc | 15 ++-- src/render/renderext.cc | 55 +++++++----- src/render/renderext.h | 8 ++ 10 files changed, 261 insertions(+), 174 deletions(-) diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc index ba67395..23e6634 100644 --- a/src/client/keyboard.cc +++ b/src/client/keyboard.cc @@ -176,7 +176,7 @@ Keyboard::Keyboard() add_key("pageup", SDLK_PAGEUP); add_key("pagedown", SDLK_PAGEDOWN); - add_key("f1", SDLK_F1, 0, "ui_menu"); + add_key("f1", SDLK_F1); add_key("f2", SDLK_F2); add_key("f3", SDLK_F3, 0, "@dock"); key = add_key("f4", SDLK_F4); diff --git a/src/client/targets.cc b/src/client/targets.cc index 496f4e5..e478d84 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -41,7 +41,6 @@ core::Cvar *snd_engines = 0; bool is_valid_hud_target(core::Entity *entity) { - if (entity->serverside()) { return false; } else if (!ext_render(entity)) { diff --git a/src/core/range.h b/src/core/range.h index aa194bb..d530f0b 100644 --- a/src/core/range.h +++ b/src/core/range.h @@ -9,19 +9,18 @@ namespace core { +/** + * @brief range and scale constants + */ namespace range { - /// maximal visiblae range (world distance) + /// maximal visible range (world distance) /** This is the distance of the frustum far plane, - * the maximal distance at which non-controlable entities can be drawn. - * the maximal radar range for controlable entities, + * the maximal distance at which entities can be drawn. + * the maximal radar range * and the maximal range to send entity updates */ const float maxdistance = 1024.0f; - /// maximal visible range for controlable entities (world distance) - const float maxvisible = 512.0f; - - /// detail/fx distance (world distance) const float fxdistance = 256.0f; } diff --git a/src/model/asefile.cc b/src/model/asefile.cc index edbd848..a9e57d4 100644 --- a/src/model/asefile.cc +++ b/src/model/asefile.cc @@ -462,7 +462,6 @@ Model * ASEFile::load(const std::string &name) fragment->add_vertex((triangle->v2() - center) * scale , triangle->n2(), triangle->t2(), false); model->model_tris_count++; - model->model_tris_detail_count++; } model->add_group(group); diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index 36dc536..a86e06e 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -1018,85 +1018,55 @@ Model * MapFile::load(std::string const &name) // new light light = new Light(); model->add_light(light); + continue; } else if (mapfile.classname().compare("light") == 0) { // light attributes if (mapfile.got_key_vector3f("origin", location)) { - light->set_location(location * SCALE); + light->get_location().assign(location * SCALE); continue; - } else if (mapfile.got_key_color("_color", light->light_color)) { + } else if (mapfile.got_key_color("_color", color)) { + light->get_color().assign(color); continue; } else if (mapfile.got_key_int("spawnflags", u)) { light->set_strobe(spawnflag_isset(u, 1)); light->set_entity(spawnflag_isset(u, 2)); light->set_engine(spawnflag_isset(u, 4)); + continue; - } else if (mapfile.got_key_float("light", light->light_radius)) { - light->light_radius *= LIGHTSCALE; + } else if (mapfile.got_key_float("light", r)) { + light->set_radius( r * LIGHTSCALE); + continue; - } else if (mapfile.got_key_float("radius", light->light_radius)) { - light->light_radius *= LIGHTSCALE; + } else if (mapfile.got_key_float("radius", r)) { + light->set_radius( r * LIGHTSCALE); + continue; - } else if (mapfile.got_key_float("frequency", light->light_frequency)) { + } else if (mapfile.got_key_float("frequency", r)) { + light->set_frequency(r); continue; - } else if (mapfile.got_key_float("offset", light->light_offset)) { + } else if (mapfile.got_key_float("offset", r)) { + light->set_offset(r); continue; - } else if (mapfile.got_key_float("time", light->light_time)) { + } else if (mapfile.got_key_float("time", r)) { + light->set_time(r); continue; - } else if (mapfile.got_key_int("flare", light->light_flare)) { + } else if (mapfile.got_key_int("flare", u)) { + light->set_flare(u); continue; } else if (mapfile.got_key()) { mapfile.unknown_key(); - - } - - } else if (mapfile.got_classname("location_dock")) { - - // new docking location - dock = new Dock(); - model->add_dock(dock); - - } else if (mapfile.classname().compare("location_dock") == 0) { - - // dock attributes - if (mapfile.got_key_vector3f("origin", dock->dock_location)) { - dock->dock_location *= SCALE; - continue; - - } else if (mapfile.got_key_float("radius", dock->dock_radius)) { - dock->dock_radius *= SCALE; - continue; - - } else if (mapfile.got_key("angle")) { continue; - - } else if (mapfile.got_key()) { - mapfile.unknown_key(); - + } - } else if (mapfile.got_classname("location_cannon")) { - // new cannon - - } else if (mapfile.classname().compare("location_cannon") == 0) { - - } else if (mapfile.got_classname("location_turret")) { - // new turret - - } else if (mapfile.classname().compare("location_turret") == 0) { - - } else if (mapfile.got_classname("location_cockpit")) { - // cockpit location - - } else if (mapfile.classname().compare("location_cockpit") == 0) { - } else if (mapfile.got_classname("fx_flare")) { // new flare @@ -1107,10 +1077,11 @@ Model * MapFile::load(std::string const &name) // flare attributes if (mapfile.got_key_vector3f("origin", location)) { - flare->set_location(location * SCALE); + flare->get_location().assign(location * SCALE); continue; - } else if (mapfile.got_key_color("_color", flare->light_color)) { + } else if (mapfile.got_key_color("_color", color)) { + flare->get_color().assign(color); continue; } else if (mapfile.got_key_int("spawnflags", u)) { @@ -1118,19 +1089,24 @@ Model * MapFile::load(std::string const &name) flare->set_entity(spawnflag_isset(u, 2)); flare->set_engine(spawnflag_isset(u, 4)); - } else if (mapfile.got_key_float("radius", flare->light_radius)) { - flare->light_radius *= LIGHTSCALE; - - } else if (mapfile.got_key_float("frequency", flare->light_frequency)) { + } else if (mapfile.got_key_float("radius", r)) { + flare->set_radius( r * LIGHTSCALE); + continue; + + } else if (mapfile.got_key_float("frequency", r)) { + flare->set_frequency(r); continue; - } else if (mapfile.got_key_float("offset", flare->light_offset)) { + } else if (mapfile.got_key_float("offset", r)) { + flare->set_offset(r); continue; - } else if (mapfile.got_key_float("time", flare->light_time)) { + } else if (mapfile.got_key_float("time", r)) { + flare->set_time(r); continue; - } else if (mapfile.got_key_int("flare", flare->light_flare)) { + } else if (mapfile.got_key_int("flare", u)) { + flare->set_flare(u); continue; } else if (mapfile.got_key_float("angle", angle)) { @@ -1167,46 +1143,6 @@ Model * MapFile::load(std::string const &name) mapfile.unknown_key(); } - } else if (mapfile.got_classname("misc_model")) { - - // new submodel - submodel = new SubModel(); - submodel_list.push_back(submodel); - - } else if (mapfile.classname().compare("misc_model") == 0) { - - // submodel attributes - if (mapfile.got_key_vector3f("origin", location)) { - submodel->set_location(location * SCALE); - continue; - - } else if (mapfile.got_key_string("model", modelname)) { - - // remove extension - if (modelname[modelname.size()-4] == '.') { - modelname.erase(modelname.size()-4); - } - - submodel->set_name(modelname); - continue; - - } else if (mapfile.got_key_float("angle", angle)) { - if (angle == ANGLEUP) { - submodel->axis().change_pitch(90.0f); - } else if (angle == ANGLEDOWN) { - submodel->axis().change_pitch(-90.0f); - } else { - submodel->axis().change_direction(angle); - } - - } else if (mapfile.got_key_float("modelscale", s)) { - if (s) { - submodel->set_scale(s); - } else { - submodel->set_scale(1.0f); - } - } - } else if (mapfile.got_classname("fx_particles")) { // new particle system @@ -1217,10 +1153,13 @@ Model * MapFile::load(std::string const &name) // particle system attributes if (mapfile.got_key_vector3f("origin", location)) { - particles->set_location(location * SCALE); + particles->get_location().assign(location * SCALE); continue; - } else if (mapfile.got_key_string("script", particles->particles_script)) { + + } else if (mapfile.got_key_string("script", str)) { + particles->set_script(str); continue; + } else if (mapfile.got_key_float("angle", angle)) { if (angle == ANGLEUP) { particles->get_axis().change_pitch(90.0f); @@ -1261,7 +1200,99 @@ Model * MapFile::load(std::string const &name) } else if (mapfile.got_key()) { mapfile.unknown_key(); } + + } else if (mapfile.got_classname("misc_model")) { + + // new submodel + submodel = new SubModel(); + submodel_list.push_back(submodel); + + } else if (mapfile.classname().compare("misc_model") == 0) { + + // submodel attributes + if (mapfile.got_key_vector3f("origin", location)) { + submodel->set_location(location * SCALE); + continue; + + } else if (mapfile.got_key_string("model", modelname)) { + + // remove extension + if (modelname[modelname.size()-4] == '.') { + modelname.erase(modelname.size()-4); + } + + submodel->set_name(modelname); + continue; + + } else if (mapfile.got_key_float("angle", angle)) { + if (angle == ANGLEUP) { + submodel->axis().change_pitch(90.0f); + } else if (angle == ANGLEDOWN) { + submodel->axis().change_pitch(-90.0f); + } else { + submodel->axis().change_direction(angle); + } + + } else if (mapfile.got_key_float("modelscale", s)) { + if (s) { + submodel->set_scale(s); + } else { + submodel->set_scale(1.0f); + } + } + + } else if (mapfile.got_classname("location_dock")) { + + // new docking location + dock = new Dock(); + model->add_dock(dock); + + } else if (mapfile.classname().compare("location_dock") == 0) { + + // dock attributes + if (mapfile.got_key_vector3f("origin", location)) { + dock->get_location().assign(location * SCALE); + continue; + + } else if (mapfile.got_key_float("radius", r)) { + dock->set_radius (r * SCALE); + continue; + + } else if (mapfile.got_key("angle")) { + // TODO + continue; + + } else if (mapfile.got_key()) { + mapfile.unknown_key(); + + } + + } else if (mapfile.got_classname("location_cannon")) { + // TODO cannon attachment point + continue; + + } else if (mapfile.classname().compare("location_cannon") == 0) { + // TODO cannon options + continue; + + } else if (mapfile.got_classname("location_turret")) { + // TODO turret attachment point + continue; + + } else if (mapfile.classname().compare("location_turret") == 0) { + // TODO turret options + continue; + + } else if (mapfile.got_classname("location_cockpit")) { + // TODO cockpit location + continue; + + } else if (mapfile.classname().compare("location_cockpit") == 0) { + // TODO cockpit options + continue; + } else if (mapfile.got_classname()) { + mapfile.unknown_class(); } } @@ -1282,7 +1313,7 @@ Model * MapFile::load(std::string const &name) } for (Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); dit++) { - (*dit)->dock_location -= mapfile.map_center; + (*dit)->get_location() -= mapfile.map_center; } // FIXME this will go wrong if a Rotate group is imported as submodel diff --git a/src/model/parts.cc b/src/model/parts.cc index bcd8446..eabc108 100644 --- a/src/model/parts.cc +++ b/src/model/parts.cc @@ -25,7 +25,7 @@ Light::Light() : light_flare = 0; - render_texture = 0; + light_texture = 0; } Light::~Light() diff --git a/src/model/parts.h b/src/model/parts.h index 78ad5e4..c3a0401 100644 --- a/src/model/parts.h +++ b/src/model/parts.h @@ -120,7 +120,7 @@ public: } /// true if this light has engine activation - inline const bool engine() const + inline bool engine() const { return light_engine; } @@ -137,7 +137,7 @@ public: return light_offset; } - /// frequency in strobes per second + /// strobe frequency in strobes per second, default is 1.0f inline float frequency() const { return light_frequency; @@ -155,41 +155,78 @@ public: return light_flare; } - /// render texture number + /// render texture id inline size_t texture() const { - return render_texture; + return light_texture; } /* ---- mutators ------------------------------------------- */ - /// set strobe on or off - inline void set_strobe(bool strobe) { light_strobe = strobe; } + /** + * @brief set strobe color on or off + */ + inline void set_strobe(const bool strobe) { light_strobe = strobe; } /** * @brief set entity color on or off */ - inline void set_entity(bool entity) { light_entity = entity; } + inline void set_entity(const bool entity) { light_entity = entity; } /** * @brief set engine activation on or off */ - inline void set_engine(bool engine) { light_engine = engine; } + inline void set_engine(const bool engine) { light_engine = engine; } + /** + * @brief set the light radius + */ + inline void set_radius(const float radius) { light_radius = radius; } - math::Color light_color; - float light_radius; - float light_frequency; - float light_offset; - float light_time; + /** + * @brief set the light strobe frequency, in strobes per second + */ + inline void set_frequency(const float frequency) { light_frequency = frequency; } - unsigned int light_flare; + /** + * @brief set the light on time, from 0.0 (always off) to 1.0 (always on) + */ + inline void set_time(const float time) { light_radius = time; } - size_t render_texture; + /** + * @brief set the light strobe time offset, in seconds + */ + inline void set_offset(const float offset) { light_offset = offset; } + + /** + * @brief set the flare texture number + */ + inline void set_flare(unsigned int flare) { light_flare = flare; } + + /** + * @brief set the render texture id + */ + inline void set_texture(size_t texture) { light_texture = texture; } + /** + * @brief mutable reference to the color + */ + inline math::Color& get_color() { return light_color; } + private: bool light_strobe; bool light_engine; bool light_entity; + + unsigned int light_flare; + + float light_radius; + float light_frequency; + float light_offset; + float light_time; + + math::Color light_color; + + size_t light_texture; }; /* ---- class Flare ------------------------------------------------ */ @@ -223,11 +260,11 @@ public: /** * @brief mutable reference to the axis */ - inline math::Axis &get_axis() { return flare_axis; } + inline math::Axis& get_axis() { return flare_axis; } private: - math::Axis flare_axis; Cull flare_cull; + math::Axis flare_axis; }; /* ---- class Particles -------------------------------------------- */ @@ -285,7 +322,9 @@ public: inline void set_radius(const float radius) { particles_radius = radius; } inline void set_cull(const Cull cull) { particles_cull = cull; } - + + inline void set_script(const std::string &script) { particles_script.assign(script); } + /* ---- actors --------------------------------------------- */ /** @@ -293,39 +332,37 @@ public: */ inline math::Axis &get_axis() { return particles_axis; } - std::string particles_script; - private: - math::Axis particles_axis; - float particles_radius; bool particles_entity; bool particles_engine; + Cull particles_cull; + + float particles_radius; + + math::Axis particles_axis; + std::string particles_script; }; /* ---- class Dock ------------------------------------------------- */ /// a docking location -class Dock +class Dock : public Part { public: Dock(); ~Dock(); - /// location of the dock - inline const math::Vector3f & location() const - { - return dock_location; - } - - /// trigger distance default is 0.01f + /// dock radius, default is 0.01f inline float radius() const { return dock_radius; } - - - math::Vector3f dock_location; + + /// set dock radius + inline void set_radius(const float radius) { dock_radius = radius; } + +private: float dock_radius; }; diff --git a/src/render/draw.cc b/src/render/draw.cc index 0b6fba2..e9e655c 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -97,7 +97,7 @@ void pass_prepare(float seconds) core::EntityGlobe *globe = static_cast(entity); // add the globe to the globes list - if (globe->visible()) { + if (globe->visible() && !ext_render(globe)->behind()) { globes_list[ext_render(globe)->distance()] = globe; } @@ -495,7 +495,7 @@ void draw_pass_default() for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); ++it) { core::Entity *entity = (*it); - if (!entity->serverside() && !entity->model() && (entity->type() != core::Entity::Globe)) { + if (!entity->model() && (entity->type() != core::Entity::Globe) && !entity->serverside() && !ext_render(entity)->behind()) { gl::push(); gl::translate(entity->location()); @@ -854,7 +854,7 @@ void draw_pass_model_fragments() for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { core::Entity *entity = (*it); - if (entity->model() && ext_render(entity)->visible()) { + if (entity->model() && ext_render(entity)->visible() && !ext_render(entity)->behind()) { gl::push(); gl::translate(entity->location()); gl::multmatrix(entity->axis()); @@ -1209,7 +1209,6 @@ void draw(float seconds) gl::enable(GL_CULL_FACE); // enable culling gl::enable(GL_COLOR_MATERIAL); // enable color tracking - gl::enable(GL_LIGHTING); // enable lighting if (r_normalize && r_normalize->value()) { // enable full normalization gl::enable(GL_NORMALIZE); @@ -1217,6 +1216,8 @@ void draw(float seconds) // enable rescaling of normals gl::enable(GL_RESCALE_NORMAL); } + + gl::enable(GL_LIGHTING); // enable lighting draw_pass_globes(); // draw globes @@ -1224,6 +1225,8 @@ void draw(float seconds) draw_pass_model_fragments(); + gl::disable(GL_LIGHTING); // disable lighting + if (r_normalize && r_normalize->value()) { // disable full normalization gl::disable(GL_NORMALIZE); @@ -1231,7 +1234,6 @@ void draw(float seconds) // disable resaling of normals gl::disable(GL_RESCALE_NORMAL); } - gl::disable(GL_LIGHTING); // disable lighting gl::enable(GL_BLEND); gl::depthmask(GL_FALSE); // disable depth buffer writing @@ -1284,6 +1286,7 @@ void draw(float seconds) // GL_BLEND must be enabled for the GUI } +// draw HUD target world space geometry, like dock indicators void draw_target(core::Entity *entity) { model::Model *model = entity->model(); @@ -1294,7 +1297,7 @@ void draw_target(core::Entity *entity) return; float d = math::distance(core::localcontrol()->location(), entity->location()) - entity->radius() - core::localcontrol()->radius(); - if (d > 100.0f) + if (d > core::range::fxdistance) return; gl::enable(GL_DEPTH_TEST); diff --git a/src/render/renderext.cc b/src/render/renderext.cc index b0462d4..b743686 100644 --- a/src/render/renderext.cc +++ b/src/render/renderext.cc @@ -41,7 +41,7 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re // load light texture std::stringstream flarename; flarename << "textures/fx/flare" << std::setfill('0') << std::setw(2) << light->flare(); - light->render_texture = Textures::load(flarename.str()); + light->set_texture(Textures::load(flarename.str())); } for (model::Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) { @@ -50,7 +50,7 @@ RenderExt::RenderExt(core::Entity *entity) : core::Extension(core::Extension::Re // load flare texture std::stringstream flarename; flarename << "textures/fx/flare" << std::setfill('0') << std::setw(2) << flare->flare(); - flare->render_texture = Textures::load(flarename.str()); + flare->set_texture(Textures::load(flarename.str())); } for(model::Model::ParticleSystems::iterator pit = model->particles().begin(); pit != model->particles().end(); pit++) { @@ -103,6 +103,10 @@ void RenderExt::frame(float elapsed) 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) { @@ -111,37 +115,44 @@ void RenderExt::frame(float elapsed) } } - if (state_visible && entity()->model()) { + if (!entity()->model()) + return; - if (distance() < core::range::fxdistance) { - // entity within detail range - state_visible = true; - state_detailvisible = true; + 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); - } else if (distance() < core::range::maxvisible) { + if (distance() < core::range::fxdistance * r) { // entity within drawing distance, outside detail range state_visible = true; state_detailvisible = false; - } else if (distance() < core::range::maxdistance) { - - if ((entity()->type() == core::Entity::Controlable)) { - // controlable entity out of range - state_visible = false; - 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; + // 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 diff --git a/src/render/renderext.h b/src/render/renderext.h index 28a2c23..3834769 100644 --- a/src/render/renderext.h +++ b/src/render/renderext.h @@ -26,8 +26,14 @@ public: virtual void frame(float elapsed); inline bool visible() const { return state_visible; } + inline bool detailvisible() const { return state_detailvisible; } + /** + * true if the entity is behind the camera + */ + inline bool behind() const { return state_behind; } + inline float fuzz() const { return state_fuzz; } /// distance to the camera @@ -35,9 +41,11 @@ public: /// particles inline ParticleSystems &particles() { return state_particles; } + private: bool state_visible; bool state_detailvisible; + bool state_behind; float state_fuzz; float state_distance; -- cgit v1.2.3