From f37cc92eaef66a777abf2fffc1b51cd5809f6f5c Mon Sep 17 00:00:00 2001 From: cinnaboot Date: Mon, 27 Jun 2022 10:45:47 -0400 Subject: [PATCH] add rotation xform to satellite struct --- src/game.cpp | 24 ++++++++++++++++-------- src/game.h | 7 +++---- src/main.cpp | 24 ++++++++++-------------- src/orbits.cpp | 1 + src/orbits.h | 3 ++- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 22d345a..0d6c73c 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -72,7 +72,7 @@ getTimeStep(GameState* gs) } Ellipse3D -ellipse3DInit(EllipseParameters ep, uint vert_count) +ellipse3DInit(dmat3 rotation, EllipseParameters ep, uint vert_count) { assert(ep.a > 0 && ep.b > 0 && ep.a >= ep.b && @@ -81,20 +81,21 @@ ellipse3DInit(EllipseParameters ep, uint vert_count) Ellipse3D e3d = { nullptr, vert_count}; // FIXME: should be allocated from GameState->arena e3d.vertices = UTIL_ALLOC(vert_count, vec3); - ellipse3DUpdate(ep, e3d); + ellipse3DUpdate(rotation, ep, e3d); return e3d; } void -ellipse3DUpdate(EllipseParameters ep, Ellipse3D& e3d) +ellipse3DUpdate(dmat3 rotation, EllipseParameters ep, Ellipse3D& e3d) { double angle = 2 * M_PI / e3d.vert_count; for (uint i = 0; i < e3d.vert_count; i++) { double a = angle * i; + // FIXME: we should have a function for this... // 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] = vec3(polarToRect(a, r), 0); + e3d.vertices[i] = rotation * vec3(polarToRect(a, r), 0); } } @@ -250,13 +251,20 @@ applyManeuver(GameOrbit* orbit, double previous_true_anomaly) double epsilon = orbitGetSpecificEnergyFromStateVectors(r, v, mu); // update orbit pararmeters - double a = orbitGetSemiMajorAxis(epsilon, mu); + sys.elements.a = orbitGetSemiMajorAxis(epsilon, mu); double p = orbitGetSemiLatusRectum(h, mu); - double e = ellipseGetEccentricity(a, p); - systemInit(orbit->system, sys.body, orbitInit(a, e)); + sys.elements.e = ellipseGetEccentricity(sys.elements.a, p); + + dvec3 pos = orbitGetPositionVector(r, theta); + dvec3 vel = orbitGetVelocityVector(mu, h, sys.elements.e, theta); + + sys.rotation = orbitGetXForm(sys.elements); + sys.sat.position = sys.rotation * pos; + sys.sat.velocity = sys.rotation * vel; + systemInit(orbit->system, sys.body, sys.elements); // update ellipse3D & GLBuffer vertices - ellipse3DUpdate(sys.ep, orbit->e3d); + ellipse3DUpdate(sys.rotation, sys.ep, orbit->e3d); GLBuffer* buf = &orbit->ellipse_entity->meshes[0].vertex_attrib_buffers[0]; assert(utilCStrMatch(buf->name, "position")); assert(buf->data_size == orbit->e3d.vert_count * sizeof(vec3)); diff --git a/src/game.h b/src/game.h index a3e4f1f..6f58525 100644 --- a/src/game.h +++ b/src/game.h @@ -4,6 +4,7 @@ #include using glm::vec3; using glm::dvec3; +using glm::dmat3; #include "tangerine.h" #include "orbits.h" @@ -82,11 +83,9 @@ void disableGameOrbit(GameState* gs, GameOrbit* orbit); double getTimeStep(GameState* gs); -// NOTE: create vertices for a 3d ellipse -// all vertices are in the x/y plane with z = 0 -Ellipse3D ellipse3DInit(EllipseParameters ep, uint vert_count); +Ellipse3D ellipse3DInit(dmat3 rotation, EllipseParameters ep, uint vert_count); -void ellipse3DUpdate(EllipseParameters ep, Ellipse3D& e3d); +void ellipse3DUpdate(dmat3 rotation, EllipseParameters ep, Ellipse3D& e3d); void selectOrbit(GameState* gs, GameOrbit* orbit); diff --git a/src/main.cpp b/src/main.cpp index 8c29a4d..c37141a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -113,24 +113,22 @@ addCoordinateOverlay(RenderState* rs) } Entity* -initEllipseEntity(RenderState* rs, - const EllipseParameters& ep, - Ellipse3D& e3d, - u32 num_vertices) +initEllipseEntity(RenderState* rs, GameOrbit* orbit, u32 num_vertices) { // FIXME: it might be worth using stack memory here, and in // initSatelliteEntity(), so we're not storing basically the same model // over and over with just different vertices // Could also use a temporary arena maybe? - e3d = ellipse3DInit(ep, num_vertices); + orbit->e3d = + ellipse3DInit(orbit->system.rotation, orbit->system.ep, num_vertices); Mesh* m = meshInit(rs->assets.arena, num_vertices, num_vertices, false, true); - for (uint i = 0; i < e3d.vert_count; i++) { - m->vertices[i] = e3d.vertices[i]; + for (uint i = 0; i < orbit->e3d.vert_count; i++) { + m->vertices[i] = orbit->e3d.vertices[i]; m->colors[i] = DEFAULT_ELLIPSE_COLOR; m->indices[i] = i; } @@ -216,10 +214,8 @@ loadOrbit(GameState* gs, GameOrbit* orbit = getFreeOrbit(gs); systemInit(orbit->system, body, elements); - orbit->ellipse_entity = initEllipseEntity(rs, - orbit->system.ep, - orbit->e3d, - DEFAULT_ORBIT_VERTICES); + orbit->ellipse_entity = + initEllipseEntity(rs, orbit, DEFAULT_ORBIT_VERTICES); setEntityPosition(orbit->ellipse_entity, vec3(0, 0, 0)); rotateEntity(orbit->ellipse_entity, vec3(1, 0, 0), (float) M_PI / 2); @@ -258,9 +254,9 @@ loadScene(GameState* gs, RenderState* rs) addManeuver(go_1, ImpulseType::PROGRADE, -2.f, 0.2); #endif - OrbitalElements oe_2 = orbitInit(r + 100, 0, 0, 0, 0, 0); + OrbitalElements oe_2 = orbitInit(r + 100, 0, 0, 0, 0, DEG2RAD(-90)); GameOrbit* go_2 = loadOrbit(gs, rs, body, oe_2, rg, "sat_02"); - addManeuver(go_2, ImpulseType::PROGRADE, M_PI / 2, 2.2); + addManeuver(go_2, ImpulseType::PROGRADE, DEG2RAD(45), 2.2); #if 0 double a_3 = r + 40000; @@ -296,7 +292,7 @@ updateSatelliteModel(TwoBodySystem& sys, double 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); - sat.position = glm::vec3(polarToRect(sat.theta, sat.r), 0); + sat.position = sys.rotation * glm::vec3(polarToRect(sat.theta, sat.r), 0); } void diff --git a/src/orbits.cpp b/src/orbits.cpp index da12546..b4da039 100644 --- a/src/orbits.cpp +++ b/src/orbits.cpp @@ -16,6 +16,7 @@ systemInit(TwoBodySystem& system, GravBody gb, OrbitalElements el) system.orbital_period = orbitGetPeriod(system.ep.a, gb.mu); system.r_periapsis = system.ep.a - system.ep.c; system.r_apoapsis = 2 * system.ep.a - system.r_periapsis; + system.rotation = orbitGetXForm(el); } GravBody diff --git a/src/orbits.h b/src/orbits.h index 156e70e..589ad55 100644 --- a/src/orbits.h +++ b/src/orbits.h @@ -44,7 +44,7 @@ struct GravBody struct Satellite { glm::vec3 position; - // glm::vec3 velocity; + glm::vec3 velocity; double theta; // true anomaly double r; // radius magnitude at theta double gamma; // (γ) flight path angle @@ -58,6 +58,7 @@ struct TwoBodySystem Satellite sat; EllipseParameters ep; OrbitalElements elements; + glm::dmat3 rotation; double epsilon; // (ε) specific orbital energy, MJ/kg double h; // angular momentum