Browse Source

fix incorrect simulation time_step

We're not tracking sim_time and sim_speed on the GameState object,
and only updating sim_time when gs->running == true

Also updated the gooey with a Simulation Window to display the new
properties
main
cinnaboot 4 years ago
parent
commit
45fa17554c
  1. 36
      src/gooey.cpp
  2. 4
      src/gooey.h
  3. 53
      src/main.cpp
  4. 16
      src/orbits.cpp
  5. 10
      src/orbits.h

36
src/gooey.cpp

@ -41,18 +41,20 @@ gooProcessEvent(SDL_Event& e)
|| ImGui::GetIO().WantCaptureKeyboard);
}
void drawSimulationWindow(bool& running, u64 sim_time_ms, float& sim_speed);
void drawEllipseParameters(ellipse_parameters& ep);
void drawGravitaationalBody(grav_body& body);
void drawOrbitalElements(orbital_elements& el);
void drawSatelliteWindow(satellite& sat);
void drawSystemWindow(system_2body& sys, bool& running);
void drawSystemWindow(system_2body& sys);
const static int G_WIDTH = 300;
const static ImVec2 V_SPACER(0, 10);
const int H_FLAGS = ImGuiTreeNodeFlags_DefaultOpen;
void
gooDraw(SDL_Window* window, system_2body& sys, bool& running)
gooDraw(SDL_Window* window, system_2body& sys,
bool& running, u64 sim_time_ms, float& sim_speed)
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame(window);
@ -64,7 +66,8 @@ gooDraw(SDL_Window* window, system_2body& sys, bool& running)
ImGui::SetNextWindowSize(ImVec2(G_WIDTH, y));
ImGui::Begin("Gooey");
drawSystemWindow(sys, running);
drawSimulationWindow(running, sim_time_ms, sim_speed);
drawSystemWindow(sys);
drawSatelliteWindow(sys.sat);
drawGravitaationalBody(sys.body);
drawOrbitalElements(sys.elements);
@ -75,6 +78,21 @@ gooDraw(SDL_Window* window, system_2body& sys, bool& running)
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
void drawSimulationWindow(bool& running, u64 sim_time_ms, float& sim_speed)
{
if (ImGui::CollapsingHeader("Simulation:", H_FLAGS)) {
if (ImGui::Button("||")) running = false;
ImGui::SameLine();
if (ImGui::Button("|>")) running = true;
ImGui::SameLine();
ImGui::Text("running: %s", (running > 0) ? "true" : "false");
ImGui::Text("sim time: %.3f s",
double(double(sim_time_ms) / 1000));
ImGui::Text("sim speed: %.1f x", sim_speed);
}
}
void drawEllipseParameters(ellipse_parameters& ep)
{
if (ImGui::CollapsingHeader("Ellipse Parameters:", H_FLAGS)) {
@ -126,19 +144,9 @@ drawSatelliteWindow(satellite& sat)
}
}
void drawSystemWindow(system_2body& sys, bool& running)
void drawSystemWindow(system_2body& sys)
{
if (ImGui::CollapsingHeader("2 Body System:", H_FLAGS)) {
if (ImGui::Button("||")) running = false;
ImGui::SameLine();
if (ImGui::Button("|>")) running = true;
ImGui::SameLine();
ImGui::Text("running: %s", (running > 0) ? "true" : "false");
ImGui::Text("time_step:");
ImGui::SameLine();
ImGui::InputDouble("##", &sys.time_step, 5);
ImGui::Text("orbital period: %f", sys.orbital_period);
ImGui::Text("epsilon, spec. orb. energy: %f", sys.epsilon);
ImGui::Text("h, angular momentum: %f", sys.h);

4
src/gooey.h

@ -16,5 +16,5 @@ bool
gooProcessEvent(SDL_Event &e);
void
gooDraw(SDL_Window* window, system_2body& sys, bool& running);
gooDraw(SDL_Window* window, system_2body& sys,
bool& running, u64 sim_time_ms, float& sim_speed);

53
src/main.cpp

@ -38,6 +38,10 @@ struct GameState
bool running;
MemoryArena* arena;
u64 game_time_ms;
u64 sim_time_ms;
float sim_speed;
system_2body system; // FIXME: we're going to need more than 1 system...
Entity* satellite_entity;
};
@ -181,9 +185,11 @@ loadScene(GameState* gs, RenderState* rs)
}
void
updateSatelliteModel(const system_2body& sys, satellite& sat)
updateSatelliteModel(const system_2body& sys,
satellite& sat,
double time_step)
{
sat.theta = getPropagatedTrueAnomaly(sys, sat.theta);
sat.theta = getPropagatedTrueAnomaly(sys, sat.theta, time_step);
sat.gamma = orbitGetFlightPathAngle(sys.ep.e, sat.theta);
sat.r = orbitGetRadialDistance(sys.ep.e, sys.ep.p, sat.theta);
sat.v = orbitGetVelocity(sys.epsilon, sys.body.mu, sat.r);
@ -193,7 +199,6 @@ updateSatelliteModel(const system_2body& sys, satellite& sat)
void
updateSatelliteEntity(Entity* e, const satellite& sat)
{
// TODO: decouple framerate from time_step
const static mat4 xform =
glm::rotate(mat4(1.0), (float) M_PI_2, vec3(1, 0, 0));
const vec3& v = sat.position;
@ -222,39 +227,50 @@ preFrameCallback(RenderState* rs, void* user_data = nullptr)
bool gooey_wants = false;
while (SDL_PollEvent(&e)) {
// FIXME: we should check for escape key here first
gooey_wants = gooProcessEvent(e);
if (!gooey_wants) inputProcessEvent(&is, e);
}
if (is.window_closed || is.escape)
rs->running = false;
}
void
postFrameCallback(RenderState* rs, void* user_data = nullptr)
{
// TODO: sim time stuff should have dedicated functions, and maybe a test
// since it's pretty important that the simulation is accurate-ish
// TODO: verify time to apoapsis/periapsis are correct
assert(user_data != nullptr);
GameState* gs = (GameState*) user_data;
gooDraw(rs->handles.window, gs->system, gs->running);
u64 last_sdl_tick = gs->game_time_ms;
gs->game_time_ms = SDL_GetTicks64();
u64 current_tick = gs->game_time_ms - last_sdl_tick;
// NOTE: update sim time base on time since last frame * sim_speed
if (gs->running) {
updateSatelliteModel(gs->system, gs->system.sat);
u64 last_game_tick = gs->sim_time_ms;
gs->sim_time_ms = gs->sim_time_ms + current_tick * gs->sim_speed;
u32 diff_ms = gs->sim_time_ms - last_game_tick;
double time_step = double(diff_ms) / 1000;
updateSatelliteModel(gs->system, gs->system.sat, time_step);
gs->system.ep = ellipseInitAE(gs->system.ep.a, gs->system.ep.e);
updateSatelliteEntity(gs->satellite_entity, gs->system.sat);
//updateOrbit(gs->system, ellipse_entity);
}
}
// FIXME: testing sim time
u64 ticks = SDL_GetTicks64();
static u32 last_T;
u32 T = ticks / 1000;
if (T != last_T) {
LOGF(Debug, "seconds since sim start: %d\n", T);
last_T = T;
}
void
postFrameCallback(RenderState* rs, void* user_data = nullptr)
{
assert(user_data != nullptr);
GameState* gs = (GameState*) user_data;
gooDraw(rs->handles.window,
gs->system,
gs->running,
gs->sim_time_ms,
gs->sim_speed);
}
#define DEFAULT_SIM_SPEED 100
int
main()
{
@ -274,6 +290,7 @@ main()
GameState gs = {0};
gs.arena = arenaInit(16);
gs.sim_speed = DEFAULT_SIM_SPEED;
loadScene(&gs, rs);
doRenderLoop(rs, 60, preFrameCallback, postFrameCallback, &gs);
gooFree();

16
src/orbits.cpp

@ -6,7 +6,7 @@ const static uint ELLIPSE_VERT_COUNT = 256;
system_2body
systemInit(grav_body gb, orbital_elements el, float time_step)
systemInit(grav_body gb, orbital_elements el)
{
system_2body s = {0};
s.body = gb;
@ -18,7 +18,6 @@ systemInit(grav_body gb, orbital_elements el, float time_step)
s.orbital_period = orbitGetPeriod(s.ep.a, gb.mu);
s.r_apoapsis = s.ep.a - s.ep.c;
s.r_periapsis = 2 * s.ep.a - s.r_apoapsis;
s.time_step = time_step;
return s;
}
@ -214,13 +213,14 @@ getNextTrialValue(double err, double ecc, double test_anom, double mean_anom)
double
getPropagatedEccAnomaly(system_2body sys,
double initial_anom)
double initial_anom,
double time_step)
{
double e = sys.ep.e;
double E1 = getEccAnomFromTrueAnom(e, initial_anom);
double M1 = getMeanAnomFromEccAnom(E1, e);
double n = getMeanMotion(sys.body.mu, sys.elements.a);
double M2 = getPropagatedMeanAnom(M1, n, sys.time_step);
double M2 = getPropagatedMeanAnom(M1, n, time_step);
double E2_1 = getInitialTrialValue(M2, e);
// test if guess is a solution to kepler's equation
@ -241,13 +241,15 @@ getPropagatedEccAnomaly(system_2body sys,
double
getPropagatedTrueAnomaly(system_2body sys,
double initial_anom)
double initial_anom,
double time_step)
{
// FIXME: I don't think we need this now that we have gs->running?
// NOTE: 'pause' simulation when time_step is set close to 0
if (sys.time_step < 1e-8 && sys.time_step > -1e-8)
if (time_step < 1e-8 && time_step > -1e-8)
return initial_anom;
double ecc_anom = getPropagatedEccAnomaly(sys, initial_anom);
double ecc_anom = getPropagatedEccAnomaly(sys, initial_anom, time_step);
return getTrueAnomFromEccAnom(sys.ep.e, ecc_anom);
}

10
src/orbits.h

@ -67,16 +67,11 @@ struct system_2body
double r_apoapsis; // NOTE: apoapse distance from body center
double r_periapsis; // NOTE: periapsis distance from body center
double orbital_period; // NOTE: in seconds
double time_step;
};
#define DEFAULT_TIME_STEP 1
system_2body
systemInit(grav_body gb,
orbital_elements el,
float time_step = DEFAULT_TIME_STEP);
systemInit(grav_body gb, orbital_elements el);
grav_body
gravBodyInit(double mu, double r);
@ -152,7 +147,8 @@ orbitUpdate(orbital_elements& o, double a, double e);
*/
double
getPropagatedTrueAnomaly(system_2body sys,
double initial_anom);
double initial_anom,
double time_step); // NOTE: in seconds
// NOTE: aka) the trajectory equation (eq. 2.45)
double

Loading…
Cancel
Save