From: Mikko Rasa Date: Wed, 3 Mar 2010 21:56:51 +0000 (+0000) Subject: Emit various signals from Train when it's loaded X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=bc8ac89bbe774bb133b758416182aa18e5e0a5a5;p=r2c2.git Emit various signals from Train when it's loaded Add Train3D class Add Object3D class as base for Track3D and Train3D Make Overlay3D use Object3Ds Overhaul Engineer code --- diff --git a/arrow.mesh b/arrow.mesh new file mode 100644 index 0000000..56caed5 --- /dev/null +++ b/arrow.mesh @@ -0,0 +1,15 @@ +vertices COLOR4UB_VERTEX2 +{ + color4 1.0 1.0 1.0 1.0; + vertex2 0.08 0.00; + vertex2 0.05 0.03; + vertex2 0.05 0.01; + vertex2 0.00 0.01; + vertex2 0.00 -0.01; + vertex2 0.05 -0.01; + vertex2 0.05 -0.03; +}; +batch TRIANGLE_FAN +{ + indices 0 1 2 3 4 5 6; +}; diff --git a/source/3d/layout.cpp b/source/3d/layout.cpp index a8fbc1e..8ea58bf 100644 --- a/source/3d/layout.cpp +++ b/source/3d/layout.cpp @@ -13,6 +13,7 @@ Distributed under the GPL #include #include #include +#include "libmarklin/trafficmanager.h" #include "layout.h" using namespace std; @@ -36,6 +37,8 @@ Layout3D::~Layout3D() { while(!tracks.empty()) delete tracks.front(); + while(!trains.empty()) + delete trains.front(); } void Layout3D::add_track(Track3D &t) @@ -95,6 +98,32 @@ Track3D *Layout3D::pick_track(float x, float y, float size) const return track; } +void Layout3D::set_traffic_manager(TrafficManager &tm) +{ + tm.signal_train_added.connect(sigc::mem_fun(this, &Layout3D::train_added)); +} + +void Layout3D::add_train(Train3D &t) +{ + trains.push_back(&t); +} + +void Layout3D::remove_train(Train3D &t) +{ + list::iterator i = find(trains.begin(), trains.end(), &t); + if(i!=trains.end()) + trains.erase(i); +} + +Train3D &Layout3D::get_train(const Train &t) const +{ + for(list::const_iterator i=trains.begin(); i!=trains.end(); ++i) + if(&(*i)->get_train()==&t) + return **i; + + throw KeyError("Unknown train"); +} + void Layout3D::track_added(Track &t) { new Track3D(*this, t); @@ -110,4 +139,9 @@ void Layout3D::track_removed(Track &t) } } +void Layout3D::train_added(Train &t) +{ + new Train3D(*this, t); +} + } // namespace Marklin diff --git a/source/3d/layout.h b/source/3d/layout.h index 9120af6..2e56ea6 100644 --- a/source/3d/layout.h +++ b/source/3d/layout.h @@ -12,6 +12,7 @@ Distributed under the GPL #include "libmarklin/layout.h" #include "catalogue.h" #include "track.h" +#include "train.h" namespace Marklin { @@ -21,6 +22,7 @@ private: Layout &layout; Catalogue3D catalogue; std::list tracks; + std::list trains; Msp::GL::Scene scene; Msp::GL::Scene ep_scene; @@ -36,12 +38,18 @@ public: Track3D &get_track(const Track &) const; Track3D *pick_track(float, float, float) const; + void set_traffic_manager(TrafficManager &); + void add_train(Train3D &); + void remove_train(Train3D &); + Train3D &get_train(const Train &) const; + Msp::GL::Scene &get_scene() { return scene; } Msp::GL::Scene &get_endpoint_scene() { return ep_scene; } private: void track_added(Track &); void track_removed(Track &); + void train_added(Train &); }; } // namespace Marklin diff --git a/source/3d/overlay.cpp b/source/3d/overlay.cpp index bc206f9..3f2d621 100644 --- a/source/3d/overlay.cpp +++ b/source/3d/overlay.cpp @@ -30,17 +30,17 @@ Overlay3D::~Overlay3D() { for(map::iterator i=graphics.begin(); i!=graphics.end(); ++i) delete i->second; - for(map::iterator i=icons.begin(); i!=icons.end(); ++i) + for(map::iterator i=icons.begin(); i!=icons.end(); ++i) delete i->second; } -void Overlay3D::set_label(const Track3D &track, const string &label) +void Overlay3D::set_label(const Object3D &track, const string &label) { get_icon(track).label = label; update_icon(get_icon(track)); } -void Overlay3D::add_graphic(const Track3D &track, const string &grf_name) +void Overlay3D::add_graphic(const Object3D &track, const string &grf_name) { const GL::Mesh *grf = get_graphic(grf_name); if(!grf) @@ -53,7 +53,7 @@ void Overlay3D::add_graphic(const Track3D &track, const string &grf_name) update_icon(icon); } -void Overlay3D::remove_graphic(const Track3D &track, const string &grf_name) +void Overlay3D::remove_graphic(const Object3D &track, const string &grf_name) { const GL::Mesh *grf = get_graphic(grf_name); Icon &icon = get_icon(track); @@ -62,15 +62,15 @@ void Overlay3D::remove_graphic(const Track3D &track, const string &grf_name) update_icon(icon); } -void Overlay3D::clear_graphics(const Track3D &track) +void Overlay3D::clear_graphics(const Object3D &track) { get_icon(track).graphics.clear(); update_icon(get_icon(track)); } -void Overlay3D::clear(const Track3D &track) +void Overlay3D::clear(const Object3D &track) { - map::iterator i = icons.find(&track); + map::iterator i = icons.find(&track); if(i!=icons.end()) { delete i->second; @@ -96,21 +96,12 @@ void Overlay3D::render(const GL::Tag &tag) const float spacing = round(size*1.1)/size; float baseline = round((0.5-font.get_ascent()*0.5-font.get_descent()*0.5)*size)/size; - for(map::const_iterator i=icons.begin(); i!=icons.end(); ++i) + for(map::const_iterator i=icons.begin(); i!=icons.end(); ++i) { const Icon &icon = *i->second; - const Point &pos = i->first->get_track().get_position(); - Point minp; - Point maxp; - i->first->get_type().get_bounds(0, minp, maxp); - float rot = i->first->get_track().get_rotation(); - float c = cos(rot); - float s = sin(rot); - - GL::Vector3 p((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, 0); - p = GL::Vector3(pos.x+c*p.x-s*p.y, pos.y+s*p.x+c*p.y, pos.z+0.02); - p = camera.project(p); + Point node = i->first->get_node(); + GL::Vector3 p = camera.project(GL::Vector3(node.x, node.y, node.z)); GL::PushMatrix push_mat; p.x = int(p.x*0.5*window.get_width()-icon.width*size/2); @@ -139,7 +130,7 @@ void Overlay3D::render(const GL::Tag &tag) const } } -Overlay3D::Icon &Overlay3D::get_icon(const Track3D &track) +Overlay3D::Icon &Overlay3D::get_icon(const Object3D &track) { Icon *&icon = icons[&track]; if(!icon) diff --git a/source/3d/overlay.h b/source/3d/overlay.h index 0a9a022..eac51be 100644 --- a/source/3d/overlay.h +++ b/source/3d/overlay.h @@ -16,7 +16,7 @@ Distributed under the GPL namespace Marklin { -class Track3D; +class Object3D; class Overlay3D: public Msp::GL::Renderable { @@ -35,22 +35,22 @@ private: const Msp::GL::Camera &camera; const Msp::GL::Font &font; std::map graphics; - std::map icons; + std::map icons; public: Overlay3D(const Msp::Graphics::Window &, const Msp::GL::Camera &, const Msp::GL::Font &); ~Overlay3D(); - void set_label(const Track3D &, const std::string &); - void add_graphic(const Track3D &, const std::string &); - void remove_graphic(const Track3D &, const std::string &); - void clear_graphics(const Track3D &); - void clear(const Track3D &); + void set_label(const Object3D &, const std::string &); + void add_graphic(const Object3D &, const std::string &); + void remove_graphic(const Object3D &, const std::string &); + void clear_graphics(const Object3D &); + void clear(const Object3D &); virtual void render(const Msp::GL::Tag &) const; private: - Icon &get_icon(const Track3D &); + Icon &get_icon(const Object3D &); const Msp::GL::Mesh *get_graphic(const std::string &); void update_icon(Icon &); }; diff --git a/source/3d/track.cpp b/source/3d/track.cpp index 3241852..a5c5dbf 100644 --- a/source/3d/track.cpp +++ b/source/3d/track.cpp @@ -63,6 +63,20 @@ void Track3D::get_bounds(float angle, Point &minp, Point &maxp) const minp.z += slope; } +Point Track3D::get_node() const +{ + const Point &pos = track.get_position(); + Point minp; + Point maxp; + type.get_bounds(0, minp, maxp); + float rot = track.get_rotation(); + float c = cos(rot); + float s = sin(rot); + + Point center((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, 0); + return Point(pos.x+c*center.x-s*center.y, pos.y+s*center.x+c*center.y, pos.z+0.02); +} + void Track3D::render(const GL::Tag &tag) const { GL::PushMatrix push_mat; diff --git a/source/3d/track.h b/source/3d/track.h index 9928e11..94865cf 100644 --- a/source/3d/track.h +++ b/source/3d/track.h @@ -14,6 +14,7 @@ Distributed under the GPL #include #include "libmarklin/track.h" #include "libmarklin/trackpart.h" +#include "object.h" namespace Marklin { @@ -21,7 +22,7 @@ class Endpoint3D; class Layout3D; class TrackType3D; -class Track3D: public Msp::GL::Renderable +class Track3D: public Object3D, public Msp::GL::Renderable { private: Layout3D &layout; @@ -38,6 +39,8 @@ public: const TrackType3D &get_type() const { return type; } void get_bounds(float, Point &, Point &) const; + virtual Point get_node() const; + virtual void render(const Msp::GL::Tag &) const; }; diff --git a/source/engineer/engineer.cpp b/source/engineer/engineer.cpp index 9774903..87a4d6d 100644 --- a/source/engineer/engineer.cpp +++ b/source/engineer/engineer.cpp @@ -1,22 +1,25 @@ /* $Id$ This file is part of the MSP Märklin suite -Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa +Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ #include #include #include -#include #include #include #include #include #include +#include +#include #include #include +#include #include +#include #include #include #include @@ -35,22 +38,21 @@ using namespace Marklin; using namespace Msp; Engineer::Engineer(int argc, char **argv): - screen_w(1280), - screen_h(960), - fullscreen(false), layout(catalogue), layout_3d(layout), server(0), placing_train(0), placing_block(0), placing_entry(0), - no_lighting(false), simulate(false) { + // Parse options + unsigned screen_w = 1280; + unsigned screen_h = 960; + bool fullscreen = false; string res; bool debug = false; string device = "/dev/ttyS0"; - unsigned quality = 4; bool network = false; GetOpt getopt; @@ -58,12 +60,14 @@ Engineer::Engineer(int argc, char **argv): getopt.add_option('f', "fullscreen", fullscreen, GetOpt::NO_ARG); getopt.add_option('g', "debug", debug, GetOpt::NO_ARG); getopt.add_option('d', "device", device, GetOpt::REQUIRED_ARG); - getopt.add_option('q', "quality", quality, GetOpt::REQUIRED_ARG); getopt.add_option('s', "simulate", simulate, GetOpt::NO_ARG); getopt.add_option('n', "network", network, GetOpt::NO_ARG); - getopt.add_option( "no-lighting", no_lighting, GetOpt::NO_ARG); getopt(argc, argv); + const vector &args = getopt.get_args(); + if(args.empty()) + throw UsageError("No layout given"); + if(!res.empty()) { if(RegMatch m=Regex("([1-9][0-9]*)x([1-9][0-9]*)").match(res)) @@ -75,26 +79,38 @@ Engineer::Engineer(int argc, char **argv): throw UsageError("Invalid resolution"); } - if(device!="none") - control.open(device); + // Setup GUI + window = new Graphics::SimpleGLWindow(screen_w, screen_h, fullscreen); + window->set_title("Railroad Engineer"); + window->signal_close.connect(sigc::bind(sigc::mem_fun(this, &Engineer::exit), 0)); - control.set_debug(debug); + DataFile::load(ui_res, "marklin.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)); + root->set_visible(true); - layout_3d.set_quality(quality); + main_panel = new MainPanel(*this, ui_res); + root->add(*main_panel); + main_panel->set_position(0, window->get_height()-main_panel->get_geometry().h); + main_panel->set_visible(true); + // Setup railroad control DataFile::load(catalogue, "tracks.dat"); DataFile::load(catalogue, "locos.dat"); - - const vector &args = getopt.get_args(); - if(args.empty()) - throw UsageError("No layout given"); DataFile::load(layout, args.front()); + if(device!="none") + control.open(device); + + control.set_debug(debug); + trfc_mgr = new TrafficManager(control, layout); - if(FS::exists("engineer.state")) - DataFile::load(*trfc_mgr, "engineer.state"); + layout_3d.set_traffic_manager(*trfc_mgr); trfc_mgr->signal_train_added.connect(sigc::mem_fun(this, &Engineer::train_added)); trfc_mgr->signal_block_reserved.connect(sigc::mem_fun(this, &Engineer::block_reserved)); + if(FS::exists("engineer.state")) + DataFile::load(*trfc_mgr, "engineer.state"); if(network) { @@ -106,8 +122,25 @@ Engineer::Engineer(int argc, char **argv): for(map::const_iterator i=sensors.begin(); i!=sensors.end(); ++i) i->second->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Engineer::sensor_event), i->second)); + // Setup 3D view + DataFile::load(arrow_mesh, "arrow.mesh"); + + overlay = new Overlay3D(*window, camera, ui_res.get_default_font()); + + pipeline = new GL::Pipeline(window->get_width(), window->get_height(), false); + pipeline->set_camera(&camera); + pipeline->add_renderable(layout_3d.get_scene()); + + light.set_position(0, -0.259, 0.966, 0); + lighting.attach(0, light); + + GL::PipelinePass &pass = pipeline->add_pass(0); + pass.depth_test = &GL::DepthTest::lequal(); + pass.lighting = &lighting; + view_all(); + // Catch various signals so we can stop the trains in case we get terminated catch_signal(SIGINT); catch_signal(SIGTERM); catch_signal(SIGSEGV); @@ -127,6 +160,12 @@ Engineer::~Engineer() if(!simulate) trfc_mgr->save("engineer.state"); + + delete pipeline; + delete overlay; + delete root; + delete window; + delete trfc_mgr; delete server; } @@ -140,124 +179,34 @@ void Engineer::place_train(Train &train) int Engineer::main() { - dpy = new Graphics::Display; - - Graphics::WindowOptions wopt; - wopt.width = screen_w; - wopt.height = screen_h; - wopt.fullscreen = fullscreen; - wnd = new Graphics::Window(*dpy, wopt); - - Graphics::GLOptions glopt; - //glopt.multisample = 4; - glc = new Graphics::GLContext(*wnd, glopt); - - wnd->signal_close.connect(sigc::bind(sigc::mem_fun(this, &Engineer::exit), 0)); - wnd->signal_button_press.connect(sigc::mem_fun(this, &Engineer::button_press)); - wnd->signal_button_release.connect(sigc::mem_fun(this, &Engineer::button_release)); - wnd->signal_pointer_motion.connect(sigc::mem_fun(this, &Engineer::pointer_motion)); - - glEnableClientState(GL_VERTEX_ARRAY); - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - glDepthFunc(GL_LEQUAL); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - DataFile::load(ui_res, "marklin.res"); - root = new GLtk::Root(ui_res, *wnd); - root->set_visible(true); - - list texs = ui_res.get_list(); - for(list::iterator i=texs.begin(); i!=texs.end(); ++i) - { - (*i)->set_min_filter(GL::NEAREST); - (*i)->set_mag_filter(GL::NEAREST); - } - - main_panel = new MainPanel(*this, ui_res); - root->add(*main_panel); - main_panel->set_position(0, screen_h-main_panel->get_geometry().h); - main_panel->set_visible(true); - - const list &trains = trfc_mgr->get_trains(); - int y = main_panel->get_geometry().y; - for(list::const_iterator i=trains.begin(); i!=trains.end(); ++i) - { - TrainPanel *tpanel = new TrainPanel(*this, ui_res, **i); - root->add(*tpanel); - tpanel->set_position(0, y-tpanel->get_geometry().h); - train_panels.push_back(tpanel); - tpanel->set_visible(true); - y -= tpanel->get_geometry().h; - } - - const list &blocks = trfc_mgr->get_blocks(); - for(list::const_iterator i=blocks.begin(); i!=blocks.end(); ++i) - reset_block_color(**i); - - wnd->show(); + window->show(); - Application::main(); - - delete root; - delete glc; - delete wnd; - delete dpy; - - return exit_code; + return Application::main(); } void Engineer::tick() { - dpy->tick(); + window->get_display().tick(); control.tick(); trfc_mgr->tick(); event_disp.tick(Time::zero); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + for(list::iterator i=new_trains.begin(); i!=new_trains.end(); ++i) + overlay->set_label(layout_3d.get_train(**i), (*i)->get_name()); + new_trains.clear(); - project_3d(); - glLoadIdentity(); - glRotatef(-cam_rot*180/M_PI, 0, 0, 1); - glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z); + GL::clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT); - if(!no_lighting) + pipeline->render_all(); { - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - float params[4]; - params[0] = 0; - params[1] = -0.2; - params[2] = 1; - params[3] = 0; - glLightfv(GL_LIGHT0, GL_POSITION, params); + GL::Bind blend(GL::Blend::alpha()); + overlay->render(0); } - //glEnable(GL_DEPTH_TEST); - glEnable(GL_MULTISAMPLE); - - layout_3d.get_scene().render(); - - glDisable(GL_LIGHTING); - glColor4f(1, 1, 1, 1); - /*const list <racks = layout_3d.get_tracks(); - for(list::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i) - { - Track &track = (*i)->get_track(); - if(track.get_turnout_id()) - { - Turnout &trnt = control.get_turnout(track.get_turnout_id()); - (*i)->render_path(trnt.get_path()); - } - else - (*i)->render_path(-1); - }*/ - if(placing_train && placing_block) { - GL::push_matrix(); + GL::PushMatrix push_mat; const Marklin::Block::Endpoint &bep = placing_block->get_endpoints()[placing_entry]; float rot = bep.track->get_endpoint_direction(bep.track_ep); @@ -265,61 +214,24 @@ void Engineer::tick() GL::translate(pos.x, pos.y, pos.z+0.03); GL::rotate(rot*180/M_PI+180, 0, 0, 1); - GL::Texture::unbind(); - GL::Immediate imm((GL::COLOR4_UBYTE, GL::VERTEX2)); - imm.color(1.0f, 1.0f, 1.0f); - imm.begin(GL::TRIANGLE_FAN); - imm.vertex(0.08, 0); - imm.vertex(0.05, 0.03); - imm.vertex(0.05, 0.01); - imm.vertex(0, 0.01); - imm.vertex(0, -0.01); - imm.vertex(0.05, -0.01); - imm.vertex(0.05, -0.03); - imm.end(); - - GL::pop_matrix(); - } - - const list &trains = trfc_mgr->get_trains(); - for(list::const_iterator i=trains.begin(); i!=trains.end(); ++i) - { - if(!(*i)->is_placed()) - continue; - - GL::PushMatrix _push; - - const Point &tp = (*i)->get_position(); - GL::translate(tp.x, tp.y, tp.z+0.02); - GL::Immediate imm((GL::COLOR4_UBYTE, GL::VERTEX2)); - imm.color(0.8f, 0.8f, 1.0f); - imm.begin(GL::TRIANGLE_FAN); - imm.vertex(0, 0); - for(unsigned j=0; j<=12; ++j) - imm.vertex(0.02*cos(j*M_PI/6), 0.02*sin(j*M_PI/6)); - imm.end(); - - GL::rotate(cam_rot*180/M_PI, 0, 0, 1); - GL::translate(0.03, -0.02, 0); - GL::scale_uniform(0.04); - ui_res.get_default_font().draw_string((*i)->get_name()); - GL::Texture::unbind(); + arrow_mesh.draw(); } + const GLtk::Geometry &rgeom = root->get_geometry(); GL::matrix_mode(GL::PROJECTION); GL::load_identity(); - GL::ortho_bottomleft(screen_w, screen_h); + GL::ortho_bottomleft(rgeom.w, rgeom.h); GL::matrix_mode(GL::MODELVIEW); GL::load_identity(); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glDisable(GL_MULTISAMPLE); - - root->render(); + { + GL::Bind blend(GL::Blend::alpha()); + root->render(); + GL::Texture::unbind(); + } - glc->swap_buffers(); + window->swap_buffers(); } void Engineer::button_press(int x, int y, unsigned btn, unsigned) @@ -328,7 +240,7 @@ void Engineer::button_press(int x, int y, unsigned btn, unsigned) { if(btn==1 && placing_block && !placing_block->get_train()) { - set_block_color(*placing_block, GL::Color(1, 1, 1)); + reset_block_color(*placing_block); placing_train->place(*placing_block, placing_entry); placing_train = 0; @@ -342,7 +254,7 @@ void Engineer::button_press(int x, int y, unsigned btn, unsigned) } else { - Track3D *track = pick_track(x, screen_h-y-1); + Track3D *track = pick_track(x, window->get_height()-y-1); if(track) { if(unsigned tid=track->get_track().get_turnout_id()) @@ -370,16 +282,12 @@ void Engineer::button_press(int x, int y, unsigned btn, unsigned) } } -void Engineer::button_release(int, int, unsigned, unsigned) -{ -} - void Engineer::pointer_motion(int x, int y) { if(placing_train) { - Track3D *track = pick_track(x, screen_h-y-1); - if(track && placing_train) + Track3D *track = pick_track(x, window->get_height()-y-1); + if(track) { Block &block = trfc_mgr->get_block_by_track(track->get_track()); if(&block!=placing_block) @@ -391,10 +299,6 @@ void Engineer::pointer_motion(int x, int y) set_block_color(*placing_block, GL::Color(0.5, 1, 0.7)); } } - else if(track && track->get_track().get_turnout_id()) - main_panel->set_status_text(format("Turnout %d", track->get_track().get_turnout_id())); - else if(!placing_train) - main_panel->set_status_text(string()); } } @@ -402,10 +306,11 @@ void Engineer::view_all() { const list &tracks = layout_3d.get_tracks(); - cam_rot = 0; - float best_height = -1; - float mid_x = 0; - float mid_y = 0; + float view_aspect = float(window->get_width()-200)/window->get_height(); + float view_height = tan(camera.get_field_of_view()/2)*2; + float best_score = 0; + GL::Vector3 pos; + GL::Vector3 up; for(float angle=0; anglebest_score) { - cam_rot = angle; - best_height = height; - mid_x = (min_x+max_x)/2; - mid_y = (min_y+max_y)/2; + best_score = score; + + float size = max(width/view_aspect, height); + float c = cos(angle); + float s = sin(angle); + float x = (min_x+max_x)/2-size*105/window->get_height(); + float y = (min_y+max_y)/2; + float z = max(size*1.05/view_height, 0.15); + + pos = GL::Vector3(c*x-s*y, s*x+c*y, z); + up = GL::Vector3(-s, c, 0); } } - float c = cos(cam_rot); - float s = sin(cam_rot); - cam_pos.x = c*mid_x-s*mid_y; - cam_pos.y = s*mid_x+c*mid_y; - cam_pos.z = max(best_height*1.05/0.82843, 0.15); + camera.set_position(pos); + camera.set_up_direction(up); + camera.set_look_direction(GL::Vector3(0, 0, -1)); } void Engineer::set_block_color(const Block &block, const GL::Color &color) { - const set &tracks = block.get_tracks(); - for(set::const_iterator i=tracks.begin(); i!=tracks.end(); ++i) - layout_3d.get_track(**i).set_color(color); + (void)block; + (void)color; } void Engineer::reset_block_color(const Block &block) @@ -480,25 +390,14 @@ void Engineer::block_reserved(const Block &block, const Train *) reset_block_color(block); } -void Engineer::project_3d() -{ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - float offset = 200.0/screen_w*0.055228; - glFrustum(-0.055228-offset, 0.055228-offset, -0.041421, 0.041421, 0.1, 10); - glMatrixMode(GL_MODELVIEW); -} - Track3D *Engineer::pick_track(int x, int y) { - float xx = (static_cast(x-static_cast(screen_w)/2-100)/screen_h)*0.82843; - float yy = (static_cast(y)/screen_h-0.5)*0.82843; - float size = 4.0/screen_h*0.82843; + float view_height = tan(camera.get_field_of_view()/2)*2; + float xx = ((float(x)-window->get_width()/2)/window->get_height())*view_height; + float yy = (float(y)/window->get_height()-0.5)*view_height; + float size = 4.0/window->get_height()*view_height; - project_3d(); - glLoadIdentity(); - glRotatef(-cam_rot*180/M_PI, 0, 0, 1); - glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z); + camera.apply(); return layout_3d.pick_track(xx, yy, size); } @@ -514,7 +413,7 @@ void Engineer::train_added(Train &train) train_panels.push_back(tpanel); tpanel->set_visible(true); - place_train(train); + new_trains.push_back(&train); } void Engineer::sighandler(int sig) diff --git a/source/engineer/engineer.h b/source/engineer/engineer.h index 31952ba..3e7a910 100644 --- a/source/engineer/engineer.h +++ b/source/engineer/engineer.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of the MSP Märklin suite -Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa +Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ @@ -9,8 +9,11 @@ Distributed under the GPL #define ENGINEER_H_ #include -#include -#include +#include +#include +#include +#include +#include #include #include #include "libmarklin/catalogue.h" @@ -19,6 +22,7 @@ Distributed under the GPL #include "libmarklin/trafficmanager.h" #include "libmarklin/train.h" #include "3d/layout.h" +#include "3d/overlay.h" #include "network/server.h" class MainPanel; @@ -28,12 +32,7 @@ class TrainProperties; class Engineer: public Msp::Application { private: - Msp::Graphics::Display *dpy; - Msp::Graphics::Window *wnd; - Msp::Graphics::GLContext *glc; - unsigned screen_w; - unsigned screen_h; - bool fullscreen; + Msp::Graphics::SimpleGLWindow *window; Msp::GLtk::Resources ui_res; Msp::GLtk::Root *root; @@ -44,9 +43,14 @@ private: Marklin::TrafficManager *trfc_mgr; Marklin::Server *server; Msp::IO::EventDispatcher event_disp; + Marklin::Overlay3D *overlay; + std::list new_trains; - Marklin::Point cam_pos; - float cam_rot; + Msp::GL::Camera camera; + Msp::GL::Lighting lighting; + Msp::GL::Light light; + Msp::GL::Pipeline *pipeline; + Msp::GL::Mesh arrow_mesh; MainPanel *main_panel; std::list train_panels; @@ -54,7 +58,6 @@ private: Marklin::Block *placing_block; unsigned placing_entry; - bool no_lighting; bool simulate; public: @@ -73,14 +76,12 @@ public: private: void tick(); void button_press(int, int, unsigned, unsigned); - void button_release(int, int, unsigned, unsigned); void pointer_motion(int, int); void view_all(); void set_block_color(const Marklin::Block &, const Msp::GL::Color &); void reset_block_color(const Marklin::Block &); void sensor_event(bool, Marklin::Sensor *); void block_reserved(const Marklin::Block &, const Marklin::Train *); - void project_3d(); Marklin::Track3D *pick_track(int, int); void train_added(Marklin::Train &); virtual void sighandler(int); diff --git a/source/engineer/trainproperties.cpp b/source/engineer/trainproperties.cpp index eb132c0..004747c 100644 --- a/source/engineer/trainproperties.cpp +++ b/source/engineer/trainproperties.cpp @@ -66,6 +66,7 @@ void TrainProperties::on_ok_clicked() unsigned addr = lexical_cast(ent_addr->get_text()); Locomotive *loco = new Locomotive(*i->second, engineer.get_control(), addr); train = new Train(engineer.get_traffic_manager(), *loco); + engineer.place_train(*train); } train->set_name(ent_name->get_text()); diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index c127086..56832c8 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -580,7 +580,7 @@ Train::Loader::Loader(Train &t): { add("block", &Loader::block); add("block_hint", &Loader::block_hint); - add("name", &Train::name); + add("name", &Loader::name); add("real_speed", &Loader::real_speed); add("route", &Loader::route); } @@ -596,7 +596,7 @@ void Train::Loader::block(unsigned id) blk.reserve(&obj); obj.cur_blocks.push_back(BlockRef(&blk, entry)); - obj.status = "Stopped"; + obj.set_status("Stopped"); obj.set_position(blk.get_endpoints()[entry]); prev_block = &blk; @@ -607,6 +607,11 @@ void Train::Loader::block_hint(unsigned id) prev_block = &obj.trfc_mgr.get_block(id); } +void Train::Loader::name(const string &n) +{ + obj.set_name(n); +} + void Train::Loader::real_speed(unsigned i, float speed, float weight) { obj.real_speed[i].speed = speed; @@ -615,7 +620,7 @@ void Train::Loader::real_speed(unsigned i, float speed, float weight) void Train::Loader::route(const string &n) { - obj.route = &obj.trfc_mgr.get_layout().get_route(n); + obj.set_route(&obj.trfc_mgr.get_layout().get_route(n)); } } // namespace Marklin diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index 4e8734f..530d020 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -34,6 +34,7 @@ public: private: void block(unsigned); void block_hint(unsigned); + void name(const std::string &); void real_speed(unsigned, float, float); void route(const std::string &); };