diff --git a/src/game.cpp b/src/game.cpp index 5c54ead..b72fd04 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -105,6 +105,47 @@ selectOrbit(GameState* gs, GameOrbit* orbit) gs->last_selected_orbit = orbit; } +bool +addManeuver(GameOrbit* orbit, + double anomaly, + vec3 impulse_vector, + double impulse_delta_v) +{ + assert(orbit); + + if (anomaly < -M_PI || anomaly > M_PI) { + LOGF(Error, "invalid true anomaly: %f\n", anomaly); + return false; + } + + if (orbit->maneuver.active) { + LOGF(Warning, "cannot add multiple maneuvers (yet)\n"); + return false; + } + + if (impulse_delta_v == 0.f) { + LOGF(Warning, "refusing to add maneuver with 0 dv\n"); + return false; + } + + orbit->maneuver.true_anomaly = anomaly; + //orbit->maneuver.impulse_vector = ... + orbit->maneuver.impulse_delta_v = impulse_delta_v; + orbit->maneuver.active = true; + + return true; +} + +void +removeManeuver(GameOrbit* orbit) +{ + assert(orbit); + + if (orbit->maneuver.active) { + orbit->maneuver = {0}; + } +} + // internal diff --git a/src/game.h b/src/game.h index b1cebc2..c79fcc4 100644 --- a/src/game.h +++ b/src/game.h @@ -19,10 +19,22 @@ struct Ellipse3D uint vert_count; }; +struct ManeuverNode +{ + double true_anomaly; + vec3 impulse_vector; + double impulse_delta_v; + // TODO: thrust calculations + + bool active; +}; + struct GameOrbit { TwoBodySystem system; Ellipse3D e3d; + // TODO: multiple maneuvers + ManeuverNode maneuver; Entity* grav_body; Entity* ellipse_entity; @@ -60,3 +72,8 @@ Ellipse3D ellipse3DInit(EllipseParameters ep, uint vert_count); void ellipse3DUpdate(EllipseParameters ep, Ellipse3D& e3d); void selectOrbit(GameState* gs, GameOrbit* orbit); + +bool addManeuver(GameOrbit* orbit, double anomaly, vec3 impulse_vector, + double impulse_delta_v); + +void removeManeuver(GameOrbit* orbit); diff --git a/src/gooey.cpp b/src/gooey.cpp index fa6b3dc..feba60d 100644 --- a/src/gooey.cpp +++ b/src/gooey.cpp @@ -10,7 +10,7 @@ using namespace ImGui; #include "orbits.h" -const static int G_WIDTH = 350; +const static int G_WIDTH = 400; const static ImVec2 V_SPACER(0, 10); const int H_FLAGS = ImGuiTreeNodeFlags_DefaultOpen; @@ -23,6 +23,7 @@ void drawGravitationalBody(GravBody& body); void drawOrbitalElements(OrbitalElements& el); void drawSatelliteWindow(Satellite& sat); void drawSystemWindow(TwoBodySystem& sys); +void drawManeuverWindow(GameState* gs); // interface @@ -75,9 +76,12 @@ gooDraw(SDL_Window* window, GameState* gs) drawSimulationWindow(gs->running, gs->sim_time_ms, gs->sim_speed); Separator(); + // FIXME: slit up orbit window into function calls here drawOrbitWindow(gs); - Separator(); - drawManeuverWinow(gs); + + BeginChild("impulsive maneuver", ImVec2(G_WIDTH - 20, 300), true); + drawManeuverWindow(gs); + EndChild(); #if 0 assert(gs->orbits[0].in_use); TwoBodySystem& sys = gs->orbits[0].system; @@ -111,11 +115,6 @@ void drawSimulationWindow(bool& running, u64 sim_time_ms, float& sim_speed) void drawOrbitWindow(GameState* gs) { - Text("WIP: Show a list of orbits, with grav\n" - "body and satellite properties.\n" - "Select a satellite to perform an inertial\n" - "maneuver\n"); - Text("Orbit Selection"); BeginChild("orbit selection", ImVec2(G_WIDTH - 20, 100), true); @@ -220,3 +219,53 @@ void drawSystemWindow(TwoBodySystem& sys) Text("time to periapsis: %.2f s", tof_periapse); Unindent(); } + +void +drawManeuverWindow(GameState* gs) +{ + GameOrbit* orbit = getSelectedOrbit(gs); + static int item_current_idx = 0; + static double anom = 0.f; + static float dv = 0.f; + + if (orbit) { + if (orbit->maneuver.active) { + Text("Orbital Maneuver"); + Indent(); + Text("true anomaly: %f", orbit->maneuver.true_anomaly); + Text("impulse dv: %f km/s", orbit->maneuver.impulse_delta_v); + Unindent(); + + if (Button("remove")) { + removeManeuver(orbit); + item_current_idx = 0; + anom = 0.f; + dv = 0.f; + } + } else { + Text("Add orbital maneuver"); + + const double min_anom = -M_PI, max_anom = M_PI; + SliderScalar("maneuver anomaly", ImGuiDataType_Double, &anom, + &min_anom, &max_anom, "%.19f"); + + // select maneuver vector + const char* items[] = { + "prograde", + "retrograde", + "some other vector" + }; + + Combo("thrust vector", &item_current_idx, items, + IM_ARRAYSIZE(items)); + + InputFloat("impulse dv, km/s", &dv, 0.1, 4.0, "%.1f"); + + if (Button("apply")) { + if (!addManeuver(orbit, anom, vec3(), dv)) { + // flash a color or something? + } + } + } + } +}