using namespace Msp;
using namespace R2C2;
-CameraController::CameraController(View3D &v, Graphics::EventSource &es):
+CameraController::CameraController(View3D &v, Input::Keyboard &k, Input::Mouse &m):
view(v),
- event_source(es),
+ keyboard(k),
+ mouse(m),
camera(view.get_camera()),
move_x(0),
move_y(0),
+ shift_pressed(false),
+ ctrl_pressed(false),
drag_mode(NONE)
{
- event_source.signal_button_press.connect(sigc::mem_fun(this, &CameraController::button_press));
- event_source.signal_button_release.connect(sigc::mem_fun(this, &CameraController::button_release));
- event_source.signal_pointer_motion.connect(sigc::mem_fun(this, &CameraController::pointer_motion));
- event_source.signal_key_press.connect(sigc::mem_fun(this, &CameraController::key_press));
- event_source.signal_key_release.connect(sigc::mem_fun(this, &CameraController::key_release));
+ mouse.signal_button_press.connect(sigc::mem_fun(this, &CameraController::button_press));
+ mouse.signal_button_release.connect(sigc::mem_fun(this, &CameraController::button_release));
+ mouse.signal_axis_motion.connect(sigc::mem_fun(this, &CameraController::axis_motion));
+ keyboard.signal_button_press.connect(sigc::mem_fun(this, &CameraController::key_press));
+ keyboard.signal_button_release.connect(sigc::mem_fun(this, &CameraController::key_release));
}
void CameraController::top_down()
}
}
-void CameraController::button_press(int x, int y, unsigned btn, unsigned mod)
+void CameraController::button_press(unsigned btn)
{
- mod = Input::mod_from_sys(mod);
if(btn==2 || btn==3)
{
- if(mod&Input::MOD_CONTROL)
+ if(ctrl_pressed)
drag_mode = DISTANCE;
else
- drag_mode = ((btn==2)==((mod&Input::MOD_SHIFT)!=0) ? ROTATE : PAN);
-
- pointer_x = x;
- pointer_y = y;
+ drag_mode = ((btn==2)==shift_pressed ? ROTATE : PAN);
}
else if(btn==4)
{
}
}
-void CameraController::button_release(int, int, unsigned btn, unsigned)
+void CameraController::button_release(unsigned btn)
{
if(btn==2 || btn==3)
drag_mode = NONE;
}
-void CameraController::pointer_motion(int x, int y)
+void CameraController::axis_motion(unsigned axis, float, float change)
{
- if(drag_mode!=NONE)
+ if(drag_mode==PAN)
+ {
+ float dx = (axis==0 ? change : 0);
+ float dy = (axis==1 ? change : 0);
+ float scale = get_view_scale();
+ move(-dx*scale, -dy*scale);
+ }
+ else if(drag_mode==ROTATE)
{
- int dx = x-pointer_x;
- int dy = y-pointer_y;
-
- if(drag_mode==PAN)
- {
- float scale = get_view_scale()/event_source.get_height();
- move(-dx*scale, dy*scale);
- }
- else if(drag_mode==ROTATE)
- {
- rotate(-dx*M_PI*2/event_source.get_width());
- pitch(-dy*M_PI/event_source.get_height());
- }
- else if(drag_mode==DISTANCE)
- adjust_distance(dy*3*get_distance()/event_source.get_height());
-
- pointer_x = x;
- pointer_y = y;
+ if(axis==0)
+ rotate(-change*M_PI);
+ else if(axis==1)
+ pitch(change*M_PI/2);
}
+ else if(drag_mode==DISTANCE && axis==1)
+ adjust_distance(-change*3*get_distance());
}
-void CameraController::key_press(unsigned code, unsigned, wchar_t)
+void CameraController::key_press(unsigned key)
{
- unsigned key = Msp::Input::key_from_sys(code);
-
if(key==Msp::Input::KEY_RIGHT)
move_x = 1;
else if(key==Msp::Input::KEY_LEFT)
view_all();
else if(key==Msp::Input::KEY_INSERT)
top_down();
+ else if(key==Msp::Input::KEY_SHIFT_L || key==Msp::Input::KEY_SHIFT_R)
+ shift_pressed = true;
+ else if(key==Msp::Input::KEY_CTRL_L || key==Msp::Input::KEY_CTRL_R)
+ ctrl_pressed = true;
}
-void CameraController::key_release(unsigned code, unsigned)
+void CameraController::key_release(unsigned key)
{
- unsigned key = Msp::Input::key_from_sys(code);
-
if(key==Msp::Input::KEY_RIGHT || key==Msp::Input::KEY_LEFT)
move_x = 0;
else if(key==Msp::Input::KEY_UP || key==Msp::Input::KEY_DOWN)
move_y = 0;
+ else if(key==Msp::Input::KEY_SHIFT_L || key==Msp::Input::KEY_SHIFT_R)
+ shift_pressed = false;
+ else if(key==Msp::Input::KEY_CTRL_L || key==Msp::Input::KEY_CTRL_R)
+ ctrl_pressed = false;
}
GL::Vector3 CameraController::get_focus() const
#include <msp/graphics/window.h>
#include <msp/gl/camera.h>
+#include <msp/input/keyboard.h>
+#include <msp/input/mouse.h>
#include "3d/view.h"
/**
};
R2C2::View3D &view;
- Msp::Graphics::EventSource &event_source;
+ Msp::Input::Keyboard &keyboard;
+ Msp::Input::Mouse &mouse;
Msp::GL::Camera &camera;
int move_x;
int move_y;
int pointer_x;
int pointer_y;
+ bool shift_pressed;
+ bool ctrl_pressed;
DragMode drag_mode;
public:
- CameraController(R2C2::View3D &, Msp::Graphics::EventSource &);
+ CameraController(R2C2::View3D &, Msp::Input::Keyboard &, Msp::Input::Mouse &);
void top_down();
void set_look_direction(const Msp::GL::Vector3 &);
void tick(float);
private:
- void button_press(int, int, unsigned, unsigned);
- void button_release(int, int, unsigned, unsigned);
- void pointer_motion(int, int);
- void key_press(unsigned, unsigned, wchar_t);
- void key_release(unsigned, unsigned);
+ void button_press(unsigned);
+ void button_release(unsigned);
+ void axis_motion(unsigned, float, float);
+ void key_press(unsigned);
+ void key_release(unsigned);
public:
/** Return the focus point, i.e. where the look ray intersects with ground. */
Designer::Designer(int argc, char **argv):
window(1280, 960),
+ keyboard(window),
+ mouse(window),
ui_res("r2c2.res"),
root(ui_res, window),
base_object(0),
cur_route(0),
cur_zone(0),
mode(SELECT),
- manipulator(*this, root, selection),
+ manipulator(*this, mouse, selection),
measure(*this)
{
window.set_title("Railway Designer");
pipeline->add_renderable_for_pass(layout_3d->get_endpoint_scene(), "unlit");
// Setup UI
- root.signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press));
- root.signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
- root.signal_pointer_motion.connect(sigc::mem_fun(this, &Designer::pointer_motion));
+ keyboard.signal_button_press.connect(sigc::mem_fun(this, &Designer::key_press));
+ mouse.signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
+ mouse.signal_axis_motion.connect(sigc::mem_fun(this, &Designer::axis_motion));
root.signal_tooltip.connect(sigc::mem_fun(this, &Designer::tooltip));
toolbars.push_back(new Layoutbar(*this));
overlay = new Overlay3D(ui_res.get_default_font());
pipeline->add_renderable_for_pass(*overlay, "overlay");
- camera_ctl = new CameraController(*main_view, root);
+ camera_ctl = new CameraController(*main_view, keyboard, mouse);
cat_view->get_camera().set_look_direction(GL::Vector3(0, 0.13053, -0.99144));
cat_view->view_all(true);
main_view->view_all();
show_zone(*cur_zone);
}
-Vector Designer::map_pointer_to_ground(int x, int y)
+Vector Designer::map_pointer_to_ground(const Vector &p)
{
- float xf = x*2.0/window.get_width()-1.0;
- float yf = y*2.0/window.get_height()-1.0;
- GL::Vector4 vec = main_view->get_camera().unproject(GL::Vector4(xf, yf, 0, 0));
+ GL::Vector4 vec = main_view->get_camera().unproject(GL::Vector4(p.x, p.y, 0, 0));
const GL::Vector3 &pos = main_view->get_camera().get_position();
return Vector(pos.x-vec.x*pos.z/vec.z, pos.y-vec.y*pos.z/vec.z);
window.swap_buffers();
}
-void Designer::key_press(unsigned key, unsigned mod, wchar_t)
+void Designer::key_press(unsigned key)
{
- key = Input::key_from_sys(key);
- mod = Input::mod_from_sys(mod);
+ bool shift = keyboard.get_button_state(Input::KEY_SHIFT_L) || keyboard.get_button_state(Input::KEY_SHIFT_R);
- if(key==Msp::Input::KEY_N && (mod&Input::MOD_SHIFT))
+ if(key==Msp::Input::KEY_N && shift)
extend_track();
else if(key==Msp::Input::KEY_N)
new_track();
save();
else if(key==Msp::Input::KEY_PLUS)
selection.select_more();
- else if(key==Msp::Input::KEY_L && (mod&Input::MOD_SHIFT))
+ else if(key==Msp::Input::KEY_L && shift)
selection.select_blocks();
else if(key==Msp::Input::KEY_L)
selection.select_linked();
}
else if(key==Msp::Input::KEY_X)
erase_tracks();
- else if(key==Msp::Input::KEY_F && (mod&Input::MOD_SHIFT))
+ else if(key==Msp::Input::KEY_F && shift)
{
const set<Track *> &tracks = selection.get_tracks();
const set<Track *> <racks = layout->get_tracks();
}
else if(key==Msp::Input::KEY_F)
flatten_tracks();
- else if(key==Msp::Input::KEY_E && (mod&Input::MOD_SHIFT))
+ else if(key==Msp::Input::KEY_E && shift)
manipulator.even_slope(true);
else if(key==Msp::Input::KEY_E)
manipulator.even_slope();
track_properties();
}
-void Designer::button_press(int x, int y, unsigned btn, unsigned mod)
+void Designer::button_press(unsigned btn)
{
- y = window.get_height()-y-1;
- mod = Input::mod_from_sys(mod);
+ bool shift = keyboard.get_button_state(Input::KEY_SHIFT_L) || keyboard.get_button_state(Input::KEY_SHIFT_R);
- Vector ground = map_pointer_to_ground(x, y);
+ Vector pointer(mouse.get_axis_value(0), mouse.get_axis_value(1));
+ Vector ground = map_pointer_to_ground(pointer);
if(mode==CATALOGUE)
{
if(btn==1)
{
- Track *ctrack = pick_track(x, y);
+ Track *ctrack = pick_track(pointer);
if(ctrack)
{
Track *track = new Track(*layout, ctrack->get_type());
{
if(btn==1)
{
- Track *track = pick_track(x, y);
+ Track *track = pick_track(pointer);
if(track)
{
- if(!(mod&Input::MOD_SHIFT))
+ if(!shift)
selection.clear();
selection.toggle_track(track);
}
}
}
else if(mode==MEASURE)
- measure.button_press(x, y, ground.x, ground.y, btn);
+ measure.button_press(ground.x, ground.y, btn);
}
-void Designer::pointer_motion(int x, int y)
+void Designer::axis_motion(unsigned, float, float)
{
- y = window.get_height()-y-1;
+ Vector pointer(mouse.get_axis_value(0), mouse.get_axis_value(1));
+ float wx = pointer.x*window.get_width();
+ float wy = pointer.y*window.get_height();
- if(!root.get_child_at(x, y))
+ if(!root.get_child_at(wx, wy))
{
- Vector ground = map_pointer_to_ground(x, y);
- measure.pointer_motion(x, y, ground.x, ground.y);
+ Vector ground = map_pointer_to_ground(pointer);
+ measure.pointer_motion(ground.x, ground.y);
}
}
new_tracks.erase(i);
}
-Track *Designer::pick_track(int x, int y)
+Track *Designer::pick_track(const Vector &pointer)
{
- float xx = x*2.0/window.get_width()-1.0;
- float yy = y*2.0/window.get_height()-1.0;
-
View3D &view = *(mode==CATALOGUE ? cat_view : main_view);
const GL::Vector3 &cpos = view.get_camera().get_position();
- GL::Vector4 cray = view.get_camera().unproject(GL::Vector4(xx, yy, 0, 0));
+ GL::Vector4 cray = view.get_camera().unproject(GL::Vector4(pointer.x, pointer.y, 0, 0));
return view.get_layout().get_layout().pick_track(Vector(cpos.x, cpos.y, cpos.z), Vector(cray.x, cray.y, cray.z));
}
string Designer::tooltip(int x, int y)
{
- if(Track *track = pick_track(x, y))
+ if(Track *track = pick_track(Vector(x*2.0f/window.get_width()-1.0f, y*2.0f/window.get_height()-1.0f, 0)))
{
const TrackType &ttype = track->get_type();
string info = format("%d %s", ttype.get_article_number(), ttype.get_description());
};
Msp::Graphics::SimpleGLWindow window;
+ Msp::Input::Keyboard keyboard;
+ Msp::Input::Mouse mouse;
Msp::GLtk::Resources ui_res;
Msp::GLtk::Root root;
R2C2::Zone *get_current_zone() const { return cur_zone; }
void add_selection_to_zone();
- R2C2::Vector map_pointer_to_ground(int, int);
+ R2C2::Vector map_pointer_to_ground(const R2C2::Vector &);
private:
void tick();
- void key_press(unsigned, unsigned, wchar_t);
- void button_press(int, int, unsigned, unsigned);
- void pointer_motion(int, int);
+ void key_press(unsigned);
+ void button_press(unsigned);
+ void axis_motion(unsigned, float, float);
void apply_camera();
void render();
void track_added(R2C2::Track &);
void track_removed(R2C2::Track &);
- R2C2::Track *pick_track(int, int);
+ R2C2::Track *pick_track(const R2C2::Vector &);
void update_track_icon(R2C2::Track3D &);
void selection_changed();
void manipulation_status(const std::string &);
entry->set_focus();
}
-void InputDialog::key_press(unsigned key, unsigned mod, wchar_t ch)
+void InputDialog::key_press(unsigned key, unsigned mod)
{
if(key==Msp::Input::KEY_ENTER)
response(1);
else if(key==Msp::Input::KEY_ESC)
response(0);
else
- Dialog::key_press(key, mod, ch);
+ Dialog::key_press(key, mod);
}
void InputDialog::on_response(int code)
public:
InputDialog(Designer &, const std::string &, const std::string & =std::string());
private:
- virtual void key_press(unsigned, unsigned, wchar_t);
+ virtual void key_press(unsigned, unsigned);
virtual void on_response(int);
};
using namespace R2C2;
using namespace Msp;
-Manipulator::Manipulator(Designer &d, Graphics::EventSource &es, Selection &s):
+Manipulator::Manipulator(Designer &d, Input::Mouse &m, Selection &s):
designer(d),
- event_source(es),
+ mouse(m),
selection(s),
mode(NONE),
angle(0)
{
- event_source.signal_button_press.connect(sigc::mem_fun(this, &Manipulator::button_press));
- event_source.signal_pointer_motion.connect(sigc::mem_fun(this, &Manipulator::pointer_motion));
+ mouse.signal_button_press.connect(sigc::mem_fun(this, &Manipulator::button_press));
+ mouse.signal_axis_motion.connect(sigc::mem_fun(this, &Manipulator::axis_motion));
selection.signal_changed.connect(sigc::mem_fun(this, &Manipulator::selection_changed));
}
if(mode)
cancel();
- elev_origin = pointer_y;
-
mode = ELEVATE;
}
signal_done.emit(false);
}
-void Manipulator::button_press(int, int, unsigned btn, unsigned)
+void Manipulator::button_press(unsigned btn)
{
if(!mode)
return;
}
}
-void Manipulator::pointer_motion(int x, int y)
+void Manipulator::axis_motion(unsigned axis, float value, float change)
{
- pointer_y = event_source.get_height()-1-y;
- gpointer = designer.map_pointer_to_ground(x, pointer_y);
+ if(axis==0)
+ pointer.x = value;
+ else if(axis==1)
+ pointer.y = value;
+ gpointer = designer.map_pointer_to_ground(pointer);
if(mode==MOVE)
{
const set<Track *> <racks = designer.get_layout().get_tracks();
float limit = max(designer.get_layout().get_catalogue().get_gauge(),
- designer.get_camera_controller().get_view_scale()*5/event_source.get_height());
+ designer.get_camera_controller().get_view_scale()/100.0f);
MTrack *snapped = 0;
for(set<Track *>::const_iterator i=ltracks.begin(); (i!=ltracks.end() && !snapped); ++i)
{
i->track->set_rotation(angle+i->rot);
}
}
- else if(mode==ELEVATE)
+ else if(mode==ELEVATE && axis==1)
{
- float dz = (pointer_y-elev_origin)/1000.;
+ float dz = -change;
signal_status.emit(format("Elevation: %+.0fmm (%.0fmm)", dz*1000, (center.z+dz)*1000));
private:
Designer &designer;
- Msp::Graphics::EventSource &event_source;
+ Msp::Input::Mouse &mouse;
Selection &selection;
std::vector<MTrack> tracks;
R2C2::Vector center;
+ R2C2::Vector pointer;
R2C2::Vector gpointer;
- int pointer_y;
Mode mode;
R2C2::Vector move_origin;
float angle;
float rot_origin;
- int elev_origin;
std::set<R2C2::Track *> neighbors;
std::vector<R2C2::Track *> extend_tracks;
public:
- Manipulator(Designer &, Msp::Graphics::EventSource &, Selection &);
+ Manipulator(Designer &, Msp::Input::Mouse &, Selection &);
void start_move();
void start_rotate();
void connect();
void cancel();
private:
- void button_press(int, int, unsigned, unsigned);
- void pointer_motion(int, int);
+ void button_press(unsigned);
+ void axis_motion(unsigned, float, float);
void selection_changed();
void update_tracks();
void update_neighbors();
return;
}
-void Measure::button_press(int, int, float gx, float gy, unsigned btn)
+void Measure::button_press(float gx, float gy, unsigned btn)
{
if(!state)
return;
}
}
-void Measure::pointer_motion(int, int, float gx, float gy)
+void Measure::pointer_motion(float gx, float gy)
{
if(!state)
return;
float get_perpendicular_distance() const { return perp_dist; }
float get_angle_difference() const { return adiff; }
void start();
- void button_press(int, int, float, float, unsigned);
- void pointer_motion(int, int, float, float);
+ void button_press(float, float, unsigned);
+ void pointer_motion(float, float);
void render();
private:
void snap_to_tracks(R2C2::Vector &, float &);
Engineer::Engineer(int argc, char **argv):
options(argc, argv),
window(options.screen_w, options.screen_h, options.fullscreen),
+ keyboard(window),
+ mouse(window),
layout(catalogue, (options.driver.empty() ? 0 : Driver::create(options.driver))),
layout_3d(layout),
server(0),
picking_track(0),
picking_entry(0),
picking_path(0),
- pointer_x(0),
- pointer_y(0),
pointer_moved(false)
{
// Setup GUI
DataFile::load(ui_res, "r2c2.res");
root = new GLtk::Root(ui_res, window);
- root->signal_button_press.connect(sigc::mem_fun(this, &Engineer::button_press));
- root->signal_pointer_motion.connect(sigc::mem_fun(this, &Engineer::pointer_motion));
+ mouse.signal_button_press.connect(sigc::mem_fun(this, &Engineer::button_press));
+ mouse.signal_axis_motion.connect(sigc::mem_fun(this, &Engineer::axis_motion));
root->set_visible(true);
main_panel = new MainPanel(*this);
if(picking)
{
- Track *track = pick_track(pointer_x, window.get_height()-pointer_y-1);
+ Track *track = pick_track(pointer);
if(track && track!=picking_track)
{
picking_track = track;
window.swap_buffers();
}
-void Engineer::button_press(int x, int y, unsigned btn, unsigned)
+void Engineer::button_press(unsigned btn)
{
if(picking)
{
}
else
{
- Track *track = pick_track(x, window.get_height()-y-1);
+ Track *track = pick_track(pointer);
if(track)
{
if(track->get_turnout_id())
}
}
-void Engineer::pointer_motion(int x, int y)
+void Engineer::axis_motion(unsigned axis, float value, float)
{
- pointer_x = x;
- pointer_y = y;
+ if(axis==0)
+ pointer.x = value;
+ if(axis==1)
+ pointer.y = value;
pointer_moved = true;
}
set_block_color(block, GL::Color(1));
}
-Track *Engineer::pick_track(int x, int y)
+Track *Engineer::pick_track(const Vector &p)
{
const GL::Vector3 &start = camera.get_position();
- float xx = x*2.0/window.get_width()-1.0;
- float yy = y*2.0/window.get_height()-1.0;
- GL::Vector4 ray = camera.unproject(GL::Vector4(xx, yy, 0, 0));
+ GL::Vector4 ray = camera.unproject(GL::Vector4(p.x, p.y, 0, 0));
return layout.pick_track(Vector(start.x, start.y, start.z), Vector(ray.x, ray.y, ray.z));
}
Options options;
Msp::Graphics::SimpleGLWindow window;
+ Msp::Input::Keyboard keyboard;
+ Msp::Input::Mouse mouse;
Msp::GLtk::Resources ui_res;
Msp::GLtk::Root *root;
R2C2::Track *picking_track;
int picking_entry;
R2C2::Path3D *picking_path;
- int pointer_x;
- int pointer_y;
+ R2C2::Vector pointer;
bool pointer_moved;
public:
void quit() { exit(0); }
private:
void tick();
- void button_press(int, int, unsigned, unsigned);
- void pointer_motion(int, int);
+ void button_press(unsigned);
+ void axis_motion(unsigned, float, float);
void view_all();
void set_block_color(const R2C2::Block &, const Msp::GL::Color &);
void reset_block_color(const R2C2::Block &);
void sensor_event(unsigned, bool);
void block_reserved(const R2C2::Block &, const R2C2::Train *);
- R2C2::Track *pick_track(int, int);
+ R2C2::Track *pick_track(const R2C2::Vector &);
void train_added(R2C2::Train &);
virtual void sighandler(int);
};