X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2F3d%2Ftracktype.cpp;h=d73387c998dbbece809ef234767e77ff8a4b5802;hb=7c98e23312cf01ce1fa6c1ffd8e36c22d2fa6110;hp=6dfd2a4f86c166cbb9b336b8cdbcaa42e45ba592;hpb=bde934f7d5ba07a9442a305192e10024820d13ed;p=r2c2.git diff --git a/source/3d/tracktype.cpp b/source/3d/tracktype.cpp index 6dfd2a4..d73387c 100644 --- a/source/3d/tracktype.cpp +++ b/source/3d/tracktype.cpp @@ -9,12 +9,13 @@ using namespace Msp; namespace R2C2 { -TrackType3D::TrackType3D(Catalogue3D &cat3d, const TrackType &tt): - catalogue(cat3d), +TrackType3D::TrackType3D(Catalogue3D &c, const TrackType &tt): + ObjectType3D(c), mesh(0), - object(0) + object(0), + own_data(false) { - const Catalogue &cat = cat3d.get_catalogue(); + const Catalogue &cat = catalogue.get_catalogue(); const vector &parts = tt.get_parts(); const Profile &ballast_profile = cat.get_ballast_profile(); @@ -53,38 +54,59 @@ TrackType3D::TrackType3D(Catalogue3D &cat3d, const TrackType &tt): object = new GL::Object; object->set_mesh(mesh); object->set_technique(&catalogue.get(cat.get_track_technique())); + + own_data = true; } - + unsigned paths = tt.get_paths(); - for(unsigned i=0; paths; ++i, paths>>=1) + for(int i=-1; i<=1; ++i) { - GL::Mesh *m = 0; - if(paths&1) + // TODO Make profile width configurable + Profile profile; + if(i==0) + { + float rail_w = (rail_max.x-rail_min.x)*2; + profile.append_vertex(Vector(rail_w*-0.5, 0, 0), false); + profile.append_vertex(Vector(rail_w*0.5, 0, 0), false); + } + else + { + profile.append_vertex(Vector(i*(gauge*0.5+rail_min.x*2), 0, 0), false); + profile.append_vertex(Vector(i*(gauge*0.5+rail_max.x*2), 0, 0), false); + } + + // TODO Avoid generating redundant meshes for single-path tracks + for(int j=-1; j<=4; ++j) { - m = new GL::Mesh(GL::VERTEX3); + if(j>=0 && !((paths>>j)&1)) + continue; + + GL::Mesh *m = new GL::Mesh(GL::VERTEX3); GL::MeshBuilder bld(*m); unsigned index = 0; - for(vector::const_iterator j=parts.begin(); j!=parts.end(); ++j) - if(j->get_path()==i) - build_part(*j, cat.get_path_profile(), Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index); + for(vector::const_iterator k=parts.begin(); k!=parts.end(); ++k) + if(j<0 || k->get_path()==static_cast(j)) + build_part(*k, profile, Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index); + path_meshes[(j&0xFF)|((i&3)<<8)] = m; } - path_meshes.push_back(m); } } TrackType3D::~TrackType3D() { - for(vector::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i) - delete *i; + for(map::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i) + delete i->second; + if(own_data) + { + delete object; + delete mesh; + } } -const GL::Mesh &TrackType3D::get_path_mesh(unsigned p) const +const GL::Mesh &TrackType3D::get_path_mesh(int p, int s) const { - if(p>=path_meshes.size()) - throw out_of_range("TrackType3D::get_path_mesh"); - if(!path_meshes[p]) - throw invalid_argument("TrackType3D::get_path_mesh"); - return *path_meshes[p]; + unsigned key = (p<0 ? 0xFF : p) | ((s&3)<<8); + return *get_item(path_meshes, key); } void TrackType3D::build_part(const TrackPart &part, const Profile &profile, const Vector &offset, bool mirror, GL::MeshBuilder &bld, unsigned &base_index) @@ -95,8 +117,8 @@ void TrackType3D::build_part(const TrackPart &part, const Profile &profile, cons unsigned n_vertices = profile.get_n_vertices(); for(unsigned i=0; i<=nsegs; ++i) { - TrackPoint basep = part.get_point(i*plen/nsegs); - Transform trans = Transform::rotation(basep.dir, Vector(0, 0, 1)); + OrientedPoint basep = part.get_point(i*plen/nsegs); + Transform trans = Transform::rotation(basep.rotation, Vector(0, 0, 1)); for(unsigned j=0; j