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