-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathDeltaglider.cpp
More file actions
475 lines (396 loc) · 21.2 KB
/
Deltaglider.cpp
File metadata and controls
475 lines (396 loc) · 21.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
// Deltaglider.cpp /////////////////////////////////////////////////////////////
// A testbed for ignition, based off of ////////////////////////////////////////
// the one and only DG, from Orbiter ///////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//#include <std_files>
//#include "Headers.h"
//#include "Headers.hpp"
//#include "Source.cpp"
#include <string>
#include <iostream>
#include <math.h>
#include "Deltaglider.hpp"
// Delta Glider Class //////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
DeltaGlider::DeltaGlider(double initial_x_position, double initial_y_position, double initial_x_velocity, double initial_y_velocity, double initial_theta, double initial_omega, double initial_main_propellant, double initial_rcs_propellant, sf::Texture vessel_textures, sf::Sprite flag_sprite, std::string ivessel_name, std::string panel_path, std::string controls_font, Propagator_type propagator)
{ Talkback("Constructing Delta Glider");
// we write to the console for feedback while debugging
NewtonianState.Current_state = Flight;
Propagator = propagator;
Start_MFD(surface_mfd, upper_right, sf::Vector2f(20, 60));
Flag_sprite = flag_sprite;
// set our flag affilation here
// this looks wrongish, I think this needs to be copied by value, definitely
// not reference, since the same flag may need to be drawn several times per
// frame
Flag_sprite.setScale(0.1,0.1);
// scales it back by 1/10 along each axis, since the original was too big
// this is baddish
Object_name = ivessel_name;
Vessel_class = "Delta Glider";
// this should rather be frozen so it cant be changed in sim, just for
// safety/not chaos
Acceleration.Set_values(0, 0);
// just an call to be safe
NewtonianState.FlightState.Position.Set_values(initial_x_position, initial_y_position);
NewtonianState.FlightState.Velocity.Set_values(initial_x_velocity, initial_y_velocity);
this->NewtonianState.Rotation.Theta = initial_theta;
this->NewtonianState.Rotation.Omega = initial_omega;
this->NewtonianState.Rotation.Alpha = 0;
// we take what we were passed and set our properties to it
// important that this gets set explicitly, without it the compiler just
// sets it to random values for some godawful reason
VectorVictor::Vector2 origin(0,0);
Hull_component = new Hull(16000, 0.4, 17.5, origin);
Object_components.insert(Object_components.end(), Hull_component);
// we construct the hull component and insert it into the general component
// list. The vessel can access it by either the Hull component reference
// that it stores internally, or through its general version in the parts
// list
// the pointer passin crap didnt work ^^
// ^ not sure exactly what that was referring to
Main_fuel = new Resource_Tank(initial_main_propellant, 800, 0.6, 0.8, 2.2, origin);
Fuel_tanks.insert(Fuel_tanks.end(), Main_fuel);
Object_components.insert(Object_components.end(), Main_fuel->Get_vessel_component_pointer());
// construct the main fuel tank and insert it into both the fuel tank list
// and the general parts list.
// Come to think of it, why exactly is there a separate list for fuel tanks?
// they arent even accessed that way, not yet anyways
Init_thruster(false, 4000, 50000, 290, 0, -6.2000, 0, -1, 0.4, 0.49, Main_fuel, main_engines);
// construct the main engine thrsuter, insert it into the thruster vector
// and the general components vector
// this is at least necessary, since the main thruster vector is used for
// throttling back all engines each frame unless the throttle up is doing
// the opposite
VectorVictor::Vector2 rcs_pos(0, 2);
RCS_fuel = new Resource_Tank(initial_rcs_propellant, 500, 0.6, 0.64, 1,rcs_pos);
Fuel_tanks.insert(Fuel_tanks.end(), RCS_fuel);
Object_components.insert(Object_components.end(), RCS_fuel->Get_vessel_component_pointer());
Init_thruster(true, 470, 49000, 61, 0, 6.2000, -1, 0, 0.10, 0.12, RCS_fuel, rotate_clockwise, translate_right);
Init_thruster(true, 470, 49000, 61, 0, 6.2000, 1, 0, 0.10, 0.12, RCS_fuel, rotate_counterclockwise, translate_left);
Init_thruster(true, 470, 49000, 46, 0, 6.400, 0, 1, 0.10, 0.12, RCS_fuel, translate_back);
Init_thruster(true, 470, 49000, 63, -0.20, -6.0000, -1, 0, 0.10, 0.12, RCS_fuel, rotate_counterclockwise, translate_right);
Init_thruster(true, 470, 49000, 63, -0.20, -6.0000, 1, 0, 0.10, 0.12, RCS_fuel, rotate_clockwise, translate_left);
Init_thruster(true, 470, 49000, 46, -0.2, -6.0000, 0, -1, 0.10, 0.12, RCS_fuel, translate_forward);
// and we construct all of the RCS thrusters in the same way
std::cout << Object_components.size() << " Vessel components" << std::endl;
// not sure why, but good to have the number of components on the vessel
// for debugging
RCS_Throttle_constant = 29.9000;
// we set this up so that the thruster goes from 0 to 2990 % in one second
// obviously that doesnt work, so it really represents 0 to 100% in 1/29.9 s
// (0.033 s, roughly 2 frames if fps is a healthy 60)
Main_throttle_constant = 0.25;
// significantly slower for the main engines, here they take a full four
// seconds to go from 0 - 100
Throttle_lock = false;
// Throttle lock keeps the main engines at their current throttle setting
// instead of trying to slide back to zero each frame, which is useful
// during long burns
Update_PMI();
// once all of the vessel components are in, this should be run to get the
// initial value
// we create it and assign it the texture passed by the constructor
// (less memory waste per vessel than each one loading a copy of the texture
// for every instance
Talkback("Setting up texture stuff");
Vessel_tex = new sf::Texture();
*Vessel_tex = vessel_textures;
Talkback("Copied texture");
// not sure why we need to copy the reference to this...
Object_sprite = new sf::Sprite();
Talkback("Init the sprite");
Object_sprite->setTexture(*Vessel_tex);
Talkback("Finished textures stuff");
// this appears to be redundant, and a good candidate to remove
text_colour = new sf::Color(194, 38, 15);
// nice red colour for all of the vessel displays
vessel_id.Init_object(controls_font, sf::Vector2f(20, 380), "-", *text_colour, 16, false);
main_fuel_level.Init_object(controls_font, sf::Vector2f(20, 420), "-", *text_colour, 14, false);
rcs_fuel_level.Init_object(controls_font, sf::Vector2f(20, 440), "-", *text_colour, 14, false);
omega_value.Init_object(controls_font, sf::Vector2f(20, 460), "-", *text_colour, 14, false);
theta_value.Init_object(controls_font, sf::Vector2f(20, 480), "-", *text_colour, 14, false);
position_values.Init_object(controls_font, sf::Vector2f(20, 500), "-", *text_colour, 14, false);
velocity_values.Init_object(controls_font, sf::Vector2f(20, 520), "-", *text_colour, 14, false);
vessel_display.Init_object(sf::Vector2f(820, 460), sf::Color(255, 255, 255, 168), false, *Vessel_tex, true);
vessel_display.sprite.setScale(sf::Vector2f(0.5f, 0.5f));
// Ill get around to it later
// the pretty semi-transparent image of the ship that appears at bottom
// right in the screen. Really just eye candy for now, but I have plans for
// it later on. Its vessel implementation-specific anywayss
display_panel.Init_object(sf::Vector2f(5, 360), sf::Color(255, 255, 255), false, panel_path);
// Ill get around to it later
// display_panel = new sf::Sprite();
// display_panel->setTexture(*panel_texture1);
// display_panel->setPosition(sf::Vector2f(5, 360));
// the metal looking thing at bottom right. Only there because the onscreen
// displays proved hard to read against the background
pix_length = Hull_component->Length*10;
// get the length of the vessels long axis in meters
// the multiple of ten thing is fine, but the current window size was
// accidentally made 10x too large, so vessels appeared 10x larger than
// they really were
// not terribly important, since this will change when the window view
// has multiple scales to be a lot like the one for planets, but it is
// important to remember that the base view has 1m = 10 pixels, for reasons
// of easiest scaling
if(Vessel_tex->getSize().y != pix_length)
{ Object_sprite->setScale((pix_length/(Vessel_tex->getSize().y)),(pix_length/(Vessel_tex->getSize().y)));
// rescale the axes of the texture to match pix_length in the y and the
// appropriate scale for the x dimension
// not sure why they both use y, but I think this was distorted when
// it used x & y.
// This area needs to be looked over again
}
Object_sprite->setOrigin((Vessel_tex->getSize().x/2), (Vessel_tex->getSize().y/2));
// ok the sprite definitely gets centered there...
Object_sprite->setRotation(this->NewtonianState.Rotation.Theta);
// and we center the origin and rotate it appropriately
Talkback("...Constructed Delta Glider");
// feed back that the constructor is now finished to the console
}
DeltaGlider::DeltaGlider(ObjectState initial_object_state, double initial_main_propellant, double initial_rcs_propellant, sf::Texture vessel_textures, sf::Sprite flag_sprite, std::string ivessel_name, std::string panel_path, std::string controls_font, Propagator_type propagator): CNewtonian_Object(initial_object_state)
{ // the new & improved constructor using the call to CNewtonians constructor
// so hopefully a fair bit shorter
// although we still have a long way to go in this area till the whole
// system is really ready to go. In fact, the current setup probably wont
// work with dynamic binding at all just yet, needs to only take CNewtonian
// parameters to get set up
// simplest way to get there would probably be to half implement scenario
// loading from file first so that the constructor is clean for calling in
// a dll callback without all of this type specific stuff
// the individual sprites and textures should probably be loaded internally
// to each object. The whole idea of sharing references between all of the
// objects was cute, but it just wont work with the way generic vessels will
// need to work
Talkback("Constructing Delta Glider");
// we write to the console for feedback while debugging
Propagator = propagator;
Start_MFD(surface_mfd, upper_right, sf::Vector2f(20, 60));
Flag_sprite = flag_sprite;
// set our flag affilation here
// this looks wrongish, I think this needs to be copied by value, definitely
// not reference, since the same flag may need to be drawn several times per
// frame
Flag_sprite.setScale(0.1,0.1);
// scales it back by 1/10 along each axis, since the original was too big
// this is baddish
Object_name = ivessel_name;
Vessel_class = "Delta Glider";
// this should rather be frozen so it cant be changed in sim, just for
// safety/not chaos
VectorVictor::Vector2 origin(0,0);
Hull_component = new Hull(16000, 0.4, 17.5, origin);
Object_components.insert(Object_components.end(), Hull_component);
// we construct the hull component and insert it into the general component
// list. The vessel can access it by either the Hull component reference
// that it stores internally, or through its general version in the parts
// list
// the pointer passin crap didnt work ^^
// ^ not sure exactly what that was referring to
Main_fuel = new Resource_Tank(initial_main_propellant, 800, 0.6, 0.8, 2.2, origin);
Fuel_tanks.insert(Fuel_tanks.end(), Main_fuel);
Object_components.insert(Object_components.end(), Main_fuel->Get_vessel_component_pointer());
// construct the main fuel tank and insert it into both the fuel tank list
// and the general parts list.
// Come to think of it, why exactly is there a separate list for fuel tanks?
// they arent even accessed that way, not yet anyways
Init_thruster(false, 4000, 50000, 290, 0, -6.2000, 0, -1, 0.4, 0.49, Main_fuel, main_engines);
// construct the main engine thrsuter, insert it into the thruster vector
// and the general components vector
// this is at least necessary, since the main thruster vector is used for
// throttling back all engines each frame unless the throttle up is doing
// the opposite
VectorVictor::Vector2 rcs_pos(0, 2);
RCS_fuel = new Resource_Tank(initial_rcs_propellant, 500, 0.6, 0.64, 1,rcs_pos);
Fuel_tanks.insert(Fuel_tanks.end(), RCS_fuel);
Object_components.insert(Object_components.end(), RCS_fuel->Get_vessel_component_pointer());
Init_thruster(true, 470, 49000, 61, 0, 6.2000, -1, 0, 0.10, 0.12, RCS_fuel, rotate_clockwise, translate_right);
Init_thruster(true, 470, 49000, 61, 0, 6.2000, 1, 0, 0.10, 0.12, RCS_fuel, rotate_counterclockwise, translate_left);
Init_thruster(true, 470, 49000, 46, 0, 6.400, 0, 1, 0.10, 0.12, RCS_fuel, translate_back);
Init_thruster(true, 470, 49000, 63, -0.20, -6.0000, -1, 0, 0.10, 0.12, RCS_fuel, rotate_counterclockwise, translate_right);
Init_thruster(true, 470, 49000, 63, -0.20, -6.0000, 1, 0, 0.10, 0.12, RCS_fuel, rotate_clockwise, translate_left);
Init_thruster(true, 470, 49000, 46, -0.2, -6.0000, 0, -1, 0.10, 0.12, RCS_fuel, translate_forward);
// and we construct all of the RCS thrusters in the same way
// this should definitely be a function to minimize mistakes
std::cout << Object_components.size() << " Vessel components" << std::endl;
// not sure why, but good to have the number of components on the vessel
// for debugging
RCS_Throttle_constant = 29.9000;
// we set this up so that the thruster goes from 0 to 2990 % in one second
// obviously that doesnt work, so it really represents 0 to 100% in 1/29.9 s
// (0.033 s, roughly 2 frames if fps is a healthy 60)
Main_throttle_constant = 0.25;
// significantly slower for the main engines, here they take a full four
// seconds to go from 0 - 100
Throttle_lock = false;
// Throttle lock keeps the main engines at their current throttle setting
// instead of trying to slide back to zero each frame, which is useful
// during long burns
Update_PMI();
// once all of the vessel components are in, this should be run to get the
// initial value
// we create it and assign it the texture passed by the constructor
// (less memory waste per vessel than each one loading a copy of the texture
// for every instance
Vessel_tex = new sf::Texture();
*Vessel_tex = vessel_textures;
// not sure why we need to copy the reference to this...
Object_sprite = new sf::Sprite();
Object_sprite->setTexture(*Vessel_tex);
// this appears to be redundant, and a good candidate to remove
text_colour = new sf::Color(194, 38, 15);
// nice red colour for all of the vessel displays
vessel_id.Init_object(controls_font, sf::Vector2f(20, 380), "-", *text_colour, 16, false);
main_fuel_level.Init_object(controls_font, sf::Vector2f(20, 420), "-", *text_colour, 14, false);
rcs_fuel_level.Init_object(controls_font, sf::Vector2f(20, 440), "-", *text_colour, 14, false);
omega_value.Init_object(controls_font, sf::Vector2f(20, 460), "-", *text_colour, 14, false);
theta_value.Init_object(controls_font, sf::Vector2f(20, 480), "-", *text_colour, 14, false);
position_values.Init_object(controls_font, sf::Vector2f(20, 500), "-", *text_colour, 14, false);
velocity_values.Init_object(controls_font, sf::Vector2f(20, 520), "-", *text_colour, 14, false);
vessel_display.Init_object(sf::Vector2f(820, 460), sf::Color(255, 255, 255, 168), false, *Vessel_tex, true);
vessel_display.sprite.setScale(sf::Vector2f(0.5f, 0.5f));
display_panel.Init_object(sf::Vector2f(5, 360), sf::Color(255, 255, 255), false, panel_path);
pix_length = Hull_component->Length*10;
// get the length of the vessels long axis in meters
// the multiple of ten thing is fine, but the current window size was
// accidentally made 10x too large, so vessels appeared 10x larger than
// they really were
// not terribly important, since this will change when the window view
// has multiple scales to be a lot like the one for planets, but it is
// important to remember that the base view has 1m = 10 pixels, for reasons
// of easiest scaling
if(Vessel_tex->getSize().y != pix_length)
{ Object_sprite->setScale((pix_length/(Vessel_tex->getSize().y)),(pix_length/(Vessel_tex->getSize().y)));
// rescale the axes of the texture to match pix_length in the y and the
// appropriate scale for the x dimension
// not sure why they both use y, but I think this was distorted when
// it used x & y.
// This area needs to be looked over again
}
Object_sprite->setOrigin((Vessel_tex->getSize().x/2), (Vessel_tex->getSize().y/2));
Object_sprite->setRotation(this->NewtonianState.Rotation.Theta);
// and we center the origin and rotate it appropriately
Talkback("...Constructed Delta Glider");
// feed back that the constructor is now finished to the console
}
void DeltaGlider::Receive_inputs(key_commands * current_inputs, double dt)
{ if(current_inputs->z == true)
{ Translate_left(dt);
}
else if(current_inputs->c == true)
{ Translate_right(dt);
}
else if(current_inputs->x == true)
{ Translate_backward(dt);
}
else if(current_inputs->w == true)
{ Translate_forward(dt);
}
else if(current_inputs->d == true)
{ Rotate_right(dt);
}
else if(current_inputs->a == true)
{ Rotate_left(dt);
}
else if(current_inputs->s == true)
{ Kill_rotation(dt);
} // map the rotational and translational commands to the WASD side of
// the keyboard. It works very similar to the numpad in Orbiter, but I
// used the keyboard for it since numpad inputs dont seem to be received
// on linux for some reason
// It can always work on both, but I think using the WASD keys makes
// more sense, since every keyboard will have that, if not necessarily
// a numpad
else
{ No_command(dt);
} // the throttle back of every thruster since no inputs are being sent
// intended for RCS thrusters, but also applies to main/retro/hover,
// not exactly a perfect setup here
if(current_inputs->up == true)
{ Throttle_up(dt*5);
}
else if(current_inputs->down == true)
{ Throttle_down(dt*5);
}
}
double DeltaGlider::Get_total_mass()
{ double net_mass = 0;
for(std::vector<Vessel_component*>::iterator it = Object_components.begin(); it != Object_components.end(); ++it)
{ net_mass += (*it)->Get_component_mass();
} // iterate through all components and get the mass. I think this was
// defined already in TVessel or Newtonian, doesnt need definition here
return net_mass;
}
long double DeltaGlider::Get_PMI()
{ return PMI;
}
void DeltaGlider::Print_data()
{ std::cout << "RCS Fuel: " << RCS_fuel->Resource_mass << std::endl;
std::cout << "Crash state: " << this->NewtonianState.Current_state << std::endl;
// general useful data
// should probably reformat this a wee bit
}
void DeltaGlider::Toggle_throttle_lock()
{ if(Throttle_lock == true)
{ Throttle_lock = false;
}
else
{ Throttle_lock = true;
}
// simple bit flippin
}
void DeltaGlider::Draw_controls(SFML_Window * iwindow, bool Map_status)
{ std::string mainfuel = std::to_string((long long int)Main_fuel->Resource_mass);
mainfuel.append(" kg");
main_fuel_level.Set_element(mainfuel);
std::string rcsfuel = std::to_string((long long int)RCS_fuel->Resource_mass);
rcsfuel.append(" kg");
rcs_fuel_level.Set_element(rcsfuel);
omega_value.Set_element(std::to_string((long long int)this->NewtonianState.Rotation.Omega));
theta_value.Set_element(std::to_string((long long int)this->NewtonianState.Rotation.Theta));
std::string pos = "Position ";
pos.append(NewtonianState.FlightState.Position.Get_vector("m"));
position_values.Set_element(pos);
std::string vel = "Velocity ";
vel.append(NewtonianState.FlightState.Velocity.Get_vector("m/s"));
velocity_values.Set_element(vel);
std::string id = Get_vessel_class();
id.append(" Class\n");
id.append(Get_vessel_name());
vessel_id.Set_element(id);
// do a hideous transfer of formatted data to the sf texts
vessel_display.Draw_element(iwindow);
display_panel.Draw_element(iwindow);
main_fuel_level.Draw_element(iwindow);
rcs_fuel_level.Draw_element(iwindow);
omega_value.Draw_element(iwindow);
theta_value.Draw_element(iwindow);
position_values.Draw_element(iwindow);
velocity_values.Draw_element(iwindow);
vessel_id.Draw_element(iwindow);
}
void DeltaGlider::Receive_cursor_inputs(Cursor_commands * cursor_action, long double dt)
{ // this way we can check if the cursor is on us, and whether that merits
// any changes on the vessels end of things
}
DeltaGlider::~DeltaGlider()
{ Thrusters.clear();
Fuel_tanks.clear();
delete Object_sprite;
delete Hull_component;
delete text_colour;
delete Hull_component;
}
TVessel * Construct_deltaglider(ObjectState initial_object_state, double initial_main_propellant, double initial_rcs_propellant, sf::Texture vessel_textures, sf::Sprite flag_sprite, std::string ivessel_name, std::string panel_path, std::string controls_font, Propagator_type propagator)
{ TVessel * new_deltaglider = new DeltaGlider(initial_object_state, initial_main_propellant, initial_rcs_propellant, vessel_textures, flag_sprite, ivessel_name, panel_path, controls_font, propagator);
// create a new DeltaGlider on the heap
return new_deltaglider;
// and pass along its pointer at the TVessel level
}
bool Create_deltaglider(std::vector<TVessel*> &Vessels_list, std::vector<CNewtonian_Object*> &Newtonian_list, TVessel* New_dg_pointer)
{ Vessels_list.insert(Vessels_list.end(), New_dg_pointer);
Newtonian_list.insert(Newtonian_list.end(), New_dg_pointer->Get_Newtonian_pointer());
return true;
}