|
|
|
@ -17,7 +17,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
const double SCALING = 0.001; |
|
|
|
const double SCALING = 0.001; |
|
|
|
static orbital_elements g_orbit = {}; |
|
|
|
static orbital_elements g_orbit = {}; |
|
|
|
static ellipse_3d g_ellipse; |
|
|
|
static ellipse_3d g_ellipse3d; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
simple_mesh* |
|
|
|
simple_mesh* |
|
|
|
@ -76,7 +76,37 @@ initOrbit() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
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
|
|
|
|
// handle input
|
|
|
|
static input_state is = {}; |
|
|
|
static input_state is = {}; |
|
|
|
@ -91,50 +121,40 @@ doFrameCallbackPre(render_state* rs) |
|
|
|
if (is.window_closed || is.escape) |
|
|
|
if (is.window_closed || is.escape) |
|
|
|
rs->running = false; |
|
|
|
rs->running = false; |
|
|
|
|
|
|
|
|
|
|
|
// update orbital elements/ellipse_3d
|
|
|
|
updateSatellitePosition(rs->render_groups[0].entities[2]); |
|
|
|
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)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
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 |
|
|
|
int |
|
|
|
main() |
|
|
|
main() |
|
|
|
{ |
|
|
|
{ |
|
|
|
render_state* rs = renInit("orbital shipping", |
|
|
|
render_state* rs = renInit("orbital shipping", |
|
|
|
glm::vec2(1920, 1080), |
|
|
|
glm::vec2(1280, 720), |
|
|
|
SDL_INIT_TIMER); |
|
|
|
SDL_INIT_TIMER); |
|
|
|
|
|
|
|
|
|
|
|
if (rs == nullptr) { |
|
|
|
if (rs == nullptr) { |
|
|
|
@ -163,8 +183,8 @@ main() |
|
|
|
rs->render_group_count = 1; |
|
|
|
rs->render_group_count = 1; |
|
|
|
|
|
|
|
|
|
|
|
entity& ellipse_entity = rs->render_groups[0].entities[0]; |
|
|
|
entity& ellipse_entity = rs->render_groups[0].entities[0]; |
|
|
|
g_ellipse = constructEllipse3D(ep, 256); |
|
|
|
g_ellipse3d = constructEllipse3D(ep, 256); |
|
|
|
simple_mesh* sm = constructEllipseMesh(g_ellipse, glm::vec3(255, 0, 255)); |
|
|
|
simple_mesh* sm = constructEllipseMesh(g_ellipse3d, glm::vec3(255, 0, 255)); |
|
|
|
entInitMesh(ellipse_entity, sm, GL_LINE_LOOP); |
|
|
|
entInitMesh(ellipse_entity, sm, GL_LINE_LOOP); |
|
|
|
entRotate(ellipse_entity, (float) M_PI_2, glm::vec3(1, 0, 0)); |
|
|
|
entRotate(ellipse_entity, (float) M_PI_2, glm::vec3(1, 0, 0)); |
|
|
|
|
|
|
|
|
|
|
|
@ -177,9 +197,9 @@ main() |
|
|
|
sm = createSatelliteMesh(); |
|
|
|
sm = createSatelliteMesh(); |
|
|
|
entInitMesh(satellite_entity, sm, GL_TRIANGLES); |
|
|
|
entInitMesh(satellite_entity, sm, GL_TRIANGLES); |
|
|
|
entRotate(satellite_entity, (float) M_PI_2, glm::vec3(1, 0, 0)); |
|
|
|
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
|
|
|
|
// TODO: clean up mesh pointers? don't remember if renderer does that
|
|
|
|
// automatically
|
|
|
|
// automatically
|
|
|
|
|