internal static void Update() { patch = Trajectory.Patches.LastOrDefault(); if ((!Util.IsFlight && !Util.IsTrackingStation) || !Trajectories.IsVesselAttached || !TargetProfile.WorldPosition.HasValue || patch == null || !patch.ImpactPosition.HasValue || patch.StartingState.ReferenceBody != TargetProfile.Body || !Ready) { SetDisplayEnabled(false); return; } body = Trajectories.AttachedVessel.mainBody; position = Trajectories.AttachedVessel.GetWorldPos3D() - body.position; velocity = Trajectories.AttachedVessel.obt_velocity - body.getRFrmVel(body.position + position); // air velocity up = position.normalized; vel_right = Vector3d.Cross(velocity, up).normalized; reference = CalcReference(); SetDisplayEnabled(true); guide_transform.gameObject.transform.localPosition = navball.attitudeGymbal * (CorrectedDirection.Value * navball.VectorUnitScale); reference_transform.gameObject.transform.localPosition = navball.attitudeGymbal * (reference * navball.VectorUnitScale); // hide if behind navball guide_transform.gameObject.SetActive(guide_transform.gameObject.transform.localPosition.z >= navball.VectorUnitCutoff); reference_transform.gameObject.SetActive(reference_transform.gameObject.transform.localPosition.z >= navball.VectorUnitCutoff); }
internal static void Update() { line.enabled = false; impact_cross.enabled = false; target_cross.enabled = false; if (!Settings.DisplayTrajectories || Util.IsMap || !Settings.DisplayTrajectoriesInFlight || Trajectory.Patches.Count == 0) { return; } line.Clear(); line.Add(Trajectories.AttachedVessel.GetWorldPos3D()); lastPatch = Trajectory.Patches[Trajectory.Patches.Count - 1]; bodyPosition = lastPatch.StartingState.ReferenceBody.position; if (lastPatch.IsAtmospheric) { for (uint i = 0; i < lastPatch.AtmosphericTrajectory.Length; ++i) { vertex = lastPatch.AtmosphericTrajectory[i].pos + bodyPosition; line.Add(vertex); } } else { time = lastPatch.StartingState.Time; time_increment = (lastPatch.EndTime - lastPatch.StartingState.Time) / DEFAULT_VERTEX_COUNT; orbit = lastPatch.SpaceOrbit; for (uint i = 0; i < DEFAULT_VERTEX_COUNT; ++i) { vertex = Util.SwapYZ(orbit.getRelativePositionAtUT(time)); if (Settings.BodyFixedMode) { vertex = Trajectory.CalculateRotatedPosition(orbit.referenceBody, vertex, time); } vertex += bodyPosition; line.Add(vertex); time += time_increment; } } line.enabled = true; // red impact cross if (lastPatch.ImpactPosition != null) { impact_cross.Position = lastPatch.ImpactPosition.Value + bodyPosition; impact_cross.Body = lastPatch.StartingState.ReferenceBody; impact_cross.enabled = true; } else { impact_cross.Position = null; impact_cross.Body = null; } // green target cross if (TargetProfile.WorldPosition != null) { target_cross.Position = TargetProfile.WorldPosition.Value + TargetProfile.Body.position; target_cross.Body = TargetProfile.Body; target_cross.enabled = true; } else { target_cross.Position = null; target_cross.Body = null; } }
private void FixedUpdate() { line.enabled = false; targetingCross.enabled = false; if (!Settings.fetch.DisplayTrajectories || Util.IsMap || !Settings.fetch.DisplayTrajectoriesInFlight || Trajectory.fetch.Patches.Count == 0) { return; } line.Vertices.Clear(); Trajectory.Patch lastPatch = Trajectory.fetch.Patches[Trajectory.fetch.Patches.Count - 1]; Vector3d bodyPosition = lastPatch.StartingState.ReferenceBody.position; if (lastPatch.IsAtmospheric) { for (uint i = 0; i < lastPatch.AtmosphericTrajectory.Length; ++i) { Vector3 vertex = lastPatch.AtmosphericTrajectory[i].pos + bodyPosition; line.Vertices.Add(vertex); } } else { double time = lastPatch.StartingState.Time; double time_increment = (lastPatch.EndTime - lastPatch.StartingState.Time) / defaultVertexCount; Orbit orbit = lastPatch.SpaceOrbit; for (uint i = 0; i < defaultVertexCount; ++i) { Vector3 vertex = Util.SwapYZ(orbit.getRelativePositionAtUT(time)); if (Settings.fetch.BodyFixedMode) { vertex = Trajectory.CalculateRotatedPosition(orbit.referenceBody, vertex, time); } vertex += bodyPosition; line.Vertices.Add(vertex); time += time_increment; } } line.Body = lastPatch.StartingState.ReferenceBody; line.enabled = true; if (lastPatch.ImpactPosition != null) { targetingCross.ImpactPosition = lastPatch.ImpactPosition.Value; targetingCross.ImpactBody = lastPatch.StartingState.ReferenceBody; targetingCross.enabled = true; } else { targetingCross.ImpactPosition = null; targetingCross.ImpactBody = null; } }
private void FixedUpdate() { if (Settings.fetch.NewGui) { return; } float t = Time.realtimeSinceStartup; if (t < lastStringRenderTime + stringRenderInterval) { return; } lastStringRenderTime = t; Trajectory traj = Trajectory.fetch; Trajectory.Patch lastPatch = traj.Patches.LastOrDefault(); CelestialBody lastPatchBody = lastPatch?.StartingState.ReferenceBody; CelestialBody targetBody = Trajectory.Target.Body; guistring_gForce = (traj.MaxAccel / 9.81).ToString("0.00"); if (lastPatch != null && lastPatch.ImpactPosition.HasValue) { Vector3 up = lastPatch.ImpactPosition.Value.normalized; Vector3 vel = lastPatch.ImpactVelocity.Value - lastPatchBody.getRFrmVel(lastPatch.ImpactPosition.Value + lastPatchBody.position); float vVelMag = Vector3.Dot(vel, up); Vector3 vVel = up * vVelMag; float hVelMag = (vel - vVel).magnitude; guistring_impactVelocity = String.Format("Impact: V = {0,6:F0}m/s, H = {1,6:F0}m/s", -vVelMag, hVelMag); } else { guistring_impactVelocity = ""; } if (Settings.fetch.DisplayTargetGUI) { if (lastPatchBody != null && targetBody != null && lastPatch.ImpactPosition.HasValue && lastPatchBody == targetBody && Trajectory.Target.WorldPosition.HasValue) { // Get Latitude and Longitude from impact position double impactLat; double impatLon; double impactAlt; // Get Latitude and Longitude from impact position impactPos = lastPatch.ImpactPosition.Value + lastPatchBody.position; lastPatchBody.GetLatLonAlt(impactPos, out impactLat, out impatLon, out impactAlt); // Get Latitude and Longitude for target position double targetLat; double targetLon; double targetAlt; targetPos = Trajectory.Target.WorldPosition.Value + targetBody.position; targetBody.GetLatLonAlt(targetPos, out targetLat, out targetLon, out targetAlt); float targetDistance = (float)(Util.DistanceFromLatitudeAndLongitude(targetBody.Radius + impactAlt, impactLat, impatLon, targetLat, targetLon) / 1e3); float targetDistanceNorth = (float)(Util.DistanceFromLatitudeAndLongitude(targetBody.Radius + impactAlt, impactLat, targetLon, targetLat, targetLon) / 1e3) * ((targetLat - impactLat) < 0 ? -1.0f : +1.0f); float targetDistanceEast = (float)(Util.DistanceFromLatitudeAndLongitude(targetBody.Radius + impactAlt, targetLat, impatLon, targetLat, targetLon) / 1e3) * ((targetLon - impatLon) < 0 ? -1.0f : +1.0f); // format distance to target string guistring_targetDistance = String.Format("{0,6:F1}km | {1}: {2,6:F1}km | {3}: {4,6:F1}km", targetDistance, targetDistanceNorth > 0.0f ? 'N' : 'S', Math.Abs(targetDistanceNorth), targetDistanceEast > 0.0f ? 'E' : 'W', Math.Abs(targetDistanceEast)); } else { guistring_targetDistance = ""; } } if (FlightGlobals.ActiveVessel != null) { var body = FlightGlobals.ActiveVessel.mainBody; guistring_Latitude = body.GetLatitude(FlightGlobals.ActiveVessel.GetWorldPos3D()).ToString("000.000000"); guistring_Longitude = body.GetLongitude(FlightGlobals.ActiveVessel.GetWorldPos3D()).ToString("000.000000"); } }
private static void MainWindow(int id) { GUILayout.BeginHorizontal(); Settings.DisplayTrajectories = GUILayout.Toggle(Settings.DisplayTrajectories, "Show trajectory", GUILayout.Width(125)); Settings.DisplayTrajectoriesInFlight = GUILayout.Toggle(Settings.DisplayTrajectoriesInFlight, "In-Flight"); // check that we have patched conics. If not, apologize to the user and return. if (Settings.DisplayTrajectories && !Util.IsPatchedConicsAvailable) { ScreenMessages.PostScreenMessage( "Can't show trajectory because patched conics are not available." + " Please update your tracking station facility."); Settings.DisplayTrajectories = false; return; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); Settings.BodyFixedMode = GUILayout.Toggle(Settings.BodyFixedMode, "Body-fixed mode"); if (Settings.DisplayTrajectories) { Settings.DisplayCompleteTrajectory = GUILayout.Toggle(Settings.DisplayCompleteTrajectory, "complete", GUILayout.Width(70)); } GUILayout.EndHorizontal(); GUILayout.Label("Max G-force: " + guistring_gForce); GUILayout.Label(guistring_impactVelocity); GUILayout.Space(10); if (Settings.DisplayTargetGUI = ToggleGroup(Settings.DisplayTargetGUI, "Target")) { GUI.enabled = TargetProfile.WorldPosition.HasValue; GUILayout.Label(guistring_targetDistance); if (GUILayout.Button("Unset target")) { TargetProfile.Clear(); } GUI.enabled = true; GUILayout.BeginHorizontal(); Trajectory.Patch patch = Trajectory.Patches.LastOrDefault(); GUI.enabled = (patch != null && patch.ImpactPosition.HasValue); if (GUILayout.Button("Set current impact", GUILayout.Width(150))) { if (patch.ImpactPosition.HasValue) { TargetProfile.SetFromWorldPos(patch.StartingState.ReferenceBody, patch.ImpactPosition.Value); } } GUI.enabled = true; if (GUILayout.Button("Set KSC", GUILayout.Width(70))) { CelestialBody homebody = FlightGlobals.GetHomeBody(); double latitude = SpaceCenter.Instance.Latitude; double longitude = SpaceCenter.Instance.Longitude; if (homebody != null) { TargetProfile.SetFromLatLonAlt(homebody, latitude, longitude); } } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); Vessel targetVessel = FlightGlobals.fetch.VesselTarget?.GetVessel(); GUI.enabled = (patch != null && targetVessel != null && targetVessel.Landed // && targetVessel.lastBody == patch.startingState.referenceBody ); if (GUILayout.Button("Target vessel")) { TargetProfile.SetFromWorldPos(targetVessel.lastBody, targetVessel.GetWorldPos3D() - targetVessel.lastBody.position); ScreenMessages.PostScreenMessage("Targeting vessel " + targetVessel.GetName()); } FinePrint.Waypoint navigationWaypoint = Trajectories.AttachedVessel?.navigationWaypoint; GUI.enabled = (navigationWaypoint != null); if (GUILayout.Button("Active waypoint")) { TargetProfile.SetFromLatLonAlt(navigationWaypoint.celestialBody, navigationWaypoint.latitude, navigationWaypoint.longitude, navigationWaypoint.altitude); ScreenMessages.PostScreenMessage("Targeting waypoint " + navigationWaypoint.name); } GUILayout.EndHorizontal(); GUI.enabled = true; GUILayout.BeginHorizontal(); coords = GUILayout.TextField(TargetProfile.ManualText, GUILayout.Width(170)); if (coords != TargetProfile.ManualText) { TargetProfile.ManualText = coords; TargetProfile.Save(); } if (GUILayout.Button(new GUIContent("Set", "Enter target latitude and longitude, separated by a comma, in decimal format (with a dot for decimal separator)"), GUILayout.Width(50))) { string[] latLng = coords.Split(new char[] { ',', ';' }); CelestialBody body = FlightGlobals.currentMainBody; if (latLng.Length == 2 && body != null) { double lat; double lng; if (double.TryParse(latLng[0].Trim(), out lat) && double.TryParse(latLng[1].Trim(), out lng)) { TargetProfile.SetFromLatLonAlt(body, lat, lng); } } } GUILayout.EndHorizontal(); } GUILayout.Space(10); GUILayout.BeginHorizontal(); bool descentProfileGroup = Settings.DisplayDescentProfileGUI = ToggleGroup(Settings.DisplayDescentProfileGUI, "Descent profile", 120); DescentProfile.DoQuickControlsGUI(); GUILayout.EndHorizontal(); if (descentProfileGroup) { DescentProfile.DoGUI(); } GUILayout.Space(10); if (Settings.DisplaySettingsGUI = ToggleGroup(Settings.DisplaySettingsGUI, "Settings")) { GUILayout.BeginHorizontal(); GUILayout.Label("Max patches", GUILayout.Width(100)); Settings.MaxPatchCount = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)Settings.MaxPatchCount, 3, 10, GUILayout.Width(100))); GUILayout.Label(Settings.MaxPatchCount.ToString(), GUILayout.Width(15)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Max frames per patch", GUILayout.Width(100)); Settings.MaxFramesPerPatch = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)Settings.MaxFramesPerPatch, 1, 50, GUILayout.Width(100))); GUILayout.Label(Settings.MaxFramesPerPatch.ToString(), GUILayout.Width(15)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); Settings.UseCache = GUILayout.Toggle(Settings.UseCache, new GUIContent("Use Cache", "Toggle cache usage. Trajectory will be more precise when cache disabled, but computation time will be higher. It's not recommended to keep it unchecked, unless your CPU can handle the load."), GUILayout.Width(80)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); Settings.AutoUpdateAerodynamicModel = GUILayout.Toggle(Settings.AutoUpdateAerodynamicModel, new GUIContent("Auto update", "Auto-update of the aerodynamic model. For example if a part is decoupled, the model needs to be updated. This is independent from trajectory update.")); if (GUILayout.Button("Update now")) { Trajectory.InvalidateAerodynamicModel(); } GUILayout.EndHorizontal(); if (ToolbarManager.ToolbarAvailable) { Settings.UseBlizzyToolbar = GUILayout.Toggle(Settings.UseBlizzyToolbar, new GUIContent("Use Blizzy's toolbar", "Will take effect after restart")); } if (Trajectories.IsVesselAttached) { GUILayout.Label("Position:"); GUILayout.BeginHorizontal(); GUILayout.Label("lat=" + guistring_Latitude, GUILayout.Width(110)); GUILayout.Label("lng=" + guistring_Longitude, GUILayout.Width(110)); GUILayout.EndHorizontal(); } GUILayout.Label("Aerodynamic model: " + Trajectory.AerodynamicModelName); GUILayout.BeginHorizontal(); GUILayout.Label(string.Format("Perf: {0,5:F1}ms ({1,4:F1})%", Trajectory.ComputationTime * 1000.0f, Trajectory.ComputationTime / Trajectory.GameFrameTime * 100.0f ), GUILayout.Width(130)); GUILayout.Label(Trajectory.ErrorCount + " error(s)", GUILayout.Width(80)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Toggle(Settings.NewGui, new GUIContent("New Gui", "Swap to the New Gui"))) { Settings.NewGui = true; Settings.MainGUIEnabled = true; Settings.GUIEnabled = false; InputLockManager.RemoveControlLock("TrajectoriesFlightLock"); clickThroughLocked = false; } else { Settings.NewGui = false; Settings.MainGUIEnabled = false; Settings.GUIEnabled = true; } GUILayout.EndHorizontal(); } tooltip = GUI.tooltip; GUI.DragWindow(); }