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