diff options
author | Stijn Buys <ingar@osirion.org> | 2008-08-06 19:35:49 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2008-08-06 19:35:49 +0000 |
commit | d240084aa7e41725a0228e123080aa7fe8a241b7 (patch) | |
tree | 09dcde28b6c301c1aff3aaeae6322cc6025d0eb9 | |
parent | 6979c74625d51897d99797b309974c2ee82a024b (diff) |
target hovering, cursors and mouse and joystick interaction
-rw-r--r-- | src/client/input.cc | 34 | ||||
-rw-r--r-- | src/client/input.h | 7 | ||||
-rw-r--r-- | src/client/targets.cc | 61 | ||||
-rw-r--r-- | src/client/view.cc | 14 |
4 files changed, 107 insertions, 9 deletions
diff --git a/src/client/input.cc b/src/client/input.cc index 2f6fb27..fce83dc 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -58,18 +58,27 @@ int mouse_y = 0; float mouse_pitch = 0; float mouse_direction = 0; -// true if the mouse is in the deadzone -bool mouse_deadzone = false; + + // true if the mouse has control +const float mouse_timeout = 0.200f; // 200 ms select time-out float mouse_control_override_time = 0; bool mouse_control_override = false; bool mouse_control = false; +// true if the mouse is in the deadzone +bool mouse_deadzone = false; +// time the mouse was last moved +float mouse_lastmoved = 0; + +// true if we're using a joystick bool joystick_control = false; +// time the joystick last moved + +float joystick_lastmoved = 0; const float thruster_offset = 0.05f; -const float mouse_timeout = 0.200f; // 200 ms mouse timout int mouse_position_x() { return mouse_x; @@ -83,6 +92,16 @@ Key *last_key_pressed() { return last_key; } +float mouse_lastmoved_time() +{ + return mouse_lastmoved; +} + +float joystick_lastmoved_time() +{ + return joystick_lastmoved; +} + //--- engine functions -------------------------------------------- void func_screenshot(std::string const & args) @@ -387,7 +406,9 @@ void action_release(Key *key, std::string const &action) } else if (action.compare("+control") == 0) { mouse_control_override = false; mouse_control_override_time = 0; - if (!input_mousecontrol->value()) { + + if (!input_mousecontrol->value() || (joystick_control && mouse_control && + (render::Camera::mode() == render::Camera::Track || render::Camera::mode() == render::Camera::Cockpit))) { local_direction = 0.0f; local_pitch = 0.0f; local_roll = 0.0f; @@ -601,7 +622,10 @@ void reset() key->key_waspressed = 0; } } + last_key = 0; + mouse_lastmoved = 0; + joystick_lastmoved = 0; } void frame(float seconds) @@ -648,6 +672,7 @@ void frame(float seconds) case SDL_MOUSEMOTION: mouse_x = event.motion.x; mouse_y = event.motion.y; + mouse_lastmoved = client()->time(); break; case SDL_MOUSEBUTTONDOWN: @@ -672,6 +697,7 @@ void frame(float seconds) case SDL_JOYAXISMOTION: axis_event((int) event.jaxis.axis, (int) event.jaxis.value); + joystick_lastmoved = client()->time(); break; case SDL_KEYDOWN: diff --git a/src/client/input.h b/src/client/input.h index f0c4c9e..cf4c169 100644 --- a/src/client/input.h +++ b/src/client/input.h @@ -37,8 +37,15 @@ int mouse_position_y(); /// the last key that was pressed Key *last_key_pressed(); +/// time the mouse was last moved +float mouse_lastmoved_time(); + +/// time the joystick was last moved +float joystick_lastmoved_time(); + extern bool mouse_deadzone; extern bool mouse_control; +extern bool joystick_control; } // namespace input diff --git a/src/client/targets.cc b/src/client/targets.cc index b16ae13..128064e 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -197,6 +197,45 @@ void func_target_prev(std::string const &args) } } +void func_target_none(std::string const &args) +{ + current_target = 0; + current_target_id = 0; +} + +void func_target_center(std::string const &args) +{ + if (!core::localcontrol()) + return; + + // this is essentialy the hover algorithm with the cursor in the center + core::Entity *new_target = 0; + math::Vector3f center = render::Camera::eye() + render::Camera::axis().forward() * (render::Camera::frustum_front() + 0.001); + float smallest_d = -1; + + for (core::Zone::Content::iterator it=core::localcontrol()->zone()->content().begin(); it != core::localcontrol()->zone()->content().end(); it++) { + core::Entity *entity = (*it); + + math::Vector3f v(entity->state()->location() - render::Camera::eye()); + v.normalize(); + + if (is_legal_target(entity) && math::dotproduct(render::Camera::axis().forward(), v) > 0.5 ) { + + // calculate the distance from entity location to the line [eye - cursor] + float d = math::Vector3f::length(math::crossproduct( (center - render::Camera::eye()) , (render::Camera::eye() - entity->location()))) / math::Vector3f::length(center - render::Camera::eye()); + + // the entity closer to the center beam + if (smallest_d < 0 || d < smallest_d) { + new_target = entity; + smallest_d = d; + } + } + } + + if (new_target) + select_target(new_target); +} + void reset() { current_target = 0; @@ -218,6 +257,12 @@ void init() core::Func::add("target_prev", func_target_prev); func->set_info("select previous target"); + core::Func::add("target_none", func_target_none); + func->set_info("deselect current target"); + + core::Func::add("target_center", func_target_center); + func->set_info("select target near center"); + reset(); } @@ -227,6 +272,8 @@ void shutdown() core::Func::remove("target_next"); core::Func::remove("target_prev"); + core::Func::remove("target_none"); + core::Func::remove("target_center"); } void render_listener_sound() @@ -378,8 +425,16 @@ void draw() float z = -1; // mouse cursor location in 3d world space - float x = (float)(input::mouse_position_x() - video::width /2) / (float)video::width; - float y = (float)(input::mouse_position_y() - video::height /2) / (float)video::height / render::Camera::aspect(); + float x = 0; + float y = 0; + + if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) { + x = 0; + y = 0; + } else { + x = (float)(input::mouse_position_x() - video::width /2) / (float)video::width; + y = (float)(input::mouse_position_y() - video::height /2) / (float)video::height / render::Camera::aspect(); + } Vector3f cursor = render::Camera::eye() + render::Camera::axis().forward() * (render::Camera::frustum_front() + 0.001); cursor -= render::Camera::axis().left() * x; @@ -408,7 +463,7 @@ void draw() if (math::dotproduct(render::Camera::axis().forward(), v) > 0.75 ) { - // caculate the distance from entity location to the line [eye - cursor] + // calculate 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; diff --git a/src/client/view.cc b/src/client/view.cc index a551bf6..610c1a5 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -222,9 +222,10 @@ void draw_cursor() if (render::Camera::mode() == render::Camera::Overview) { render::Textures::bind("bitmaps/pointers/aim"); + } else { // draw center cursor in Cockpit and Track mode - if (input::mouse_control && + if ((input::mouse_control || input::joystick_control) && (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) { if (ui_pointercolor) { @@ -264,6 +265,11 @@ void draw_cursor() cursor_animated = true; + if (input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) { + x = (video::width - pointer_size) /2; + y = (video::height - pointer_size) /2; + } + } else if (input::mouse_control) { if (ui_pointercolor) { @@ -283,7 +289,11 @@ void draw_cursor() } } else { - + if ((input::joystick_lastmoved_time() > input::mouse_lastmoved_time()) && (render::Camera::mode() == render::Camera::Cockpit || render::Camera::mode() == render::Camera::Track)) { + color.assign(1.0, 0.0); + } else { + color.assign(1.0, 0.5); + } render::Textures::bind("bitmaps/pointers/aim"); } |