+void CameraController::top_down()
+{
+ const GL::Vector3 &look = camera.get_look_direction();
+ float xy_len = sqrt(look.x*look.x+look.y*look.y);
+ set_look_direction(GL::Vector3(look.x*0.01/xy_len, look.y*0.01/xy_len, -0.99995));
+}
+
+void CameraController::set_look_direction(const GL::Vector3 &look)
+{
+ GL::Vector3 focus = get_focus();
+ float dist = get_distance();
+ camera.set_look_direction(look);
+ camera.set_position(GL::Vector3(focus.x-look.x*dist, focus.y-look.y*dist, focus.z-look.z*dist));
+}
+
+void CameraController::view_all()
+{
+ Point minp;
+ Point maxp;
+
+ const Layout3D::TrackMap &tracks = designer.get_layout_3d().get_tracks();
+ for(Layout3D::TrackMap::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ {
+ Point tmin;
+ Point tmax;
+ i->second->get_bounds(0, tmin, tmax);
+ minp.x = min(minp.x, tmin.x);
+ minp.y = min(minp.y, tmin.y);
+ maxp.x = max(maxp.x, tmax.x);
+ maxp.y = max(maxp.y, tmax.y);
+ }
+
+ float t = tan(camera.get_field_of_view()/2)*2;
+ float size = max((maxp.y-minp.y+0.1), (maxp.x-minp.x+0.1)/camera.get_aspect());
+ float dist = size/t+size*0.25;
+ GL::Vector3 center((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, 0);
+ const GL::Vector3 &look = camera.get_look_direction();
+ camera.set_position(GL::Vector3(center.x-look.x*dist, center.y-look.y*dist, center.z-look.z*dist));
+}
+
+void CameraController::move(float x, float y)
+{
+ const GL::Vector3 &pos = camera.get_position();
+ const GL::Vector3 &look = camera.get_look_direction();
+ float xy_len = sqrt(look.x*look.x+look.y*look.y);
+ float dx = (look.x*y+look.y*x)/xy_len;
+ float dy = (look.y*y-look.x*x)/xy_len;
+ camera.set_position(GL::Vector3(pos.x+dx, pos.y+dy, pos.z));
+}
+
+void CameraController::adjust_distance(float delta)
+{
+ const GL::Vector3 &pos = camera.get_position();
+ const GL::Vector3 &look = camera.get_look_direction();
+ camera.set_position(GL::Vector3(pos.x-look.x*delta, pos.y-look.y*delta, pos.z-look.z*delta));
+}
+
+void CameraController::rotate(float angle)