3 #include <msp/gl/technique.h>
12 TrackType3D::TrackType3D(Catalogue3D &cat3d, const TrackType &tt):
18 const Catalogue &cat = cat3d.get_catalogue();
19 const vector<TrackPart> &parts = tt.get_parts();
21 const Profile &ballast_profile = cat.get_ballast_profile();
22 const Vector &ballast_min = ballast_profile.get_min_coords();
23 const Vector &ballast_max = ballast_profile.get_max_coords();
24 float ballast_h = ballast_max.y-ballast_min.y;
26 const Profile &rail_profile = cat.get_rail_profile();
27 const Vector &rail_min = rail_profile.get_min_coords();
28 const Vector &rail_max = rail_profile.get_max_coords();
29 float rail_h = rail_max.y-rail_min.y;
31 float gauge = cat.get_gauge();
33 string obj_name = tt.get_object();
35 object = &catalogue.get<GL::Object>(obj_name);
38 mesh = new GL::Mesh((GL::NORMAL3, GL::TEXCOORD2, GL::VERTEX3));
39 mesh->set_winding(&GL::WindingTest::counterclockwise());
40 GL::MeshBuilder bld(*mesh);
43 bld.texcoord(0.25, 0.5);
44 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
45 build_part(*i, ballast_profile, Vector(0, -ballast_min.y, 0), false, bld, index);
47 bld.texcoord(0.75, 0.5);
48 float y = ballast_h-rail_min.y;
49 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
50 build_part(*i, rail_profile, Vector(0, gauge/2, y), true, bld, index);
51 for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
52 build_part(*i, rail_profile, Vector(0, -gauge/2, y), false, bld, index);
54 object = new GL::Object;
55 object->set_mesh(mesh);
56 object->set_technique(&catalogue.get<GL::Technique>(cat.get_track_technique()));
61 unsigned paths = tt.get_paths();
62 for(unsigned i=0; paths; ++i, paths>>=1)
67 m = new GL::Mesh(GL::VERTEX3);
68 GL::MeshBuilder bld(*m);
70 for(vector<TrackPart>::const_iterator j=parts.begin(); j!=parts.end(); ++j)
72 build_part(*j, cat.get_path_profile(), Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index);
74 path_meshes.push_back(m);
78 TrackType3D::~TrackType3D()
80 for(vector<GL::Mesh *>::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i)
89 const GL::Mesh &TrackType3D::get_path_mesh(unsigned p) const
91 if(p>=path_meshes.size())
92 throw out_of_range("TrackType3D::get_path_mesh");
94 throw invalid_argument("TrackType3D::get_path_mesh");
95 return *path_meshes[p];
98 void TrackType3D::build_part(const TrackPart &part, const Profile &profile, const Vector &offset, bool mirror, GL::MeshBuilder &bld, unsigned &base_index)
100 float plen = part.get_length();
101 unsigned nsegs = (part.is_curved() ? static_cast<unsigned>(plen*32)+1 : 1);
103 unsigned n_vertices = profile.get_n_vertices();
104 for(unsigned i=0; i<=nsegs; ++i)
106 TrackPoint basep = part.get_point(i*plen/nsegs);
107 Transform trans = Transform::rotation(basep.dir, Vector(0, 0, 1));
109 for(unsigned j=0; j<n_vertices; ++j)
111 const Profile::Vertex &v = profile.get_vertex(mirror ? n_vertices-1-j : j);
112 Vector p(0, -v.pos.x, v.pos.y);
115 p = basep.pos+trans.transform(offset+p);
117 Vector n(0, -v.normal.x, v.normal.y);
120 n = trans.transform(n);
122 bld.normal(n.x, n.y, n.z);
123 bld.vertex(p.x, p.y, p.z);
127 for(unsigned i=0; i+1<n_vertices; )
129 bld.begin(GL::TRIANGLE_STRIP);
130 for(unsigned j=0; j<=nsegs; ++j)
132 unsigned k = j*n_vertices+i;
133 bld.element(base_index+k+1);
134 bld.element(base_index+k);
139 if(!profile.get_vertex(i).smooth)
143 base_index += (nsegs+1)*n_vertices;