]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/vehicletype.cpp
Strip Id tags and copyright notices from files
[r2c2.git] / source / libr2c2 / vehicletype.cpp
1 #include "vehicletype.h"
2
3 using namespace std;
4 using namespace Msp;
5
6 namespace R2C2 {
7
8 VehicleType::VehicleType(const ArticleNumber &an):
9         art_nr(an),
10         locomotive(false),
11         swap_direction(false),
12         length(0),
13         width(0),
14         height(0)
15 { }
16
17 unsigned VehicleType::get_max_function() const
18 {
19         if(functions.empty())
20                 return 0;
21         return (--functions.end())->first;
22 }
23
24 const VehicleType::Axle &VehicleType::get_fixed_axle(unsigned i) const
25 {
26         if(i>=axles.size())
27                 throw InvalidParameterValue("Axle index out of range");
28         return axles[i];
29 }
30
31 const VehicleType::Bogie &VehicleType::get_bogie(unsigned i) const
32 {
33         if(i>=bogies.size())
34                 throw InvalidParameterValue("Axle index out of range");
35         return bogies[i];
36 }
37
38 const VehicleType::Axle &VehicleType::get_bogie_axle(unsigned i, unsigned j) const
39 {
40         if(i>=bogies.size())
41                 throw InvalidParameterValue("Axle index out of range");
42         if(j>=bogies[i].axles.size())
43                 throw InvalidParameterValue("Axle index out of range");
44         return bogies[i].axles[j];
45 }
46
47 const VehicleType::Rod &VehicleType::get_rod(unsigned i) const
48 {
49         if(i>=rods.size())
50                 throw InvalidParameterValue("Rod index out of range");
51         return rods[i];
52 }
53
54 float VehicleType::get_front_axle_offset() const
55 {
56         float front = length/2;
57         if(!axles.empty())
58                 front = axles.front().position;
59         if(!bogies.empty())
60         {
61                 const Bogie &bogie = bogies.front();
62                 front = max(front, bogie.position+bogie.axles.front().position);
63         }
64         return front;
65 }
66
67 float VehicleType::get_back_axle_offset() const
68 {
69         float back = -length/2;
70         if(!axles.empty())
71                 back = axles.back().position;
72         if(!bogies.empty())
73         {
74                 const Bogie &bogie = bogies.back();
75                 back = min(back, bogie.position+bogie.axles.back().position);
76         }
77         return back;
78 }
79
80
81 VehicleType::Axle::Axle():
82         position(0),
83         wheel_dia(0),
84         powered(false)
85 { }
86
87
88 VehicleType::Bogie::Bogie():
89         position(0),
90         rotate_object(false)
91 { }
92
93
94 VehicleType::Rod::Rod():
95         pivot(BODY),
96         pivot_index(0),
97         pivot_index2(0),
98         limit(ROTATE),
99         connect_index(-1),
100         mirror_object(false)
101 { }
102
103
104 VehicleType::Loader::Loader(VehicleType &vt):
105         DataFile::ObjectLoader<VehicleType>(vt)
106 {
107         add("axle",       &Loader::axle);
108         add("bogie",      &Loader::bogie);
109         add("function",   &Loader::function);
110         add("height",     &Loader::height);
111         add("length",     &Loader::length);
112         add("locomotive", &VehicleType::locomotive);
113         add("name",       &VehicleType::name);
114         add("object",     &VehicleType::object);
115         add("rod",        &Loader::rod);
116         add("swap_direction", &VehicleType::swap_direction);
117         add("width",      &Loader::width);
118 }
119
120 void VehicleType::Loader::axle()
121 {
122         Axle axl;
123         load_sub(axl);
124         obj.axles.push_back(axl);
125 }
126
127 void VehicleType::Loader::bogie()
128 {
129         Bogie bog;
130         load_sub(bog);
131         obj.bogies.push_back(bog);
132 }
133
134 void VehicleType::Loader::function(unsigned i, const string &f)
135 {
136         obj.functions[i] = f;
137 }
138
139 void VehicleType::Loader::height(float h)
140 {
141         obj.height = h/1000;
142 }
143
144 void VehicleType::Loader::length(float l)
145 {
146         obj.length = l/1000;
147 }
148
149 void VehicleType::Loader::rod()
150 {
151         Rod rd;
152         Rod::Loader ldr(rd, rod_tags);
153         load_sub_with(ldr);
154         obj.rods.push_back(rd);
155         if(!ldr.get_tag().empty())
156                 rod_tags[ldr.get_tag()] = obj.rods.size()-1;
157         rod_tags["previous"] = obj.rods.size()-1;
158 }
159
160 void VehicleType::Loader::width(float w)
161 {
162         obj.width = w/1000;
163 }
164
165
166 VehicleType::Axle::Loader::Loader(Axle &a):
167         DataFile::ObjectLoader<Axle>(a)
168 {
169         add("object",         &Axle::object);
170         add("position",       &Loader::position);
171         add("powered",        &Axle::powered);
172         add("wheel_diameter", &Loader::wheel_diameter);
173 }
174
175 void VehicleType::Axle::Loader::position(float p)
176 {
177         obj.position = p/1000;
178 }
179
180 void VehicleType::Axle::Loader::wheel_diameter(float d)
181 {
182         obj.wheel_dia = d/1000;
183 }
184
185
186 VehicleType::Bogie::Loader::Loader(Bogie &b):
187         DataFile::ObjectLoader<Bogie>(b)
188 {
189         add("axle",          &Loader::axle);
190         add("object",        &Bogie::object);
191         add("position",      &Loader::position);
192         add("rotate_object", &Bogie::rotate_object);
193 }
194
195 void VehicleType::Bogie::Loader::axle()
196 {
197         Axle axl;
198         load_sub(axl);
199         obj.axles.push_back(axl);
200 }
201
202 void VehicleType::Bogie::Loader::position(float p)
203 {
204         obj.position = p/1000;
205 }
206
207
208 VehicleType::Rod::Loader::Loader(Rod &r, const map<string, unsigned> &t):
209         DataFile::ObjectLoader<Rod>(r),
210         tags(t)
211 {
212         add("connect",       &Loader::connect);
213         add("limit",         &Rod::limit);
214         add("mirror_object", &Rod::mirror_object);
215         add("object",        &Rod::object);
216         add("pivot_body",    &Loader::pivot_body);
217         add("pivot_axle",    &Loader::pivot_axle);
218         add("pivot_axle",    &Loader::pivot_bogie_axle);
219         add("pivot_rod",     &Loader::pivot_rod);
220         add("position",      &Loader::position);
221         add("tag",           &Loader::set_tag);
222 }
223
224 void VehicleType::Rod::Loader::connect(const string &t, float px, float pz, float ox, float oz)
225 {
226         map<string, unsigned>::const_iterator i = tags.find(t);
227         if(i==tags.end())
228                 throw KeyError("Unknown rod tag", t);
229         obj.connect_index = i->second;
230         obj.connect_point = Vector(px/1000, 0, pz/1000);
231         obj.connect_offset = Vector(ox/1000, 0, oz/1000);
232 }
233
234 void VehicleType::Rod::Loader::pivot_body()
235 {
236         obj.pivot = BODY;
237 }
238
239 void VehicleType::Rod::Loader::pivot_axle(unsigned i)
240 {
241         obj.pivot = AXLE;
242         obj.pivot_index = i;
243 }
244
245 void VehicleType::Rod::Loader::pivot_bogie_axle(unsigned i, unsigned j)
246 {
247         obj.pivot = BOGIE_AXLE;
248         obj.pivot_index = i;
249         obj.pivot_index2 = j;
250 }
251
252 void VehicleType::Rod::Loader::pivot_rod(const string &t)
253 {
254         map<string, unsigned>::const_iterator i = tags.find(t);
255         if(i==tags.end())
256                 throw KeyError("Unknown rod tag", t);
257         obj.pivot = ROD;
258         obj.pivot_index = i->second;
259 }
260
261 void VehicleType::Rod::Loader::position(float x, float y, float z)
262 {
263         obj.pivot_point = Vector(x/1000, y/1000, z/1000);
264 }
265
266 void VehicleType::Rod::Loader::set_tag(const string &t)
267 {
268         tag = t;
269 }
270
271
272 void operator>>(const LexicalConverter &c, VehicleType::Rod::Limit &l)
273 {
274         const string &s = c.get();
275         if(s=="FIXED")
276                 l = VehicleType::Rod::FIXED;
277         else if(s=="ROTATE")
278                 l = VehicleType::Rod::ROTATE;
279         else if(s=="SLIDE_X")
280                 l = VehicleType::Rod::SLIDE_X;
281         else
282                 throw LexicalError("Invalid value for Rod::Limit");
283 }
284
285 } // namespace R2C2