3 This file is part of the MSP Märklin suite
4 Copyright © 2010 Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
12 #include "tracktype.h"
14 #include "vehicletype.h"
20 Vehicle::Vehicle(Layout &l, const VehicleType &t):
27 layout.add_vehicle(*this);
32 layout.remove_vehicle(*this);
35 void Vehicle::place(Track *t, unsigned e, float o, PlaceMode m)
37 track_pos = TrackPosition(t, e, o);
41 float front = type.get_length()/2;
42 if(!type.get_axles().empty())
43 front = type.get_axles().front().position;
44 if(!type.get_bogies().empty())
46 const VehicleType::Bogie &bogie = type.get_bogies().front();
47 front = max(front, bogie.position+bogie.axles.front().position);
49 track_pos.advance(-front);
51 else if(m==FRONT_BUFFER)
52 track_pos.advance(-type.get_length()/2);
55 float back = type.get_length()/2;
56 if(!type.get_axles().empty())
57 back = type.get_axles().back().position;
58 if(!type.get_bogies().empty())
60 const VehicleType::Bogie &bogie = type.get_bogies().back();
61 back = min(back, bogie.position+bogie.axles.back().position);
63 track_pos.advance(-back);
65 else if(m==BACK_BUFFER)
66 track_pos.advance(type.get_length()/2);
71 void Vehicle::advance(float d)
77 void Vehicle::update_position()
81 const vector<VehicleType::Axle> &axles = type.get_axles();
83 tp = get_position(axles.front().position, axles.back().position, track_pos);
86 const vector<VehicleType::Bogie> &bogies = type.get_bogies();
88 // XXX Calculate bogie positions correctly
89 tp = get_position(bogies.front().position, bogies.back().position, track_pos);
91 tp = track_pos.get_point();
97 TrackPoint Vehicle::get_position(float front, float back, const TrackPosition &tpos)
99 TrackPosition front_pos = tpos;
100 front_pos.advance(front);
102 TrackPosition back_pos = tpos;
103 back_pos.advance(back);
105 float target_dist = front-back;
109 Point front_point = front_pos.get_point().pos;
110 Point back_point = back_pos.get_point().pos;
112 float dx = front_point.x-back_point.x;
113 float dy = front_point.y-back_point.y;
114 float dz = front_point.z-back_point.z;
115 float dist = sqrt(dx*dx+dy*dy+dz*dz);
119 float adjust = target_dist-dist+0.01*layout.get_catalogue().get_scale();
120 front_pos.advance(adjust/2);
121 back_pos.advance(-adjust/2);
125 float f = -back/target_dist;
127 pt.pos = Point(back_point.x+dx*f, back_point.y+dy*f, back_point.z+dz*f);
128 pt.dir = atan2(dy, dx);
135 Vehicle::TrackPosition::TrackPosition():
141 Vehicle::TrackPosition::TrackPosition(Track *t, unsigned e, float o):
147 void Vehicle::TrackPosition::advance(float d)
152 unsigned path = track->get_active_path();
155 float path_len = track->get_type().get_path_length(path);
156 while(track && offs>=path_len)
158 unsigned out = track->traverse(ep, path);
159 Track *next = track->get_link(out);
163 ep = next->get_endpoint_by_link(*track);
167 path = track->get_active_path();
168 path_len = track->get_type().get_path_length(path);
174 while(track && offs<0)
176 Track *prev = track->get_link(ep);
179 unsigned in = prev->get_endpoint_by_link(*track);
182 path = track->get_active_path();
183 ep = track->traverse(in, path);
185 path_len = track->get_type().get_path_length(path);
199 TrackPoint Vehicle::TrackPosition::get_point() const
202 return track->get_point(ep, offs);
207 } // namespace Marklin