]> git.tdb.fi Git - r2c2.git/commitdiff
Separate track wrap to its own class
authorMikko Rasa <tdb@tdb.fi>
Mon, 25 Oct 2010 18:12:23 +0000 (18:12 +0000)
committerMikko Rasa <tdb@tdb.fi>
Mon, 25 Oct 2010 18:12:23 +0000 (18:12 +0000)
source/designer/designer.cpp
source/designer/designer.h
source/designer/manipulator.cpp
source/designer/manipulator.h
source/designer/trackwrap.cpp [new file with mode: 0644]
source/designer/trackwrap.h [new file with mode: 0644]

index c60ae8e8688b5c318262d71e40a48d48aebacfb4..5fd0f4468797793301db6fb919377f1fd92d0b08 100644 (file)
@@ -48,7 +48,8 @@ Designer::Designer(int argc, char **argv):
        mode(SELECT),
        manipulator(*this, selection),
        measure(*this),
-       camera_ctl(window, camera)
+       camera_ctl(window, camera),
+       track_wrap(*this, selection)
 {
        window.set_title("Railway Designer");
        window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Designer::exit), 0));
@@ -87,6 +88,7 @@ Designer::Designer(int argc, char **argv):
        pipeline->add_renderable_for_pass(layout_3d->get_scene(), 0);
        if(base_object)
                pipeline->add_renderable_for_pass(*base_object, 0);
+       pipeline->add_renderable_for_pass(track_wrap, "unlit");
        pipeline->add_renderable_for_pass(layout_3d->get_path_scene(), "unlit");
        pipeline->add_renderable_for_pass(layout_3d->get_endpoint_scene(), "unlit");
 
@@ -444,7 +446,6 @@ void Designer::render()
                }
 
                GL::Bind bind_depth(GL::DepthTest::lequal());
-               manipulator.render();
                if(mode==MEASURE)
                        measure.render();
        }
index a43906043da391e681622a11d98b26b7b9fa9240..e9ba62ae06ffbd4e25a598ca385a38a5d1a31dd2 100644 (file)
@@ -30,6 +30,7 @@ Distributed under the GPL
 #include "manipulator.h"
 #include "measure.h"
 #include "selection.h"
+#include "trackwrap.h"
 
 class Toolbar;
 
@@ -69,6 +70,7 @@ private:
        Manipulator manipulator;
        Measure measure;
        CameraController camera_ctl;
+       TrackWrap track_wrap;
 
        Msp::Time::TimeStamp last_tick;
 
index 029bbbad8890eb74854c53721b9f661fa6bb9d5d..64cbbd4ac68e70745512f4ce56e96809c17f9e0e 100644 (file)
@@ -7,9 +7,7 @@ Distributed under the GPL
 
 #include <algorithm>
 #include <cmath>
-#include <GL/gl.h>
 #include <msp/strings/formatter.h>
-#include "3d/layout.h"
 #include "libmarklin/tracktype.h"
 #include "designer.h"
 #include "manipulator.h"
@@ -22,7 +20,6 @@ using namespace Msp;
 Manipulator::Manipulator(Designer &d, Selection &s):
        designer(d),
        selection(s),
-       wrap_rot(0),
        mode(NONE),
        angle(0)
 {
@@ -105,7 +102,7 @@ void Manipulator::flatten()
        for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
                (*i)->check_slope();
 
-       update_wrap();
+       update_tracks();
 }
 
 void Manipulator::even_slope(bool smooth)
@@ -192,7 +189,7 @@ void Manipulator::even_slope(bool smooth)
        for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
                (*i)->check_slope();
 
-       update_wrap();
+       update_tracks();
 }
 
 void Manipulator::cancel()
@@ -201,7 +198,6 @@ void Manipulator::cancel()
                return;
        mode = NONE;
 
-       wrap_pos = center;
        for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                i->track->set_position(Point(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z));
@@ -212,7 +208,6 @@ void Manipulator::cancel()
                (*i)->check_slope();
 
        angle = 0;
-       wrap_rot = 0;
 
        signal_done.emit(false);
 }
