]> git.tdb.fi Git - r2c2.git/blobdiff - source/designer/cameracontroller.cpp
Use a GL::Camera
[r2c2.git] / source / designer / cameracontroller.cpp
diff --git a/source/designer/cameracontroller.cpp b/source/designer/cameracontroller.cpp
new file mode 100644 (file)
index 0000000..fb16bb8
--- /dev/null
@@ -0,0 +1,99 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <cmath>
+#include <msp/input/keys.h>
+#include "cameracontroller.h"
+
+using namespace std;
+using namespace Msp;
+
+CameraController::CameraController(Graphics::Window &w, GL::Camera &c):
+       window(w),
+       camera(c),
+       move_x(0),
+       move_y(0),
+       zoom(0),
+       rotate(0),
+       pitch(0)
+{
+       window.signal_key_press.connect(sigc::mem_fun(this, &CameraController::key_press));
+       window.signal_key_release.connect(sigc::mem_fun(this, &CameraController::key_release));
+}
+
+void CameraController::tick(float dt)
+{
+       if(!move_x && !move_y && !zoom && !rotate && !pitch)
+               return;
+
+       GL::Vector3 pos = camera.get_position();
+       GL::Vector3 look = camera.get_look_direction();
+       float xy_len = sqrt(look.x*look.x+look.y*look.y);
+       GL::Vector3 look_xy(look.x/xy_len, look.y/xy_len, 0);
+       GL::Vector3 ground(pos.x-look.x*pos.z/look.z, pos.y-look.y*pos.z/look.z, 0);
+
+       if(rotate || pitch)
+       {
+               float speed = -3*dt*xy_len*pos.z/look.z;
+               pos.x += (look_xy.y*rotate - look_xy.x*look.z*pitch)*speed;
+               pos.y += (-look_xy.x*rotate - look_xy.y*look.z*pitch)*speed;
+               pos.z += xy_len*pitch*speed;
+               camera.set_position(pos);
+               camera.look_at(ground);
+       }
+
+       if(move_x || move_y || zoom)
+       {
+               float zoom_speed = -zoom*pos.z/look.z;
+               pos.x += (look_xy.x*move_y + look_xy.y*move_x + look.x*zoom_speed)*dt;
+               pos.y += (look_xy.y*move_y - look_xy.x*move_x + look.y*zoom_speed)*dt;
+               pos.z += look.z*dt*zoom_speed;
+               camera.set_position(pos);
+       }
+}
+
+void CameraController::key_press(unsigned code, unsigned, wchar_t)
+{
+       unsigned key = Msp::Input::key_from_sys(code);
+
+       if(key==Msp::Input::KEY_RIGHT)
+               rotate = -1;
+       else if(key==Msp::Input::KEY_LEFT)
+               rotate = 1;
+       else if(key==Msp::Input::KEY_UP)
+               move_y = 1;
+       else if(key==Msp::Input::KEY_DOWN)
+               move_y = -1;
+       else if(key==Msp::Input::KEY_INSERT)
+               zoom = -1;
+       else if(key==Msp::Input::KEY_PGUP)
+               zoom = 1;
+       else if(key==Msp::Input::KEY_HOME)
+               pitch = 1;
+       else if(key==Msp::Input::KEY_END)
+               pitch = -1;
+       else if(key==Msp::Input::KEY_DELETE)
+               move_x = -1;
+       else if(key==Msp::Input::KEY_PGDN)
+               move_x = 1;
+}
+
+void CameraController::key_release(unsigned code, unsigned)
+{
+       unsigned key = Msp::Input::key_from_sys(code);
+
+       if(key==Msp::Input::KEY_RIGHT || key==Msp::Input::KEY_LEFT)
+               rotate = 0;
+       else if(key==Msp::Input::KEY_UP || key==Msp::Input::KEY_DOWN)
+               move_y = 0;
+       else if(key==Msp::Input::KEY_INSERT || key==Msp::Input::KEY_PGUP)
+               zoom = 0;
+       else if(key==Msp::Input::KEY_HOME || key==Msp::Input::KEY_END)
+               pitch = 0;
+       else if(key==Msp::Input::KEY_DELETE || key==Msp::Input::KEY_PGDN)
+               move_x = 0;
+}