/* client/camera.cc This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include "client/client.h" #include "client/camera.h" #include "render/render.h" #include "math/mathlib.h" using math::degrees360f; using math::degrees180f; using namespace render; namespace client { namespace camera { // public variables // camera target math::Vector3f target; // target yaw, angle in XZ plane, positive is looking left float yaw_target; // target pitch, angle in XZ plane, positive is looking left float pitch_target; // distance from the camera to the target float distance; // current camera mode Mode mode; // private variables // current yaw, angle in XZ plane, positive is looking left float yaw_current; // current pitch, angle in XY, positive is looking up float pitch_current; // default pitch in mode::Track float pitch_track; // default pitch in mode::Overview float pitch_overview; // default offset increment float offset_inc; void init() { pitch_overview = -60.0f; pitch_track = -15.0f; offset_inc = 5.0f; yaw_current = 0; yaw_target = 0; pitch_current = pitch_track * 2; pitch_target = pitch_track; distance = 0.4f; mode = Track; } void shutdown() { } void draw(float elapsed) { // TODO camera needs to get this from selected core entity if (mode == Track) { yaw_target = game.ship.yaw(); } // adjust yaw float d = degrees180f(yaw_current - yaw_target); yaw_current = degrees360f( yaw_current - d * elapsed) ; // adjust pitch target d = degrees180f(pitch_current - pitch_target); pitch_current = degrees360f( pitch_current - d *elapsed); switch (mode) { case Free: gl::translate(1.0f+distance, -distance/2, 0.0f); gl::rotate(-pitch_current, 0, 0, 1.0f); gl::rotate(-yaw_current, 0, 1.0f, 0); break; case Track: gl::translate(1.0f+distance, -distance , 0.0f); gl::rotate(-pitch_current, 0, 0, 1.0f); gl::rotate(-yaw_current, 0, 1.0f, 0); break; case Overview: gl::translate(-distance/2, -distance, 0.0f); gl::rotate(-pitch_current, 0, 0, 1.0f); gl::rotate(-yaw_current, 0, 1.0f, 0); break; default: break; } } void rotate_right() { if (mode == Free || mode == Overview) { yaw_target = degrees360f( yaw_target + offset_inc); } } void rotate_left() { if (mode == Free || mode == Overview) { yaw_target = degrees360f( yaw_target - offset_inc); } } void rotate_up() { if (mode == Free) { pitch_target = pitch_target - offset_inc; if (pitch_target < -90.0f) pitch_target = -90.0f; } } void rotate_down() { if (mode == Free) { pitch_target = pitch_target + offset_inc; if (pitch_target > 90.0f) pitch_target = 90.0f; } } void nextmode() { switch(mode) { case Overview: // switch camera to Track mode mode = Track; yaw_target = game.ship.yaw(); yaw_current = yaw_target; pitch_target = pitch_track; pitch_current = pitch_target; distance = 0.4f; break; case Track: // switch camera to Free mode mode = Free; yaw_target = game.ship.yaw(); yaw_current = yaw_target; pitch_target = pitch_track; pitch_current = pitch_target; distance = 0.4f; break; case Free: // switch camera to Overview mode mode = Overview; yaw_target = 0; yaw_current = 0; pitch_target = pitch_overview; pitch_current = pitch_target; distance = 10.0f; default: break; } } } // namespace camera } // namespace client