@@ -224,7 +219,6 @@ void Manipulator::button_press(int, int, float, float, unsigned btn)
        else if(mode)
        {
                mode = NONE;
-               update_wrap();
                angle = 0;
 
                for(set<Track *>::iterator i=neighbors.begin(); i!=neighbors.end(); ++i)
@@ -243,9 +237,7 @@ void Manipulator::button_press(int, int, float, float, unsigned btn)
                                j->track->snap_to(**i, true);
                }
 
-               for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
-                       i->rot = i->track->get_rotation();
-
+               update_tracks();
                update_neighbors();
 
                signal_done.emit(true);
@@ -260,11 +252,10 @@ void Manipulator::pointer_motion(int, int y, float gx, float gy)
        if(mode==MOVE)
        {
                Point delta(gpointer.x-move_origin.x, gpointer.y-move_origin.y, 0);
-
-               wrap_pos = Point(center.x+delta.x, center.y+delta.y, center.z);
+               Point offset(center.x+delta.x, center.y+delta.y, center.z);
                for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
-                       i->track->set_position(Point(wrap_pos.x+i->pos.x, wrap_pos.y+i->pos.y, wrap_pos.z+i->pos.z));
+                       i->track->set_position(Point(offset.x+i->pos.x, offset.y+i->pos.y, offset.z+i->pos.z));
                        i->track->set_rotation(i->rot);
                }
 
@@ -305,12 +296,11 @@ void Manipulator::pointer_motion(int, int y, float gx, float gy)
                angle += a-rot_origin;
                rot_origin = a;
 
-               wrap_rot = angle;
                for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                {
                        float c = cos(angle);
                        float s = sin(angle);
-                       i->track->set_position(Point(center.x+c*i->pos.x-s*i->pos.y, center.y+s*i->pos.x+c*i->pos.y, center.z*i->pos.z));
+                       i->track->set_position(Point(center.x+c*i->pos.x-s*i->pos.y, center.y+s*i->pos.x+c*i->pos.y, center.z+i->pos.z));
                        i->track->set_rotation(angle+i->rot);
                }
        }
@@ -320,7 +310,6 @@ void Manipulator::pointer_motion(int, int y, float gx, float gy)
 
                signal_status.emit(format("Elevation: %+.0fmm (%.0fmm)", dz*1000, (center.z+dz)*1000));
 
-               wrap_pos.z = center.z+dz;
                for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
                        i->track->set_position(Point(center.x+i->pos.x, center.y+i->pos.y, center.z+i->pos.z+dz));
 
@@ -329,33 +318,6 @@ void Manipulator::pointer_motion(int, int y, float gx, float gy)
        }
 }
 
-void Manipulator::render()
-{
-       glPushMatrix();
-       glTranslatef(wrap_pos.x, wrap_pos.y, wrap_pos.z);
-       glRotatef(wrap_rot*180/M_PI, 0, 0, 1);
-
-       glLineWidth(2);
-       glColor4f(0, 1, 0, 0.5);
-       for(list<TrackWrap>::iterator i=wrap.begin(); i!=wrap.end(); ++i)
-       {
-               glPushMatrix();
-               glTranslatef(i->pos.x, i->pos.y, i->pos.z);
-               glRotatef(i->rot*180/M_PI, 0, 0, 1);
-
-               glBegin(GL_LINE_LOOP);
-               glVertex2f(-i->width/2, -i->height/2);
-               glVertex2f(i->width/2, -i->height/2);
-               glVertex2f(i->width/2, i->height/2);
-               glVertex2f(-i->width/2, i->height/2);
-               glEnd();
-
-               glPopMatrix();
-       }
-
-       glPopMatrix();
-}
-
 void Manipulator::selection_changed()
 {
        if(mode)
@@ -366,71 +328,37 @@ void Manipulator::selection_changed()
        tracks.insert(tracks.end(), stracks.begin(), stracks.end());
 
        update_neighbors();
-       update_wrap();
+       update_tracks();
 }
 
