private IEnumerable <bool> ComputeTrajectoryIncrement(Vessel vessel, DescentProfile profile) { // create or update aerodynamic model if (aerodynamicModel_ == null || !aerodynamicModel_.isValidFor(vessel, vessel.mainBody)) { aerodynamicModel_ = AerodynamicModelFactory.GetModel(vessel, vessel.mainBody); } else { aerodynamicModel_.IncrementalUpdate(); } // create new VesselState from vessel, or null if it's on the ground var state = new VesselState(vessel); // iterate over patches until MaxPatchCount is reached for (int patchIdx = 0; patchIdx < Settings.MaxPatchCount; ++patchIdx) { // stop if we don't have a vessel state if (state == null) { state = new VesselState(vessel); } // If we spent more time in this calculation than allowed, pause until the next frame if (incrementTime_.ElapsedMilliseconds > MaxIncrementTime) { yield return(false); } // if we have a patched conics solver, check for maneuver nodes if (null != attachedVessel.patchedConicSolver) { // search through maneuver nodes of the vessel var maneuverNodes = attachedVessel.patchedConicSolver.maneuverNodes; foreach (var node in maneuverNodes) { // if the maneuver node time corresponds to the end time of the last patch if (node.UT == state.Time) { // add the velocity change of the burn to the velocity of the last patch state.Velocity += node.GetBurnVector(CreateOrbitFromState(state)); break; } } // Add one patch, then pause execution after every patch foreach (bool result in AddPatch(state, true)) { yield return(false); } } else { // Add one patch, then pause execution after every patch foreach (bool result in AddPatch(state, false)) { yield return(false); } } state = AddPatch_outState; } }
/* * public void Update() * { * while (true) * { * // compute frame time * computationTime_ = computationTime_ * 0.99f + frameTime_ * 0.01f; * float offset = frameTime_ - computationTime_; * frameTime_ = 0; * * if (gameFrameTime_ != null) * { * float t = (float) gameFrameTime_.ElapsedMilliseconds; * averageGameFrameTime_ = averageGameFrameTime_ * 0.99f + t * 0.01f; * } * * gameFrameTime_ = Stopwatch.StartNew(); * * * * * // should the trajectory be calculated? * if (attachedVessel != null) * { * if (attachedVessel.Parts.Count != 0) * ComputeTrajectory(attachedVessel, DescentProfile.fetch); * } * } * } */ public void ComputeTrajectory(Vessel vessel, DescentProfile profile) { try { // start of trajectory calculation in current frame incrementTime_ = Stopwatch.StartNew(); // if there is no ongoing partial computation, start a new one if (partialComputation_ == null || vessel != attachedVessel) { // restart the public buffers patchesBackBuffer_.Clear(); maxAccelBackBuffer_ = 0; attachedVessel = vessel; // no vessel, no calculation if (attachedVessel == null) { patches_.Clear(); return; } // Create enumerator for Trajectory increment calculator partialComputation_ = ComputeTrajectoryIncrement(vessel, profile).GetEnumerator(); } // we are finished when there are no more partial computations to be done //bool finished = !partialComputation_.MoveNext(); bool b = true; while (b) { b = partialComputation_.MoveNext(); } //partialComputation_.MoveNext(); bool finished = true; // when calculation is finished, if (finished) { // swap the buffers for the patches and the maximum acceleration, // "publishing" the results var tmp = patches_; patches_ = patchesBackBuffer_; patchesBackBuffer_ = tmp; maxAccel_ = maxAccelBackBuffer_; // Reset partial computation partialComputation_.Dispose(); partialComputation_ = null; } // how long did the calculation in this frame take? frameTime_ += (float)incrementTime_.ElapsedMilliseconds; } catch (Exception e) { ++errorCount_; throw; } }