]> git.tdb.fi Git - r2c2.git/blob - source/designer/cameracontroller.cpp
Halt all trains in various unexpected situations
[r2c2.git] / source / designer / cameracontroller.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <cmath>
9 #include <msp/input/keys.h>
10 #include "cameracontroller.h"
11
12 using namespace std;
13 using namespace Msp;
14
15 CameraController::CameraController(Graphics::Window &w, GL::Camera &c):
16         window(w),
17         camera(c),
18         move_x(0),
19         move_y(0),
20         zoom(0),
21         rotate(0),
22         pitch(0)
23 {
24         window.signal_key_press.connect(sigc::mem_fun(this, &CameraController::key_press));
25         window.signal_key_release.connect(sigc::mem_fun(this, &CameraController::key_release));
26 }
27
28 void CameraController::tick(float dt)
29 {
30         if(!move_x && !move_y && !zoom && !rotate && !pitch)
31                 return;
32
33         GL::Vector3 pos = camera.get_position();
34         GL::Vector3 look = camera.get_look_direction();
35         float xy_len = sqrt(look.x*look.x+look.y*look.y);
36         GL::Vector3 look_xy(look.x/xy_len, look.y/xy_len, 0);
37         GL::Vector3 ground(pos.x-look.x*pos.z/look.z, pos.y-look.y*pos.z/look.z, 0);
38
39         if(rotate || pitch)
40         {
41                 float speed = -3*dt*xy_len*pos.z/look.z;
42                 pos.x += (look_xy.y*rotate - look_xy.x*look.z*pitch)*speed;
43                 pos.y += (-look_xy.x*rotate - look_xy.y*look.z*pitch)*speed;
44                 pos.z += xy_len*pitch*speed;
45                 camera.set_position(pos);
46                 camera.look_at(ground);
47         }
48
49         if(move_x || move_y || zoom)
50         {
51                 float zoom_speed = -zoom*pos.z/look.z;
52                 pos.x += (look_xy.x*move_y + look_xy.y*move_x + look.x*zoom_speed)*dt;
53                 pos.y += (look_xy.y*move_y - look_xy.x*move_x + look.y*zoom_speed)*dt;
54                 pos.z += look.z*dt*zoom_speed;
55                 camera.set_position(pos);
56         }
57 }
58
59 void CameraController::key_press(unsigned code, unsigned, wchar_t)
60 {
61         unsigned key = Msp::Input::key_from_sys(code);
62
63         if(key==Msp::Input::KEY_RIGHT)
64                 rotate = -1;
65         else if(key==Msp::Input::KEY_LEFT)
66                 rotate = 1;
67         else if(key==Msp::Input::KEY_UP)
68                 move_y = 1;
69         else if(key==Msp::Input::KEY_DOWN)
70                 move_y = -1;
71         else if(key==Msp::Input::KEY_INSERT)
72                 zoom = -1;
73         else if(key==Msp::Input::KEY_PGUP)
74                 zoom = 1;
75         else if(key==Msp::Input::KEY_HOME)
76                 pitch = 1;
77         else if(key==Msp::Input::KEY_END)
78                 pitch = -1;
79         else if(key==Msp::Input::KEY_DELETE)
80                 move_x = -1;
81         else if(key==Msp::Input::KEY_PGDN)
82                 move_x = 1;
83 }
84
85 void CameraController::key_release(unsigned code, unsigned)
86 {
87         unsigned key = Msp::Input::key_from_sys(code);
88
89         if(key==Msp::Input::KEY_RIGHT || key==Msp::Input::KEY_LEFT)
90                 rotate = 0;
91         else if(key==Msp::Input::KEY_UP || key==Msp::Input::KEY_DOWN)
92                 move_y = 0;
93         else if(key==Msp::Input::KEY_INSERT || key==Msp::Input::KEY_PGUP)
94                 zoom = 0;
95         else if(key==Msp::Input::KEY_HOME || key==Msp::Input::KEY_END)
96                 pitch = 0;
97         else if(key==Msp::Input::KEY_DELETE || key==Msp::Input::KEY_PGDN)
98                 move_x = 0;
99 }