]> git.tdb.fi Git - r2c2.git/blob - source/engineer/trainview.cpp
4e43993954ba5fc57c9b6d13df0a9374f6f094eb
[r2c2.git] / source / engineer / trainview.cpp
1 #include <msp/core/maputils.h>
2 #include <msp/gl/tests.h>
3 #include <msp/gltk/button.h>
4 #include <msp/gltk/image.h>
5 #include <msp/gltk/label.h>
6 #include <msp/strings/format.h>
7 #include "libr2c2/vehicle.h"
8 #include "libr2c2/vehicletype.h"
9 #include "engineer.h"
10 #include "trainview.h"
11
12 using namespace Msp;
13 using namespace R2C2;
14
15 TrainView::TrainView(Engineer &e, const Train &t):
16         engineer(e),
17         train(t),
18         mode(SIDE),
19         forward(true),
20         view(engineer.get_layout_3d(), 400, 300)
21 {
22         Loader::WidgetMap widgets;
23         DataFile::load(*this, "data/trainview.ui", widgets);
24
25         dynamic_cast<GLtk::Label *>(get_item(widgets, "lbl_title"))->set_text(format("View of %s", train.get_name()));
26         dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_forward"))->signal_toggled.connect(sigc::mem_fun(this, &TrainView::set_forward));
27         dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_roof"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainView::ui_mode_toggled), ROOF));
28         dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_side"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainView::ui_mode_toggled), SIDE));
29         dynamic_cast<GLtk::Toggle *>(get_item(widgets, "tgl_head"))->signal_toggled.connect(sigc::bind(sigc::mem_fun(this, &TrainView::ui_mode_toggled), HEAD));
30
31         tex.set_min_filter(GL::LINEAR);
32         tex.storage(GL::RGB, 400, 300);
33         tex.image(0, GL::RGB, GL::UNSIGNED_BYTE, 0);
34         fbo.attach(GL::COLOR_ATTACHMENT0, tex, 0);
35         depth.storage(GL::DEPTH_COMPONENT, 400, 300);
36         fbo.attach(GL::DEPTH_ATTACHMENT, depth);
37
38         view.get_camera().set_depth_clip(0.01, 10);
39
40         dynamic_cast<GLtk::Image *>(get_item(widgets, "img_view"))->set_image(&tex);
41
42         engineer.add_train_view(*this);
43 }
44
45 TrainView::~TrainView()
46 {
47         engineer.remove_train_view(*this);
48 }
49
50 void TrainView::set_mode(Mode m)
51 {
52         mode = m;
53 }
54
55 void TrainView::ui_mode_toggled(bool v, Mode m)
56 {
57         if(v)
58                 set_mode(m);
59 }
60
61 void TrainView::set_forward(bool f)
62 {
63         forward = f;
64 }
65
66 void TrainView::prepare()
67 {
68         const Vehicle &veh = train.get_vehicle(0);
69         const Vector &pos = veh.get_position();
70         Angle angle = veh.get_rotation();
71         if(!forward)
72                 angle += Angle::half_turn();
73         Vector fwd_vec = rotated_vector(Vector(1, 0, 0), angle);
74         Vector side_vec = rotated_vector(Vector(0, -1, 0), angle);
75         float l = veh.get_type().get_length();
76
77         GL::Camera &camera = view.get_camera();
78         switch(mode)
79         {
80         case ROOF:
81                 camera.set_position(pos-l*fwd_vec+Vector(0, 0, 0.07));
82                 camera.set_look_direction(fwd_vec-Vector(0, 0, 0.2));
83                 break;
84         case SIDE:
85                 camera.set_position(pos-0.08f*fwd_vec+0.05f*side_vec+Vector(0, 0, 0.03));
86                 camera.set_look_direction(fwd_vec-side_vec*0.2f);
87                 break;
88         case HEAD:
89                 camera.set_position(pos+fwd_vec*(l*0.55f)+Vector(0, 0, 0.03));
90                 camera.set_look_direction(fwd_vec);
91                 break;
92         }
93
94         GL::Bind _bind_fbo(fbo);
95         fbo.clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
96         view.render();
97 }