private void SetProgradeInput(string input) { float value = 0; if (!float.TryParse(input, out value)) { return; } if (_gizmo != null) { _gizmo.DeltaV = new Vector3d(_gizmo.DeltaV.x, _gizmo.DeltaV.y, value); _node.OnGizmoUpdated(_gizmo.DeltaV, _node.UT); } else { _node.DeltaV = new Vector3d(_node.DeltaV.x, _node.DeltaV.y, value); _node.solver.UpdateFlightPlan(); } double magnitude = _node.DeltaV.magnitude; if (magnitude < 100000) { _inputPanel.TotaldVText.OnTextUpdate.Invoke(string.Format("Maneuver Node #{0}: {1:N2}m/s", _index + 1, magnitude)); } else if (magnitude < 1000000000) { _inputPanel.TotaldVText.OnTextUpdate.Invoke(string.Format("Maneuver Node #{0}: {1:N1}km/s", _index + 1, magnitude / 1000)); } else { _inputPanel.TotaldVText.OnTextUpdate.Invoke(string.Format("Maneuver Node #{0}: {1:N1}Mm/s", _index + 1, magnitude / 1000000)); } }
private void CreateManeuverNode(double UT, Vector3d dV) { Vessel vessel = FlightGlobals.ActiveVessel; if (vessel == null) { return; } //placing a maneuver node with bad dV values can really mess up the game, so try to protect against that //and log an exception if we get a bad dV vector: for (int i = 0; i < 3; i++) { if (double.IsNaN(dV[i]) || double.IsInfinity(dV[i])) { throw new Exception("Kerbulator: bad dV: " + dV); } } if (double.IsNaN(UT) || double.IsInfinity(UT)) { throw new Exception("Kerbulator: bad UT: " + UT); } //It seems that sometimes the game can freak out if you place a maneuver node in the past, so this //protects against that. UT = Math.Max(UT, Planetarium.GetUniversalTime()); ManeuverNode mn = vessel.patchedConicSolver.AddManeuverNode(UT); mn.OnGizmoUpdated(dV, UT); }
private static void AdjustManeuver(BurnModel burn, Vector3d direction, double fraction = 1.0) { const double DELTA_V_INCREMENT_LARGE = 0.5, DELTA_V_INCREMENT_SMALL = 0.01; if (burn != null && FlightGlobals.ActiveVessel != null) { ManeuverNode n = burn?.node; if (n != null) { if (GameSettings.MODIFIER_KEY.GetKey()) { n.DeltaV += DELTA_V_INCREMENT_SMALL * fraction * direction; } else { n.DeltaV += DELTA_V_INCREMENT_LARGE * fraction * direction; } if (n.attachedGizmo != null) { n.attachedGizmo.DeltaV = n.DeltaV; try { n.OnGizmoUpdated(n.DeltaV, burn.atTime ?? 0); } catch (Exception ex) { DbgExc("Problem updating gizmo", ex); } } n.solver.UpdateFlightPlan(); } } }
//input dV should be in world coordinates public static ManeuverNode PlaceManeuverNode(this Vessel vessel, Orbit patch, Vector3d dV, double UT) { //placing a maneuver node with bad dV values can really mess up the game, so try to protect against that //and log an exception if we get a bad dV vector: for (int i = 0; i < 3; i++) { if (double.IsNaN(dV[i]) || double.IsInfinity(dV[i])) { throw new Exception("MechJeb VesselExtensions.PlaceManeuverNode: bad dV: " + dV); } } if (double.IsNaN(UT) || double.IsInfinity(UT)) { throw new Exception("MechJeb VesselExtensions.PlaceManeuverNode: bad UT: " + UT); } //It seems that sometimes the game can freak out if you place a maneuver node in the past, so this //protects against that. UT = Math.Max(UT, Planetarium.GetUniversalTime()); //convert a dV in world coordinates into the coordinate system of the maneuver node, //which uses (x, y, z) = (radial+, normal-, prograde) Vector3d nodeDV = patch.DeltaVToManeuverNodeCoordinates(UT, dV); ManeuverNode mn = vessel.patchedConicSolver.AddManeuverNode(UT); mn.OnGizmoUpdated(nodeDV, UT); return(mn); }
public void updateNode() { // Node manager policy: // if the manager has been changed from the last update manager snapshot, take the manager // UNLESS // if the node has been changed from the last update node snapshot, take the node if (curNodeState.compare(node)) { // the node hasn't changed, do our own thing if (changed) { if (node.attachedGizmo != null) { node.attachedGizmo.DeltaV = curState.getVector(); node.attachedGizmo.UT = curState.UT; } node.OnGizmoUpdated(curState.getVector(), curState.UT); updateCurrentNodeState(); changed = false; // new } } else { // the node has changed, take the node's new information for ourselves. updateCurrentNodeState(); curState.update(node); } }
private void ToNodeRef() { if (nodeRef == null) { return; } nodeRef.OnGizmoUpdated(new Vector3d(radialOut, normal, prograde), time); }
/// <summary> /// Restores the maneuvers. /// </summary> /// <param name="stored">Stored maneuver.</param> void RestoreManeuver(StoredManeuver stored) { DeleteAll(); StoredManeuver restore = stored; while (restore != null) { ManeuverNode node = FlightGlobals.ActiveVessel.patchedConicSolver.AddManeuverNode(restore.UT); node.OnGizmoUpdated(restore.DeltaV, restore.UT); restore = restore.Next; } }
private void ToNodeRef() { if (nodeRef == null) { return; } if (nodeRef.attachedGizmo == null) { // Copy the logic from OnGizmoUpdated, excluding the two calls to attachedGizmo nodeRef.DeltaV = new Vector3d(radialOut, normal, prograde); nodeRef.UT = time; nodeRef.solver.UpdateFlightPlan(); } else { nodeRef.OnGizmoUpdated(new Vector3d(radialOut, normal, prograde), time); } }
/// <summary> /// Merges the given node into the next lowest node (n's index - 1). If there is no lower node, does nothing. /// </summary> /// <param name="n">The ManeuverNode to merge down.</param> internal static void mergeNodeDown(this ManeuverNode n) { PatchedConicSolver p = NodeTools.getSolver(); Orbit o = FlightGlobals.ActiveVessel.orbit; int nodes = p.maneuverNodes.Count; int idx = p.maneuverNodes.IndexOf(n); // if we're the last or only node, don't bother. if (idx == 0 || nodes < 2) { return; } ManeuverNode mergeInto = p.maneuverNodes[idx - 1]; Vector3d deltaV = mergeBurnVectors(mergeInto.UT, mergeInto, n.patch); mergeInto.OnGizmoUpdated(deltaV, mergeInto.UT); p.maneuverNodes.Remove(n); }
public void UpdateManeuverNodes(PatchedConicSolver solver) { if (solver == null) { return; } // Avoid flickering by not overwriting nodes where possible var maneuversLength = this.Maneuvers == null ? 0 : this.Maneuvers.Length; int commonLength = Math.Min(solver.maneuverNodes.Count, maneuversLength); // update the common ones for (int i = 0; i < commonLength; i++) { var node = solver.maneuverNodes[i]; var nodeUpdate = this.Maneuvers[i]; node.UT = nodeUpdate.UniversalTime; node.DeltaV = nodeUpdate.DeltaV; node.OnGizmoUpdated(node.DeltaV, node.UT); } // remove any extra ones for (int i = solver.maneuverNodes.Count; i > maneuversLength; i--) { var node = solver.maneuverNodes[i - 1]; solver.RemoveManeuverNode(node); } // add any new ones for (int i = solver.maneuverNodes.Count; i < maneuversLength; i++) { var maneuver = this.Maneuvers[i]; ManeuverNode node = solver.AddManeuverNode(maneuver.UniversalTime); node.DeltaV = maneuver.DeltaV; node.OnGizmoUpdated(node.DeltaV, node.UT); } }
/// <summary> /// Draw the main window. /// </summary> /// <param name="windowId">Window identifier.</param> void OnWindow(int windowId) { if (FlightGlobals.ActiveVessel == null) { return; } PatchedConicSolver solver = FlightGlobals.ActiveVessel.patchedConicSolver; GUILayout.BeginVertical(GUILayout.Width(320.0f)); GUILayout.BeginHorizontal(); if (GUILayout.Button("New") && IsAllowed()) { _maneuver = solver.AddManeuverNode(Planetarium.GetUniversalTime() + (10.0 * 60.0)); _mindex = solver.maneuverNodes.IndexOf(_maneuver); } if (GUILayout.Button("Delete") && _maneuver != null) { _maneuver.RemoveSelf(); } if (GUILayout.Button("Delete All") && _maneuver != null) { DeleteAll(); } if (GUILayout.Button("Store") && solver.maneuverNodes.Count > 0) { StoredManeuver start = null; StoredManeuver prev = null; foreach (ManeuverNode node in solver.maneuverNodes) { StoredManeuver temp = new StoredManeuver(node.DeltaV, node.UT); if (start == null) { start = temp; } if (prev != null) { prev.Next = temp; } prev = temp; } _stored.Add(start); } if (GUILayout.Button("Close")) { ToggleWindow(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Warp"); if (GUILayout.Button("+10m")) { // Cancel any existing warp. TimeWarp.SetRate(0, true); // Warp to the maneuver. TimeWarp.fetch.WarpTo(Planetarium.GetUniversalTime() + 10.0 * Format.ONE_KMIN); } if (GUILayout.Button("+1h")) { // Cancel any existing warp. TimeWarp.SetRate(0, true); // Warp to the maneuver. TimeWarp.fetch.WarpTo(Planetarium.GetUniversalTime() + Format.ONE_KHOUR); } if (GUILayout.Button("+1d")) { // Cancel any existing warp. TimeWarp.SetRate(0, true); // Warp to the maneuver. TimeWarp.fetch.WarpTo(Planetarium.GetUniversalTime() + Format.ONE_KDAY); } if (GUILayout.Button("+10d")) { // Cancel any existing warp. TimeWarp.SetRate(0, true); // Warp to the maneuver. TimeWarp.fetch.WarpTo(Planetarium.GetUniversalTime() + 10.0 * Format.ONE_KDAY); } if (FlightGlobals.ActiveVessel.orbit.patchEndTransition != Orbit.PatchTransitionType.FINAL) { if (GUILayout.Button("Transition")) { // Cancel any existing warp. TimeWarp.SetRate(0, true); // Warp to the maneuver. TimeWarp.fetch.WarpTo(FlightGlobals.ActiveVessel.orbit.EndUT - Format.ONE_KMIN); } } GUILayout.EndHorizontal(); if (solver.maneuverNodes.Count > 0) { if (_maneuver == null || _mvessel != FlightGlobals.ActiveVessel || !solver.maneuverNodes.Contains(_maneuver)) { _maneuver = solver.maneuverNodes [0]; _mvessel = FlightGlobals.ActiveVessel; _mindex = 0; } GUILayout.BeginHorizontal(); GUILayout.Label("Maneuver:" + (_mindex + 1) + " of " + solver.maneuverNodes.Count); if (GUILayout.Button("Prev")) { _mindex--; if (_mindex < 0) { _mindex = solver.maneuverNodes.Count - 1; } _maneuver = solver.maneuverNodes [_mindex]; _mvessel = FlightGlobals.ActiveVessel; } if (GUILayout.Button("Next")) { _mindex++; if (_mindex >= solver.maneuverNodes.Count) { _mindex = 0; } _maneuver = solver.maneuverNodes [_mindex]; _mvessel = FlightGlobals.ActiveVessel; } GUILayout.EndHorizontal(); if (_maneuver != null) { double timeToNode = Planetarium.GetUniversalTime() - _maneuver.UT; if (_mindex == 0) { GUILayout.BeginHorizontal(); GUILayout.Label("Warp To Maneuver"); if (GUILayout.Button("-1m") && -timeToNode > Format.ONE_KMIN) { // Cancel any existing warp. TimeWarp.SetRate(0, true); // Warp to the maneuver. TimeWarp.fetch.WarpTo(_maneuver.UT - Format.ONE_KMIN); } if (GUILayout.Button("-10m") && -timeToNode > 10.0 * Format.ONE_KMIN) { // Cancel any existing warp. TimeWarp.SetRate(0, true); // Warp to the maneuver. TimeWarp.fetch.WarpTo(_maneuver.UT - 10.0 * Format.ONE_KMIN); } if (GUILayout.Button("-1h") && -timeToNode > Format.ONE_KHOUR) { // Cancel any existing warp. TimeWarp.SetRate(0, true); // Warp to the maneuver. TimeWarp.fetch.WarpTo(_maneuver.UT - Format.ONE_KHOUR); } GUILayout.EndHorizontal(); } else { GUILayout.Label("Warp To Maneuver - Switch to first maneuver"); } GUILayout.Label("Time:" + KSPUtil.dateTimeFormatter.PrintDateDeltaCompact(timeToNode, true, true, true)); GUILayout.Label("Δv:" + Format.GetNumberString(_maneuver.DeltaV.magnitude) + "m/s"); GUILayout.BeginHorizontal(); _menuSelection = GUILayout.SelectionGrid(_menuSelection, new string [] { ".01 m/s", ".1 m/s", "1 m/s", "10 m/s", "100 m/s", "1000 m/s" }, 3, GUILayout.MinWidth(300.0f)); if (_menuSelection == 0) { _increment = 0.01d; } else if (_menuSelection == 1) { _increment = 0.1d; } else if (_menuSelection == 2) { _increment = 1.0d; } else if (_menuSelection == 3) { _increment = 10.0d; } else if (_menuSelection == 4) { _increment = 100.0d; } else if (_menuSelection == 5) { _increment = 1000.0d; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Prograde:" + Format.GetNumberString(_maneuver.DeltaV.z) + "m/s", GUILayout.MinWidth(200.0f)); if (GUILayout.Button("-")) { Vector3d dv = _maneuver.DeltaV; dv.z -= _increment; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } if (GUILayout.Button("0")) { Vector3d dv = _maneuver.DeltaV; dv.z = 0.0d; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } if (GUILayout.Button("+")) { Vector3d dv = _maneuver.DeltaV; dv.z += _increment; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Normal :" + Format.GetNumberString(_maneuver.DeltaV.y) + "m/s", GUILayout.MinWidth(200.0f)); if (GUILayout.Button("-")) { Vector3d dv = _maneuver.DeltaV; dv.y -= _increment; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } if (GUILayout.Button("0")) { Vector3d dv = _maneuver.DeltaV; dv.y = 0.0d; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } if (GUILayout.Button("+")) { Vector3d dv = _maneuver.DeltaV; dv.y += _increment; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Radial :" + Format.GetNumberString(_maneuver.DeltaV.x) + "m/s", GUILayout.MinWidth(200.0f)); if (GUILayout.Button("-")) { Vector3d dv = _maneuver.DeltaV; dv.x -= _increment; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } if (GUILayout.Button("0")) { Vector3d dv = _maneuver.DeltaV; dv.x = 0.0d; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } if (GUILayout.Button("+")) { Vector3d dv = _maneuver.DeltaV; dv.x += _increment; _maneuver.OnGizmoUpdated(dv, _maneuver.UT); } GUILayout.EndHorizontal(); double ut = _maneuver.UT; double utUpdate = _timeControl.TimeGUI(ut, FlightGlobals.ActiveVessel); if (utUpdate != ut) { _maneuver.OnGizmoUpdated(_maneuver.DeltaV, utUpdate); } GUILayout.BeginHorizontal(); if (GUILayout.Button("=10min")) { _maneuver.OnGizmoUpdated(_maneuver.DeltaV, Planetarium.GetUniversalTime() + (10.0 * 60.0)); } double period = _maneuver.patch.period; if (GUILayout.Button("-10 Orbit") && period > 0 && -timeToNode > 10.0 * period) { _maneuver.OnGizmoUpdated(_maneuver.DeltaV, _maneuver.UT - (10.0 * period)); } if (GUILayout.Button("-1 Orbit") && period > 0 && -timeToNode > period) { _maneuver.OnGizmoUpdated(_maneuver.DeltaV, _maneuver.UT - period); } if (GUILayout.Button("+1 Orbit") && period > 0) { _maneuver.OnGizmoUpdated(_maneuver.DeltaV, _maneuver.UT + period); } if (GUILayout.Button("+10 Orbit") && period > 0) { _maneuver.OnGizmoUpdated(_maneuver.DeltaV, _maneuver.UT + (10.0 * period)); } GUILayout.EndHorizontal(); } else { _windowPos.height = 0; } } else if (_maneuver != null) { _maneuver = null; _windowPos.height = 0; } GUILayout.EndVertical(); GUI.DragWindow(); }
public void PlaceNode(List <string> ids, List <System.Object> output) { double dr = 0, dn = 0, dp = 0; double UT = 0; // Look at the resulting variables and create a maneuver node with them for (int i = 0; i < ids.Count; i++) { if (output[i].GetType() != typeof(double)) { continue; } string id = ids[i]; double val = (double)output[i]; if (id == "Δv_r" || id == "dv_r") { dr = val; } else if (id == "Δv_n" || id == "dv_n") { dn = val; } else if (id == "Δv_p" || id == "dv_p") { dp = val; } else if (id == "Δt" || id == "dt") { UT = val + Planetarium.GetUniversalTime(); } } Vector3d dV = new Vector3d(dr, dn, dp); Vessel vessel = FlightGlobals.ActiveVessel; if (vessel == null) { return; } //placing a maneuver node with bad dV values can really mess up the game, so try to protect against that //and log an exception if we get a bad dV vector: for (int i = 0; i < 3; i++) { if (double.IsNaN(dV[i]) || double.IsInfinity(dV[i])) { throw new Exception("Kerbulator: bad dV: " + dV); } } if (double.IsNaN(UT) || double.IsInfinity(UT)) { throw new Exception("Kerbulator: bad UT: " + UT); } //It seems that sometimes the game can freak out if you place a maneuver node in the past, so this //protects against that. UT = Math.Max(UT, Planetarium.GetUniversalTime()); ManeuverNode mn = vessel.patchedConicSolver.AddManeuverNode(UT); mn.OnGizmoUpdated(dV, UT); }
private void UpdateAll() { nodeRef.OnGizmoUpdated(new Vector3d(radOut, norm, pro), time); }
internal void createManeuverNode(PatchedConicSolver p) { ManeuverNode newnode = p.AddManeuverNode(UT); newnode.OnGizmoUpdated(deltaV, UT); }
protected override void WindowGUI(int windowID) { if (vessel.patchedConicSolver.maneuverNodes.Count == 0) { GUILayout.Label("No maneuver nodes to edit."); RelativityModeSelectUI(); base.WindowGUI(windowID); return; } GUILayout.BeginVertical(); ManeuverNode oldNode = node; if (vessel.patchedConicSolver.maneuverNodes.Count == 1) { node = vessel.patchedConicSolver.maneuverNodes[0]; } else { if (!vessel.patchedConicSolver.maneuverNodes.Contains(node)) { node = vessel.patchedConicSolver.maneuverNodes[0]; } int nodeIndex = vessel.patchedConicSolver.maneuverNodes.IndexOf(node); int numNodes = vessel.patchedConicSolver.maneuverNodes.Count; nodeIndex = GuiUtils.ArrowSelector(nodeIndex, numNodes, "Maneuver node #" + (nodeIndex + 1)); node = vessel.patchedConicSolver.maneuverNodes[nodeIndex]; } if (node != oldNode) { prograde = node.DeltaV.z; radialPlus = node.DeltaV.x; normalPlus = node.DeltaV.y; } if (gizmo != node.attachedGizmo) { if (gizmo != null) { gizmo.OnGizmoUpdated -= GizmoUpdateHandler; } gizmo = node.attachedGizmo; if (gizmo != null) { gizmo.OnGizmoUpdated += GizmoUpdateHandler; } } GUILayout.BeginHorizontal(); GuiUtils.SimpleTextBox("Prograde:", prograde, "m/s", 60); if (LimitedRepeatButtoon("-")) { prograde -= progradeDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } progradeDelta.text = GUILayout.TextField(progradeDelta.text, GUILayout.Width(50)); if (LimitedRepeatButtoon("+")) { prograde += progradeDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } GUILayout.Label("m/s", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GuiUtils.SimpleTextBox("Radial+:", radialPlus, "m/s", 60); if (LimitedRepeatButtoon("-")) { radialPlus -= radialPlusDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } radialPlusDelta.text = GUILayout.TextField(radialPlusDelta.text, GUILayout.Width(50)); if (LimitedRepeatButtoon("+")) { radialPlus += radialPlusDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } GUILayout.Label("m/s", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GuiUtils.SimpleTextBox("Normal+:", normalPlus, "m/s", 60); if (LimitedRepeatButtoon("-")) { normalPlus -= normalPlusDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } normalPlusDelta.text = GUILayout.TextField(normalPlusDelta.text, GUILayout.Width(50)); if (LimitedRepeatButtoon("+")) { normalPlus += normalPlusDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } GUILayout.Label("m/s", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Set delta to:", GUILayout.ExpandWidth(true)); if (GUILayout.Button("0.01", GUILayout.ExpandWidth(true))) { progradeDelta = radialPlusDelta = normalPlusDelta = 0.01; } if (GUILayout.Button("0.1", GUILayout.ExpandWidth(true))) { progradeDelta = radialPlusDelta = normalPlusDelta = 0.1; } if (GUILayout.Button("1", GUILayout.ExpandWidth(true))) { progradeDelta = radialPlusDelta = normalPlusDelta = 1; } if (GUILayout.Button("10", GUILayout.ExpandWidth(true))) { progradeDelta = radialPlusDelta = normalPlusDelta = 10; } if (GUILayout.Button("100", GUILayout.ExpandWidth(true))) { progradeDelta = radialPlusDelta = normalPlusDelta = 100; } GUILayout.EndHorizontal(); if (GUILayout.Button("Update")) { node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } GUILayout.BeginHorizontal(); GUILayout.Label("Shift time", GUILayout.ExpandWidth(true)); if (GUILayout.Button("-o", GUILayout.ExpandWidth(false))) { node.OnGizmoUpdated(node.DeltaV, node.UT - node.patch.period); } if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) { node.OnGizmoUpdated(node.DeltaV, node.UT - timeOffset); } timeOffset.text = GUILayout.TextField(timeOffset.text, GUILayout.Width(100)); if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) { node.OnGizmoUpdated(node.DeltaV, node.UT + timeOffset); } if (GUILayout.Button("+o", GUILayout.ExpandWidth(false))) { node.OnGizmoUpdated(node.DeltaV, node.UT + node.patch.period); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Snap node to", GUILayout.ExpandWidth(true))) { Orbit o = node.patch; double UT = node.UT; switch (snap) { case Snap.PERIAPSIS: UT = o.NextPeriapsisTime(UT - o.period / 2); //period is who-knows-what for e > 1, but this should still work break; case Snap.APOAPSIS: if (o.eccentricity < 1) { UT = o.NextApoapsisTime(UT - o.period / 2); } break; case Snap.EQ_ASCENDING: if (o.AscendingNodeEquatorialExists()) { UT = o.TimeOfAscendingNodeEquatorial(UT - o.period / 2); } break; case Snap.EQ_DESCENDING: if (o.DescendingNodeEquatorialExists()) { UT = o.TimeOfDescendingNodeEquatorial(UT - o.period / 2); } break; case Snap.REL_ASCENDING: if (core.target.NormalTargetExists && core.target.TargetOrbit.referenceBody == o.referenceBody) { if (o.AscendingNodeExists(core.target.TargetOrbit)) { UT = o.TimeOfAscendingNode(core.target.TargetOrbit, UT - o.period / 2); } } break; case Snap.REL_DESCENDING: if (core.target.NormalTargetExists && core.target.TargetOrbit.referenceBody == o.referenceBody) { if (o.DescendingNodeExists(core.target.TargetOrbit)) { UT = o.TimeOfDescendingNode(core.target.TargetOrbit, UT - o.period / 2); } } break; } node.OnGizmoUpdated(node.DeltaV, UT); } snap = (Snap)GuiUtils.ArrowSelector((int)snap, numSnaps, snapStrings[(int)snap]); GUILayout.EndHorizontal(); RelativityModeSelectUI(); if (core.node != null) { if (vessel.patchedConicSolver.maneuverNodes.Count > 0 && !core.node.enabled) { if (GUILayout.Button("Execute next node")) { core.node.ExecuteOneNode(this); } if (vessel.patchedConicSolver.maneuverNodes.Count > 1) { if (GUILayout.Button("Execute all nodes")) { core.node.ExecuteAllNodes(this); } } } else if (core.node.enabled) { if (GUILayout.Button("Abort node execution")) { core.node.Abort(); } } GUILayout.BeginHorizontal(); core.node.autowarp = GUILayout.Toggle(core.node.autowarp, "Auto-warp", GUILayout.ExpandWidth(true)); GUILayout.Label("Tolerance:", GUILayout.ExpandWidth(false)); core.node.tolerance.text = GUILayout.TextField(core.node.tolerance.text, GUILayout.Width(35), GUILayout.ExpandWidth(false)); GUILayout.Label("m/s", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); } GUILayout.EndVertical(); base.WindowGUI(windowID); }
protected override void WindowGUI(int windowID) { if (vessel.patchedConicSolver.maneuverNodes.Count == 0) { GUILayout.Label("No maneuver nodes to edit."); GUI.DragWindow(); return; } GUILayout.BeginVertical(); ManeuverNode oldNode = node; if (vessel.patchedConicSolver.maneuverNodes.Count == 1) { node = vessel.patchedConicSolver.maneuverNodes[0]; } else { if (!vessel.patchedConicSolver.maneuverNodes.Contains(node)) { node = vessel.patchedConicSolver.maneuverNodes[0]; } int nodeIndex = vessel.patchedConicSolver.maneuverNodes.IndexOf(node); int numNodes = vessel.patchedConicSolver.maneuverNodes.Count; nodeIndex = GuiUtils.ArrowSelector(nodeIndex, numNodes, "Maneuver node #" + (nodeIndex + 1)); node = vessel.patchedConicSolver.maneuverNodes[nodeIndex]; } if (node != oldNode) { prograde = node.DeltaV.z; radialPlus = node.DeltaV.x; normalPlus = -node.DeltaV.y; } if (gizmo != node.attachedGizmo) { if (gizmo != null) { gizmo.OnGizmoUpdated -= GizmoUpdateHandler; } gizmo = node.attachedGizmo; if (gizmo != null) { gizmo.OnGizmoUpdated += GizmoUpdateHandler; } } GUILayout.BeginHorizontal(); GuiUtils.SimpleTextBox("Prograde:", prograde, "m/s", 60); if (GUILayout.Button("Add", GUILayout.ExpandWidth(false))) { prograde += progradeDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } progradeDelta.text = GUILayout.TextField(progradeDelta.text, GUILayout.Width(50)); GUILayout.Label("m/s", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GuiUtils.SimpleTextBox("Radial+:", radialPlus, "m/s", 60); if (GUILayout.Button("Add", GUILayout.ExpandWidth(false))) { radialPlus += radialPlusDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } radialPlusDelta.text = GUILayout.TextField(radialPlusDelta.text, GUILayout.Width(50)); GUILayout.Label("m/s", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GuiUtils.SimpleTextBox("Normal+:", normalPlus, "m/s", 60); if (GUILayout.Button("Add", GUILayout.ExpandWidth(false))) { normalPlus += normalPlusDelta; node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } normalPlusDelta.text = GUILayout.TextField(normalPlusDelta.text, GUILayout.Width(50)); GUILayout.Label("m/s", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); if (GUILayout.Button("Update")) { node.OnGizmoUpdated(new Vector3d(radialPlus, normalPlus, prograde), node.UT); } GUILayout.BeginHorizontal(); if (GUILayout.Button("Shift time by", GUILayout.ExpandWidth(true))) { node.OnGizmoUpdated(node.DeltaV, node.UT + timeOffset); } timeOffset.text = GUILayout.TextField(timeOffset.text, GUILayout.Width(100)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Snap node to", GUILayout.ExpandWidth(true))) { Orbit o = node.patch; double UT = node.UT; switch (snap) { case Snap.PERIAPSIS: UT = o.NextPeriapsisTime(UT - o.period / 2); //period is who-knows-what for e > 1, but this should still work break; case Snap.APOAPSIS: if (o.eccentricity < 1) { UT = o.NextApoapsisTime(UT - o.period / 2); } break; case Snap.EQ_ASCENDING: if (o.AscendingNodeEquatorialExists()) { UT = o.TimeOfAscendingNodeEquatorial(UT - o.period / 2); } break; case Snap.EQ_DESCENDING: if (o.DescendingNodeEquatorialExists()) { UT = o.TimeOfDescendingNodeEquatorial(UT - o.period / 2); } break; case Snap.REL_ASCENDING: if (core.target.NormalTargetExists && core.target.Orbit.referenceBody == o.referenceBody) { if (o.AscendingNodeExists(core.target.Orbit)) { UT = o.TimeOfAscendingNode(core.target.Orbit, UT - o.period / 2); } } break; case Snap.REL_DESCENDING: if (core.target.NormalTargetExists && core.target.Orbit.referenceBody == o.referenceBody) { if (o.DescendingNodeExists(core.target.Orbit)) { UT = o.TimeOfDescendingNode(core.target.Orbit, UT - o.period / 2); } } break; } node.OnGizmoUpdated(node.DeltaV, UT); } snap = (Snap)GuiUtils.ArrowSelector((int)snap, numSnaps, snapStrings[(int)snap]); GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUI.DragWindow(); }
public void UpdateAll() { nodeRef.OnGizmoUpdated(new Vector3d(RadOut, Norm, Pro), Time); }
private void ToNodeRef() { nodeRef.OnGizmoUpdated(new Vector3d(radialOut, normal, prograde), time); }
protected void MaintainAerobrakeNode() { if (makeAerobrakeNodes) { //Remove node after finishing aerobraking: if (aerobrakeNode != null && vessel.patchedConicSolver.maneuverNodes.Contains(aerobrakeNode)) { if (aerobrakeNode.UT < vesselState.time && vesselState.altitudeASL > mainBody.RealMaxAtmosphereAltitude()) { vessel.patchedConicSolver.RemoveManeuverNode(aerobrakeNode); aerobrakeNode = null; } } //Update or create node if necessary: ReentrySimulation.Result r = Result; if (r != null && r.outcome == ReentrySimulation.Outcome.AEROBRAKED) { //Compute the node dV: Orbit preAerobrakeOrbit = GetReenteringPatch(); //Put the node at periapsis, unless we're past periapsis. In that case put the node at the current time. double UT; if (preAerobrakeOrbit == orbit && vesselState.altitudeASL < mainBody.RealMaxAtmosphereAltitude() && vesselState.speedVertical > 0) { UT = vesselState.time; } else { UT = preAerobrakeOrbit.NextPeriapsisTime(preAerobrakeOrbit.StartUT); } Orbit postAerobrakeOrbit = MuUtils.OrbitFromStateVectors(r.WorldAeroBrakePosition(), r.WorldAeroBrakeVelocity(), r.body, r.aeroBrakeUT); Vector3d dV = OrbitalManeuverCalculator.DeltaVToChangeApoapsis(preAerobrakeOrbit, UT, postAerobrakeOrbit.ApR); if (aerobrakeNode != null && vessel.patchedConicSolver.maneuverNodes.Contains(aerobrakeNode)) { //update the existing node Vector3d nodeDV = preAerobrakeOrbit.DeltaVToManeuverNodeCoordinates(UT, dV); aerobrakeNode.OnGizmoUpdated(nodeDV, UT); } else { //place a new node aerobrakeNode = vessel.PlaceManeuverNode(preAerobrakeOrbit, dV, UT); } } else { //no aerobraking, remove the node: if (aerobrakeNode != null && vessel.patchedConicSolver.maneuverNodes.Contains(aerobrakeNode)) { vessel.patchedConicSolver.RemoveManeuverNode(aerobrakeNode); } } } else { //Remove aerobrake node when it is turned off: if (aerobrakeNode != null && vessel.patchedConicSolver.maneuverNodes.Contains(aerobrakeNode)) { vessel.patchedConicSolver.RemoveManeuverNode(aerobrakeNode); } } }