]> git.tdb.fi Git - r2c2.git/blob - source/engineer/trainview.cpp
Add framework for generating simple meshes for vehicles
[r2c2.git] / source / engineer / trainview.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <msp/gl/tests.h>
9 #include <msp/gltk/button.h>
10 #include <msp/gltk/image.h>
11 #include "libmarklin/vehicle.h"
12 #include "libmarklin/vehicletype.h"
13 #include "engineer.h"
14 #include "trainview.h"
15
16 using namespace Msp;
17 using namespace Marklin;
18
19 TrainView::TrainView(Engineer &e, const Train &t):
20         GLtk::Widget(e.get_ui_resources()),
21         GLtk::Panel(e.get_ui_resources()),
22         engineer(e),
23         train(t),
24         mode(SIDE),
25         forward(true),
26         pipeline(280, 280, false),
27         stale(false)
28 {
29         set_size(300, 330);
30
31         tex.set_min_filter(GL::LINEAR);
32         tex.storage(GL::RGB, 280, 280, 0);
33         tex.image(0, GL::RGB, GL::UNSIGNED_BYTE, 0);
34         fbo.attach(GL::COLOR_ATTACHMENT0, tex, 0);
35         depth.storage(GL::DEPTH_COMPONENT, 280, 280);
36         fbo.attach(GL::DEPTH_ATTACHMENT, depth);
37
38         camera.set_up_direction(GL::Vector3(0, 0, 1));
39         camera.set_depth_clip(0.01, 10);
40         camera.set_aspect(1);
41         pipeline.set_camera(&camera);
42
43         pipeline.add_renderable(engineer.get_layout_3d().get_scene());
44
45         GL::PipelinePass *pass = &pipeline.add_pass(0);
46         pass->depth_test = &GL::DepthTest::lequal();
47         pass->lighting = &engineer.get_lighting();
48
49         GLtk::Image *image;
50         add(*(image = new GLtk::Image(res, &tex)));
51         image->set_geometry(GLtk::Geometry(10, 40, geom.w-20, geom.h-50));
52
53         GLtk::Button *btn;
54
55         add(*(btn = new GLtk::Button(res, "Roof")));
56         btn->set_geometry(GLtk::Geometry(10, 10, 36, 25));
57         btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), ROOF));
58
59         add(*(btn = new GLtk::Button(res, "Side")));
60         btn->set_geometry(GLtk::Geometry(46, 10, 36, 25));
61         btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), SIDE));
62
63         add(*(btn = new GLtk::Button(res, "Head")));
64         btn->set_geometry(GLtk::Geometry(82, 10, 36, 25));
65         btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), HEAD));
66
67         add(*(tgl_forward = new GLtk::Toggle(res, "Fwd")));
68         tgl_forward->set_geometry(GLtk::Geometry(118, 8, 36, 27));
69         tgl_forward->set_value(true);
70         tgl_forward->signal_toggled.connect(sigc::mem_fun(this, &TrainView::set_forward));
71
72         add(*(btn = new GLtk::Button(res, "Close")));
73         btn->set_geometry(GLtk::Geometry(geom.w-46, 10, 36, 25));
74         btn->signal_clicked.connect(sigc::mem_fun(this, &TrainView::close_clicked));
75
76         engineer.add_train_view(*this);
77 }
78
79 TrainView::~TrainView()
80 {
81         engineer.remove_train_view(*this);
82 }
83
84 void TrainView::set_mode(Mode m)
85 {
86         mode = m;
87 }
88
89 void TrainView::set_forward(bool f)
90 {
91         forward = f;
92 }
93
94 void TrainView::prepare()
95 {
96         const Vehicle &veh = train.get_vehicle(0);
97         const Point &pos = veh.get_position();
98         float angle = veh.get_direction();
99         if(!forward)
100                 angle += M_PI;
101         float c = cos(angle);
102         float s = sin(angle);
103         float l = veh.get_type().get_length();
104
105         switch(mode)
106         {
107         case ROOF:
108                 camera.set_position(GL::Vector3(pos.x-l*c, pos.y-l*s, pos.z+0.07));
109                 camera.set_look_direction(GL::Vector3(c, s, -0.2));
110                 break;
111         case SIDE:
112                 camera.set_position(GL::Vector3(pos.x-l*0.8*c+0.05*s, pos.y-l*0.8*s-0.05*c, pos.z+0.03));
113                 camera.set_look_direction(GL::Vector3(c-0.2*s, s+0.2*c, 0));
114                 break;
115         case HEAD:
116                 camera.set_position(GL::Vector3(pos.x+l*0.55*c, pos.y+l*0.55*s, pos.z+0.03));
117                 camera.set_look_direction(GL::Vector3(c, s, 0));
118                 break;
119         }
120
121         GL::Bind _bind_fbo(fbo);
122         fbo.clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
123         pipeline.render_all();
124 }
125
126 void TrainView::button_release(int x, int y, unsigned btn)
127 {
128         GLtk::Panel::button_release(x, y, btn);
129         if(stale)
130                 delete this;
131 }
132
133 void TrainView::close_clicked()
134 {
135         stale = true;
136 }