2 #include <msp/input/keys.h>
4 #include "cameracontroller.h"
10 CameraController::CameraController(View3D &v, Input::Keyboard &k, Input::Mouse &m):
14 camera(view.get_camera()),
21 mouse.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &CameraController::button_press), false));
22 mouse.signal_button_release.connect(sigc::bind_return(sigc::mem_fun(this, &CameraController::button_release), false));
23 mouse.signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &CameraController::axis_motion), false));
24 keyboard.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &CameraController::key_press), false));
25 keyboard.signal_button_release.connect(sigc::bind_return(sigc::mem_fun(this, &CameraController::key_release), false));
28 void CameraController::top_down()
30 const GL::Vector3 &look = camera.get_look_direction();
31 float xy_len = sqrt(look.x*look.x+look.y*look.y);
32 set_look_direction(GL::Vector3(look.x*0.01/xy_len, look.y*0.01/xy_len, -0.99995));
35 void CameraController::set_look_direction(const GL::Vector3 &look)
37 GL::Vector3 focus = get_focus();
38 float dist = get_distance();
39 camera.set_look_direction(look);
40 camera.set_position(focus-look*dist);
43 void CameraController::view_all()
48 void CameraController::move(float x, float y)
50 const GL::Vector3 &pos = camera.get_position();
51 const GL::Vector3 &look = camera.get_look_direction();
52 GL::Vector3 fwd_dir = normalize(GL::Vector3(look.x, look.y, 0));
53 GL::Vector3 right_dir = cross(fwd_dir, GL::Vector3(0, 0, 1));
54 camera.set_position(pos+fwd_dir*y+right_dir*x);
57 void CameraController::adjust_distance(float delta)
59 const GL::Vector3 &pos = camera.get_position();
60 const GL::Vector3 &look = camera.get_look_direction();
61 float dist = get_distance();
62 // XXX This should probably depend on the layout contents in some way
66 camera.set_position(pos-look*delta);
68 camera.set_depth_clip(dist*0.02, dist*50);
71 void CameraController::rotate(const Angle &angle)
73 GL::Vector3 look = camera.get_look_direction();
74 set_look_direction(rotated_vector(look, angle));
77 void CameraController::pitch(const Angle &angle)
79 GL::Vector3 look = camera.get_look_direction();
80 float xy_len = sqrt(look.x*look.x+look.y*look.y);
83 if(xy_len*c-look.z*s<0.01)
85 else if(xy_len*s+look.z*c>-0.01)
86 set_look_direction(GL::Vector3(look.x*0.99995/xy_len, look.y*0.99995/xy_len, -0.01));
89 float xy_scale = (xy_len*c-look.z*s)/xy_len;
90 set_look_direction(GL::Vector3(look.x*xy_scale, look.y*xy_scale, xy_len*s+look.z*c));
94 void CameraController::tick(float dt)
98 float scale = get_view_scale()*dt;
99 move(move_x*scale, move_y*scale);
103 void CameraController::button_press(unsigned btn)
108 drag_mode = DISTANCE;
110 drag_mode = ((btn==2)==shift_pressed ? ROTATE : PAN);
114 adjust_distance(-get_distance()*0.1);
118 adjust_distance(get_distance()*0.1);
122 void CameraController::button_release(unsigned btn)
128 void CameraController::axis_motion(unsigned axis, float, float change)
132 float dx = (axis==0 ? change : 0);
133 float dy = (axis==1 ? change : 0);
134 float scale = get_view_scale();
135 move(-dx*scale, -dy*scale);
137 else if(drag_mode==ROTATE)
140 rotate(Angle::from_turns(-change/2));
142 pitch(Angle::from_turns(change/4));
144 else if(drag_mode==DISTANCE && axis==1)
145 adjust_distance(-change*3*get_distance());
148 void CameraController::key_press(unsigned key)
150 if(key==Msp::Input::KEY_RIGHT)
152 else if(key==Msp::Input::KEY_LEFT)
154 else if(key==Msp::Input::KEY_UP)
156 else if(key==Msp::Input::KEY_DOWN)
158 else if(key==Msp::Input::KEY_HOME)
160 else if(key==Msp::Input::KEY_INSERT)
162 else if(key==Msp::Input::KEY_SHIFT_L || key==Msp::Input::KEY_SHIFT_R)
163 shift_pressed = true;
164 else if(key==Msp::Input::KEY_CTRL_L || key==Msp::Input::KEY_CTRL_R)
168 void CameraController::key_release(unsigned key)
170 if(key==Msp::Input::KEY_RIGHT || key==Msp::Input::KEY_LEFT)
172 else if(key==Msp::Input::KEY_UP || key==Msp::Input::KEY_DOWN)
174 else if(key==Msp::Input::KEY_SHIFT_L || key==Msp::Input::KEY_SHIFT_R)
175 shift_pressed = false;
176 else if(key==Msp::Input::KEY_CTRL_L || key==Msp::Input::KEY_CTRL_R)
177 ctrl_pressed = false;
180 GL::Vector3 CameraController::get_focus() const
182 const GL::Vector3 &pos = camera.get_position();
183 const GL::Vector3 &look = camera.get_look_direction();
184 float dist = get_distance();
185 return GL::Vector3(pos.x+look.x*dist, pos.y+look.y*dist, pos.z+look.z*dist);
188 float CameraController::get_distance() const
190 return -camera.get_position().z/camera.get_look_direction().z;
193 float CameraController::get_view_scale() const
195 float t = tan(camera.get_field_of_view()/2.0f)*2.0f;
196 return get_distance()*t;