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