#include <cmath>
#include <msp/gl/matrix.h>
#include <msp/gl/misc.h>
+#include <msp/gl/renderer.h>
#include "endpoint.h"
#include "layout.h"
#include "track.h"
track.get_layout().get_endpoint_scene().remove(*this);
}
-void Endpoint3D::render(const GL::Tag &tag) const
+void Endpoint3D::render(GL::Renderer &renderer, const GL::Tag &tag) const
{
if(tag=="unlit")
{
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::MatrixStack::Push push_mtx(renderer.matrix_stack());
+ GL::Matrix matrix;
+ matrix.translate(p.x, p.y, p.z);
+ matrix.rotate(a, 0, 0, 1);
+ renderer.matrix_stack() *= matrix;
- 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();
+ mesh.draw(renderer);
}
}
Endpoint3D(const Track3D &, unsigned);
~Endpoint3D();
- virtual void render(const Msp::GL::Tag &) const;
+ virtual void render(Msp::GL::Renderer &, const Msp::GL::Tag &) const;
};
} // namespace R2C2
VehicleMap vehicles;
Msp::GL::InstanceScene scene;
Msp::GL::SimpleScene ep_scene;
- Msp::GL::SimpleScene path_scene;
+ Msp::GL::InstanceScene path_scene;
public:
Layout3D(Layout &);
*/
#include <msp/gl/matrix.h>
+#include <msp/gl/renderer.h>
#include "libr2c2/tracktype.h"
#include "layout.h"
#include "path.h"
z_offs = l*track.get_track().get_layout().get_catalogue().get_gauge()*0.01;
}
-void Path3D::render(const GL::Tag &tag) const
+long Path3D::get_instance_key() const
+{
+ return reinterpret_cast<long>(&track.get_type());
+}
+
+void Path3D::render(GL::Renderer &renderer, const GL::Tag &tag) const
{
if(tag=="unlit")
{
if(!mask)
return;
- GL::MatrixStack::Push push_mtx(GL::MatrixStack::modelview());
+ GL::MatrixStack::Push push_mtx(renderer.matrix_stack());
GL::Matrix matrix = track.get_matrix();
matrix.translate(0, 0, z_offs);
- GL::MatrixStack::modelview() *= matrix;
+ renderer.matrix_stack() *= matrix;
glColor4f(color.r, color.g, color.b, color.a);
for(unsigned i=0; mask; ++i, mask>>=1)
if(mask&1)
- track.get_type().get_path_mesh(i).draw();
+ track.get_type().get_path_mesh(i).draw(renderer);
}
}
void set_color(const Msp::GL::Color &);
void set_layer(float);
- virtual void render(const Msp::GL::Tag &) const;
+ virtual long get_instance_key() const;
+
+ virtual void render(Msp::GL::Renderer &, const Msp::GL::Tag &) const;
};
} // namespace R2C2
layout.get_scene().add(*this);
const vector<TrackType::Endpoint> &type_eps = track.get_type().get_endpoints();
+ const vector<Track *> &links = track.get_links();
for(unsigned i=0; i<type_eps.size(); ++i)
- endpoints.push_back(new Endpoint3D(*this, i));
+ {
+ if(!links[i] || links[i]>&track)
+ endpoints.push_back(new Endpoint3D(*this, i));
+ else
+ endpoints.push_back(0);
+ }
+
+ track.signal_link_changed.connect(sigc::mem_fun(this, &Track3D::link_changed));
}
Track3D::~Track3D()
glPopName();
}
+void Track3D::link_changed(unsigned i, Track *trk)
+{
+ if(!trk || trk>&track)
+ {
+ if(!endpoints[i])
+ endpoints[i] = new Endpoint3D(*this, i);
+ }
+ else if(endpoints[i])
+ {
+ delete endpoints[i];
+ endpoints[i] = 0;
+ }
+}
+
} // namespace R2C2
#define R2C2_3D_TRACK_H_
#include <list>
+#include <sigc++/trackable.h>
#include <msp/gl/matrix.h>
#include <msp/gl/objectinstance.h>
#include "libr2c2/track.h"
class Path3D;
class TrackType3D;
-class Track3D: public Object3D, public Msp::GL::ObjectInstance
+class Track3D: public Object3D, public Msp::GL::ObjectInstance, public sigc::trackable
{
private:
Layout3D &layout;
Msp::GL::Matrix get_matrix() const;
virtual void setup_render(Msp::GL::Renderer &, const Msp::GL::Tag &) const;
virtual void finish_render(Msp::GL::Renderer &, const Msp::GL::Tag &) const;
+private:
+ void link_changed(unsigned, Track *);
};
} // namespace R2C2
build_part(*i, rail_profile, Point(gauge/2-rail_min.x, y), bld, index);
}
+ mesh.set_winding(&GL::WindingTest::counterclockwise());
object.set_mesh(&mesh);
object.set_technique(catalogue.get<GL::Technique>(cat.get_track_technique()));
return;
ObjectInstance::render(renderer, tag);
-
- /*if(tag==0)
- {
- GL::PushMatrix push_mat;
-
- const Point &pos = vehicle.get_position();
- GL::translate(pos.x, pos.y, pos.z);
- GL::rotate(vehicle.get_direction()*180/M_PI, 0, 0, 1);
-
- if(const GL::Object *obj = type.get_body_object())
- obj->render(tag);*/
-
- /*const vector<VehicleType::Axle> &axles = vehicle.get_type().get_axles();
- for(unsigned i=0; i<axles.size(); ++i)
- if(const GL::Object *obj = type.get_axle_object(i))
- {
- GL::PushMatrix push_mat2;
- GL::translate(axles[i].position, 0, axles[i].wheel_dia/2);
- GL::rotate(vehicle.get_axle(i).angle*180/M_PI, 0, 1, 0);
- obj->render(tag);
- }
-
- const vector<VehicleType::Bogie> &bogies = vehicle.get_type().get_bogies();
- for(unsigned i=0; i<bogies.size(); ++i)
- {
- GL::PushMatrix push_mat2;
- GL::translate(bogies[i].position, 0, 0);
- float angle = vehicle.get_bogie(i).direction*180/M_PI;
- GL::rotate(angle, 0, 0, 1);
-
- for(unsigned j=0; j<bogies[i].axles.size(); ++j)
- if(const GL::Object *obj = type.get_bogie_axle_object(i, j))
- {
- GL::PushMatrix push_mat3;
- GL::translate(bogies[i].axles[j].position, 0, bogies[i].axles[j].wheel_dia/2);
- GL::rotate(vehicle.get_bogie_axle(i, j).angle*180/M_PI, 0, 1, 0);
- obj->render(tag);
- }
-
- if(bogies[i].rotate_object)
- GL::rotate(180, 0, 0, 1);
- if(const GL::Object *obj = type.get_bogie_object(i))
- obj->render(tag);
- }*/
-
- /*const vector<VehicleType::Rod> &rods = vehicle.get_type().get_rods();
- for(unsigned i=0; i<rods.size(); ++i)
- if(const GL::Object *obj = type.get_rod_object(i))
- {
- GL::PushMatrix push_mat2;
- const Point &rpos = vehicle.get_rod(i).position;
- float angle = vehicle.get_rod(i).angle;
- GL::translate(rpos.x, rpos.y, rpos.z);
- if(rods[i].mirror_object)
- GL::scale(1, -1, 1);
- GL::rotate(angle*180/M_PI, 0, -1, 0);
- obj->render(tag);
- }*/
- //}
}
void Vehicle3D::setup_render(GL::Renderer &renderer, const GL::Tag &) const
}
// Setup OpenGL
- GL::enable(GL_CULL_FACE);
-
pipeline = new GL::Pipeline(window.get_width(), window.get_height(), false);
pipeline->set_camera(&camera);
pipeline->add_renderable_for_pass(layout_3d->get_scene(), 0);
else
{
pipeline->render_all();
- GL::enable(GL_CULL_FACE);
{
GL::Bind bind_blend(GL::Blend::alpha());
overlay->render(0);
GL::matrix_mode(GL::MODELVIEW);
GL::load_identity();
- GL::disable(GL::DEPTH_TEST);
-
GL::Bind bind_blend(GL::Blend::alpha());
root.render();
GL::Texture::unbind();
links[i] = &other;
other.links[j] = this;
layout.create_blocks(*this);
+
+ signal_link_changed.emit(i, &other);
+ other.signal_link_changed.emit(j, this);
}
return true;
trk.break_link(*this);
// XXX Creates the blocks twice
layout.create_blocks(*this);
+ signal_link_changed.emit(i-links.begin(), 0);
return;
}
}
void turnout_id(unsigned);
};
+ sigc::signal<void, unsigned, Track *> signal_link_changed;
sigc::signal<void, unsigned> signal_path_changed;
private: