From 36ce28a7557c4b2b73316621471558354024ca54 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Thu, 1 May 2008 21:08:40 +0000 Subject: roll control --- README | 9 ++++---- ROADMAP | 4 +++- TODO | 8 +++---- src/client/camera.cc | 60 +++++++++++++++++++++++++++++++++++----------------- src/client/camera.h | 3 +++ src/client/input.cc | 24 +++++++++++++++++++-- src/core/entity.cc | 13 ++++++++++++ src/core/entity.h | 7 ++++++ src/game/ship.cc | 53 +++++++++++++++++++++++++++++++--------------- src/game/ship.h | 4 ++++ src/math/functions.h | 6 ++++++ 11 files changed, 144 insertions(+), 47 deletions(-) diff --git a/README b/README index b9c71af..2a345c5 100644 --- a/README +++ b/README @@ -30,11 +30,12 @@ Keyboard ~ toggle console space bar switch camera mode - left/right/up/down arrow keys + left right up down arrow rotate camera in free mode - keypad left/right - turn the ship left/right - keypad +/- increase/decrease forward thruster + keypad left right up down + steer the ship left/right/up/down + keypad / * roll left/right + keypad + - increase/decrease forward thruster T open the chat window print screen screenshot diff --git a/ROADMAP b/ROADMAP index 310a001..39f07ec 100644 --- a/ROADMAP +++ b/ROADMAP @@ -23,7 +23,9 @@ Requires: Requires: weapons - collision detection + turret and cannon models + + clip brushes and collision detection * MILESTONE 3 diff --git a/TODO b/TODO index 698466b..b26597c 100644 --- a/TODO +++ b/TODO @@ -10,8 +10,8 @@ core: split client and server configuration (ok) parse command line options (ok) game module loading/unloading - execute command line options - globe entity + execute command line options (ok) + globe entity (ok) network: UDP datagrams (ok) @@ -38,7 +38,7 @@ render: text quads render pipe win32 port: - network not functional - texture loading is broken + network not functional (ok) + texture loading is broken (ok) screenshots are broken diff --git a/src/client/camera.cc b/src/client/camera.cc index e2dbacf..c2bbc83 100644 --- a/src/client/camera.cc +++ b/src/client/camera.cc @@ -43,6 +43,11 @@ float yaw_current; // current pitch, angle in XY, positive is looking up float pitch_current; +// current direction rotation speed +float current_direction_speed; +// current pitcj rotation speed +float current_pitch_speed; + // default pitch in mode::Overview float pitch_overview; @@ -55,6 +60,8 @@ float rotate_offset_inc; // default translate offset increase/decrease const float translate_offset_inc = 0.1; +void set_mode(Mode newmode); + void init() { rotate_offset_inc = 5.0f; @@ -67,7 +74,8 @@ void init() distance = 0.4f; - mode = Track; + set_mode(Track); + } void shutdown() @@ -75,25 +83,24 @@ void shutdown() } void set_mode(Mode newmode) { + + current_direction_speed = 0; + current_pitch_speed = 0; + yaw_target = 0; + yaw_current = yaw_target; + pitch_target = pitch_track; + pitch_current = pitch_target; + distance = 0.4f; + switch(newmode) { case Track: // switch camera to Track mode mode = Track; - yaw_target = 0; - yaw_current = yaw_target; - pitch_target = pitch_track; - pitch_current = pitch_target; - distance = 0.4f; break; case Free: // switch camera to Free mode mode = Free; - yaw_target = 0; - yaw_current = yaw_target; - pitch_target = pitch_track; - pitch_current = pitch_target; - distance = 0.4f; break; case Overview: @@ -128,7 +135,7 @@ void next_mode() } } -void draw(float elapsed) +void draw(float seconds) { math::Matrix4f matrix; @@ -153,25 +160,34 @@ void draw(float elapsed) set_mode(Track); target.assign(core::localcontrol()->location()); - - axis.assign(core::localcontrol()->axis()); - + if (core::localcontrol()->model()) + target += core::localcontrol()->model()->maxbbox().z * core::localcontrol()->axis().up(); + if (mode == Track) { // make the camera swing while turning yaw_target = -25.0f * core::localcontrol()->target_direction; pitch_target = pitch_track - 25 * core::localcontrol()->target_pitch; - } + /* + d = -math::dotproduct(axis.forward(), core::localcontrol()->axis().forward()) + 1; + axis.change_direction(360.0f * d * seconds); + + //d = -math::dotproduct(axis.left(), core::localcontrol()->axis().left()) + 1; + // axis.change_pitch(360.0f * d * seconds); + */ + } + + axis.assign(core::localcontrol()->axis()); // adjust direction d = degrees180f(yaw_current - yaw_target); - yaw_current = degrees360f( yaw_current - d * elapsed); + yaw_current = degrees360f( yaw_current - d * seconds); axis.change_direction(yaw_current); // adjust pitch target d = degrees180f(pitch_current - pitch_target); - pitch_current = degrees360f(pitch_current - d *elapsed); + pitch_current = degrees360f(pitch_current - d *seconds); axis.change_pitch(pitch_current); - + if (core::localcontrol()->model()) distance = 1+core::localcontrol()->model()->radius(); else @@ -228,6 +244,12 @@ void key_up() } } + +void reset() +{ + set_mode(mode); +} + } // namespace camera } // namespace client diff --git a/src/client/camera.h b/src/client/camera.h index 25e179d..751ff02 100644 --- a/src/client/camera.h +++ b/src/client/camera.h @@ -41,6 +41,9 @@ namespace camera /// switch to next camera mode void next_mode(); + /// reset the current mode + void reset(); + /// gameworld coordinates of the camera target extern math::Vector3f target; diff --git a/src/client/input.cc b/src/client/input.cc index d10c8bc..87492c4 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -27,8 +27,8 @@ namespace input // local controls float local_turn = 0.0f; float local_pitch = 0.0f; -float local_roll = 0.0f; float local_thrust = 0.0f; +float local_roll = 0.0f; // last controlled entity unsigned int last_control = 0; @@ -84,6 +84,14 @@ void keyreleased(const SDL_keysym &keysym) local_turn = 0.0f; break; + case SDLK_KP_DIVIDE: // roll left + local_roll = 0.0f; + break; + + case SDLK_KP_MULTIPLY: // roll light + local_roll = 0.0f; + break; + default: break; } @@ -132,9 +140,18 @@ void keypressed(const SDL_keysym &keysym) local_turn = -1.0f; break; - case SDLK_KP5: + case SDLK_KP5: // level local_turn = 0; local_pitch = 0; + local_roll = 0; + break; + + case SDLK_KP_DIVIDE: // roll left + local_roll = 1.0f; + break; + + case SDLK_KP_MULTIPLY: // roll light + local_roll = -1.0f; break; @@ -165,8 +182,10 @@ void frame(float seconds) if (core::localcontrol() && (last_control != core::localcontrol()->id())) { local_turn = 0.0f; local_pitch = 0.0f; + local_roll = 0.0f; local_thrust = core::localcontrol()->thrust(); last_control = core::localcontrol()->id(); + camera::reset(); } SDL_Event event; @@ -281,6 +300,7 @@ void frame(float seconds) core::localcontrol()->set_thrust(local_thrust); core::localcontrol()->set_direction(local_turn); core::localcontrol()->set_pitch(local_pitch / video::aspect ); + core::localcontrol()->set_roll(local_roll); } } diff --git a/src/core/entity.cc b/src/core/entity.cc index ea5b9bc..d05bef2 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -262,6 +262,7 @@ EntityControlable::EntityControlable(Player *player, unsigned int flags) : target_direction = 0.0f; target_thrust = 0.0f; target_pitch = 0.0f; + target_roll = 0.0f; } EntityControlable::EntityControlable(std::istream & is) : @@ -296,6 +297,7 @@ void EntityControlable::serialize_client_update(std::ostream & os) const os << " " << target_direction; os << " " << target_pitch; os << " " << target_thrust; + os << " " << target_roll; } @@ -305,6 +307,7 @@ void EntityControlable::recieve_client_update(std::istream &is) is >> target_direction; is >> target_pitch; is >> target_thrust; + is >> target_roll; } void EntityControlable::serialize_server_update(std::ostream & os) const @@ -360,6 +363,16 @@ void EntityControlable::set_pitch(float pitch) } } +void EntityControlable::set_roll(float roll) +{ + if ((flags() & Static) == Static) + return; + + if (target_roll != roll) { + target_roll = roll; + entity_dirty = true; + } +} /*----- EntityGlobe ------------------------------------------------ */ diff --git a/src/core/entity.h b/src/core/entity.h index e71b034..7e6493a 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -269,6 +269,9 @@ public: /// set the target pitch void set_pitch(float pitch); + /// set target roll + void set_roll(float roll); + /// runs one game frame for the entity /** * The default implementation will set direction() and thrust() to the desired targets @@ -293,6 +296,10 @@ public: /** target_pitch must be in the [-1, 1] range */ float target_pitch; + /// target roll as set by the client + /** target_roll must be in the [-1, 1] range + */ + float target_roll; }; /// a Globe entity diff --git a/src/game/ship.cc b/src/game/ship.cc index 538a1e6..af98513 100644 --- a/src/game/ship.cc +++ b/src/game/ship.cc @@ -25,6 +25,10 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : ship_shipmodel = shipmodel; entity_moduletypeid = ship_enttype; + + current_target_direction = 0.0f; + current_target_pitch = 0.0f;; + current_target_roll = 0.0f;; } Ship::~Ship() @@ -35,33 +39,48 @@ Ship::~Ship() void Ship::frame(float seconds) { + const float direction_change_speed = 2; + // update thrust + math::clamp(target_thrust, 0.0f, 1.0f); entity_thrust = target_thrust; - if (entity_thrust < 0.0f) - entity_thrust = 0.0f; - else if(entity_thrust > 1.0f) - entity_thrust = 1.0f; - + // update pitch - if (target_pitch > 1.0f) - target_pitch = 1.0f; - else if (target_pitch < -1.0f) - target_pitch = -1.0f; - - float pitch_offset = seconds * target_pitch; + math::clamp(target_pitch, -1.0f, 1.0f); + if (current_target_pitch < target_pitch) { + current_target_pitch += direction_change_speed * seconds; + } else if (current_target_pitch > target_pitch) { + current_target_pitch -= direction_change_speed * seconds; + } + math::clamp(current_target_pitch, -1.0f, 1.0f); + float pitch_offset = seconds * current_target_pitch; if (pitch_offset) entity_axis.change_pitch(360.0f * ship_shipmodel->turnspeed() * pitch_offset); // update direction - if (target_direction > 1.0f) - target_direction = 1.0f; - else if (target_direction < -1.0f) - target_direction = -1.0f; - - float direction_offset = seconds * target_direction; + math::clamp(target_direction, -1.0f, 1.0f); + if (current_target_direction < target_direction) { + current_target_direction += direction_change_speed * seconds; + } else if (current_target_direction > target_direction) { + current_target_direction -= direction_change_speed * seconds; + } + math::clamp(current_target_direction, -1.0f, 1.0f); + float direction_offset = seconds * current_target_direction; if (direction_offset) entity_axis.change_direction(360.0f * ship_shipmodel->turnspeed() * direction_offset); + // update roll + math::clamp(target_roll, -1.0f, 1.0f); + if (current_target_roll < target_roll) { + current_target_roll += direction_change_speed * seconds; + } else if (current_target_roll > target_roll) { + current_target_roll -= direction_change_speed * seconds; + } + math::clamp(current_target_roll, -1.0f, 1.0f); + float roll_offset = seconds * current_target_roll; + if (roll_offset) + entity_axis.change_roll(360.0f * ship_shipmodel->turnspeed() * roll_offset); + // update speed if (entity_speed < entity_thrust * ship_shipmodel->maxspeed()) { entity_speed += ship_shipmodel->acceleration() * seconds; diff --git a/src/game/ship.h b/src/game/ship.h index 633c722..9e978bb 100644 --- a/src/game/ship.h +++ b/src/game/ship.h @@ -26,6 +26,10 @@ public: private: ShipModel *ship_shipmodel; + + float current_target_direction; + float current_target_pitch; + float current_target_roll; }; } diff --git a/src/math/functions.h b/src/math/functions.h index d9f78df..b44a4e5 100644 --- a/src/math/functions.h +++ b/src/math/functions.h @@ -49,6 +49,12 @@ float degrees180f(float angle); /// return an angle in the [0,360[ range float degrees360f(float angle); +/// clamp a float to a specified range +inline void clamp(float &value, float min=0.0f, float max=1.0f) +{ + if (value < min) value = min; else if (value > max) value = max; +} + } // namespace math #endif // __INCLUDED_MATH_FUNCTIONS_H__ -- cgit v1.2.3