]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/vehicle.h
bd815ab19f497bec7d07470d09700186765548ce
[r2c2.git] / source / libr2c2 / vehicle.h
1 #ifndef LIBR2C2_VEHICLE_H_
2 #define LIBR2C2_VEHICLE_H_
3
4 #include "geometry.h"
5 #include "object.h"
6 #include "vehicletype.h"
7
8 namespace R2C2 {
9
10 class Layout;
11 class Track;
12
13 class attachment_error: public std::logic_error
14 {
15 public:
16         attachment_error(const std::string &w): std::logic_error(w) { }
17         virtual ~attachment_error() throw() { }
18 };
19
20
21 class Vehicle: public Object
22 {
23 public:
24         enum PlaceMode
25         {
26                 CENTER,
27                 FRONT_AXLE,
28                 FRONT_BUFFER,
29                 BACK_AXLE,
30                 BACK_BUFFER
31         };
32
33         struct Axle
34         {
35                 const VehicleType::Axle *type;
36                 Angle angle;
37
38                 Axle(const VehicleType::Axle &);
39         };
40
41         struct Bogie
42         {
43                 const VehicleType::Bogie *type;
44                 Angle direction;
45                 std::vector<Axle> axles;
46
47                 Bogie(const VehicleType::Bogie &);
48         };
49
50         struct Rod
51         {
52                 const VehicleType::Rod *type;
53                 Vector position;
54                 Angle angle;
55
56                 Rod(const VehicleType::Rod &);
57         };
58
59 private:
60         struct TrackPosition
61         {
62                 Track *track;
63                 unsigned ep;
64                 float offs;
65
66                 TrackPosition();
67                 TrackPosition(Track *, unsigned, float);
68                 void advance(float);
69                 TrackPoint get_point() const;
70         };
71
72         const VehicleType &type;
73         Vehicle *next;
74         Vehicle *prev;
75         TrackPosition track_pos;
76         std::vector<Axle> axles;
77         std::vector<Bogie> bogies;
78         std::vector<Rod> rods;
79         unsigned front_sensor;
80         unsigned back_sensor;
81
82 public:
83         Vehicle(Layout &, const VehicleType &);
84         ~Vehicle();
85
86         virtual Vehicle *clone(Layout * = 0) const;
87         virtual const VehicleType &get_type() const { return type; }
88
89         void attach_back(Vehicle &);
90         void attach_front(Vehicle &);
91         void detach_back();
92         void detach_front();
93         Vehicle *get_next() const { return next; }
94         Vehicle *get_previous() const { return prev; }
95
96         // TODO implement these - should call place() with suitable parameters
97         virtual void set_position(const Vector &) { }
98         virtual void set_rotation(const Angle &) { }
99         void place(Track &, unsigned, float, PlaceMode = CENTER);
100         void unplace();
101         void advance(float);
102         Track *get_track() const { return track_pos.track; }
103         unsigned get_entry() const { return track_pos.ep; }
104         float get_offset() const { return track_pos.offs; }
105         const Axle &get_fixed_axle(unsigned) const;
106         const Bogie &get_bogie(unsigned) const;
107         const Axle &get_bogie_axle(unsigned, unsigned) const;
108         const Rod &get_rod(unsigned) const;
109 private:
110         void update_position();
111         void update_position_from(const Vehicle &);
112         void propagate_position();
113         void propagate_forward();
114         void propagate_backward();
115         void check_sensor(float, unsigned &);
116         void turn_axles(float);
117         void update_rods();
118
119         void adjust_for_distance(TrackPosition &, TrackPosition &, float, float = 0.5) const;
120         TrackPoint get_point(const Vector &, const Vector &, float = 0.5) const;
121         TrackPoint get_point(const TrackPosition &, float, float = 0.5) const;
122
123 public:
124         virtual unsigned get_n_link_slots() const;
125         virtual Vehicle *get_link(unsigned) const;
126         virtual int get_link_slot(const Object &) const;
127
128         virtual bool collide_ray(const Vector &, const Vector &) const { return false; }
129 };
130
131 } // namespace R2C2
132
133 #endif