|
|
|
|
@ -164,8 +164,68 @@ removeManeuver(GameOrbit* orbit)
|
|
|
|
|
orbit->maneuver = {0}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// NOTE: test if the maneuver node would have occured between 2 orbit positions
|
|
|
|
|
// eg) between 2 time steps
|
|
|
|
|
bool |
|
|
|
|
testManeuverStep(const ManeuverNode& maneuver, |
|
|
|
|
double previous_theta, |
|
|
|
|
double next_theta) |
|
|
|
|
{ |
|
|
|
|
if (!maneuver.active) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
double r = maneuver.true_anomaly; |
|
|
|
|
previous_theta = orbitClampAngle(previous_theta); |
|
|
|
|
next_theta = orbitClampAngle(next_theta); |
|
|
|
|
|
|
|
|
|
// FIXME: 2 unhandled cases:
|
|
|
|
|
// 1) sat passes through 0 degrees
|
|
|
|
|
// 2) direction is ccw
|
|
|
|
|
//
|
|
|
|
|
if (previous_theta <= r && next_theta >= r) |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
applyManeuver(GameOrbit* orbit) |
|
|
|
|
{ |
|
|
|
|
LOGF(Debug, "applying maneuver\n"); |
|
|
|
|
|
|
|
|
|
// FIXME: assuming prograde impulse vector
|
|
|
|
|
assert(orbit->maneuver.impulse_type == ManeuverType::PROGRADE); |
|
|
|
|
|
|
|
|
|
// re-calculate state vectors at the maneuver node
|
|
|
|
|
TwoBodySystem& sys = orbit->system; |
|
|
|
|
double theta = orbit->maneuver.true_anomaly; |
|
|
|
|
double mu = sys.body.mu; |
|
|
|
|
double r = orbitGetRadialDistance(sys.ep.e, sys.ep.p, theta); |
|
|
|
|
double v = orbitGetVelocity(sys.epsilon, mu, r); |
|
|
|
|
double gamma = orbitGetFlightPathAngle(sys.ep.e, theta); |
|
|
|
|
|
|
|
|
|
// calculate new satellite state vectors
|
|
|
|
|
v += orbit->maneuver.impulse_delta_v; // prograde only
|
|
|
|
|
|
|
|
|
|
// get new angular momentum and specific orbital energy
|
|
|
|
|
double h = orbitGetAngularMomentumFromStateVectors(r, v, gamma); |
|
|
|
|
double epsilon = orbitGetSpecificEnergyFromStateVectors(r, v, mu); |
|
|
|
|
|
|
|
|
|
// update orbit pararmeters
|
|
|
|
|
double a = orbitGetSemiMajorAxis(epsilon, mu); |
|
|
|
|
double p = orbitGetSemiLatusRectum(h, mu); |
|
|
|
|
double e = ellipseGetEccentricity(a, p); |
|
|
|
|
systemInit(orbit->system, sys.body, orbitInit(a, e)); |
|
|
|
|
|
|
|
|
|
// update ellipse3D & GLBuffer vertices
|
|
|
|
|
ellipse3DUpdate(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)); |
|
|
|
|
updateGLBuffer(buf, orbit->e3d.vertices); |
|
|
|
|
|
|
|
|
|
removeManeuver(orbit); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// internal
|
|
|
|
|
|
|
|
|
|
|