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