X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2F3d%2Ftracktype.cpp;h=a5e97cc55a09ad10e89c0a7babbfa119fad1467b;hb=7a36d396eded897c421424905b2c938d770df341;hp=6dab43c4f7d59de418bcbbe8622fba641298e7d4;hpb=0a09ce2f652314e221b88c5202795be1120c7229;p=r2c2.git diff --git a/source/3d/tracktype.cpp b/source/3d/tracktype.cpp index 6dab43c..a5e97cc 100644 --- a/source/3d/tracktype.cpp +++ b/source/3d/tracktype.cpp @@ -1,13 +1,6 @@ -/* $Id$ - -This file is part of the MSP Märklin suite -Copyright © 2010 Mikkosoft Productions, Mikko Rasa -Distributed under the GPL -*/ - #include #include -#include +#include #include "catalogue.h" #include "tracktype.h" @@ -16,7 +9,7 @@ using namespace Msp; namespace { -bool compare_z(const Marklin::Point &p1, const Marklin::Point &p2) +bool compare_z(const R2C2::Vector &p1, const R2C2::Vector &p2) { return p1.zxx==lowest.x && i->y>lowest.y)) lowest = *i; @@ -40,7 +33,7 @@ Iter graham_scan(Iter begin, Iter end) for(Iter k=begin, i=k++, j=k++;; ) { // Compute winding by cross product - float turn = (j->x-i->x)*(k->y-j->y) - (k->x-j->x)*(j->y-i->y); + float turn = cross(*j-*i, *k-*j).z; if(turn<1e-5) { @@ -69,65 +62,85 @@ Iter graham_scan(Iter begin, Iter end) } -namespace Marklin { +namespace R2C2 { -TrackType3D::TrackType3D(const Catalogue3D &cat3d, const TrackType &tt): +TrackType3D::TrackType3D(Catalogue3D &cat3d, const TrackType &tt): catalogue(cat3d), - ballast_mesh((GL::NORMAL3, GL::COLOR4_UBYTE, GL::VERTEX3)), - rail_mesh((GL::NORMAL3, GL::COLOR4_UBYTE, GL::VERTEX3)) + mesh(0), + object(0) { const Catalogue &cat = cat3d.get_catalogue(); const vector &parts = tt.get_parts(); const Profile &ballast_profile = cat.get_ballast_profile(); - const Point &ballast_min = ballast_profile.get_min_coords(); - const Point &ballast_max = ballast_profile.get_max_coords(); + const Vector &ballast_min = ballast_profile.get_min_coords(); + const Vector &ballast_max = ballast_profile.get_max_coords(); float ballast_h = ballast_max.y-ballast_min.y; const Profile &rail_profile = cat.get_rail_profile(); - const Point &rail_min = rail_profile.get_min_coords(); - const Point &rail_max = rail_profile.get_max_coords(); + const Vector &rail_min = rail_profile.get_min_coords(); + const Vector &rail_max = rail_profile.get_max_coords(); float rail_h = rail_max.y-rail_min.y; float gauge = cat.get_gauge(); + string obj_name = tt.get_object(); + if(!obj_name.empty()) { - unsigned index = 0; - GL::MeshBuilder bld(ballast_mesh); - bld.color(0.25f, 0.25f, 0.25f); - for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) - build_part(*i, ballast_profile, Point(0, -ballast_min.y), bld, index); + object = &catalogue.get(obj_name); + const GL::Mesh *m = object->get_mesh(); + const GL::VertexArray &vertices = m->get_vertices(); + int vertex_offs = vertices.get_format().offset(GL::VERTEX2); + if(vertex_offs>=0) + { + for(unsigned i=0; iset_winding(&GL::WindingTest::counterclockwise()); + GL::MeshBuilder bld(*mesh); + unsigned index = 0; - GL::MeshBuilder bld(rail_mesh); - bld.color(0.85f, 0.85f, 0.85f); + bld.texcoord(0.25, 0.5); + for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) + build_part(*i, ballast_profile, Vector(0, -ballast_min.y, 0), false, bld, index); + + bld.texcoord(0.75, 0.5); float y = ballast_h-rail_min.y; for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) - build_part(*i, rail_profile, Point(-gauge/2-rail_max.x, y), bld, index); + build_part(*i, rail_profile, Vector(0, gauge/2, y), true, bld, index); for(vector::const_iterator i=parts.begin(); i!=parts.end(); ++i) - build_part(*i, rail_profile, Point(gauge/2-rail_min.x, y), bld, index); + build_part(*i, rail_profile, Vector(0, -gauge/2, y), false, bld, index); + + object = new GL::Object; + object->set_mesh(mesh); + object->set_technique(&catalogue.get(cat.get_track_technique())); } unsigned paths = tt.get_paths(); for(unsigned i=0; paths; ++i, paths>>=1) { - GL::Mesh *mesh = 0; + GL::Mesh *m = 0; if(paths&1) { - mesh = new GL::Mesh(GL::VERTEX3); - GL::MeshBuilder bld(*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(), Point(0, ballast_h+1.5*rail_h), bld, index); + build_part(*j, cat.get_path_profile(), Vector(0, 0, ballast_h+1.5*rail_h), false, bld, index); } - path_meshes.push_back(mesh); + path_meshes.push_back(m); } min_z = max_z = border.front().z; - for(vector::iterator i=border.begin(); i!=border.end(); ++i) + for(vector::iterator i=border.begin(); i!=border.end(); ++i) { min_z = min(min_z, i->z); max_z = max(max_z, i->z); @@ -141,93 +154,82 @@ TrackType3D::~TrackType3D() delete *i; } -void TrackType3D::get_bounds(float angle, Point &minp, Point &maxp) const +void TrackType3D::get_bounds(const Angle &angle, Vector &minp, Vector &maxp) const { - float c = cos(-angle); - float s = sin(-angle); + Transform trans = Transform::rotation(-angle, Vector(0, 0, 1)); - minp = maxp = Point(); + minp = maxp = Vector(); minp.z = min_z; maxp.z = max_z; - for(vector::const_iterator i=border.begin(); i!=border.end(); ++i) + for(vector::const_iterator i=border.begin(); i!=border.end(); ++i) { - float x = c*i->x-s*i->y; - float y = s*i->x+c*i->y; + Vector v = trans.transform(*i); - minp.x = min(minp.x, x); - minp.y = min(minp.y, y); - maxp.x = max(maxp.x, x); - maxp.y = max(maxp.y, y); + minp.x = min(minp.x, v.x); + minp.y = min(minp.y, v.y); + maxp.x = max(maxp.x, v.x); + maxp.y = max(maxp.y, v.y); } } const GL::Mesh &TrackType3D::get_path_mesh(unsigned p) const { - if(p>=path_meshes.size() || !path_meshes[p]) - throw InvalidParameterValue("Invalid path"); + 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]; } -void TrackType3D::render(const GL::Tag &tag) const -{ - if(tag==0) - { - catalogue.get_ballast_material().bind(); - ballast_mesh.draw(); - catalogue.get_rail_material().bind(); - rail_mesh.draw(); - } -} - -void TrackType3D::build_part(const TrackPart &part, const Profile &profile, const Point &offset, GL::MeshBuilder &bld, unsigned &base_index) +void TrackType3D::build_part(const TrackPart &part, const Profile &profile, const Vector &offset, bool mirror, GL::MeshBuilder &bld, unsigned &base_index) { float plen = part.get_length(); unsigned nsegs = (part.is_curved() ? static_cast(plen*32)+1 : 1); - unsigned n_points = profile.get_n_points(); + unsigned n_vertices = profile.get_n_vertices(); for(unsigned i=0; i<=nsegs; ++i) { TrackPoint basep = part.get_point(i*plen/nsegs); - float c = cos(basep.dir); - float s = sin(basep.dir); + Transform trans = Transform::rotation(basep.dir, Vector(0, 0, 1)); - Point p; - for(unsigned j=0; j0) - bld.vertex(p.x, p.y, p.z); + Vector n(0, -v.normal.x, v.normal.y); + if(mirror) + n.y = -n.y; + n = trans.transform(n); - if(j+1