]> git.tdb.fi Git - r2c2.git/blob - source/3d/layout.cpp
Add Id tags and copyright notices to files
[r2c2.git] / source / 3d / layout.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2006-2008 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <algorithm>
9 #include <fstream>
10 #include <msp/gl/rendermode.h>
11 #include <msp/gl/select.h>
12 #include <msp/gl/texture.h>
13 #include <msp/datafile/parser.h>
14 #include "layout.h"
15
16 using namespace std;
17 using namespace Msp;
18
19 namespace Marklin {
20
21 Layout3D::Layout3D(Layout &l):
22         layout(l),
23         quality(4)
24 {
25         layout.signal_track_added.connect(sigc::mem_fun(this, &Layout3D::track_added));
26         layout.signal_track_removed.connect(sigc::mem_fun(this, &Layout3D::track_removed));
27 }
28
29 Layout3D::~Layout3D()
30 {
31         for(list<Track3D *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
32                 delete *i;
33 }
34
35 void Layout3D::set_quality(unsigned q)
36 {
37         quality=q;
38         for(list<Track3D *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
39                 (*i)->set_quality(quality);
40 }
41
42 void Layout3D::render(bool endpoints) const
43 {
44         GL::Texture::unbind();
45         glEnable(GL_DEPTH_TEST);
46
47         for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
48                 (*i)->render();
49
50         if(endpoints)
51         {
52                 glDepthMask(false);
53                 for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
54                         (*i)->render_endpoints();
55                 glDepthMask(true);
56         }
57 }
58
59 Track3D &Layout3D::get_track(const Track &t) const
60 {
61         for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
62                 if(&(*i)->get_track()==&t)
63                         return **i;
64         
65         throw KeyError("Unknown track");
66 }
67
68 Track3D *Layout3D::pick_track(float x, float y, float size) const
69 {
70         vector<GL::SelectRecord> select_buf;
71         GL::select_buffer(select_buf);
72         GL::render_mode(GL::SELECT);
73
74         glPushMatrix();
75         glLoadIdentity();
76
77         double clip[4];
78         clip[0]=1;
79         clip[1]=0;
80         clip[2]=x-size;
81         clip[3]=0;
82         glClipPlane(GL_CLIP_PLANE0, clip);
83         glEnable(GL_CLIP_PLANE0);
84
85         clip[0]=-1;
86         clip[2]=-(x+size);
87         glClipPlane(GL_CLIP_PLANE1, clip);
88         glEnable(GL_CLIP_PLANE1);
89
90         clip[0]=0;
91         clip[1]=1;
92         clip[2]=y-size;
93         glClipPlane(GL_CLIP_PLANE2, clip);
94         glEnable(GL_CLIP_PLANE2);
95
96         clip[1]=-1;
97         clip[2]=-(y+size);
98         glClipPlane(GL_CLIP_PLANE3, clip);
99         glEnable(GL_CLIP_PLANE3);
100
101         glPopMatrix();
102
103         render();
104
105         glDisable(GL_CLIP_PLANE0);
106         glDisable(GL_CLIP_PLANE1);
107         glDisable(GL_CLIP_PLANE2);
108         glDisable(GL_CLIP_PLANE3);
109
110         GL::render_mode(GL::RENDER);
111         Track3D *track=0;
112         unsigned track_depth=numeric_limits<unsigned>::max();
113         for(vector<GL::SelectRecord>::iterator i=select_buf.begin(); i!=select_buf.end(); ++i)
114                 if(i->min_depth<track_depth)
115                 {
116                         track=reinterpret_cast<Track3D *>(i->names.back());
117                         track_depth=i->min_depth;
118                 }
119
120         return track;
121 }
122
123 void Layout3D::track_added(Track &t)
124 {
125         tracks.push_back(new Track3D(t, quality));
126 }
127
128 void Layout3D::track_removed(Track &t)
129 {
130         for(list<Track3D *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
131                 if(&(*i)->get_track()==&t)
132                 {
133                         delete *i;
134                         tracks.erase(i);
135                         return;
136                 }
137 }
138
139 } // namespace Marklin