]> git.tdb.fi Git - r2c2.git/blob - source/designer/trackwrap.cpp
b5070757efad2697e2ddc513934b33f172bc18d7
[r2c2.git] / source / designer / trackwrap.cpp
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <msp/gl/matrix.h>
9 #include <msp/gl/meshbuilder.h>
10 #include "3d/tracktype.h"
11 #include "designer.h"
12 #include "selection.h"
13 #include "trackwrap.h"
14
15 using namespace std;
16 using namespace Msp;
17 using namespace Marklin;
18
19 TrackWrap::TrackWrap(Designer &d, Selection &s):
20         designer(d),
21         selection(s)
22 {
23         selection.signal_changed.connect(sigc::mem_fun(this, &TrackWrap::selection_changed));
24 }
25
26 void TrackWrap::render(const GL::Tag &) const
27 {
28         for(list<Wrap>::const_iterator i=wraps.begin(); i!=wraps.end(); ++i)
29         {
30                 GL::PushMatrix _pushm;
31                 const Point &pos = i->track->get_position();
32                 GL::translate(pos.x, pos.y, pos.z);
33                 GL::rotate(i->track->get_rotation()*180/M_PI, 0, 0, 1);
34                 i->mesh->draw();
35         }
36 }
37
38 void TrackWrap::selection_changed()
39 {
40         wraps.clear();
41         const set<Track *> &tracks = selection.get_tracks();
42         for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
43         {
44                 Wrap wrap;
45                 wrap.track = *i;
46                 wrap.mesh = &get_mesh((*i)->get_type());
47                 wraps.push_back(wrap);
48         }
49 }
50
51 GL::Mesh &TrackWrap::get_mesh(const TrackType &type)
52 {
53         map<const TrackType *, GL::Mesh *>::iterator j = meshes.find(&type);
54         if(j!=meshes.end())
55                 return *j->second;
56
57         const TrackType3D &type3d = designer.get_layout_3d().get_catalogue().get_track(type);
58
59         float min_area = -1;
60         float angle = 0;
61         Point center;
62         float width = 0;
63         float height = 0;
64         for(float a=0; a<M_PI; a+=0.01)
65         {
66                 Point minp, maxp;
67                 type3d.get_bounds(a, minp, maxp);
68                 float area = (maxp.x-minp.x)*(maxp.y-minp.y);
69                 if(area<min_area || min_area<0)
70                 {
71                         float c = cos(a);
72                         float s = sin(a);
73                         float x = (minp.x+maxp.x)/2;
74                         float y = (minp.y+maxp.y)/2;
75                         center = Point(c*x-s*y, s*x+c*y, minp.z);
76                         angle = a;
77                         width = maxp.x-minp.x+0.01;
78                         height = maxp.y-minp.y+0.01;
79
80                         min_area = area;
81                 }
82         }
83
84         GL::Mesh *mesh = new GL::Mesh((GL::COLOR4_UBYTE, GL::VERTEX2));
85         GL::MeshBuilder bld(*mesh);
86         bld.color(0.0f, 1.0f, 0.0f, 1.0f);
87
88         float c = cos(angle);
89         float s = sin(angle);
90
91         bld.begin(GL::LINE_LOOP);
92         bld.vertex(center.x-c*width/2+s*height/2, center.y-s*width/2-c*height/2);
93         bld.vertex(center.x+c*width/2+s*height/2, center.y+s*width/2-c*height/2);
94         bld.vertex(center.x+c*width/2-s*height/2, center.y+s*width/2+c*height/2);
95         bld.vertex(center.x-c*width/2-s*height/2, center.y-s*width/2+c*height/2);
96         bld.end();
97
98         meshes[&type] = mesh;
99
100         return *mesh;
101 }