3 #include <msp/gl/technique.h>
12 TrackType3D::TrackType3D(Catalogue3D &cat3d, const TrackType &tt):
17 const Catalogue &cat = cat3d.get_catalogue();
18 const vector<TrackPart> &parts = tt.get_parts();
20 const Profile &ballast_profile = cat.get_ballast_profile();
21 const Vector &ballast_min = ballast_profile.get_min_coords();
22 const Vector &ballast_max = ballast_profile.get_max_coords();
23 float ballast_h = ballast_max.y-ballast_min.y;
25 const Profile &rail_profile = cat.get_rail_profile();
26 const Vector &rail_min = rail_profile.get_min_coords();
27 const Vector &rail_max = rail_profile.get_max_coords();
28 float rail_h = rail_max.y-rail_min.y;
30 float gauge = cat.get_gauge();
32 string obj_name = tt.get_object();
34 object = &catalogue.get<GL::Object>(obj_name);
37 mesh = new GL::Mesh((GL::NORMAL3, GL::TEXCOORD2, GL::VERTEX3));
38 mesh->set_winding(&GL::WindingTest::counterclockwise());
39 GL::MeshBuilder bld(*mesh);
42 bld.texcoord(0.25, 0.5);
43 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
44 build_part(*i, ballast_profile, Vector(0, -ballast_min.y, 0), false, bld, index);
46 bld.texcoord(0.75, 0.5);
47 float y = ballast_h-rail_min.y;
48 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
49 build_part(*i, rail_profile, Vector(0, gauge/2, y), true, bld, index);
50 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
51 build_part(*i, rail_profile, Vector(0, -gauge/2, y), false, bld, index);
53 object = new GL::Object;
54 object->set_mesh(mesh);
55 object->set_technique(&catalogue.get<GL::Technique>(cat.get_track_technique()));
58 unsigned paths = tt.get_paths();
59 for(unsigned i=0; paths; ++i, paths>>=1)
64 m = new GL::Mesh(GL::VERTEX3);
65 GL::MeshBuilder bld(*m);
67 for(vector<TrackPart>::const_iterator j=parts.begin(); j!=parts.end(); ++j)
69 build_part(*j, cat.get_path_profile(), Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index);
71 path_meshes.push_back(m);
75 TrackType3D::~TrackType3D()
77 for(vector<GL::Mesh *>::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i)
81 const GL::Mesh &TrackType3D::get_path_mesh(unsigned p) const
83 if(p>=path_meshes.size())
84 throw out_of_range("TrackType3D::get_path_mesh");
86 throw invalid_argument("TrackType3D::get_path_mesh");
87 return *path_meshes[p];
90 void TrackType3D::build_part(const TrackPart &part, const Profile &profile, const Vector &offset, bool mirror, GL::MeshBuilder &bld, unsigned &base_index)
92 float plen = part.get_length();
93 unsigned nsegs = (part.is_curved() ? static_cast<unsigned>(plen*32)+1 : 1);
95 unsigned n_vertices = profile.get_n_vertices();
96 for(unsigned i=0; i<=nsegs; ++i)
98 TrackPoint basep = part.get_point(i*plen/nsegs);
99 Transform trans = Transform::rotation(basep.dir, Vector(0, 0, 1));
101 for(unsigned j=0; j<n_vertices; ++j)
103 const Profile::Vertex &v = profile.get_vertex(mirror ? n_vertices-1-j : j);
104 Vector p(0, -v.pos.x, v.pos.y);
107 p = basep.pos+trans.transform(offset+p);
109 Vector n(0, -v.normal.x, v.normal.y);
112 n = trans.transform(n);
114 bld.normal(n.x, n.y, n.z);
115 bld.vertex(p.x, p.y, p.z);
119 for(unsigned i=0; i+1<n_vertices; )
121 bld.begin(GL::TRIANGLE_STRIP);
122 for(unsigned j=0; j<=nsegs; ++j)
124 unsigned k = j*n_vertices+i;
125 bld.element(base_index+k+1);
126 bld.element(base_index+k);
131 if(!profile.get_vertex(i).smooth)
135 base_index += (nsegs+1)*n_vertices;