private void PredictIntersection(SourceIntersections sourceIntersectionsEntry, int segmentIndex, OrbitalBody orbitalBody, Vector2 orbitalPosition, Vector2 orbitalVelocity, float timeToPosition, Trajectory trajectory, Color intersectionColor) { // Calculate time of flight of current object to destination Vector2 worldDestination = sourceIntersectionsEntry.SegmentIntersections[segmentIndex].ClosestPoint; Vector2 localDestination = (worldDestination - trajectory.ParentGravitySource.Position).RotateVector(-trajectory.ArgumentOfPeriapsis); float timeOfFlight = timeToPosition + OrbitalMechanics.UniversalVariableMethod.CalculateTimeOfFlight(orbitalPosition, orbitalVelocity, localDestination, trajectory.EccentricityVector, trajectory.ParentGravitySource.Mass); if (float.IsNaN(timeOfFlight)) { // timeOfFlight not properly calculated. hide sprites. sourceIntersectionsEntry.HideIntersectionObjects(segmentIndex); return; } // Plot current object's future position sourceIntersectionsEntry.InitiateIntersectionSprite(segmentIndex, sourceIntersectionsEntry.SegmentIntersections[segmentIndex].ClosestPoint, intersectionColor, true); // Plot this source object's position at timeOfFlight Vector2 predictedWorldPosition = sourceIntersectionsEntry.Source.PredictPosition(timeOfFlight); sourceIntersectionsEntry.InitiateIntersectionSprite(segmentIndex, predictedWorldPosition, intersectionColor, false); StartNewIntersectionCoroutine(orbitalBody, timeOfFlight, trajectory, sourceIntersectionsEntry, segmentIndex); }
private void UpdateNearbySourceIntersections(GravitySource gravitySource) { if (gravitySource != currentGravitySource) { // Gravity source changed. Re-initialize source intersections currentGravitySource = gravitySource; InitializeSourceIntersections(); return; } // Update source intersection entries for (int i = 0; i < sourceIntersections.Count; i++) { SourceIntersections thisSourceIntersectionEntry = sourceIntersections[i]; // Hide all intersection sprites thisSourceIntersectionEntry.HideIntersectionObjects(); // Stop coroutines running for each existing segment intersection for (int j = 0; j < thisSourceIntersectionEntry.IntersectionCount; j++) { IEnumerator thisRoutine = thisSourceIntersectionEntry.intersectionCoroutines[j]; if (thisRoutine == null) { continue; } StopCoroutine(thisRoutine); } // Update this entry with now valid intersection objects SegmentIntersection[] validIntersections = GetValidSegmentIntersections(thisSourceIntersectionEntry.Source); thisSourceIntersectionEntry.UpdateSegmentIntersections(validIntersections); } }
private void StopIntersectionCoroutines() { for (int i = 0; i < sourceIntersections.Count; i++) { SourceIntersections thisSourceIntersectionEntry = sourceIntersections[i]; for (int j = 0; j < thisSourceIntersectionEntry.IntersectionCount; j++) { StopCoroutine(thisSourceIntersectionEntry.intersectionCoroutines[j]); } } }
public void PlotNearestSourceIntersections(OrbitalBody orbitalBody, Vector2 orbitalPosition, Vector2 orbitalVelocity, float timeToPosition, Trajectory trajectory) { // orbitalPosition/Velocity are not necessarily equivalent to orbitalBody.orbitalPosition/Velocity (ManeuverNode predicted trajectories for instance) // Update sources considered candidates for intersection UpdateNearbySourceIntersections(trajectory.ParentGravitySource); for (int i = 0; i < sourceIntersections.Count; i++) { Color intersectionColor = sourceIntersectionColors[MathUtilities.IntModulo(i, sourceIntersectionColorCount)]; SourceIntersections sourceIntersectionsEntry = sourceIntersections[i]; for (int j = 0; j < sourceIntersectionsEntry.SegmentIntersections.Length; j++) { PredictIntersection(sourceIntersectionsEntry, j, orbitalBody, orbitalPosition, orbitalVelocity, timeToPosition, trajectory, intersectionColor); } } }
private void UpdateIntersectionSprites(OrbitalBody orbitalBody, Trajectory trajectory, SourceIntersections sourceIntersectionsEntry, int segmentIndex) { // Calculate time of flight to next closest point -- FIXME: Still needed????? if (trajectory.TrajectoryType != OrbitalMechanics.Globals.TrajectoryType.Ellipse) { sourceIntersectionsEntry.HideIntersectionObjects(segmentIndex); return; } // Use trajectory period as timeOfFlight float timeOfFlight = trajectory.Period; Vector2 predictedWorldPosition = sourceIntersectionsEntry.Source.PredictPosition(timeOfFlight); sourceIntersectionsEntry.InitiateIntersectionSprite(segmentIndex, predictedWorldPosition, false); StartNewIntersectionCoroutine(orbitalBody, trajectory.Period, trajectory, sourceIntersectionsEntry, segmentIndex); }
private void StartNewIntersectionCoroutine(OrbitalBody orbitalBody, float timeOfFlight, Trajectory trajectory, SourceIntersections sourceIntersectionsEntry, int segmentIndex) { IEnumerator timeOfFlightEnum = TimerToPosition(orbitalBody, timeOfFlight, trajectory, sourceIntersectionsEntry, segmentIndex); StartCoroutine(timeOfFlightEnum); // Adding reference to this source intersections entry sourceIntersectionsEntry.intersectionCoroutines[segmentIndex] = timeOfFlightEnum; }
private IEnumerator TimerToPosition(OrbitalBody orbitalBody, float time, Trajectory trajectory, SourceIntersections sourceIntersectionsEntry, int segmentIndex) { // Waits until interval expires, then sets bool back to false yield return(new WaitForSeconds(time)); // Recalculate time of flight for orbitalBody to reach orbitalBodyPosition and then source's predicted position UpdateIntersectionSprites(orbitalBody, trajectory, sourceIntersectionsEntry, segmentIndex); }