]> git.tdb.fi Git - r2c2.git/blob - source/3d/layout.cpp
Add accessors adding things to a Catalogue from the outside
[r2c2.git] / source / 3d / layout.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <algorithm>
9 #include <limits>
10 #include <msp/gl/clip.h>
11 #include <msp/gl/matrix.h>
12 #include <msp/gl/rendermode.h>
13 #include <msp/gl/select.h>
14 #include <msp/gl/texture.h>
15 #include <msp/datafile/parser.h>
16 #include "layout.h"
17
18 using namespace std;
19 using namespace Msp;
20
21 namespace Marklin {
22
23 Layout3D::Layout3D(Layout &l):
24         layout(l),
25         catalogue(layout.get_catalogue())
26 {
27         layout.signal_track_added.connect(sigc::mem_fun(this, &Layout3D::track_added));
28         layout.signal_track_removed.connect(sigc::mem_fun(this, &Layout3D::track_removed));
29
30         const set<Track *> &ltracks = layout.get_tracks();
31         for(set<Track *>::iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
32                 track_added(**i);
33 }
34
35 Layout3D::~Layout3D()
36 {
37         while(!tracks.empty())
38                 delete tracks.front();
39 }
40
41 void Layout3D::add_track(Track3D &t)
42 {
43         tracks.push_back(&t);
44 }
45
46 void Layout3D::remove_track(Track3D &t)
47 {
48         list<Track3D *>::iterator i = find(tracks.begin(), tracks.end(), &t);
49         if(i!=tracks.end())
50                 tracks.erase(i);
51 }
52
53 Track3D &Layout3D::get_track(const Track &t) const
54 {
55         for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
56                 if(&(*i)->get_track()==&t)
57                         return **i;
58
59         throw KeyError("Unknown track");
60 }
61
62 Track3D *Layout3D::pick_track(float x, float y, float size) const
63 {
64         vector<GL::SelectRecord> select_buf;
65         GL::select_buffer(select_buf);
66         GL::render_mode(GL::SELECT);
67
68         {
69                 GL::PushMatrix push_mat;
70                 GL::load_identity();
71
72                 GL::ClipPlane(1, 0, x-size, 0).apply_to(0);
73                 GL::ClipPlane(-1, 0, -x-size, 0).apply_to(1);
74                 GL::ClipPlane(0, 1, y-size, 0).apply_to(2);
75                 GL::ClipPlane(0, -1, -y-size, 0).apply_to(3);
76         }
77
78         scene.render(0);
79
80         GL::ClipPlane::disable(0);
81         GL::ClipPlane::disable(1);
82         GL::ClipPlane::disable(2);
83         GL::ClipPlane::disable(3);
84
85         GL::render_mode(GL::RENDER);
86         Track3D *track = 0;
87         unsigned track_depth = numeric_limits<unsigned>::max();
88         for(vector<GL::SelectRecord>::iterator i=select_buf.begin(); i!=select_buf.end(); ++i)
89                 if(i->min_depth<track_depth)
90                 {
91                         track = reinterpret_cast<Track3D *>(i->names.back());
92                         track_depth = i->min_depth;
93                 }
94
95         return track;
96 }
97
98 void Layout3D::track_added(Track &t)
99 {
100         new Track3D(*this, t);
101 }
102
103 void Layout3D::track_removed(Track &t)
104 {
105         for(list<Track3D *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
106                 if(&(*i)->get_track()==&t)
107                 {
108                         delete *i;
109                         return;
110                 }
111 }
112
113 } // namespace Marklin