--- /dev/null
+vertices VERTEX2
+{
+ vertex2 0.0 0.45;
+ vertex2 0.4 0.45;
+ vertex2 0.0 0.65;
+ vertex2 0.4 0.65;
+ vertex2 1.0 0.35;
+ vertex2 0.6 0.35;
+ vertex2 1.0 0.55;
+ vertex2 0.6 0.55;
+};
+batch LINES
+{
+ indices 0 1;
+ indices 2 3;
+ indices 4 5;
+ indices 6 7;
+};
+
--- /dev/null
+vertices VERTEX2
+{
+ vertex2 0.0 0.45;
+ vertex2 0.3 0.45;
+ vertex2 1.0 0.45;
+ vertex2 0.7 0.45;
+ vertex2 0.3 0.65;
+};
+batch LINES
+{
+ indices 0 1;
+ indices 2 3 3 4;
+};
--- /dev/null
+vertices VERTEX2
+{
+ vertex2 0.0 0.3;
+ vertex2 1.0 0.3;
+ vertex2 0.34730 0.33038;
+ vertex2 0.68404 0.42061;
+ vertex2 1.0 0.56795;
+ vertex2 0.0 0.5;
+ vertex2 1.0 0.5;
+ vertex2 0.31257 0.52735;
+ vertex2 0.61564 0.60855;
+ vertex2 0.9 0.74115;
+};
+batch LINES
+{
+ indices 0 1;
+ indices 0 2 2 3 3 4;
+ indices 5 6;
+ indices 5 7 7 8 8 9;
+};
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <algorithm>
+#include <cmath>
+#include <msp/fs/path.h>
+#include <msp/gl/matrix.h>
+#include <msp/gl/texture.h>
+#include <msp/io/print.h>
+#include "overlay.h"
+#include "track.h"
+#include "tracktype.h"
+
+using namespace std;
+using namespace Msp;
+
+namespace Marklin {
+
+Overlay3D::Overlay3D(const Graphics::Window &w, const GL::Camera &c, const GL::Font &f):
+ window(w),
+ camera(c),
+ font(f)
+{ }
+
+Overlay3D::~Overlay3D()
+{
+ for(map<string, GL::Mesh *>::iterator i=graphics.begin(); i!=graphics.end(); ++i)
+ delete i->second;
+}
+
+void Overlay3D::set_label(const Track3D &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)
+{
+ const GL::Mesh *grf = get_graphic(grf_name);
+ if(!grf)
+ return;
+
+ Icon &icon = get_icon(track);
+ if(find(icon.graphics.begin(), icon.graphics.end(), grf)==icon.graphics.end())
+ icon.graphics.push_back(grf);
+
+ update_icon(icon);
+}
+
+void Overlay3D::remove_graphic(const Track3D &track, const string &grf_name)
+{
+ const GL::Mesh *grf = get_graphic(grf_name);
+ Icon &icon = get_icon(track);
+ icon.graphics.erase(remove(icon.graphics.begin(), icon.graphics.end(), grf), icon.graphics.end());
+
+ update_icon(icon);
+}
+
+void Overlay3D::clear_graphics(const Track3D &track)
+{
+ get_icon(track).graphics.clear();
+ update_icon(get_icon(track));
+}
+
+void Overlay3D::clear(const Track3D &track)
+{
+ map<const Track3D *, Icon *>::iterator i = icons.find(&track);
+ if(i!=icons.end())
+ {
+ delete i->second;
+ icons.erase(i);
+ }
+}
+
+void Overlay3D::render(const GL::Tag &tag) const
+{
+ if(tag==0)
+ {
+ GL::matrix_mode(GL::PROJECTION);
+ GL::push_matrix();
+ GL::load_identity();
+ GL::scale(2.0/window.get_width(), 2.0/window.get_height(), 1.0);
+ GL::matrix_mode(GL::MODELVIEW);
+ GL::push_matrix();
+ GL::load_identity();
+
+ glLineWidth(1);
+
+ int size = int(font.get_default_size()+0.5);
+ 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 Track3D *, Icon *>::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);
+
+ GL::PushMatrix push_mat;
+ p.x = int(p.x*0.5*window.get_width()-icon.width*size/2);
+ p.y = int(p.y*0.5*window.get_height());
+ GL::translate(p.x, p.y, p.z);
+ GL::scale_uniform(size);
+
+ icon.background.draw();
+
+ glColor3f(0.0, 1.0, 0.0);
+ for(vector<const GL::Mesh *>::const_iterator j=icon.graphics.begin(); j!=icon.graphics.end(); ++j)
+ {
+ (*j)->draw();
+ GL::translate(spacing, 0, 0);
+ }
+
+ GL::translate(0, baseline, 0);
+ font.draw_string(icon.label);
+ GL::Texture::unbind();
+ }
+
+ GL::matrix_mode(GL::PROJECTION);
+ GL::pop_matrix();
+ GL::matrix_mode(GL::MODELVIEW);
+ GL::pop_matrix();
+ }
+}
+
+Overlay3D::Icon &Overlay3D::get_icon(const Track3D &track)
+{
+ Icon *&icon = icons[&track];
+ if(!icon)
+ icon = new Icon;
+
+ return *icon;
+}
+
+const GL::Mesh *Overlay3D::get_graphic(const string &name)
+{
+ GL::Mesh *&grf = graphics[name];
+ if(!grf)
+ {
+ grf = new GL::Mesh;
+ try
+ {
+ DataFile::load(*grf, (FS::Path("icons")/(name+".mesh")).str());
+ }
+ catch(const Exception &e)
+ {
+ IO::print("Error loading overlay graphic '%s': %s\n", name, e.what());
+ delete grf;
+ grf = 0;
+ }
+ }
+
+ return grf;
+}
+
+void Overlay3D::update_icon(Icon &icon)
+{
+ icon.background.clear();
+
+ icon.width = max(icon.graphics.size()*1.1+font.get_string_width(icon.label), 1.0);
+
+ GL::MeshBuilder bld(icon.background);
+ bld.color(0.2f, 0.2f, 0.2f, 0.7f);
+
+ bld.begin(GL::TRIANGLE_FAN);
+ bld.vertex(0.4, 0.5);
+ bld.vertex(icon.width-0.4, 0.5);
+ bld.vertex(icon.width-0.4, 1.2);
+ for(int i=4; i<=12; ++i)
+ bld.vertex(0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
+ bld.end();
+
+ bld.begin(GL::TRIANGLE_FAN);
+ bld.vertex(icon.width-0.4, 0.5);
+ bld.vertex(0.4, 0.5);
+ bld.vertex(0.4, -0.2);
+ for(int i=-4; i<=4; ++i)
+ bld.vertex(icon.width-0.4+cos(i*M_PI/8)*0.7, 0.5+sin(i*M_PI/8)*0.7);
+ bld.end();
+}
+
+
+Overlay3D::Icon::Icon():
+ width(1.0),
+ background((GL::COLOR4_UBYTE, GL::VERTEX2))
+{ }
+
+} // namespace Marklin
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef MARKLIN3D_OVERLAY_H_
+#define MARKLIN3D_OVERLAY_H_
+
+#include <msp/gbase/window.h>
+#include <msp/gl/camera.h>
+#include <msp/gl/font.h>
+#include <msp/gl/mesh.h>
+#include <msp/gl/renderable.h>
+
+namespace Marklin {
+
+class Track3D;
+
+class Overlay3D: public Msp::GL::Renderable
+{
+private:
+ struct Icon
+ {
+ std::vector<const Msp::GL::Mesh *> graphics;
+ std::string label;
+ float width;
+ Msp::GL::Mesh background;
+
+ Icon();
+ };
+
+ const Msp::Graphics::Window &window;
+ const Msp::GL::Camera &camera;
+ const Msp::GL::Font &font;
+ std::map<std::string, Msp::GL::Mesh *> graphics;
+ std::map<const Track3D *, Icon *> 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 &);
+
+ virtual void render(const Msp::GL::Tag &) const;
+
+private:
+ Icon &get_icon(const Track3D &);
+ const Msp::GL::Mesh *get_graphic(const std::string &);
+ void update_icon(Icon &);
+};
+
+} // namespace Marklin
+
+#endif
Track3D::Track3D(Layout3D &l, Track &t):
layout(l),
track(t),
- type(layout.get_catalogue().get_track(track.get_type())),
- color(1, 1, 1)
+ type(layout.get_catalogue().get_track(track.get_type()))
{
layout.add_track(*this);
layout.get_scene().add(*this);
delete *i;
}
-void Track3D::set_color(const Msp::GL::Color &c)
-{
- color = c;
-}
-
void Track3D::get_bounds(float angle, Point &minp, Point &maxp) const
{
type.get_bounds(angle-track.get_rotation(), minp, maxp);
Track &track;
const TrackType3D &type;
std::vector<Endpoint3D *> endpoints;
- Msp::GL::Color color;
public:
Track3D(Layout3D &, Track &);
Layout3D &get_layout() const { return layout; }
Track &get_track() const { return track; }
- void set_color(const Msp::GL::Color &);
+ const TrackType3D &get_type() const { return type; }
+ void set_color(const Msp::GL::Color &) { }
void get_bounds(float, Point &, Point &) const;
virtual void render(const Msp::GL::Tag &) const;
/* $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
*/
{
filename = argv[1];
DataFile::load(*layout, argv[1]);
- const list<Track3D *> <racks = layout_3d->get_tracks();
- for(list<Track3D *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
- update_track_color(**i);
if(!layout->get_base().empty())
{
root->add(*toolbar);
toolbar->set_position(0, window.get_height()-toolbar->get_geometry().h);
toolbar->set_visible(true);
+
+ overlay = new Overlay3D(window, camera, ui_res.get_default_font());
+
+ const list<Track3D *> &tracks = layout_3d->get_tracks();
+ for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ update_track_icon(**i);
}
Designer::~Designer()
if(*j!=*i)
(*i)->snap_to(**j, true);
- update_track_color(layout_3d->get_track(**i));
+ update_track_icon(layout_3d->get_track(**i));
}
}
else if(key==Msp::Input::KEY_F)
pipeline->render_all();
layout_3d->get_endpoint_scene().render();
GL::enable(GL_CULL_FACE);
+ GL::disable(GL::DEPTH_TEST);
+ overlay->render(0);
+ GL::enable(GL::DEPTH_TEST);
/*if(cur_route)
{
glColor4f(0.5, 0.8, 1.0, 1.0);
return l->pick_track(xx, yy, size);
}
-void Designer::update_track_color(Track3D &track)
+void Designer::update_track_icon(Track3D &track)
{
- if(track.get_track().get_sensor_id())
+ overlay->clear(track);
+
+ if(track.get_track().get_flex())
+ overlay->add_graphic(track, "flex");
+
+ if(unsigned sid = track.get_track().get_sensor_id())
{
- if(track.get_track().get_flex())
- track.set_color(GL::Color(1, 0.6, 1));
- else
- track.set_color(GL::Color(0.7, 0.7, 1));
+ overlay->add_graphic(track, "sensor");
+ overlay->set_label(track, lexical_cast(sid));
+ }
+ else if(unsigned tid = track.get_track().get_turnout_id())
+ {
+ overlay->add_graphic(track, "turnout");
+ overlay->set_label(track, lexical_cast(tid));
}
- else if(track.get_track().get_turnout_id())
- track.set_color(GL::Color(0.8, 1, 0.8));
- else if(track.get_track().get_flex())
- track.set_color(GL::Color(1, 0.8, 0.8));
- else
- track.set_color(GL::Color(1, 1, 1));
}
void Designer::manipulation_status(const string &status)
unsigned id = lexical_cast<unsigned>(input->get_text());
track->set_turnout_id(id);
- update_track_color(layout_3d->get_track(*track));
+ update_track_icon(layout_3d->get_track(*track));
input_dismiss();
}
{
(*i)->set_sensor_id(id);
- update_track_color(layout_3d->get_track(**i));
+ update_track_icon(layout_3d->get_track(**i));
}
input_dismiss();
/* $Id$
This file is part of the MSP Märklin suite
-Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa
+Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa
Distributed under the GPL
*/
#include "libmarklin/catalogue.h"
#include "libmarklin/layout.h"
#include "3d/layout.h"
+#include "3d/overlay.h"
#include "3d/track.h"
#include "cameracontroller.h"
#include "manipulator.h"
std::string filename;
Marklin::Layout *layout;
Marklin::Layout3D *layout_3d;
+ Marklin::Overlay3D *overlay;
Msp::GL::Object *base_object;
Marklin::Route *cur_route;
Msp::GL::Pipeline *pipeline;
Marklin::Layout *get_layout() { return layout; }
Marklin::Layout3D *get_layout_3d() { return layout_3d; }
+ const Msp::GL::Camera &get_camera() const { return camera; }
const Msp::GLtk::Resources &get_ui_resources() const { return ui_res; }
Msp::GLtk::Root &get_root() const { return *root; }
void edit_route(Marklin::Route &);
void apply_camera();
void render();
Marklin::Track3D *pick_track(int, int);
- void update_track_color(Marklin::Track3D &);
+ void update_track_icon(Marklin::Track3D &);
void manipulation_status(const std::string &);
void manipulation_done(bool);
void measure_changed();