diff options
-rw-r--r-- | src/client/targets.cc | 146 | ||||
-rw-r--r-- | src/client/targets.h | 3 | ||||
-rw-r--r-- | src/client/view.cc | 232 | ||||
-rw-r--r-- | src/game/game.cc | 7 | ||||
-rw-r--r-- | src/model/dock.cc | 2 | ||||
-rw-r--r-- | src/model/dock.h | 2 | ||||
-rw-r--r-- | src/model/map.cc | 1 | ||||
-rw-r--r-- | src/render/draw.cc | 19 |
8 files changed, 247 insertions, 165 deletions
diff --git a/src/client/targets.cc b/src/client/targets.cc index b87f056..e53e530 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -24,9 +24,7 @@ #include "core/range.h" #include "math/axis.h" #include "math/vector3f.h" -#include "render/gl.h" -#include "render/render.h" -#include "render/text.h" +#include "render/camera.h" namespace client { @@ -377,145 +375,8 @@ void render_entity_sound(core::EntityControlable *entity) state->location() - state->axis().forward() * entity->model()->maxbbox().y , state->axis().forward() * speed); } -void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target) -{ - - math::Vector3f target(entity->state()->location() - render::Camera::eye()); - target = render::Camera::axis().transpose() * target; - - float cx = 0; - float cy = 0; - - if ( target.y*target.y + target.z*target.z < 0.0001 ) { - // X - bound, behind (front is visible) - cx = 0.0f; - cy = -0.5f; - - } else if (fabs(target.y) > fabs(target.z)) { - // Y-bound - cx = math::sgnf(target.y) * 0.5f; - cy = 0.5f * target.z / fabs(target.y); - } else { - // Z-bound - cx = 0.5f * target.y / fabs(target.z); - cy = math::sgnf(target.z) * 0.5f; - } - - const float r = 16; - cx = (0.5f - cx) * (float) video::width; - cy = (0.5f - cy) * (float)video::height; - - render::gl::disable(GL_TEXTURE_2D); - render::gl::color(0, 0, 0, 1); - render::gl::begin(render::gl::LineLoop); - glVertex3f(cx+r, cy+2, 0); - glVertex3f(cx, cy+r+2, 0); - glVertex3f(cx-r, cy+2, 0); - glVertex3f(cx, cy-r+2, 0); - render::gl::end(); - - if (entity->type() == core::Entity::Controlable) { - render::gl::color(0, 1, 0, 1); - } else { - render::gl::color(1, 1, 1, 1); - } - - render::gl::begin(render::gl::LineLoop); - glVertex3f(cx+r, cy, 0); - glVertex3f(cx, cy+r, 0); - glVertex3f(cx-r, cy, 0); - glVertex3f(cx, cy-r, 0); - render::gl::end(); - render::gl::enable(GL_TEXTURE_2D); -} - -void draw_entity_target(core::Entity *entity, bool is_active_target) -{ - using math::Vector3f; - - // don't draw target if we're very close to it - if (entity->state()->distance() < 0.001f) - return; - - // don't draw target if it is outside the visible cone - Vector3f target(entity->state()->location() - render::Camera::eye()); - if (math::dotproduct(render::Camera::axis().forward(), Vector3f::normalized(target)) < 0.75 ) { - draw_entity_offscreen_target(entity, is_active_target); - return; - } - - // transform the target into the camera coordinate system - target = render::Camera::axis().transpose() * target; - - // calculate the intersection between the line (0,0,0)-target and the frustum front - float t = (render::Camera::frustum_front() + 0.001f) / target.x; - Vector3f center(target *t); - - float cx = video::width * (0.5 - center.y); - float cy = video::height * (0.5 - center.z * render::Camera::aspect()); - - if ((cx < 0 ) || (cy < 0) || (cx > video::width) || (cy > video::height)) { - draw_entity_offscreen_target(entity, is_active_target); - return; - } - - const float pointer_size = 48.0f; - float r = pointer_size; - if (!is_active_target) - r *= 0.5; - - render::gl::disable(GL_TEXTURE_2D); - // outer square shadow - render::gl::color(0, 0, 0, 1); - render::gl::begin(render::gl::LineLoop); - glVertex3f(cx+r, cy+2, 0); - glVertex3f(cx, cy+r+2, 0); - glVertex3f(cx-r, cy+2, 0); - glVertex3f(cx, cy-r+2, 0); - render::gl::end(); - - if (entity->type() == core::Entity::Controlable) { - render::gl::color(0, 1, 0, 1); - } else { - render::gl::color(1, 1, 1, 1); - } - // outer square0 - render::gl::begin(render::gl::LineLoop); - glVertex3f(cx+r, cy, 0); - glVertex3f(cx, cy+r, 0); - glVertex3f(cx-r, cy, 0); - glVertex3f(cx, cy-r, 0); - render::gl::end(); - - render::gl::enable(GL_TEXTURE_2D); - - if (is_active_target) { - // entity name and distance - std::stringstream strdistance; - float d = math::distance(core::localcontrol()->location(), entity->state()->location()) - entity->radius() - core::localcontrol()->radius(); - if (d > 0 ) { - if (d > 100.0f) { - strdistance << roundf(d * 0.1f) << "km"; - } else { - strdistance << roundf(d * 100.0f) << "m"; - } - } else { - strdistance << "--"; - } - if (entity->type() == core::Entity::Controlable) { - render::Text::setcolor('B'); - } else { - render::Text::setcolor('N'); - } - render::Text::draw(cx-aux::text_length(entity->name()) * render::Text::fontwidth()*0.5f, - cy-r-4-render::Text::fontheight(), entity->name()); - - render::Text::draw(cx - aux::text_length(strdistance.str()) * render::Text::fontwidth() * 0.5f, - cy+r+4, strdistance); - } -} -// render targets and sounds +// render targets and sounds (in world coordinates) void draw() { core::Zone *zone = core::localplayer()->zone(); @@ -564,9 +425,6 @@ void draw() if (entity->id() == current_target_id) { current_target = entity; - draw_entity_target(current_target, true); - } else if (entity->type() == core::Entity::Controlable) { - draw_entity_target(entity, false); } // check if the mouse is hovering the entity diff --git a/src/client/targets.h b/src/client/targets.h index f805305..0366415 100644 --- a/src/client/targets.h +++ b/src/client/targets.h @@ -22,6 +22,9 @@ void shutdown(); void reset(); +/// return true if the entity is a legal target +bool is_legal_target(core::Entity *entity); + /// render targets and sounds void draw(); diff --git a/src/client/view.cc b/src/client/view.cc index 1fdbcdc..24cd72e 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -11,6 +11,7 @@ #include <sstream> #include <iomanip> +#include "auxiliary/functions.h" #include "client/client.h" #include "client/chat.h" #include "client/console.h" @@ -23,6 +24,7 @@ #include "render/camera.h" #include "core/core.h" #include "core/stats.h" +#include "core/zone.h" #include "math/mathlib.h" #include "sys/sys.h" @@ -105,6 +107,211 @@ void draw_loader() gl::end(); } + +/* + FIXME should be merged with the render passes + and in the bbox pass +*/ + +void draw_entity_world_target(core::Entity *entity) +{ + using namespace render; + + model::Model *model = entity->model(); + if (!model) + return; + + if (!model->docks().size()) + return; + + gl::enable(GL_DEPTH_TEST); + gl::push(); + gl::translate(entity->state()->location()); + gl::multmatrix(entity->state()->axis()); + + gl::color(0, 1.0f, 1.0f, 1.0f); + + for (model::Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); dit++) { + model::Dock *dock = (*dit); + math::Vector3f maxbox(dock->location()); + math::Vector3f minbox(dock->location()); + + for (size_t i=0; i < 3; i++) { + maxbox[i] += dock->radius(); + minbox[i] -= dock->radius(); + } + + // top + gl::begin(gl::LineLoop); + gl::vertex(maxbox.x, maxbox.y, maxbox.z); + gl::vertex(minbox.x, maxbox.y, maxbox.z); + gl::vertex(minbox.x, minbox.y, maxbox.z); + gl::vertex(maxbox.x, minbox.y, maxbox.z); + gl::end(); + + // bottom + gl::begin(gl::LineLoop); + gl::vertex(maxbox.x, maxbox.y, minbox.z); + gl::vertex(minbox.x, maxbox.y, minbox.z); + gl::vertex(minbox.x, minbox.y, minbox.z); + gl::vertex(maxbox.x, minbox.y, minbox.z); + gl::end(); + + gl::begin(gl::Lines); + gl::vertex(maxbox.x, maxbox.y, maxbox.z); + gl::vertex(maxbox.x, maxbox.y, minbox.z); + gl::vertex(minbox.x, maxbox.y, maxbox.z); + gl::vertex(minbox.x, maxbox.y, minbox.z); + gl::vertex(minbox.x, minbox.y, maxbox.z); + gl::vertex(minbox.x, minbox.y, minbox.z); + gl::vertex(maxbox.x, minbox.y, maxbox.z); + gl::vertex(maxbox.x, minbox.y, minbox.z); + gl::end(); + } + + gl::pop(); + gl::disable(GL_DEPTH_TEST); + +} + +void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target) +{ + + math::Vector3f target(entity->state()->location() - render::Camera::eye()); + target = render::Camera::axis().transpose() * target; + + float cx = 0; + float cy = 0; + + if ( target.y*target.y + target.z*target.z < 0.0001 ) { + // X - bound, behind (front is visible) + cx = 0.0f; + cy = -0.5f; + + } else if (fabs(target.y) > fabs(target.z)) { + // Y-bound + cx = math::sgnf(target.y) * 0.5f; + cy = 0.5f * target.z / fabs(target.y); + } else { + // Z-bound + cx = 0.5f * target.y / fabs(target.z); + cy = math::sgnf(target.z) * 0.5f; + } + + const float r = 16; + cx = (0.5f - cx) * (float) video::width; + cy = (0.5f - cy) * (float)video::height; + + render::gl::disable(GL_TEXTURE_2D); + render::gl::color(0, 0, 0, 1); + render::gl::begin(render::gl::LineLoop); + glVertex3f(cx+r, cy+2, 0); + glVertex3f(cx, cy+r+2, 0); + glVertex3f(cx-r, cy+2, 0); + glVertex3f(cx, cy-r+2, 0); + render::gl::end(); + + if (entity->type() == core::Entity::Controlable) { + render::gl::color(0, 1, 0, 1); + } else { + render::gl::color(1, 1, 1, 1); + } + + render::gl::begin(render::gl::LineLoop); + glVertex3f(cx+r, cy, 0); + glVertex3f(cx, cy+r, 0); + glVertex3f(cx-r, cy, 0); + glVertex3f(cx, cy-r, 0); + render::gl::end(); + render::gl::enable(GL_TEXTURE_2D); +} + +void draw_entity_target(core::Entity *entity, bool is_active_target) +{ + using math::Vector3f; + + // don't draw target if we're very close to it + if (entity->state()->distance() < 0.001f) + return; + + // don't draw target if it is outside the visible cone + Vector3f target(entity->state()->location() - render::Camera::eye()); + if (math::dotproduct(render::Camera::axis().forward(), Vector3f::normalized(target)) < 0.75 ) { + draw_entity_offscreen_target(entity, is_active_target); + return; + } + + // transform the target into the camera coordinate system + target = render::Camera::axis().transpose() * target; + + // calculate the intersection between the line (0,0,0)-target and the frustum front + float t = (render::Camera::frustum_front() + 0.001f) / target.x; + Vector3f center(target *t); + + float cx = video::width * (0.5 - center.y); + float cy = video::height * (0.5 - center.z * render::Camera::aspect()); + + if ((cx < 0 ) || (cy < 0) || (cx > video::width) || (cy > video::height)) { + draw_entity_offscreen_target(entity, is_active_target); + return; + } + + const float pointer_size = 48.0f; + float r = pointer_size; + if (!is_active_target) + r *= 0.5; + + render::gl::disable(GL_TEXTURE_2D); + // outer square shadow + render::gl::color(0, 0, 0, 1); + render::gl::begin(render::gl::LineLoop); + glVertex3f(cx+r, cy+2, 0); + glVertex3f(cx, cy+r+2, 0); + glVertex3f(cx-r, cy+2, 0); + glVertex3f(cx, cy-r+2, 0); + render::gl::end(); + + if (entity->type() == core::Entity::Controlable) { + render::gl::color(0, 1, 0, 1); + } else { + render::gl::color(1, 1, 1, 1); + } + // outer square0 + render::gl::begin(render::gl::LineLoop); + glVertex3f(cx+r, cy, 0); + glVertex3f(cx, cy+r, 0); + glVertex3f(cx-r, cy, 0); + glVertex3f(cx, cy-r, 0); + render::gl::end(); + + render::gl::enable(GL_TEXTURE_2D); + + if (is_active_target) { + // entity name and distance + std::stringstream strdistance; + float d = math::distance(core::localcontrol()->location(), entity->state()->location()) - entity->radius() - core::localcontrol()->radius(); + if (d > 0 ) { + if (d > 100.0f) { + strdistance << roundf(d * 0.1f) << "km"; + } else { + strdistance << roundf(d * 100.0f) << "m"; + } + } else { + strdistance << "--"; + } + if (entity->type() == core::Entity::Controlable) { + render::Text::setcolor('B'); + } else { + render::Text::setcolor('N'); + } + render::Text::draw(cx-aux::text_length(entity->name()) * render::Text::fontwidth()*0.5f, + cy-r-4-render::Text::fontheight(), entity->name()); + + render::Text::draw(cx - aux::text_length(strdistance.str()) * render::Text::fontwidth() * 0.5f, + cy+r+4, strdistance); + } +} + void draw_status() { using namespace render; @@ -168,7 +375,21 @@ void draw_status() } // draw a basic HUD - if (core::localcontrol()) { + if (core::localcontrol() && core::localcontrol()->zone()) { + core::Zone *zone = core::localcontrol()->zone(); + + // draw targets + for (core::Zone::Content::iterator it=zone->content().begin(); it != zone->content().end(); it++) { + core::Entity *entity = (*it); + + if (targets::is_legal_target(entity)) { + if (entity == targets::current()) { + draw_entity_target(entity, true); + } else if (entity->type() == core::Entity::Controlable) { + draw_entity_target(entity, false); + } + } + } unsigned int state = core::localcontrol()->eventstate(); if (state) { @@ -472,6 +693,10 @@ void frame(float seconds) if (core::application()->connected() && core::game()->serverframetime()) { render::draw(seconds); // draw the world + targets::draw(); // validate current target, render sound + + if (targets::current()) // draw target docks etc + draw_entity_world_target(targets::current()); } // switch to orthographic projection to draw the GUI @@ -501,11 +726,6 @@ void frame(float seconds) if (draw_ui->value()) { Text::setfont("bitmaps/fonts/gui", 12, 18); - // draw the current targets - if (core::application()->connected() && core::game()->serverframetime()) { - targets::draw(); - } - // draw the player status draw_status(); diff --git a/src/game/game.cc b/src/game/game.cc index ca06c81..5f754df 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -345,6 +345,7 @@ bool Game::load_zone(core::Zone *zone) con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; } } else if (zoneini.section().compare("star") == 0) { + if (zoneini.got_key_string("label", strval)) { aux::to_label(strval); star->entity_label.assign(strval); @@ -358,12 +359,12 @@ bool Game::load_zone(core::Zone *zone) } else if (zoneini.got_key_angle("radius", star->entity_radius)) { continue; } else if (zoneini.got_key_angle("direction", direction)) { - planet->axis().change_direction(direction); + star->axis().change_direction(direction); continue; - } else if (zoneini.got_key_string("texture", planet->entity_texture)) { + } else if (zoneini.got_key_string("texture", star->entity_texture)) { continue; } else if (zoneini.got_key_angle("pitch", pitch)) { - planet->axis().change_pitch(pitch); + star->axis().change_pitch(pitch); continue; } else { con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; diff --git a/src/model/dock.cc b/src/model/dock.cc index b850722..bdc63e3 100644 --- a/src/model/dock.cc +++ b/src/model/dock.cc @@ -10,7 +10,7 @@ namespace model { Dock::Dock() { - dock_radius = 1.0f; + dock_radius = 0.01f; } Dock::~Dock() diff --git a/src/model/dock.h b/src/model/dock.h index 0ad2738..89a4026 100644 --- a/src/model/dock.h +++ b/src/model/dock.h @@ -26,7 +26,7 @@ public: return dock_location; } - /// trigger distance in game units, default is 1.0f + /// trigger distance default is 0.01f inline float radius() const { return dock_radius; diff --git a/src/model/map.cc b/src/model/map.cc index d138b49..6494cd7 100644 --- a/src/model/map.cc +++ b/src/model/map.cc @@ -885,6 +885,7 @@ Model * Map::load(std::string const &name) continue; } else if (mapfile.got_key_float("radius", dock->dock_radius)) { + dock->dock_radius /= 100.0f; continue; } diff --git a/src/render/draw.cc b/src/render/draw.cc index 18234f5..af19abe 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -150,6 +150,15 @@ void pass_prepare(float seconds) globes_list[globe->state()->distance()] = globe; + // 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(); + } + if (flag_is_set(globe->flags(), core::Entity::Bright)) { // bright globes set level light @@ -170,16 +179,6 @@ void pass_prepare(float seconds) glLightfv(GL_LIGHT1, GL_SPECULAR, specular_light); gl::enable(GL_LIGHT1); has_zone_light = true; - } else { - - // 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(); - } } } } |