]> git.tdb.fi Git - r2c2.git/blobdiff - source/engineer/trainview.cpp
Add TrainView for viewing the layout from the train's perspective
[r2c2.git] / source / engineer / trainview.cpp
diff --git a/source/engineer/trainview.cpp b/source/engineer/trainview.cpp
new file mode 100644 (file)
index 0000000..b27136c
--- /dev/null
@@ -0,0 +1,123 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010  Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <msp/gl/tests.h>
+#include <msp/gltk/button.h>
+#include <msp/gltk/image.h>
+#include "libmarklin/vehicle.h"
+#include "libmarklin/vehicletype.h"
+#include "engineer.h"
+#include "trainview.h"
+
+using namespace Msp;
+using namespace Marklin;
+
+TrainView::TrainView(Engineer &e, const Train &t):
+       GLtk::Widget(e.get_ui_resources()),
+       GLtk::Panel(e.get_ui_resources()),
+       engineer(e),
+       train(t),
+       mode(SIDE),
+       pipeline(280, 280, false),
+       stale(false)
+{
+       set_size(300, 330);
+
+       tex.set_min_filter(GL::LINEAR);
+       tex.storage(GL::RGB, 280, 280, 0);
+       tex.image(0, GL::RGB, GL::UNSIGNED_BYTE, 0);
+       fbo.attach(GL::COLOR_ATTACHMENT0, tex, 0);
+       depth.storage(GL::DEPTH_COMPONENT, 280, 280);
+       fbo.attach(GL::DEPTH_ATTACHMENT, depth);
+
+       camera.set_up_direction(GL::Vector3(0, 0, 1));
+       camera.set_depth_clip(0.01, 10);
+       camera.set_aspect(1);
+       pipeline.set_camera(&camera);
+
+       pipeline.add_renderable(engineer.get_layout_3d().get_scene());
+
+       GL::PipelinePass *pass = &pipeline.add_pass(0);
+       pass->depth_test = &GL::DepthTest::lequal();
+       pass->lighting = &engineer.get_lighting();
+
+       GLtk::Image *image;
+       add(*(image = new GLtk::Image(res, &tex)));
+       image->set_geometry(GLtk::Geometry(10, 40, geom.w-20, geom.h-50));
+
+       GLtk::Button *btn;
+
+       add(*(btn = new GLtk::Button(res, "Roof")));
+       btn->set_geometry(GLtk::Geometry(10, 10, 36, 25));
+       btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), ROOF));
+
+       add(*(btn = new GLtk::Button(res, "Side")));
+       btn->set_geometry(GLtk::Geometry(46, 10, 36, 25));
+       btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), SIDE));
+
+       add(*(btn = new GLtk::Button(res, "Head")));
+       btn->set_geometry(GLtk::Geometry(82, 10, 36, 25));
+       btn->signal_clicked.connect(sigc::bind(sigc::mem_fun(this, &TrainView::set_mode), HEAD));
+
+       add(*(btn = new GLtk::Button(res, "Close")));
+       btn->set_geometry(GLtk::Geometry(geom.w-46, 10, 36, 25));
+       btn->signal_clicked.connect(sigc::mem_fun(this, &TrainView::close_clicked));
+
+       engineer.add_train_view(*this);
+}
+
+TrainView::~TrainView()
+{
+       engineer.remove_train_view(*this);
+}
+
+void TrainView::set_mode(Mode m)
+{
+       mode = m;
+}
+
+void TrainView::prepare()
+{
+       const Vehicle &veh = train.get_vehicle(0);
+       const Point &pos = veh.get_position();
+       float angle = veh.get_direction();
+       float c = cos(angle);
+       float s = sin(angle);
+       float l = veh.get_type().get_length();
+
+       switch(mode)
+       {
+       case ROOF:
+               camera.set_position(GL::Vector3(pos.x-l*c, pos.y-l*s, pos.z+0.07));
+               camera.set_look_direction(GL::Vector3(c, s, -0.2));
+               break;
+       case SIDE:
+               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));
+               camera.set_look_direction(GL::Vector3(c-0.2*s, s+0.2*c, 0));
+               break;
+       case HEAD:
+               camera.set_position(GL::Vector3(pos.x+l*0.55*c, pos.y+l*0.55*s, pos.z+0.03));
+               camera.set_look_direction(GL::Vector3(c, s, 0));
+               break;
+       }
+
+       GL::Bind _bind_fbo(fbo);
+       fbo.clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT);
+       pipeline.render_all();
+}
+
+void TrainView::button_release(int x, int y, unsigned btn)
+{
+       GLtk::Panel::button_release(x, y, btn);
+       if(stale)
+               delete this;
+}
+
+void TrainView::close_clicked()
+{
+       stale = true;
+}