]> git.tdb.fi Git - r2c2.git/blob - source/designer/trackwrap.cpp
863434fb3d1299d5433f5547e77b1ce7f05621eb
[r2c2.git] / source / designer / trackwrap.cpp
1 #include <msp/gl/matrix.h>
2 #include <msp/gl/meshbuilder.h>
3 #include <msp/gl/renderer.h>
4 #include "3d/tracktype.h"
5 #include "selection.h"
6 #include "trackwrap.h"
7
8 using namespace std;
9 using namespace Msp;
10 using namespace R2C2;
11
12 TrackWrap::TrackWrap(Layout3D &l, Selection &s):
13         layout(l),
14         selection(s)
15 {
16         selection.signal_changed.connect(sigc::mem_fun(this, &TrackWrap::selection_changed));
17 }
18
19 TrackWrap::~TrackWrap()
20 {
21         for(map<const TrackType *, GL::Mesh *>::iterator i=meshes.begin(); i!=meshes.end(); ++i)
22                 delete i->second;
23 }
24
25 void TrackWrap::render(GL::Renderer &renderer, const GL::Tag &) const
26 {
27         for(list<Wrap>::const_iterator i=wraps.begin(); i!=wraps.end(); ++i)
28         {
29                 GL::MatrixStack::Push push(renderer.matrix_stack());
30                 const Vector &pos = i->track->get_position();
31                 renderer.matrix_stack() *= GL::Matrix::translation(pos.x, pos.y, pos.z);
32                 renderer.matrix_stack() *= GL::Matrix::rotation(i->track->get_rotation(), 0, 0, 1);
33                 i->mesh->draw(renderer);
34         }
35 }
36
37 void TrackWrap::selection_changed()
38 {
39         wraps.clear();
40         const set<Track *> &tracks = selection.get_objects<Track>();
41         for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
42         {
43                 Wrap wrap;
44                 wrap.track = *i;
45                 wrap.mesh = &get_mesh((*i)->get_type());
46                 wraps.push_back(wrap);
47         }
48 }
49
50 GL::Mesh &TrackWrap::get_mesh(const TrackType &type)
51 {
52         map<const TrackType *, GL::Mesh *>::iterator j = meshes.find(&type);
53         if(j!=meshes.end())
54                 return *j->second;
55
56         const TrackType3D &type3d = layout.get_catalogue().get_track(type);
57
58         float min_area = -1;
59         float angle = 0;
60         Vector center;
61         float width = 0;
62         float height = 0;
63         for(float a=0; a<M_PI; a+=0.01)
64         {
65                 Vector minp, maxp;
66                 type3d.get_bounds(a, minp, maxp);
67                 float area = (maxp.x-minp.x)*(maxp.y-minp.y);
68                 if(area<min_area || min_area<0)
69                 {
70                         float c = cos(a);
71                         float s = sin(a);
72                         float x = (minp.x+maxp.x)/2;
73                         float y = (minp.y+maxp.y)/2;
74                         center = Vector(c*x-s*y, s*x+c*y, minp.z);
75                         angle = a;
76                         width = maxp.x-minp.x+0.01;
77                         height = maxp.y-minp.y+0.01;
78
79                         min_area = area;
80                 }
81         }
82
83         GL::Mesh *mesh = new GL::Mesh((GL::COLOR4_UBYTE, GL::VERTEX2));
84         GL::MeshBuilder bld(*mesh);
85         bld.color(0.0f, 1.0f, 0.0f, 1.0f);
86
87         float c = cos(angle);
88         float s = sin(angle);
89
90         bld.begin(GL::LINE_LOOP);
91         bld.vertex(center.x-c*width/2+s*height/2, center.y-s*width/2-c*height/2);
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.end();
96
97         meshes[&type] = mesh;
98
99         return *mesh;
100 }