]> git.tdb.fi Git - r2c2.git/blob - source/3d/layout.cpp
Split mesh generation from Track3D to TrackType3D
[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/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         catalogue(layout.get_catalogue()),
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 }
40
41 void Layout3D::render(bool endpoints) const
42 {
43         GL::Texture::unbind();
44         glEnable(GL_DEPTH_TEST);
45
46         for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
47                 (*i)->render();
48
49         if(endpoints)
50         {
51                 glDepthMask(false);
52                 for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
53                         (*i)->render_endpoints();
54                 glDepthMask(true);
55         }
56 }
57
58 Track3D &Layout3D::get_track(const Track &t) const
59 {
60         for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
61                 if(&(*i)->get_track()==&t)
62                         return **i;
63         
64         throw KeyError("Unknown track");
65 }
66
67 Track3D *Layout3D::pick_track(float x, float y, float size) const
68 {
69         vector<GL::SelectRecord> select_buf;
70         GL::select_buffer(select_buf);
71         GL::render_mode(GL::SELECT);
72
73         glPushMatrix();
74         glLoadIdentity();
75
76         double clip[4];
77         clip[0] = 1;
78         clip[1] = 0;
79         clip[2] = x-size;
80         clip[3] = 0;
81         glClipPlane(GL_CLIP_PLANE0, clip);
82         glEnable(GL_CLIP_PLANE0);
83
84         clip[0] = -1;
85         clip[2] = -(x+size);
86         glClipPlane(GL_CLIP_PLANE1, clip);
87         glEnable(GL_CLIP_PLANE1);
88
89         clip[0] = 0;
90         clip[1] = 1;
91         clip[2] = y-size;
92         glClipPlane(GL_CLIP_PLANE2, clip);
93         glEnable(GL_CLIP_PLANE2);
94
95         clip[1] = -1;
96         clip[2] = -(y+size);
97         glClipPlane(GL_CLIP_PLANE3, clip);
98         glEnable(GL_CLIP_PLANE3);
99
100         glPopMatrix();
101
102         render();
103
104         glDisable(GL_CLIP_PLANE0);
105         glDisable(GL_CLIP_PLANE1);
106         glDisable(GL_CLIP_PLANE2);
107         glDisable(GL_CLIP_PLANE3);
108
109         GL::render_mode(GL::RENDER);
110         Track3D *track = 0;
111         unsigned track_depth = numeric_limits<unsigned>::max();
112         for(vector<GL::SelectRecord>::iterator i=select_buf.begin(); i!=select_buf.end(); ++i)
113                 if(i->min_depth<track_depth)
114                 {
115                         track = reinterpret_cast<Track3D *>(i->names.back());
116                         track_depth = i->min_depth;
117                 }
118
119         return track;
120 }
121
122 void Layout3D::track_added(Track &t)
123 {
124         tracks.push_back(new Track3D(*this, t));
125 }
126
127 void Layout3D::track_removed(Track &t)
128 {
129         for(list<Track3D *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
130                 if(&(*i)->get_track()==&t)
131                 {
132                         delete *i;
133                         tracks.erase(i);
134                         return;
135                 }
136 }
137
138 } // namespace Marklin