]> git.tdb.fi Git - r2c2.git/blobdiff - source/designer/manipulator.cpp
Introduce a tilt (vertical angle) property to Object
[r2c2.git] / source / designer / manipulator.cpp
index 8620fe7af8a6a53e8c0a43fd960d509805fa736f..b61d9a7ae5e28642344554f01b001f9887480c12 100644 (file)
@@ -101,9 +101,9 @@ void Manipulator::flatten()
        float z = 0;
        for(vector<MObject>::iterator i=objects.begin(); i!=objects.end(); ++i)
        {
-               z += i->object->get_position().z;
-               if(Track *track = dynamic_cast<Track *>(i->object))
-                       z += track->get_slope()/2;
+               unsigned nsn = i->object->get_n_snap_nodes();
+               for(unsigned j=0; j<nsn; ++j)
+                       z += i->object->get_snap_node(j).position.z/nsn;
        }
        z /= static_cast<int>(objects.size());
 
@@ -112,7 +112,7 @@ void Manipulator::flatten()
                Vector p = i->object->get_position();
                i->object->set_position(Vector(p.x, p.y, z));
                if(Track *track = dynamic_cast<Track *>(i->object))
-                       track->set_slope(0);
+                       track->set_tilt(Angle::zero());
        }
 
        update_objects();
@@ -177,27 +177,26 @@ void Manipulator::even_slope(bool smooth)
                while((end_z-start_z)*dir/total_len>cur_slope+0.025 && order.size()>2)
                {
                        cur_slope += 0.025;
+                       Angle tilt = Geometry::atan(cur_slope);
+
+                       set_slope(order.front(), start_z, tilt);
+                       start_z += order.front().track->get_type().get_path_length(0)*dir*cur_slope;
+                       total_len -= order.front().track->get_type().get_path_length(0);
+                       order.pop_front();
 
-                       float dz = order.front().track->get_type().get_total_length()*dir*cur_slope;
-                       set_slope(order.front(), start_z, dz);
-                       start_z += dz;
-                       total_len -= order.front().track->get_type().get_total_length();
-                       order.erase(order.begin());
-
-                       dz = order.back().track->get_type().get_total_length()*dir*cur_slope;
-                       set_slope(order.back(), end_z-dz, dz);
-                       end_z -= dz;
-                       total_len -= order.back().track->get_type().get_total_length();
-                       order.erase(--order.end());
+                       end_z -= order.back().track->get_type().get_path_length(0)*dir*cur_slope;
+                       set_slope(order.back(), end_z, tilt);
+                       total_len -= order.back().track->get_type().get_path_length(0);
+                       order.pop_back();
                }
        }
 
        float cur_z = start_z;
+       Angle tilt = Geometry::atan((end_z-start_z)/total_len);
        for(list<TrackOrder>::iterator i=order.begin(); i!=order.end(); ++i)
        {
-               float dz = i->track->get_type().get_total_length()*(end_z-start_z)/total_len;
-               set_slope(*i, cur_z, dz);
-               cur_z += dz;
+               set_slope(*i, cur_z, tilt);
+               cur_z += i->track->get_type().get_path_length(0)*(end_z-start_z)/total_len;
        }
 
        update_objects();
@@ -322,7 +321,7 @@ void Manipulator::button_press(unsigned btn)
                                        j->object->break_link(**i);
                }
 
-               const set<Track *> &ltracks = designer.get_layout().get_tracks();
+               const set<Track *> &ltracks = designer.get_layout().get_all<Track>();
                for(set<Track *>::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
                {
                        bool ok = true;
@@ -366,7 +365,7 @@ void Manipulator::axis_motion(unsigned axis, float value, float)
                        i->object->set_rotation(i->rot);
                }
 
-               const set<Track *> &ltracks = designer.get_layout().get_tracks();
+               const set<Track *> &ltracks = designer.get_layout().get_all<Track>();
                float limit = max(designer.get_layout().get_catalogue().get_gauge(),
                        designer.get_camera_controller().get_view_scale()/100.0f);
                MObject *snapped = 0;
@@ -504,38 +503,12 @@ void Manipulator::selection_changed()
 
 void Manipulator::update_objects()
 {
-       Vector minp, maxp;
+       Geometry::BoundingBox<float, 3> bbox;
        for(vector<MObject>::iterator i=objects.begin(); i!=objects.end(); ++i)
-       {
-               // XXX Use generic bounding box when it is implemented
-               if(Track *track = dynamic_cast<Track *>(i->object))
-               {
-                       unsigned n_endpoints = track->get_type().get_endpoints().size();
-                       for(unsigned j=0; j<n_endpoints; ++j)
-                       {
-                               Vector p = track->get_snap_node(j).position;
-                               if(i==objects.begin() && j==0)
-                                       minp = maxp = p;
-                               else
-                               {
-                                       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);
-                               }
-                       }
-               }
-               else
-               {
-                       const Vector &p = i->object->get_position();
-                       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);
-               }
-       }
+               bbox = bbox|i->object->get_bounding_box();
+
+       const Vector &minp = bbox.get_minimum_point();
+       const Vector &maxp = bbox.get_maximum_point();
 
        center = (minp+maxp)/2.0f;
        center.z = minp.z;
@@ -570,18 +543,19 @@ void Manipulator::update_neighbors()
        }
 }
 
-void Manipulator::set_slope(TrackOrder &track, float z, float dz)
+void Manipulator::set_slope(TrackOrder &track, float z, const Angle &tilt)
 {
        const Vector &p = track.track->get_position();
+       float dz = tan(tilt)*track.track->get_type().get_path_length(0);
        if(track.rev)
        {
                track.track->set_position(Vector(p.x, p.y, z+dz));
-               track.track->set_slope(-dz);
+               track.track->set_tilt(-tilt);
        }
        else
        {
                track.track->set_position(Vector(p.x, p.y, z));
-               track.track->set_slope(dz);
+               track.track->set_tilt(tilt);
        }
 }