diff options
author | Stijn Buys <ingar@osirion.org> | 2008-07-20 23:10:08 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2008-07-20 23:10:08 +0000 |
commit | ac3ca340c9502e2e0c83c75d5aba5211429e25ae (patch) | |
tree | c274e47559cee9504af279d9c010c08214fd1691 /src/client/targets.cc | |
parent | 6e7540c701059ca82de7cc5e2f5089578ab5c469 (diff) |
targetting
Diffstat (limited to 'src/client/targets.cc')
-rw-r--r-- | src/client/targets.cc | 117 |
1 files changed, 95 insertions, 22 deletions
diff --git a/src/client/targets.cc b/src/client/targets.cc index 418ca47..1264cbb 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -14,14 +14,16 @@ #include "audio/audio.h" #include "audio/sources.h" +#include "client/input.h" #include "client/view.h" +#include "client/video.h" #include "core/application.h" -#include "core/gameinterface.h" #include "core/entity.h" #include "core/func.h" +#include "core/gameinterface.h" #include "math/vector3f.h" -#include "render/render.h" #include "render/gl.h" +#include "render/render.h" #include "render/text.h" namespace client { @@ -30,9 +32,12 @@ namespace targets { const float TARGETBOXRADIUS = 0.025f; unsigned int current_target_id = 0; +unsigned int current_hover = 0; + core::Entity *current_target = 0; core::Cvar *snd_engines = 0; + bool is_legal_target(core::Entity *entity) { if (entity->id() == core::localcontrol()->id()) @@ -41,6 +46,31 @@ bool is_legal_target(core::Entity *entity) return true; } +core::Entity* current() +{ + return current_target; +} + +unsigned int hover() +{ + return current_hover; +} + +void select_target(core::Entity *entity) +{ + current_target = entity; + current_target_id = current_target->id(); + core::application()->notify_sound("ui/target"); +} + +void select_target(unsigned int id) +{ + // FIXME validate + core::Entity * entity = core::Entity::find(id); + if (entity) + select_target(entity); +} + void func_target_next(std::string const &args) { if (!core::localcontrol()) @@ -83,9 +113,7 @@ void func_target_next(std::string const &args) } if (it != core::Entity::registry.end()) { - current_target = (*it).second; - current_target_id = current_target->id(); - core::application()->notify_sound("ui/target"); + select_target((*it).second); } else { current_target = 0; current_target_id = 0; @@ -134,19 +162,20 @@ void func_target_prev(std::string const &args) } if (rit != core::Entity::registry.rend()) { - current_target = (*rit).second; - current_target_id = current_target->id(); - core::application()->notify_sound("ui/target"); + select_target((*rit).second); + } else { current_target = 0; current_target_id = 0; - } } -core::Entity* current() +void reset() { - return current_target; + current_target = 0; + current_target_id = 0; + current_hover = 0; + } void init() @@ -162,25 +191,17 @@ void init() core::Func::add("target_prev", func_target_prev); func->set_info("select previous target"); - current_target = 0; - current_target_id = 0; + reset(); } void shutdown() { - current_target = 0; - current_target_id = 0; + reset(); core::Func::remove("target_next"); core::Func::remove("target_prev"); } -void reset() -{ - current_target = 0; - current_target_id = 0; -} - void render_listener_sound() { if (!(snd_engines && snd_engines->value())) @@ -238,11 +259,26 @@ void render_entity_sound(core::Entity *entity) void draw() { + /* Notes + http://en.wikipedia.org/wiki/Line-plane_intersection + http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html + */ using math::Vector3f; render_listener_sound(); current_target = 0; + current_hover = 0; + + float z = -1; + + // mouse cursor location in 3d world space + float x = (float)(input::mouse_x - video::width /2) / (float)video::width * render::Camera::aspect(); + float y = (float)(input::mouse_y - video::height /2) / (float)video::height; + + Vector3f cursor = render::Camera::eye() + render::Camera::axis().forward() * (render::frustum_front + 0.001); + cursor -= render::Camera::axis().left() * x; + cursor -= render::Camera::axis().up() * y; math::Vector3f center = render::Camera::eye() + (render::Camera::axis().forward() * (render::frustum_front +0.01f)); for (std::map<unsigned int, core::Entity *>::iterator it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { @@ -251,10 +287,30 @@ void draw() // render entity sound render_entity_sound(entity); - // calculate target information + // find the current target if (entity->id() == current_target_id) { current_target = entity; + } + + // check if the mouse is hovering the entity + if (core::localcontrol() && entity->state()->visible()) { + Vector3f v(entity->state()->location() - render::Camera::eye()); + v.normalize(); + if (is_legal_target(entity) && (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()); + + // if the cursor-beam hits the entity sphere + if (d < entity->radius() * 0.5f) { + float myz = math::distance(cursor, entity->location()); + if (z < 0 || myz < z) { + current_hover = entity->id(); + z = myz; + } + } + } } } @@ -294,6 +350,23 @@ void draw() render::gl::end(); } } + +/* + math::Color color(1, 1, 1, 1); + core::Cvar *cl_crosshaircolor = core::Cvar::get("cl_crosshaircolor", "1 1 1"); + if (cl_crosshaircolor) { + std::stringstream colorstr(cl_crosshaircolor->str()); + colorstr >> color; + } + const float r = 0.05; + render::gl::color(color); + render::gl::begin(render::gl::LineLoop); + render::gl::vertex(cursorposition + render::Camera::axis().up() * r); + render::gl::vertex(cursorposition + render::Camera::axis().left() * r); + render::gl::vertex(cursorposition - render::Camera::axis().up() * r); + render::gl::vertex(cursorposition - render::Camera::axis().left() * r); + render::gl::end(); +*/ } } |