-void Manipulator::update_wrap()
+void Manipulator::update_tracks()
 {
-       wrap.clear();
-       float min_x = 0, max_x = 0;
-       float min_y = 0, max_y = 0;
-       float min_z = 0;
+       Point minp, maxp;
        for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
-               Track3D &t3d = designer.get_layout_3d()->get_track(*i->track);
-
-               TrackWrap tw;
-               float min_area = 100;
-               for(float a=0; a<M_PI; a+=0.01)
+               unsigned n_endpoints = i->track->get_type().get_endpoints().size();
+               for(unsigned j=0; j<n_endpoints; ++j)
                {
-                       Point minp, maxp;
-                       t3d.get_bounds(a, minp, maxp);
-                       float area = (maxp.x-minp.x)*(maxp.y-minp.y);
-                       if(area<min_area)
+                       Point p = i->track->get_endpoint_position(j);
+                       if(i==tracks.begin() && j==0)
+                               minp = maxp = p;
+                       else
                        {
-                               float c = cos(a);
-                               float s = sin(a);
-                               float x = (minp.x+maxp.x)/2;
-                               float y = (minp.y+maxp.y)/2;
-                               tw.pos = Point(c*x-s*y, s*x+c*y, minp.z);
-                               tw.rot = a;
-                               tw.width = maxp.x-minp.x+0.01;
-                               tw.height = maxp.y-minp.y+0.01;
-
-                               min_area = area;
+                               minp.x = min(minp.x, p.x);
+                               maxp.x = max(maxp.x, p.x);
+                               minp.y = min(minp.y, p.y);
+                               maxp.y = max(maxp.y, p.y);
+                               minp.z = min(minp.z, p.z);
                        }
                }
-
-               if(i==tracks.begin())
-               {
-                       min_x = max_x = tw.pos.x;
-                       min_y = max_y = tw.pos.y;
-                       min_z = tw.pos.z;
-               }
-               else
-               {
-                       min_x = min(min_x, tw.pos.x);
-                       max_x = max(max_x, tw.pos.x);
-                       min_y = min(min_y, tw.pos.y);
-                       max_y = max(max_y, tw.pos.y);
-                       min_z = min(min_z, tw.pos.z);
-               }
-               wrap.push_back(tw);
        }
 
-       center = Point((min_x+max_x)/2, (min_y+max_y)/2, min_z);
-       wrap_pos = center;
-       wrap_rot = 0;
+       center = Point((minp.x+maxp.x)/2, (minp.y+maxp.y)/2, minp.z);
        for(vector<MTrack>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
        {
                const Point &tp = i->track->get_position();
                i->pos = Point(tp.x-center.x, tp.y-center.y, tp.z-center.z);
-       }
-       for(list<TrackWrap>::iterator i=wrap.begin(); i!=wrap.end(); ++i)
-       {
-               i->pos.x -= center.x;
-               i->pos.y -= center.y;
-               i->pos.z -= center.z;
+               i->rot = i->track->get_rotation();
        }
 }
 
index 2ed49fb1a754bf8a2f1caf6e336896a78aafc7be..fa8598db186f7ebb55126777cd4a3cf375902720 100644 (file)
@@ -9,7 +9,6 @@ Distributed under the GPL
 #define MANIPULATOR_H_
 
 #include <sigc++/sigc++.h>
-#include "3d/track.h"
 
 class Designer;
 class Selection;
@@ -42,14 +41,6 @@ private:
                TrackOrder(Marklin::Track *t, bool r): track(t), rev(r) { }
        };
 
-       struct TrackWrap
-       {
-               Marklin::Point pos;
-               float rot;
-               float width;
-               float height;
-       };
-
 public:
        sigc::signal<void, const std::string &> signal_status;
        sigc::signal<void, bool> signal_done;
@@ -60,10 +51,6 @@ private:
        std::vector<MTrack> tracks;
        Marklin::Point center;
 
-       std::list<TrackWrap> wrap;
-       Marklin::Point wrap_pos;
-       float wrap_rot;
-
        Marklin::Point gpointer;
        int pointer_y;
        Mode mode;
@@ -85,10 +72,9 @@ public:
        void cancel();
        void button_press(int, int, float, float, unsigned);
        void pointer_motion(int, int, float, float);
-       void render();
 private:
        void selection_changed();
-       void update_wrap();
+       void update_tracks();
        void update_neighbors();
        void set_slope(TrackOrder &, float, float);
 };
