]> git.tdb.fi Git - r2c2.git/blobdiff - source/3d/tracktype.cpp
Use generic ObjectTypes in Catalogue
[r2c2.git] / source / 3d / tracktype.cpp
index 6dfd2a4f86c166cbb9b336b8cdbcaa42e45ba592..d73387c998dbbece809ef234767e77ff8a4b5802 100644 (file)
@@ -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<TrackPart> &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<GL::Technique>(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<TrackPart>::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<TrackPart>::const_iterator k=parts.begin(); k!=parts.end(); ++k)
+                               if(j<0 || k->get_path()==static_cast<unsigned>(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<GL::Mesh *>::iterator i=path_meshes.begin(); i!=path_meshes.end(); ++i)
-               delete *i;
+       for(map<unsigned, GL::Mesh *>::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<n_vertices; ++j)
                {
@@ -104,7 +126,7 @@ void TrackType3D::build_part(const TrackPart &part, const Profile &profile, cons
                        Vector p(0, -v.pos.x, v.pos.y);
                        if(mirror)
                                p.y = -p.y;
-                       p = basep.pos+trans.transform(offset+p);
+                       p = basep.position+trans.transform(offset+p);
 
                        Vector n(0, -v.normal.x, v.normal.y);
                        if(mirror)