+#include <msp/core/maputils.h>
#include <msp/fs/stat.h>
#include <msp/gl/meshbuilder.h>
#include <msp/gl/object.h>
namespace R2C2 {
Catalogue3D::Catalogue3D(Catalogue &c):
- catalogue(c),
- endpoint_mesh((GL::NORMAL3, GL::VERTEX3))
+ catalogue(c)
{
add_type<GL::Material>().creator(&Catalogue3D::create<GL::Material>);
add_type<GL::Mesh>().creator(&Catalogue3D::create<GL::Mesh>);
const Catalogue::ObjectMap &objs = catalogue.get_all();
for(Catalogue::ObjectMap::const_iterator i=objs.begin(); i!=objs.end(); ++i)
object_added(*i->second);
-
- build_endpoint_mesh();
}
Catalogue3D::~Catalogue3D()
void Catalogue3D::object_added(const ObjectType &ot)
{
if(const TrackType *tt = dynamic_cast<const TrackType *>(&ot))
+ {
objects[&ot] = new TrackType3D(*this, *tt);
+ const TrackAppearance &appearance = tt->get_appearance();
+ if(!endpoint_meshes.count(&appearance))
+ build_endpoint_mesh(appearance);
+ }
else if(const SignalType *st = dynamic_cast<const SignalType *>(&ot))
objects[&ot] = new SignalType3D(*this, *st);
else if(const VehicleType *vt = dynamic_cast<const VehicleType *>(&ot))
return *get_item(objects, &ot);
}
-void Catalogue3D::build_endpoint_mesh()
+void Catalogue3D::build_endpoint_mesh(const TrackAppearance &appearance)
{
- const Profile &ballast_profile = catalogue.get_ballast_profile();
+ const Profile &ballast_profile = appearance.get_ballast_profile();
const Vector &ballast_min = ballast_profile.get_min_coords();
const Vector &ballast_max = ballast_profile.get_max_coords();
- const Profile &rail_profile = catalogue.get_rail_profile();
+ const Profile &rail_profile = appearance.get_rail_profile();
const Vector &rail_min = rail_profile.get_min_coords();
const Vector &rail_max = rail_profile.get_max_coords();
float width = max(max(-ballast_min.x, ballast_max.x)*2, gauge+(rail_max.x-rail_min.x)*2)+0.004;
float height = ballast_max.y-ballast_min.y+rail_max.y-rail_min.y+0.01;
- GL::MeshBuilder bld(endpoint_mesh);
+ GL::Mesh *mesh = new GL::Mesh((GL::NORMAL3, GL::VERTEX3));
+ GL::MeshBuilder bld(*mesh);
bld.normal(1, 0, 0);
bld.begin(GL::QUADS);
bld.vertex(0, width/2, 0);
bld.vertex(0, -width/2, height);
bld.vertex(0, -width/2, 0);
bld.end();
+
+ endpoint_meshes[&appearance] = mesh;
+}
+
+const GL::Mesh &Catalogue3D::get_endpoint_mesh(const TrackAppearance &appearance) const
+{
+ return *get_item(endpoint_meshes, &appearance);
}
FS::Path Catalogue3D::locate_file(const string &name)
private:
Catalogue &catalogue;
std::map<const ObjectType *, ObjectType3D *> objects;
- Msp::GL::Mesh endpoint_mesh;
+ std::map<const TrackAppearance *, Msp::GL::Mesh *> endpoint_meshes;
public:
Catalogue3D(Catalogue &);
{ return dynamic_cast<const typename TypeMap3D<T>::Type3D &>(get_3d(static_cast<const ObjectType &>(ot))); }
private:
- void build_endpoint_mesh();
+ void build_endpoint_mesh(const TrackAppearance &);
public:
- const Msp::GL::Mesh &get_endpoint_mesh() const { return endpoint_mesh; }
+ const Msp::GL::Mesh &get_endpoint_mesh(const TrackAppearance &) const;
private:
Msp::FS::Path locate_file(const std::string &);
Endpoint3D::Endpoint3D(const Track3D &t, unsigned i):
track(t),
index(i),
- mesh(track.get_layout().get_catalogue().get_endpoint_mesh())
+ mesh(track.get_layout().get_catalogue().get_endpoint_mesh(track.get_track().get_type().get_appearance()))
{
track.get_layout().get_endpoint_scene().add(*this);
}
object(0),
own_data(false)
{
+ const TrackAppearance &appearance = tt.get_appearance();
const Catalogue &cat = catalogue.get_catalogue();
const vector<TrackPart> &parts = tt.get_parts();
- const Profile &ballast_profile = cat.get_ballast_profile();
+ const Profile &ballast_profile = appearance.get_ballast_profile();
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 Profile &rail_profile = appearance.get_rail_profile();
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;
object = new GL::Object;
object->set_mesh(mesh);
- object->set_technique(&catalogue.get<GL::Technique>(cat.get_track_technique()));
+ object->set_technique(&catalogue.get<GL::Technique>(appearance.get_technique()));
own_data = true;
}
{
gauge = layout.get_catalogue().get_gauge()*1000;
- const Profile &rail_profile = layout.get_catalogue().get_rail_profile();
- const Vector &rail_min = rail_profile.get_min_coords();
- const Vector &rail_max = rail_profile.get_max_coords();
- rail_width = (rail_max.x-rail_min.x)*1000;
+ // XXX This should be retrieved from track appearance
+ rail_width = 2;
xmlpp::Document *doc = new xmlpp::Document;
xmlpp::Element *root = doc->create_root_node("svg", "http://www.w3.org/2000/svg");
delete i->second;
}
-float Catalogue::get_rail_elevation() const
-{
- return ballast_profile.get_height()+rail_profile.get_height();
-}
-
void Catalogue::add(ObjectType &object)
{
insert_unique(objects, object.get_article_number(), &object);
Catalogue::Loader::Loader(Catalogue &c):
DataFile::ObjectLoader<Catalogue>(c)
{
- add("ballast_profile", &Loader::ballast_profile);
add("gauge", &Loader::gauge);
add("layout", &Loader::layout);
- add("rail_profile", &Loader::rail_profile);
add("scale", &Loader::scale);
add("signal", &Loader::signal);
add("terrain", &Loader::terrain);
add("track", &Loader::track);
- add("track_technique", &Catalogue::track_technique);
+ add("track_appearance", &Loader::track_appearance);
add("vehicle", &Loader::vehicle);
}
-void Catalogue::Loader::ballast_profile()
-{
- load_sub(obj.ballast_profile);
-}
-
void Catalogue::Loader::gauge(float g)
{
obj.gauge = g/1000;
load_sub(obj.layout);
}
-void Catalogue::Loader::rail_profile()
-{
- load_sub(obj.rail_profile);
-}
-
void Catalogue::Loader::scale(float n, float d)
{
obj.scale = n/d;
if(obj.objects.count(art_nr))
throw key_error(art_nr);
- RefPtr<TrackType> trk = new TrackType(art_nr);
+ RefPtr<TrackType> trk = new TrackType(art_nr, obj.appearance);
load_sub(*trk);
obj.add(*trk.release());
}
+void Catalogue::Loader::track_appearance()
+{
+ load_sub(obj.appearance);
+}
+
void Catalogue::Loader::vehicle(ArticleNumber art_nr)
{
if(obj.objects.count(art_nr))
#include <msp/datafile/objectloader.h>
#include "articlenumber.h"
#include "layout.h"
-#include "profile.h"
+#include "trackappearance.h"
namespace R2C2 {
public:
Loader(Catalogue &);
private:
- void ballast_profile();
void gauge(float);
void layout();
- void rail_profile();
void scale(float, float);
void signal(ArticleNumber);
void terrain(ArticleNumber);
void track(ArticleNumber);
+ void track_appearance();
void vehicle(ArticleNumber);
};
private:
float scale;
float gauge;
- Profile rail_profile;
- Profile ballast_profile;
- std::string track_technique;
+ TrackAppearance appearance;
ObjectMap objects;
Layout layout;
float get_scale() const { return scale; }
float get_gauge() const { return gauge; }
- float get_rail_elevation() const;
- const Profile &get_rail_profile() const { return rail_profile; }
- const Profile &get_ballast_profile() const { return ballast_profile; }
- const std::string &get_track_technique() const { return track_technique; }
void add(ObjectType &);
const ObjectType &get(const ArticleNumber &) const;
--- /dev/null
+#include "trackappearance.h"
+
+using namespace std;
+using namespace Msp;
+
+namespace R2C2 {
+
+float TrackAppearance::get_rail_elevation() const
+{
+ return ballast_profile.get_height()+rail_profile.get_height();
+}
+
+
+TrackAppearance::Loader::Loader(TrackAppearance &a):
+ ObjectLoader<TrackAppearance>(a)
+{
+ add("ballast_profile", &Loader::ballast_profile);
+ add("rail_profile", &Loader::rail_profile);
+ add("technique", &TrackAppearance::technique);
+}
+
+void TrackAppearance::Loader::ballast_profile()
+{
+ load_sub(obj.ballast_profile);
+}
+
+void TrackAppearance::Loader::rail_profile()
+{
+ load_sub(obj.rail_profile);
+}
+
+} // namespace R2C2
--- /dev/null
+#ifndef LIBR2C2_TRACKAPPEARANCE_H_
+#define LIBR2C2_TRACKAPPEARANCE_H_
+
+#include <string>
+#include <msp/datafile/objectloader.h>
+#include "profile.h"
+
+namespace R2C2 {
+
+class TrackAppearance
+{
+public:
+ class Loader: public Msp::DataFile::ObjectLoader<TrackAppearance>
+ {
+ public:
+ Loader(TrackAppearance &);
+
+ private:
+ void ballast_profile();
+ void rail_profile();
+ };
+
+private:
+ Profile rail_profile;
+ Profile ballast_profile;
+ std::string technique;
+
+public:
+ float get_rail_elevation() const;
+ const Profile &get_rail_profile() const { return rail_profile; }
+ const Profile &get_ballast_profile() const { return ballast_profile; }
+ const std::string &get_technique() const { return technique; }
+};
+
+} // namespace R2C2
+
+#endif
namespace R2C2 {
-TrackType::TrackType(const ArticleNumber &an):
+TrackType::TrackType(const ArticleNumber &an, const TrackAppearance &ta):
ObjectType(an),
+ appearance(ta),
state_bits(0),
autofit_preference(1)
{ }
namespace R2C2 {
+class TrackAppearance;
+
class TrackType: public ObjectType
{
public:
};
private:
+ const TrackAppearance &appearance;
std::vector<TrackPart> parts;
std::vector<Endpoint> endpoints;
unsigned state_bits;
std::string object;
public:
- TrackType(const ArticleNumber &);
+ TrackType(const ArticleNumber &, const TrackAppearance &);
+ const TrackAppearance &get_appearance() const { return appearance; }
float get_total_length() const;
float get_path_length(int) const;
unsigned get_paths() const;
{
OrientedPoint p = placement.get_point();
position = p.position;
- position.z += layout.get_catalogue().get_rail_elevation();
+ // TODO Move the z adjustment to VehiclePlacement
+ position.z += placement.get_position(VehiclePlacement::FRONT_AXLE)->get_type().get_appearance().get_rail_elevation();
rotation = p.rotation;
tilt = p.tilt;
scale 1 87;
gauge 16.5;
-rail_profile
-{
- point 1.5 0.0;
- smooth_point 1.5 0.3;
- smooth_point 0.8 0.4;
- smooth_point 0.8 1.4;
- smooth_point 1.0 1.6;
- smooth_point 1.0 2.1;
- smooth_point 0.8 2.3;
- smooth_point 0.2 2.3;
- smooth_point 0.0 2.1;
- smooth_point 0.0 1.6;
- smooth_point 0.2 1.4;
- smooth_point 0.2 0.4;
- smooth_point -0.5 0.3;
- point -0.5 0.0;
-};
-ballast_profile
-{
- point 20.0 0.0;
- point 14.0 8.0;
- point -14.0 8.0;
- point -20.0 0.0;
-};
-
-track_technique "track.technique";
+
+track_appearance
+{
+ rail_profile
+ {
+ point 1.5 0.0;
+ smooth_point 1.5 0.3;
+ smooth_point 0.8 0.4;
+ smooth_point 0.8 1.4;
+ smooth_point 1.0 1.6;
+ smooth_point 1.0 2.1;
+ smooth_point 0.8 2.3;
+ smooth_point 0.2 2.3;
+ smooth_point 0.0 2.1;
+ smooth_point 0.0 1.6;
+ smooth_point 0.2 1.4;
+ smooth_point 0.2 0.4;
+ smooth_point -0.5 0.3;
+ point -0.5 0.0;
+ };
+ ballast_profile
+ {
+ point 20.0 0.0;
+ point 14.0 8.0;
+ point -14.0 8.0;
+ point -20.0 0.0;
+ };
+
+ technique "track.technique";
+};
// Straight