Browse Source

update demo GUI, and add input validation

main
= 5 years ago
parent
commit
a9df4b1ac7
  1. 17
      src/gooey.cpp
  2. 100
      src/main.cpp
  3. 52
      src/orbits.cpp
  4. 17
      src/orbits.h

17
src/gooey.cpp

@ -50,12 +50,23 @@ gooDraw(SDL_Window* window, orbital_elements& orbit)
ImGui::NewFrame();
ImGui::SetNextWindowPos(ImVec2(0,0));
ImGui::SetNextWindowSize(ImVec2(300,400));
ImGui::SetNextWindowSize(ImVec2(300,270));
ImGui::Begin("Orbital Elements");
ImGui::Text("iota, inclination: %f", orbit.iota);
ImGui::Text("omega, argument of periapsis: %f", orbit.omega);
ImGui::Text("mu, gravitational parameter: %f", orbit.mu);
ImGui::Text("nu, true anomoly: %f", orbit.nu);
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Ellipse Parameters:");
ImGui::Text("a: %f km", orbit.ep.a);
ImGui::Text("b: %f km", orbit.ep.b);
ImGui::Text("e: %f", orbit.ep.e);
ImGui::Text("mu: %f km^3/s^2", orbit.mu);
ImGui::Text("c: %f km", orbit.ep.c);
ImGui::Text("a:");
ImGui::SameLine();
@ -63,7 +74,7 @@ gooDraw(SDL_Window* window, orbital_elements& orbit)
ImGui::Text("e:");
ImGui::SameLine();
ImGui::InputDouble("##orbit.ep.e", &orbit.ep.e, 0.1f);
ImGui::InputDouble("##orbit.ep.e", &orbit.ep.e, 0.01f);
ImGui::End();

100
src/main.cpp

