From 1f36b993d603c56251aa15eb6edc6b92ecf599ae Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Thu, 7 Aug 2008 14:15:17 +0000 Subject: off-screen target indicators --- src/client/targets.cc | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'src/client/targets.cc') diff --git a/src/client/targets.cc b/src/client/targets.cc index 1fc7ec9..b913d55 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -332,7 +332,53 @@ void render_entity_sound(core::Entity *entity) } } -//core::Entity *entity = current_target; +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(); + + 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; @@ -343,10 +389,12 @@ void draw_entity_target(core::Entity *entity, bool is_active_target) // 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 ) + 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 normalized coordinate system + // 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 @@ -356,6 +404,11 @@ void draw_entity_target(core::Entity *entity, bool is_active_target) 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) -- cgit v1.2.3