1 #include <msp/core/maputils.h>
2 #include <msp/geometry/box.h>
3 #include <msp/geometry/transformedshape.h>
4 #include <msp/strings/format.h>
5 #include "vehicletype.h"
12 VehicleType::VehicleType(const ArticleNumber &an):
15 swap_direction(false),
22 unsigned VehicleType::get_max_function() const
26 return (--functions.end())->first;
29 const VehicleType::Axle &VehicleType::get_axle(unsigned i) const
32 throw out_of_range("VehicleType::get_axle");
36 const VehicleType::Axle &VehicleType::get_fixed_axle(unsigned i) const
38 if(i>=fixed_axles.size())
39 throw out_of_range("VehicleType::get_fixed_axle");
40 return *fixed_axles[i];
43 const VehicleType::Bogie &VehicleType::get_bogie(unsigned i) const
46 throw out_of_range("VehicleType::get_bogie");
50 const VehicleType::Axle &VehicleType::get_bogie_axle(unsigned i, unsigned j) const
53 throw out_of_range("VehicleType::get_bogie_axle");
54 if(j>=bogies[i].axles.size())
55 throw out_of_range("VehicleType::get_bogie_axle");
56 return *bogies[i].axles[j];
59 const VehicleType::Rod &VehicleType::get_rod(unsigned i) const
62 throw out_of_range("VehicleType::get_rod");
66 float VehicleType::get_front_axle_offset() const
69 return axles.front().position;
73 float VehicleType::get_back_axle_offset() const
76 return axles.back().position;
81 VehicleType::Axle::Axle():
91 VehicleType::Bogie::Bogie():
97 VehicleType::Rod::Rod():
107 VehicleType::Loader::Loader(VehicleType &vt):
108 DataFile::DerivedObjectLoader<VehicleType, ObjectType::Loader>(vt)
110 add("axle", &Loader::axle);
111 add("bogie", &Loader::bogie);
112 add("function", &Loader::function);
113 add("height", &Loader::height);
114 add("length", &Loader::length);
115 add("locomotive", &VehicleType::locomotive);
116 add("object", &VehicleType::object);
117 add("rod", &Loader::rod);
118 add("rotate_object", &VehicleType::rotate_object);
119 add("swap_direction", &VehicleType::swap_direction);
120 add("width", &Loader::width);
123 void VehicleType::Loader::finish()
125 for(unsigned i=0; i<obj.bogies.size(); ++i)
127 obj.bogies[i].index = i;
128 for(unsigned j=0; j<obj.bogies[i].axles.size(); ++j)
130 obj.bogies[i].axles[j] = &obj.axles[obj.bogies[i].first_axle+j];
131 obj.bogies[i].axles[j]->bogie = &obj.bogies[i];
132 obj.bogies[i].axles[j]->position += obj.bogies[i].position;
136 for(unsigned i=0; i<obj.axles.size(); ++i)
138 obj.axles[i].index = i;
139 if(!obj.axles[i].bogie)
140 obj.fixed_axles.push_back(&obj.axles[i]);
143 obj.shape = new Geometry::TransformedShape<float, 3>(
144 Geometry::Box<float>(obj.length, obj.width, obj.height),
145 Transform::translation(Vector(0, 0, obj.height/2)));
148 void VehicleType::Loader::axle()
152 obj.axles.push_back(axl);
155 void VehicleType::Loader::bogie()
158 Bogie::Loader ldr(obj, bog);
160 obj.bogies.push_back(bog);
163 void VehicleType::Loader::function(unsigned i, const string &f)
165 obj.functions[i] = f;
168 void VehicleType::Loader::height(float h)
173 void VehicleType::Loader::length(float l)
178 void VehicleType::Loader::rod()
181 Rod::Loader ldr(rd, rod_tags);
183 obj.rods.push_back(rd);
184 if(!ldr.get_tag().empty())
185 rod_tags[ldr.get_tag()] = obj.rods.size()-1;
186 rod_tags["previous"] = obj.rods.size()-1;
189 void VehicleType::Loader::width(float w)
195 VehicleType::Axle::Loader::Loader(Axle &a):
196 DataFile::ObjectLoader<Axle>(a)
198 add("object", &Axle::object);
199 add("position", &Loader::position);
200 add("powered", &Axle::powered);
201 add("wheel_diameter", &Loader::wheel_diameter);
204 void VehicleType::Axle::Loader::position(float p)
206 obj.local_position = p/1000;
207 obj.position = obj.local_position;
210 void VehicleType::Axle::Loader::wheel_diameter(float d)
212 obj.wheel_dia = d/1000;
216 VehicleType::Bogie::Loader::Loader(VehicleType &t, Bogie &b):
217 DataFile::ObjectLoader<Bogie>(b),
220 add("axle", &Loader::axle);
221 add("object", &Bogie::object);
222 add("position", &Loader::position);
223 add("rotate_object", &Bogie::rotate_object);
226 void VehicleType::Bogie::Loader::axle()
230 if(obj.axles.empty())
231 obj.first_axle = parent.axles.size();
232 parent.axles.push_back(axl);
233 // Actual pointers will be filled after everything is loaded
234 obj.axles.push_back(0);
237 void VehicleType::Bogie::Loader::position(float p)
239 obj.position = p/1000;
243 VehicleType::Rod::Loader::Loader(Rod &r, const map<string, unsigned> &t):
244 DataFile::ObjectLoader<Rod>(r),
247 add("connect", &Loader::connect);
248 add("limit", &Rod::limit);
249 add("mirror_object", &Rod::mirror_object);
250 add("object", &Rod::object);
251 add("pivot_body", &Loader::pivot_body);
252 add("pivot_axle", &Loader::pivot_axle);
253 add("pivot_axle", &Loader::pivot_bogie_axle);
254 add("pivot_rod", &Loader::pivot_rod);
255 add("position", &Loader::position);
256 add("tag", &Loader::set_tag);
259 void VehicleType::Rod::Loader::connect(const string &t, float px, float pz, float ox, float oz)
261 obj.connect_index = get_item(tags, t);
262 obj.connect_point = Vector(px/1000, 0, pz/1000);
263 obj.connect_offset = Vector(ox/1000, 0, oz/1000);
266 void VehicleType::Rod::Loader::pivot_body()
271 void VehicleType::Rod::Loader::pivot_axle(unsigned i)
277 void VehicleType::Rod::Loader::pivot_bogie_axle(unsigned i, unsigned j)
279 obj.pivot = BOGIE_AXLE;
281 obj.pivot_index2 = j;
284 void VehicleType::Rod::Loader::pivot_rod(const string &t)
286 obj.pivot_index = get_item(tags, t);
290 void VehicleType::Rod::Loader::position(float x, float y, float z)
292 obj.pivot_point = Vector(x/1000, y/1000, z/1000);
295 void VehicleType::Rod::Loader::set_tag(const string &t)
301 void operator>>(const LexicalConverter &c, VehicleType::Rod::Limit &l)
303 const string &s = c.get();
305 l = VehicleType::Rod::FIXED;
307 l = VehicleType::Rod::ROTATE;
308 else if(s=="SLIDE_X")
309 l = VehicleType::Rod::SLIDE_X;
311 throw lexical_error(format("conversion of '%s' to Rod::Limit", s));