#include <signal.h>
#include <cmath>
#include <GL/gl.h>
+#include <msp/gl/blend.h>
#include <msp/gl/matrix.h>
#include <msp/gl/misc.h>
#include <msp/gl/projection.h>
Application::RegApp<Designer> Designer::reg;
Designer::Designer(int argc, char **argv):
- screen_w(1280),
- screen_h(960),
+ window(1280, 960),
base_object(0),
cur_route(0),
mode(SELECT),
+ manipulator(*this, selection),
+ measure(*this),
input(0),
cam_yaw(M_PI/2),
cam_pitch(-M_PI/4),
rotate(0),
pitch(0)
{
+ window.set_title("Railway Designer");
+ window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Designer::exit), 0));
+ window.signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press));
+ window.signal_key_release.connect(sigc::mem_fun(this, &Designer::key_release));
+ window.signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
+ window.signal_pointer_motion.connect(sigc::mem_fun(this, &Designer::pointer_motion));
+
+ manipulator.signal_status.connect(sigc::mem_fun(this, &Designer::manipulation_status));
+ manipulator.signal_done.connect(sigc::mem_fun(this, &Designer::manipulation_done));
+ measure.signal_changed.connect(sigc::mem_fun(this, &Designer::measure_changed));
+ measure.signal_done.connect(sigc::mem_fun(this, &Designer::measure_done));
+
+ // Setup catalogue and layout
DataFile::load(catalogue, "tracks.dat");
- cat_layout = new Layout(catalogue);
- cat_layout_3d = new Layout3D(*cat_layout);
-
- const map<unsigned, TrackType *> &ctracks = catalogue.get_tracks();
- unsigned n = 0;
- for(map<unsigned, TrackType *>::const_iterator i=ctracks.begin(); i!=ctracks.end(); ++i, ++n)
- {
- Track *track = new Track(*i->second);
- track->set_position(Point((n%11)*0.1-0.5, 0.2-n/11*0.3, 0));
- track->set_rotation(M_PI/2);
- cat_layout->add_track(*track);
- }
-
- manipulator = new Manipulator(*this);
- manipulator->signal_status.connect(sigc::mem_fun(this, &Designer::manipulation_status));
- manipulator->signal_done.connect(sigc::mem_fun(this, &Designer::manipulation_done));
+ cat_layout_3d = new Layout3D(catalogue.get_layout());
layout = new Layout(catalogue);
layout_3d = new Layout3D(*layout);
}
}
- selection = new Selection;
- manipulator->set_selection(selection);
-
- measure = new Measure(*this);
- measure->signal_changed.connect(sigc::mem_fun(this, &Designer::measure_changed));
- measure->signal_done.connect(sigc::mem_fun(this, &Designer::measure_done));
-}
-
-Designer::~Designer()
-{
- delete manipulator;
- delete selection;
- delete layout;
- delete layout_3d;
- delete cat_layout;
- delete cat_layout_3d;
- delete measure;
-}
-
-int Designer::main()
-{
- dpy = new Graphics::Display;
- wnd = new Graphics::Window(*dpy, screen_w, screen_h);
- glc = new Graphics::GLContext(*wnd);
- wnd->set_title("Railway Designer");
-
- wnd->signal_close.connect(sigc::bind(sigc::mem_fun(this, &Designer::exit), 0));
- wnd->show();
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_CULL_FACE);
+ // Setup OpenGL
+ GL::enable(GL::DEPTH_TEST);
+ GL::enable(GL::BLEND);
+ GL::blend_func(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);
+ GL::enable(GL_CULL_FACE);
- pipeline = new GL::Pipeline(screen_w, screen_h, false);
+ pipeline = new GL::Pipeline(window.get_width(), window.get_height(), false);
pipeline->add_renderable(layout_3d->get_scene());
if(base_object)
pipeline->add_renderable(*base_object);
GL::PipelinePass *pass = &pipeline->add_pass(GL::Tag());
pass->lighting = &lighting;
+ // Setup UI
DataFile::load(ui_res, "marklin.res");
- root = new GLtk::Root(ui_res, *wnd);
+ root = new GLtk::Root(ui_res, window);
lbl_tooltip = new GLtk::Label(ui_res);
lbl_tooltip->set_style("tooltip");
toolbar = new Toolbar(*this);
root->add(*toolbar);
- toolbar->set_position(0, screen_h-toolbar->get_geometry().h);
+ toolbar->set_position(0, window.get_height()-toolbar->get_geometry().h);
toolbar->set_visible(true);
+}
+Designer::~Designer()
+{
+ delete root;
+ delete layout;
+ delete layout_3d;
+ delete cat_layout_3d;
+}
- wnd->signal_key_press.connect(sigc::mem_fun(this, &Designer::key_press));
- wnd->signal_key_release.connect(sigc::mem_fun(this, &Designer::key_release));
- wnd->signal_button_press.connect(sigc::mem_fun(this, &Designer::button_press));
- wnd->signal_pointer_motion.connect(sigc::mem_fun(this, &Designer::pointer_motion));
+int Designer::main()
+{
+ window.show();
mode = SELECT;
- Application::main();
-
- delete root;
-
- delete glc;
- delete wnd;
- delete dpy;
-
- return exit_code;
+ return Application::main();
}
void Designer::save()
try
{
- const set<Track *> &stracks = selection->get_tracks();
+ const set<Track *> &stracks = selection.get_tracks();
set<const Track *> tracks(stracks.begin(), stracks.end());
cur_route->add_tracks(tracks);
}
float uy = sin_yaw*-sin_pitch*0.41421;
float uz = cos_pitch*0.41421;
- float xf = static_cast<float>(x)*2/screen_w-1;
- float yf = static_cast<float>(y)*2/screen_h-1;
+ float xf = static_cast<float>(x)*2/window.get_width()-1;
+ float yf = static_cast<float>(y)*2/window.get_height()-1;
float vx = cos_yaw*cos_pitch + xf*rx + yf*ux;
float vy = sin_yaw*cos_pitch + xf*ry + yf*uy;
float dt = (t-last_tick)/Msp::Time::sec;
last_tick = t;
- dpy->tick();
+ window.get_display().tick();
if(move_y)
{
render();
- glc->swap_buffers();
+ window.swap_buffers();
}
void Designer::key_press(unsigned code, unsigned mod, wchar_t)
mode = CATALOGUE;
else if(key==Msp::Input::KEY_G)
{
- manipulator->start_move();
+ manipulator.start_move();
mode = MANIPULATE;
}
else if(key==Msp::Input::KEY_R)
{
- manipulator->start_rotate();
+ manipulator.start_rotate();
mode = MANIPULATE;
}
else if(key==Msp::Input::KEY_D)
{
- manipulator->duplicate();
- manipulator->start_move();
+ manipulator.duplicate();
+ manipulator.start_move();
mode = MANIPULATE;
}
else if(key==Msp::Input::KEY_W)
save();
else if(key==Msp::Input::KEY_PLUS)
- selection->select_more();
+ selection.select_more();
else if(key==Msp::Input::KEY_L && (mod&1))
{
const set<Track *> &tracks = layout->get_tracks();
IO::print("Total length: %.1fm\n", len);
}
else if(key==Msp::Input::KEY_L)
- selection->select_linked();
+ selection.select_linked();
else if(key==Msp::Input::KEY_M)
{
- measure->start();
+ measure.start();
mode = MEASURE;
}
else if(key==Msp::Input::KEY_Z)
{
- manipulator->start_elevate();
+ manipulator.start_elevate();
mode = MANIPULATE;
}
else if(key==Msp::Input::KEY_ESC)
{
if(mode==MANIPULATE)
- manipulator->cancel();
+ manipulator.cancel();
else if(mode==CATALOGUE)
mode = SELECT;
else
- selection->clear();
+ selection.clear();
}
else if(key==Msp::Input::KEY_X)
{
- set<Track *> tracks = selection->get_tracks();
- selection->clear();
+ set<Track *> tracks = selection.get_tracks();
+ selection.clear();
for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
{
layout->remove_track(**i);
}
else if(key==Msp::Input::KEY_F && (mod&1))
{
- const set<Track *> &tracks = selection->get_tracks();
+ const set<Track *> &tracks = selection.get_tracks();
const set<Track *> <racks = layout->get_tracks();
for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
{
}
}
else if(key==Msp::Input::KEY_F)
- manipulator->flatten();
+ manipulator.flatten();
else if(key==Msp::Input::KEY_E && (mod&1))
- manipulator->even_slope(true);
+ manipulator.even_slope(true);
else if(key==Msp::Input::KEY_E)
- manipulator->even_slope();
+ manipulator.even_slope();
else if(key==Msp::Input::KEY_T)
{
- Track *track = selection->get_track();
- if(selection->size()==1 && track->get_type().get_n_paths()>1)
+ Track *track = selection.get_track();
+ if(selection.size()==1 && track->get_type().get_n_paths()>1)
{
input = new ::Input(*this, "Turnout ID", lexical_cast(track->get_turnout_id()));
input->signal_cancel.connect(sigc::mem_fun(this, &Designer::input_dismiss));
}
else if(key==Msp::Input::KEY_S)
{
- const set<Track *> &tracks = selection->get_tracks();
+ const set<Track *> &tracks = selection.get_tracks();
bool ok = false;
int id = -1;
for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
void Designer::button_press(int x, int y, unsigned btn, unsigned)
{
- y = screen_h-y-1;
+ y = window.get_height()-y-1;
float gx, gy;
map_pointer_coords(x, y, gx, gy);
track->set_position(Point(gx, gy, 0));
layout->add_track(*track);
- selection->clear();
- selection->add_track(track);
+ selection.clear();
+ selection.add_track(track);
mode = SELECT;
}
if(track)
{
if(!shift)
- selection->clear();
- selection->toggle_track(&track->get_track());
+ selection.clear();
+ selection.toggle_track(&track->get_track());
}
}
}
else if(mode==MANIPULATE)
- manipulator->button_press(x, y, gx, gy, btn);
+ manipulator.button_press(x, y, gx, gy, btn);
else if(mode==MEASURE)
- measure->button_press(x, y, gx, gy, btn);
+ measure.button_press(x, y, gx, gy, btn);
}
void Designer::pointer_motion(int x, int y)
{
- y = screen_h-y-1;
+ y = window.get_height()-y-1;
pointer_x = x;
pointer_y = y;
{
float gx, gy;
map_pointer_coords(x, y, gx, gy);
- manipulator->pointer_motion(x, y, gx, gy);
- measure->pointer_motion(x, y, gx, gy);
+ manipulator.pointer_motion(x, y, gx, gy);
+ measure.pointer_motion(x, y, gx, gy);
}
}
}
}*/
- manipulator->render();
+ manipulator.render();
if(mode==MEASURE)
- measure->render();
+ measure.render();
}
GL::matrix_mode(GL::PROJECTION);
GL::load_identity();
- GL::ortho_bottomleft(screen_w, screen_h);
+ GL::ortho_bottomleft(window.get_width(), window.get_height());
GL::matrix_mode(GL::MODELVIEW);
GL::load_identity();
if(mode==CATALOGUE)
l = cat_layout_3d;
- float xx = (static_cast<float>(x-static_cast<int>(screen_w)/2)/screen_h)*0.82843;
- float yy = (static_cast<float>(y)/screen_h-0.5)*0.82843;
- float size = 4.0/screen_h*0.82843;
+ float xx = ((float(x)-window.get_width()/2)/window.get_height())*0.82843;
+ float yy = (float(y)/window.get_height()-0.5)*0.82843;
+ float size = 4.0/window.get_height()*0.82843;
project_3d();
apply_camera();
void Designer::measure_changed()
{
- float pard = measure->get_parallel_distance()*1000;
- float perpd = measure->get_perpendicular_distance()*1000;
+ float pard = measure.get_parallel_distance()*1000;
+ float perpd = measure.get_perpendicular_distance()*1000;
float d = sqrt(pard*pard+perpd*perpd);
- float adiff = measure->get_angle_difference()*180/M_PI;
+ float adiff = measure.get_angle_difference()*180/M_PI;
string info = format("Par %.1fmm - Perp %.1fmm - Total %.1fmm - Angle %.1f°", pard, perpd, d, adiff);
set_tooltip(pointer_x, pointer_y, info);
}
int fontsize = ui_res.get_default_font().get_default_size();
int h = fontsize+6;
int w = static_cast<int>(ui_res.get_default_font().get_string_width(text)*fontsize)+6;
- x = max(min(static_cast<int>(screen_w)-w, x), 0);
- y = max(min(static_cast<int>(screen_h)-h, y), 0);
+ x = max(min(static_cast<int>(window.get_width())-w, x), 0);
+ y = max(min(static_cast<int>(window.get_height())-h, y), 0);
lbl_tooltip->set_text(text);
lbl_tooltip->set_geometry(GLtk::Geometry(x, y, w, h));
lbl_tooltip->set_visible(true);
void Designer::turnout_id_accept()
{
- Track *track = selection->get_track();
+ Track *track = selection.get_track();
unsigned id = lexical_cast<unsigned>(input->get_text());
track->set_turnout_id(id);
void Designer::sensor_id_accept()
{
- const set<Track *> &tracks = selection->get_tracks();
+ const set<Track *> &tracks = selection.get_tracks();
unsigned id = lexical_cast<unsigned>(input->get_text());
for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
{