@ -17,7 +17,7 @@
const double SCALING = 0.001;
static orbital_elements g_orbit = {};
static ellipse_3d g_ellipse;
static ellipse_3d g_ellipse3d;
simple_mesh*
@ -76,7 +76,37 @@ initOrbit()
}
void
doFrameCallbackPre(render_state* rs)
updateSatellitePosition(entity& satellite)
{
const static glm::mat4 xform =
glm::rotate(glm::mat4(1.0), (float) M_PI_2, glm::vec3(1, 0, 0));
// TODO: decouple framerate from time_step
unsigned int time_step = 100; // NOTE: seconds
g_orbit.nu = getPropagatedTrueAnomaly(g_orbit, g_orbit.nu, time_step);
double r2 = getRadialPosition(g_orbit.ep, g_orbit.nu);
glm::vec2 coords = polarToRect(g_orbit.nu, r2);
glm::vec3 v = glm::vec3(coords, 0);
entSetWorldPosition(satellite, xform * glm::vec4(v.x, v.y, v.z, 1));
}
// NOTE: use validateEllipse(orbit.ep) before calling to avoid failing
// assertions
void
updateOrbit(orbital_elements& orbit, ellipse_3d& e3d, entity& ellipse_entity)
{
orbit.ep = constructEllipseAE(orbit.ep.a, orbit.ep.e);
ellipse3DUpdate(orbit.ep, e3d);
for (uint i = 0; i < e3d.vert_count; i++)
ellipse_entity.mesh->vertices[i] = e3d.vertices[i];
entUpdateSimpleMesh(ellipse_entity, ellipse_entity.mesh, GL_LINE_LOOP);
}
void
preFrameCallback(render_state* rs)
{
// handle input
static input_state is = {};
@ -91,50 +121,40 @@ doFrameCallbackPre(render_state* rs)
if (is.window_closed || is.escape)
rs->running = false;
// update orbital elements/ellipse_3d
g_orbit.ep = constructEllipseAE(g_orbit.ep.a, g_orbit.ep.e);
entity& ellipse_entity = rs->render_groups[0].entities[0];
// TODO: fix this
double angle = 2 * M_PI / g_ellipse.vert_count;
for (uint i = 0; i < g_ellipse.vert_count; i++) {
double a = angle * i;
double r = g_orbit.ep.a *
(1 - pow(g_orbit.ep.e, 2)) / (1 + g_orbit.ep.e * cos(a));
g_ellipse.vertices[i] = glm::vec3(polarToRect(a, r), 0);
// NOTE: update mesh
ellipse_entity.mesh->vertices[i] = g_ellipse.vertices[i];
// NOTE: update entity.render_object
entUpdateSimpleMesh(ellipse_entity, ellipse_entity.mesh, GL_LINE_LOOP);
}
// update satellite position
const static glm::mat4 xform =
glm::rotate(glm::mat4(1.0), (float) M_PI_2, glm::vec3(1, 0, 0));
entity& satellite = rs->render_groups[0].entities[2];
// TODO: decouple framerate from time_step
unsigned int time_step = 100; // NOTE: seconds
g_orbit.nu = getPropagatedTrueAnomaly(g_orbit, g_orbit.nu, time_step);
double r2 = getRadialPosition(g_orbit.ep, g_orbit.nu);
glm::vec2 coords = polarToRect(g_orbit.nu, r2);
glm::vec3 v = glm::vec3(coords, 0);
entSetWorldPosition(satellite, xform * glm::vec4(v.x, v.y, v.z, 1));
updateSatellitePosition(rs->render_groups[0].entities[2]);
}
void
doFrameCallbackPost(render_state* rs)
postFrameCallback(render_state* rs)
{
static orbital_elements c_orb = {};
orbitCopy(g_orbit, c_orb);
gooDraw(rs->handles->window, c_orb);
// TODO: will need more validation from GUI as added
if (!ellipsesEqual(c_orb.ep, g_orbit.ep)) {
// NOTE: handle the case where semimajor axis lowered with low
// eccentricity would fail validation
if (c_orb.ep.a < g_orbit.ep.a && c_orb.ep.a > 0
&& c_orb.ep.e == g_orbit.ep.e)
{
gooDraw(rs->handles->window, g_orbit);
c_orb.ep.b = c_orb.ep.a * sqrt(1 - pow(c_orb.ep.e, 2.0));
}
if (validateEllipse(c_orb.ep)) {
c_orb.ep = constructEllipseAE(c_orb.ep.a, c_orb.ep.e);
ellipseCopy(c_orb.ep, g_orbit.ep);
entity& ellipse_entity = rs->render_groups[0].entities[0];
updateOrbit(g_orbit, g_ellipse3d, ellipse_entity);
}
}
}
int
main()
{
render_state* rs = renInit("orbital shipping",
glm::vec2(1920, 1080),
glm::vec2(1280, 720),
SDL_INIT_TIMER);
if (rs == nullptr) {
@ -163,8 +183,8 @@ main()
rs->render_group_count = 1;
entity& ellipse_entity = rs->render_groups[0].entities[0];
g_ellipse = constructEllipse3D(ep, 256);
simple_mesh* sm = constructEllipseMesh(g_ellipse, glm::vec3(255, 0, 255));
g_ellipse3d = constructEllipse3D(ep, 256);
simple_mesh* sm = constructEllipseMesh(g_ellipse3d, glm::vec3(255, 0, 255));
entInitMesh(ellipse_entity, sm, GL_LINE_LOOP);
entRotate(ellipse_entity, (float) M_PI_2, glm::vec3(1, 0, 0));
@ -177,9 +197,9 @@ main()
sm = createSatelliteMesh();
entInitMesh(satellite_entity, sm, GL_TRIANGLES);
entRotate(satellite_entity, (float) M_PI_2, glm::vec3(1, 0, 0));
entSetWorldPosition(satellite_entity, g_ellipse.vertices[0]);
entSetWorldPosition(satellite_entity, g_ellipse3d.vertices[0]);
renDoRenderLoop(rs, 60 , doFrameCallbackPre, doFrameCallbackPost);
renDoRenderLoop(rs, 60 , preFrameCallback, postFrameCallback);
// TODO: clean up mesh pointers? don't remember if renderer does that
// automatically

52
src/orbits.cpp

@ -24,9 +24,43 @@ constructEllipseAE(double a, double e)
}
bool
validateEllipse(ellipse_parameters)
validateEllipse(const ellipse_parameters ep)
{
return false;
return (ep.a > 0 &&
ep.b > 0 &&
ep.a >= ep.b &&
ep.e >= 0 &&
ep.e < 1);
}
bool
ellipsesEqual(ellipse_parameters& e1, ellipse_parameters& e2)
{
return (e1.a == e2.a &&
e1.b == e2.b &&
e1.e == e2.e);
}
void
ellipseCopy(const ellipse_parameters& e1, ellipse_parameters& e2)
{
e2.a = e1.a;
e2.b = e1.b;
e2.e = e1.e;
e2.c = e1.c;
e2.p = e1.p;
e2.f1 = e1.f1;
e2.f2 = e1.f2;
}
void
orbitCopy(const orbital_elements& o1, orbital_elements& o2)
{
ellipseCopy(o1.ep, o2.ep);
o2.iota = o1.iota;
o2.omega = o1.omega;
o2.mu = o1.mu;
o2.nu = o1.nu;
}
ellipse_3d
@ -37,17 +71,23 @@ constructEllipse3D(ellipse_parameters ep, uint vert_count)
vert_count > 0);
ellipse_3d e3d = { ep, nullptr, vert_count};
// TODO: need to free this allocation at some point
e3d.vertices = UTIL_ALLOC(vert_count, glm::vec3);
double angle = 2 * M_PI / vert_count;
ellipse3DUpdate(ep, e3d);
return e3d;
}
for (uint i = 0; i < vert_count; i++) {
void
ellipse3DUpdate(ellipse_parameters ep, ellipse_3d& e3d)
{
double angle = 2 * M_PI / e3d.vert_count;
for (uint i = 0; i < e3d.vert_count; i++) {
double a = angle * i;
// NOTE: solving for distance in polar coordinates relative to focus
double r = ep.a * (1 - pow(ep.e, 2)) / (1 + ep.e * cos(a));
e3d.vertices[i] = glm::vec3(polarToRect(a, r), 0);
}
return e3d;
}
double

17
src/orbits.h

@ -24,7 +24,7 @@ struct orbital_elements
ellipse_parameters ep;
double iota; // NOTE: (ι) inclination
double omega; // NOTE: (ω) argument of periapsis
double mu; // NOTE: (μ) gravittional parameter
double mu; // NOTE: (μ) gravitational parameter
double nu; // NOTE: (ν) true anomaly
};
@ -43,15 +43,24 @@ ellipse_parameters
constructEllipseAE(double a, double e);
bool
validateEllipse(ellipse_parameters);
validateEllipse(const ellipse_parameters);
bool
ellipsesEqual(ellipse_parameters& e1, ellipse_parameters& e2);
void
ellipseCopy(const ellipse_parameters& e1, ellipse_parameters& e2);
void
orbitCopy(const orbital_elements& o1, orbital_elements& o2);
// NOTE: create vertices for a 3d ellipse
// NOTE: all vertices are in the x/y plane with z = 0
ellipse_3d
constructEllipse3D(ellipse_parameters ep, uint vert_count);
bool
ellipsesEqual(ellipse_parameters e1, ellipse_parameters e2);
void
ellipse3DUpdate(ellipse_parameters ep, ellipse_3d& e3d);
/* NOTE: how-to propagate orbit position given initial true anomaly, semimajor
* axis, mean motion, and eccentricity: ref) section 4.4, Kepler's Problem,

Loading…
Cancel
Save