diff options
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/targets.cc | 208 | ||||
-rw-r--r-- | src/client/targets.h | 7 | ||||
-rw-r--r-- | src/client/view.cc | 7 |
3 files changed, 119 insertions, 103 deletions
diff --git a/src/client/targets.cc b/src/client/targets.cc index e140df2..b16ae13 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -19,6 +19,7 @@ #include "core/entity.h" #include "core/func.h" #include "core/gameinterface.h" +#include "core/range.h" #include "math/axis.h" #include "math/vector3f.h" #include "render/gl.h" @@ -39,10 +40,20 @@ core::Cvar *snd_engines = 0; bool is_legal_target(core::Entity *entity) { - if (entity->id() == core::localcontrol()->id()) + if (entity->id() == core::localcontrol()->id()) { return false; - else - return true; + } else if (entity->state()->distance() < 0.001f) { + return false; + } else { + if (entity->type() != core::Entity::Controlable) { + return entity->state()->visible(); + + } else if (entity->state()->distance() < core::range::max) { + return true; + } + } + + return false; } core::Entity* current() @@ -271,8 +282,83 @@ void render_entity_sound(core::Entity *entity) } } -// render client targets -void frame() +//core::Entity *entity = current_target; +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 ) + return; + + // transform the target into the normalized 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()); + + const float pointer_size = 48.0f; + float r = pointer_size; + if (!is_active_target) + r *= 0.5; + + 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(); + + 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); + + 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) { + 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 - render::Text::fontheight() * 0.5f, strdistance); + } +} + +// render targets and sounds +void draw() { core::Zone *zone = core::localplayer()->zone(); if (!zone) @@ -299,7 +385,7 @@ void frame() cursor -= render::Camera::axis().left() * x; cursor -= render::Camera::axis().up() * y; - math::Vector3f center = render::Camera::eye() + (render::Camera::axis().forward() * (render::Camera::frustum_front() +0.01f)); + math::Vector3f center = render::Camera::eye() + (render::Camera::axis().forward() * (render::Camera::frustum_front() +0.001f)); for (core::Zone::Content::iterator it=zone->content().begin(); it != zone->content().end(); it++) { core::Entity *entity = (*it); @@ -307,22 +393,35 @@ void frame() render_entity_sound(entity); // find the current target - if (entity->id() == current_target_id) { - current_target = entity; - } + if (core::localcontrol() && is_legal_target(entity)) { + + 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 - if (core::localcontrol() && entity->state()->visible()) { + // check if the mouse is hovering the entity Vector3f v(entity->state()->location() - render::Camera::eye()); v.normalize(); - if (is_legal_target(entity) && (math::dotproduct(render::Camera::axis().forward(), v) > 0.75 )) { + if (math::dotproduct(render::Camera::axis().forward(), v) > 0.75 ) { // caculate the distance from entity location to the line [eye - cursor] float d = math::Vector3f::length(math::crossproduct( (cursor - render::Camera::eye()) , (render::Camera::eye() - entity->location()))) / math::Vector3f::length(cursor - render::Camera::eye()); + float r = entity->radius() * 0.5f; + + if (entity->state()->distance() > 512) + math::clamp(r, 8.0f,r); + else if (entity->state()->distance() > 256) + math::clamp(r, 4.0f,r); + else if (entity->state()->distance() > 128.0f) + math::clamp(r, 2.0f,r); + // if the cursor-beam hits the entity sphere - if (d < entity->radius() * 0.5f) { + if (d < r) { float myz = math::distance(cursor, entity->location()); if (z < 0 || myz < z) { current_hover = entity->id(); @@ -337,89 +436,8 @@ void frame() current_target_id = 0; } else { current_target_id = current_target->id(); - } -} - -void draw_target() -{ - using math::Vector3f; - - if (!current_target) - return; - - core::Entity *entity = current_target; - - - - // if target is in visible space - Vector3f v(entity->state()->location() - render::Camera::eye()); - v.normalize(); - if (math::dotproduct(render::Camera::axis().forward(), v) > 0.75 ) { - - // find the intersection of the line [ eye - target ] in the frustum front plane - Vector3f const &plane_normal = render::Camera::axis().forward(); - Vector3f const &plane_point = render::Camera::eye() + render::Camera::axis().forward() * (render::Camera::frustum_front() + 0.001); - - float d = (plane_normal.x * plane_point.x + plane_normal.y * plane_point.y + plane_normal.z * plane_point.z); - float t = d - plane_normal.x * render::Camera::eye().x - - plane_normal.y * render::Camera::eye().y - - plane_normal.z * render::Camera::eye().z; - t /= plane_normal.x * (entity->state()->location().x - render::Camera::eye().x) - + plane_normal.y * (entity->state()->location().y - render::Camera::eye().y) - + plane_normal.z * (entity->state()->location().z - render::Camera::eye().z); - - //Vector3f intersection = render::Camera::eye() + (entity->state()->location() - render::Camera::eye()) * t; - //intersection -= render::Camera::eye() - Vector3f intersection = (entity->state()->location() - render::Camera::eye()) * t; - - Vector3f center(render::Camera::axis().transpose()*intersection); - - float cx = video::width * (0.5 - center.y); - float cy = video::height * (0.5 - center.z * render::Camera::aspect()); - - const float pointer_size = 48.0f; - const float r = pointer_size; - - 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(); - - 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); - - std::stringstream str; - - // entity name - render::Text::setcolor('B'); - render::Text::draw(cx-aux::text_length(entity->name()) * render::Text::fontwidth()*0.5f, cy-r-4- render::Text::fontheight(), entity->name()); - - - d = math::distance(core::localcontrol()->location(), entity->state()->location()) - entity->radius() - core::localcontrol()->radius(); - if (d > 0 ) { - if (d > 100) { - str << roundf(d * 0.1f) << "km"; - } else { - str << roundf(d * 100.0f) << "m"; - } - } else { - str << "--"; - } - render::Text::setcolor('B'); - render::Text::draw(cx - aux::text_length(str.str()) * render::Text::fontwidth() * 0.5f, cy - render::Text::fontheight() * 0.5f, str); + } } diff --git a/src/client/targets.h b/src/client/targets.h index 0df9df7..f805305 100644 --- a/src/client/targets.h +++ b/src/client/targets.h @@ -22,11 +22,8 @@ void shutdown(); void reset(); -/// render client side entity properties -void frame(); - -/// draw target box -void draw_target(); +/// render targets and sounds +void draw(); /// render sound listener properties void render_listener_sound(); diff --git a/src/client/view.cc b/src/client/view.cc index 4fe7a33..a551bf6 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -391,7 +391,6 @@ void frame(float seconds) if (core::application()->connected() && core::game()->serverframetime()) { render::draw(seconds); // draw the world - targets::frame(); } // switch to orthographic projection to draw the GUI @@ -421,8 +420,10 @@ void frame(float seconds) if (draw_ui->value()) { Text::setfont("bitmaps/fonts/gui", 12, 18); - // draw the current target selection - targets::draw_target(); + // draw the current targets + if (core::application()->connected() && core::game()->serverframetime()) { + targets::draw(); + } // draw the player status draw_status(); |