Distributed under the GPL
*/
+#include <msp/gl/meshbuilder.h>
#include "catalogue.h"
#include "tracktype.h"
namespace Marklin {
Catalogue3D::Catalogue3D(const Catalogue &c):
- catalogue(c)
+ catalogue(c),
+ endpoint_mesh((GL::NORMAL3, GL::VERTEX3))
{
const map<unsigned, TrackType *> &trks = catalogue.get_tracks();
for(map<unsigned, TrackType *>::const_iterator i=trks.begin(); i!=trks.end(); ++i)
tracks[i->second] = new TrackType3D(*this, *i->second);
+
+ ballast_material.set_diffuse(GL::Color(0.25, 0.25, 0.25));
+ rail_material.set_diffuse(GL::Color(0.85, 0.85, 0.85));
+
+ build_endpoint_mesh();
}
const TrackType3D &Catalogue3D::get_track(const TrackType &tt) const
return *i->second;
}
+void Catalogue3D::build_endpoint_mesh()
+{
+ const Profile &ballast_profile = catalogue.get_ballast_profile();
+ const Point &ballast_min = ballast_profile.get_min_coords();
+ const Point &ballast_max = ballast_profile.get_max_coords();
+
+ const Profile &rail_profile = catalogue.get_rail_profile();
+ const Point &rail_min = rail_profile.get_min_coords();
+ const Point &rail_max = rail_profile.get_max_coords();
+
+ float gauge = catalogue.get_gauge();
+
+ 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);
+ 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, height);
+ bld.vertex(0, -width/2, 0);
+ bld.end();
+}
+
} // namespace Marklin
#define MARKLIN3D_CATALOGUE_H_
#include <msp/gl/material.h>
+#include <msp/gl/mesh.h>
#include "libmarklin/catalogue.h"
namespace Marklin {
private:
const Catalogue &catalogue;
std::map<const TrackType *, TrackType3D *> tracks;
- Msp::GL::Material *ballast_material;
+ Msp::GL::Material ballast_material;
+ Msp::GL::Material rail_material;
+ Msp::GL::Mesh endpoint_mesh;
public:
Catalogue3D(const Catalogue &);
const Catalogue &get_catalogue() const { return catalogue; }
const TrackType3D &get_track(const TrackType &) const;
+ const Msp::GL::Material &get_ballast_material() const { return ballast_material; }
+ const Msp::GL::Material &get_rail_material() const { return rail_material; }
+ const Msp::GL::Mesh &get_endpoint_mesh() const { return endpoint_mesh; }
+private:
+ void build_endpoint_mesh();
};
}
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <cmath>
+#include <msp/gl/matrix.h>
+#include <msp/gl/misc.h>
+#include "endpoint.h"
+#include "layout.h"
+#include "track.h"
+
+using namespace Msp;
+
+namespace Marklin {
+
+Endpoint3D::Endpoint3D(const Track3D &t, unsigned i):
+ track(t),
+ index(i),
+ mesh(track.get_layout().get_catalogue().get_endpoint_mesh())
+{
+ track.get_layout().get_endpoint_scene().add(*this);
+}
+
+Endpoint3D::~Endpoint3D()
+{
+ track.get_layout().get_endpoint_scene().remove(*this);
+}
+
+void Endpoint3D::render(const GL::Tag &tag) const
+{
+ if(tag==0)
+ {
+ Point p = track.get_track().get_endpoint_position(index);
+ float a = track.get_track().get_endpoint_direction(index)+M_PI;
+
+ GL::PushMatrix push_mat;
+ GL::translate(p.x, p.y, p.z);
+ GL::rotate(a*180/M_PI, 0, 0, 1);
+
+ GL::set(GL_CULL_FACE, track.get_track().get_link(index));
+ if(track.get_track().get_link(index))
+ glColor4f(0.5, 0, 1, 0.5);
+ else
+ glColor4f(1, 0, 0.5, 0.5);
+
+ mesh.draw();
+ }
+}
+
+} // namespace Marklin
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef MARKLIN3D_ENDPOINT_H_
+#define MARKLIN3D_ENDPOINT_H_
+
+#include <msp/gl/mesh.h>
+#include <msp/gl/renderable.h>
+#include "libmarklin/track.h"
+
+namespace Marklin {
+
+class Track3D;
+
+class Endpoint3D: public Msp::GL::Renderable
+{
+private:
+ const Track3D &track;
+ unsigned index;
+ const Msp::GL::Mesh &mesh;
+
+public:
+ Endpoint3D(const Track3D &, unsigned);
+ ~Endpoint3D();
+
+ virtual void render(const Msp::GL::Tag &) const;
+};
+
+} // namespace Marklin
+
+#endif
Layout3D::~Layout3D()
{
- for(list<Track3D *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
- delete *i;
+ while(!tracks.empty())
+ delete tracks.front();
}
void Layout3D::set_quality(unsigned q)
quality = q;
}
-void Layout3D::render(bool endpoints) const
+void Layout3D::add_track(Track3D &t)
{
- GL::Texture::unbind();
- glEnable(GL_DEPTH_TEST);
+ tracks.push_back(&t);
+}
- for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
- (*i)->render();
-
- if(endpoints)
- {
- glDepthMask(false);
- for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
- (*i)->render_endpoints();
- glDepthMask(true);
- }
+void Layout3D::remove_track(Track3D &t)
+{
+ list<Track3D *>::iterator i = find(tracks.begin(), tracks.end(), &t);
+ if(i!=tracks.end())
+ tracks.erase(i);
}
Track3D &Layout3D::get_track(const Track &t) const
for(list<Track3D *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
if(&(*i)->get_track()==&t)
return **i;
-
+
throw KeyError("Unknown track");
}
glPopMatrix();
- render();
+ scene.render(0);
glDisable(GL_CLIP_PLANE0);
glDisable(GL_CLIP_PLANE1);
void Layout3D::track_added(Track &t)
{
- tracks.push_back(new Track3D(*this, t));
+ new Track3D(*this, t);
}
void Layout3D::track_removed(Track &t)
if(&(*i)->get_track()==&t)
{
delete *i;
- tracks.erase(i);
return;
}
}
#ifndef MARKLIN3D_LAYOUT_H_
#define MARKLIN3D_LAYOUT_H_
+#include <msp/gl/scene.h>
#include "libmarklin/layout.h"
#include "catalogue.h"
#include "track.h"
Layout &layout;
Catalogue3D catalogue;
std::list<Track3D *> tracks;
+ Msp::GL::Scene scene;
+ Msp::GL::Scene ep_scene;
unsigned quality;
public:
const Catalogue3D &get_catalogue() const { return catalogue; }
void set_quality(unsigned);
+
+ void add_track(Track3D &);
+ void remove_track(Track3D &);
const std::list<Track3D *> &get_tracks() const { return tracks; }
- void render(bool =false) const;
Track3D &get_track(const Track &) const;
Track3D *pick_track(float, float, float) const;
+
+ Msp::GL::Scene &get_scene() { return scene; }
+ Msp::GL::Scene &get_endpoint_scene() { return ep_scene; }
+
private:
void track_added(Track &);
void track_removed(Track &);
*/
#include <cmath>
-#include <GL/gl.h>
+#include <msp/gl/matrix.h>
#include <msp/gl/misc.h>
#include "libmarklin/tracktype.h"
+#include "endpoint.h"
#include "layout.h"
#include "track.h"
#include "tracktype.h"
track(t),
type(layout.get_catalogue().get_track(track.get_type())),
color(1, 1, 1)
-{ }
+{
+ layout.add_track(*this);
+ layout.get_scene().add(*this);
+
+ const vector<Endpoint> &type_eps = track.get_type().get_endpoints();
+ for(unsigned i=0; i<type_eps.size(); ++i)
+ endpoints.push_back(new Endpoint3D(*this, i));
+}
+
+Track3D::~Track3D()
+{
+ layout.remove_track(*this);
+ layout.get_scene().remove(*this);
+
+ for(vector<Endpoint3D *>::iterator i=endpoints.begin(); i!=endpoints.end(); ++i)
+ delete *i;
+}
void Track3D::set_color(const Msp::GL::Color &c)
{
maxp.x += c*pos.x-s*pos.y;
minp.y += s*pos.x+c*pos.y;
maxp.y += s*pos.x+c*pos.y;
+ minp.z += pos.z;
+ maxp.z += pos.z;
float slope = track.get_slope();
if(slope>0)
minp.z += slope;
}
-void Track3D::render() const
-{
- prepare_render(true);
-
- glPushName(reinterpret_cast<unsigned>(this));
-
- type.render();
-
- glPopName();
- glPopMatrix();
-}
-
-void Track3D::render_endpoints() const
-{
- prepare_render(false);
-
- const vector<Endpoint> &endpoints = track.get_type().get_endpoints();
- for(unsigned i=0; i<endpoints.size(); ++i)
- {
- const Endpoint &ep = endpoints[i];
- GL::set(GL_CULL_FACE, track.get_link(i));
- if(track.get_link(i))
- glColor4f(0.5, 0, 1, 0.5);
- else
- glColor4f(1, 0, 0.5, 0.5);
-
- float c = cos(ep.dir);
- float s = sin(ep.dir);
- float z = (i==1 ? track.get_slope() : 0);
-
- glBegin(GL_QUADS);
- glVertex3f(ep.pos.x-s*0.025, ep.pos.y+c*0.025, z);
- glVertex3f(ep.pos.x+s*0.025, ep.pos.y-c*0.025, z);
- glVertex3f(ep.pos.x+s*0.025, ep.pos.y-c*0.025, z+0.02);
- glVertex3f(ep.pos.x-s*0.025, ep.pos.y+c*0.025, z+0.02);
- glEnd();
- }
-
- if(abs(track.get_slope())>1e-4)
- {
- Point p;
- if(track.get_slope()>0)
- {
- p = endpoints[1].pos;
- p.z += track.get_slope();
- }
- else
- p = endpoints[0].pos;
- glBegin(GL_TRIANGLE_STRIP);
- for(unsigned i=0; i<=16; ++i)
- {
- float c = cos(i*M_PI/8);
- float s = sin(i*M_PI/8);
- glNormal3f(c, s, 0);
- glVertex3f(p.x+c*0.01, p.y+s*0.01, p.z);
- glVertex3f(p.x+c*0.01, p.y+s*0.01, -track.get_position().z);
- }
- glEnd();
- }
-
- glPopMatrix();
-}
-
-void Track3D::render_path(int path) const
+void Track3D::render(const GL::Tag &tag) const
{
- prepare_render(true);
-
- (void)path;
- /*varray.apply();
- if(path>=0 && static_cast<unsigned>(path)<path_seq.size())
- glDrawElements(GL_QUADS, path_seq[path].size(), GL_UNSIGNED_INT, &path_seq[path][0]);
- else
- {
- for(unsigned i=0; i<path_seq.size(); ++i)
- glDrawElements(GL_QUADS, path_seq[i].size(), GL_UNSIGNED_INT, &path_seq[i][0]);
- }*/
-
- glPopMatrix();
-}
+ GL::PushMatrix push_mat;
-void Track3D::prepare_render(bool slope) const
-{
const Point &pos = track.get_position();
float rot = track.get_rotation();
- glPushMatrix();
glTranslatef(pos.x, pos.y, pos.z);
glRotatef(rot*180/M_PI, 0, 0, 1);
- if(slope)
- glRotatef(track.get_slope()/track.get_type().get_total_length()*180/M_PI, 0, -1, 0);
+ glRotatef(track.get_slope()/track.get_type().get_total_length()*180/M_PI, 0, -1, 0);
+
+ glPushName(reinterpret_cast<unsigned>(this));
+
+ type.render(tag);
+
+ glPopName();
}
} // namespace Marklin
#include <list>
#include <msp/gl/color.h>
+#include <msp/gl/renderable.h>
#include <msp/gl/vertexarray.h>
#include <msp/gl/vertexarraybuilder.h>
#include "libmarklin/track.h"
namespace Marklin {
+class Endpoint3D;
class Layout3D;
class TrackType3D;
-class Track3D
+class Track3D: public Msp::GL::Renderable
{
private:
Layout3D &layout;
Track &track;
const TrackType3D &type;
+ std::vector<Endpoint3D *> endpoints;
Msp::GL::Color color;
public:
Track3D(Layout3D &, Track &);
+ ~Track3D();
+ Layout3D &get_layout() const { return layout; }
Track &get_track() const { return track; }
void set_color(const Msp::GL::Color &);
void get_bounds(float, Point &, Point &) const;
- void render() const;
- void render_endpoints() const;
- void render_path(int) const;
-private:
- void prepare_render(bool) const;
+
+ virtual void render(const Msp::GL::Tag &) const;
};
} // namespace Marklin
namespace Marklin {
TrackType3D::TrackType3D(const 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))
{
}
}
-void TrackType3D::render() const
+void TrackType3D::render(const GL::Tag &tag) const
{
- ballast_mesh.draw();
- rail_mesh.draw();
+ 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)
#include <msp/gl/mesh.h>
#include <msp/gl/meshbuilder.h>
+#include <msp/gl/renderable.h>
#include "libmarklin/profile.h"
#include "libmarklin/tracktype.h"
class Catalogue3D;
-class TrackType3D
+class TrackType3D: public Msp::GL::Renderable
{
private:
+ const Catalogue3D &catalogue;
Msp::GL::Mesh ballast_mesh;
Msp::GL::Mesh rail_mesh;
std::vector<Point> border;
void get_bounds(float, Point &, Point &) const;
- void render() const;
+ virtual void render(const Msp::GL::Tag &) const;
private:
void build_part(const TrackPart &, const Profile &, const Point &, Msp::GL::MeshBuilder &, unsigned &);
Designer::Designer(int argc, char **argv):
screen_w(1280),
screen_h(960),
- base_mesh(0),
+ base_object(0),
cur_route(0),
mode(SELECT),
input(0),
if(!layout->get_base().empty())
{
- base_mesh = new GL::Mesh;
- DataFile::load(*base_mesh, layout->get_base());
+ base_object = new GL::Object;
+ DataFile::load(*base_object, layout->get_base());
}
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
+ pipeline = new GL::Pipeline(screen_w, screen_h, false);
+ pipeline->add_renderable(layout_3d->get_scene());
+ if(base_object)
+ pipeline->add_renderable(*base_object);
+
+ light.set_position(0, -0.259, 0.966, 0);
+ lighting.attach(0, light);
+
+ GL::PipelinePass *pass = &pipeline->add_pass(GL::Tag());
+ pass->lighting = &lighting;
+
DataFile::load(ui_res, "marklin.res");
root = new GLtk::Root(ui_res, *wnd);
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
GL::enable(GL::DEPTH_TEST);
+ GL::Texture::unbind();
project_3d();
apply_camera();
if(mode==CATALOGUE)
- cat_layout_3d->render();
+ cat_layout_3d->get_scene().render();
else
{
- if(base_mesh)
- {
- GL::Texture::unbind();
- base_mesh->draw();
- }
- layout_3d->render(true);
- if(cur_route)
+ pipeline->render_all();
+ layout_3d->get_endpoint_scene().render();
+ GL::enable(GL_CULL_FACE);
+ /*if(cur_route)
{
glColor4f(0.5, 0.8, 1.0, 1.0);
const set<const Track *> &rtracks = cur_route->get_tracks();
}
layout_3d->get_track(**i).render_path(path);
}
- }
+ }*/
+
manipulator->render();
if(mode==MEASURE)
measure->render();
#include <msp/gbase/window.h>
#include <msp/gbase/glcontext.h>
#include <msp/gl/font.h>
-#include <msp/gl/mesh.h>
+#include <msp/gl/light.h>
+#include <msp/gl/lighting.h>
+#include <msp/gl/object.h>
+#include <msp/gl/pipeline.h>
#include <msp/gltk/label.h>
#include <msp/gltk/resources.h>
#include <msp/gltk/root.h>
std::string filename;
Marklin::Layout *layout;
Marklin::Layout3D *layout_3d;
- Msp::GL::Mesh *base_mesh;
+ Msp::GL::Object *base_object;
Marklin::Route *cur_route;
+ Msp::GL::Pipeline *pipeline;
+ Msp::GL::Lighting lighting;
+ Msp::GL::Light light;
Mode mode;
Selection *selection;
//glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
- layout_3d.render();
+ layout_3d.get_scene().render();
glDisable(GL_LIGHTING);
glColor4f(1, 1, 1, 1);
- const list<Track3D *> <racks = layout_3d.get_tracks();
+ /*const list<Track3D *> <racks = layout_3d.get_tracks();
for(list<Track3D *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
{
Track &track = (*i)->get_track();
}
else
(*i)->render_path(-1);
- }
+ }*/
if(placing_train && placing_block)
{
float dx = points[i+1].x-points[i].x;
float dy = points[i+1].y-points[i].y;
float len = sqrt(dx*dx+dy*dy);
- return Point(-dx/len, dy/len);
+ return Point(dy/len, -dx/len);
}