diff --git a/source/designer/trackwrap.cpp b/source/designer/trackwrap.cpp
new file mode 100644 (file)
index 0000000..febeade
--- /dev/null
@@ -0,0 +1,101 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010  Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <msp/gl/matrix.h>
+#include <msp/gl/meshbuilder.h>
+#include "3d/tracktype.h"
+#include "designer.h"
+#include "selection.h"
+#include "trackwrap.h"
+
+using namespace std;
+using namespace Msp;
+using namespace Marklin;
+
+TrackWrap::TrackWrap(Designer &d, Selection &s):
+       designer(d),
+       selection(s)
+{
+       selection.signal_changed.connect(sigc::mem_fun(this, &TrackWrap::selection_changed));
+}
+
+void TrackWrap::render(const GL::Tag &) const
+{
+       for(list<Wrap>::const_iterator i=wraps.begin(); i!=wraps.end(); ++i)
+       {
+               GL::PushMatrix _pushm;
+               const Point &pos = i->track->get_position();
+               GL::translate(pos.x, pos.y, pos.z);
+               GL::rotate(i->track->get_rotation()*180/M_PI, 0, 0, 1);
+               i->mesh->draw();
+       }
+}
+
+void TrackWrap::selection_changed()
+{
+       wraps.clear();
+       const set<Track *> &tracks = selection.get_tracks();
+       for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+       {
+               Wrap wrap;
+               wrap.track = *i;
+               wrap.mesh = &get_mesh((*i)->get_type());
+               wraps.push_back(wrap);
+       }
+}
+
+GL::Mesh &TrackWrap::get_mesh(const TrackType &type)
+{
+       map<const TrackType *, GL::Mesh *>::iterator j = meshes.find(&type);
+       if(j!=meshes.end())
+               return *j->second;
+
+       const TrackType3D &type3d = designer.get_layout_3d()->get_catalogue().get_track(type);
+
+       float min_area = -1;
+       float angle;
+       Point center;
+       float width;
+       float height;
+       for(float a=0; a<M_PI; a+=0.01)
+       {
+               Point minp, maxp;
+               type3d.get_bounds(a, minp, maxp);
+               float area = (maxp.x-minp.x)*(maxp.y-minp.y);
+               if(area<min_area || min_area<0)
+               {
+                       float c = cos(a);
+                       float s = sin(a);
+                       float x = (minp.x+maxp.x)/2;
+                       float y = (minp.y+maxp.y)/2;
+                       center = Point(c*x-s*y, s*x+c*y, minp.z);
+                       angle = a;
+                       width = maxp.x-minp.x+0.01;
+                       height = maxp.y-minp.y+0.01;
+
+                       min_area = area;
+               }
+       }
+
+       GL::Mesh *mesh = new GL::Mesh((GL::COLOR4_UBYTE, GL::VERTEX2));
+       GL::MeshBuilder bld(*mesh);
+       bld.color(0.0f, 1.0f, 0.0f, 1.0f);
+
+       float c = cos(angle);
+       float s = sin(angle);
+
+       bld.begin(GL::LINE_LOOP);
+       bld.vertex(center.x-c*width/2+s*height/2, center.y-s*width/2-c*height/2);
+       bld.vertex(center.x+c*width/2+s*height/2, center.y+s*width/2-c*height/2);
+       bld.vertex(center.x+c*width/2-s*height/2, center.y+s*width/2+c*height/2);
+       bld.vertex(center.x-c*width/2-s*height/2, center.y-s*width/2+c*height/2);
+       bld.end();
+
+       meshes[&type] = mesh;
+
+       return *mesh;
+}
diff --git a/source/designer/trackwrap.h b/source/designer/trackwrap.h
new file mode 100644 (file)
index 0000000..09bacda
--- /dev/null
@@ -0,0 +1,42 @@
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010  Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef TRACKWRAP_H_
+#define TRACKWRAP_H_
+
+#include <msp/gl/mesh.h>
+#include <msp/gl/renderable.h>
+#include "libmarklin/track.h"
+
+class Designer;
+class Selection;
+
+class TrackWrap: public Msp::GL::Renderable
+{
+private:
+       struct Wrap
+       {
+               Marklin::Track *track;
+               Msp::GL::Mesh *mesh;
+       };
+
+       Designer &designer;
+       Selection &selection;
+       std::map<const Marklin::TrackType *, Msp::GL::Mesh *> meshes;
+       std::list<Wrap> wraps;
+
+public:
+       TrackWrap(Designer &, Selection &);
+
+       virtual void render(const Msp::GL::Tag &) const;
+
+private:
+       void selection_changed();
+       Msp::GL::Mesh &get_mesh(const Marklin::TrackType &);
+};
+
+#endif