/* 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 "math/mathlib.h" #include "core/core.h" #include "client/client.h" #include "client/camera.h" #include "render/render.h" using math::degrees360f; using math::degrees180f; using namespace render; namespace client { namespace camera { // public variables // gameworld coordinates of the camera target math::Vector3f target; // gameworld coordinates of the camera eye math::Vector3f eye; // 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::Overview float pitch_overview; // current x offset float x_offset; // current z offset float z_offset; // default pitch in mode::Track const float pitch_track = 0.0f; // 15.0f; // default rotate offset increase/decrease float rotate_offset_inc; // default translate offset increase/decrease const float translate_offset_inc = 0.1; void init() { rotate_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 set_mode(Mode newmode) { switch(newmode) { case Track: // switch camera to Track mode mode = Track; yaw_target = core::localcontrol()->direction(); 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 = core::localcontrol()->direction(); yaw_current = yaw_target; pitch_target = pitch_track; pitch_current = pitch_target; distance = 0.4f; break; case Overview: // switch camera to Overview mode mode = Overview; x_offset = 0; z_offset = 0; distance = 20.0f; default: break; } } void next_mode() { if (!core::localcontrol()) { set_mode(Overview); return; } switch(mode) { case Free: // switch camera to Track mode set_mode(Track); break; case Track: // switch camera to Free mode set_mode(Free); break; default: break; } } void draw(float elapsed) { if (!core::localcontrol()) { // switch the camera to Overview of the player is not controling anything if (mode != Overview) { set_mode(Overview); camera::target = math::Vector3f(0,0,0); } } else { if (mode == Overview) set_mode(Track); camera::target = core::localcontrol()->location(); } if (mode == Track) { yaw_target = core::localcontrol()->direction(); } if ((mode == Free) || (mode == Track)) { // 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); } // map world coordinates to opengl coordinates gl::rotate(90.0f, 0, 1.0, 0); gl::rotate(-90.0f, 1.0f , 0, 0); // map camera coordinates to opengl coordinates switch (mode) { case Free: case Track: if (core::localcontrol()->model()) distance = core::localcontrol()->model()->radius(); else distance = 0.5f; // draw the camera transformation gl::translate(0.0f, 0.0f, -3*distance/4); gl::translate(1.2+distance, 0.0f, 0.0f); gl::rotate(-pitch_current, 0.0f, 1.0f, 0.0f); gl::rotate(-yaw_current, 0.0f, 0.0f, 1.0f); gl::translate(-1*target); break; case Overview: eye = target; eye.z = eye.z + distance-1; gl::rotate(-75.0f, 0.0f, 1.0f, 0.0f); gl::translate(0.0f, 0.0f, -distance); //gl::translate(x_offset, 0.0f, z_offset); gl::translate(-1*target); break; default: break; } } void key_right() { if (mode == Free) { yaw_target = degrees360f( yaw_target + rotate_offset_inc); } else if (mode == Overview) { z_offset += translate_offset_inc; } } void key_left() { if (mode == Free) { yaw_target = degrees360f( yaw_target - rotate_offset_inc); } else if (mode == Overview) { z_offset -= translate_offset_inc; } } void key_up() { if (mode == Free) { pitch_target = pitch_target + rotate_offset_inc; if (pitch_target > 90.0f) pitch_target = 90.0f; } else if (mode == Overview) { x_offset += translate_offset_inc; } } void key_down() { if (mode == Free) { pitch_target = pitch_target - rotate_offset_inc; if (pitch_target < -90.0f) pitch_target = -90.0f; } else if (mode == Overview) { x_offset -= translate_offset_inc; } } } // namespace camera } // namespace client