/// <summary> /// Overridden function from MonoBehavior /// </summary> internal void Update() { if (!FlightDriver.Pause && canShowNodeEditor) { PatchedConicSolver solver = NodeTools.getSolver(); if (solver.maneuverNodes.Count > 0) { if (!curState.hasNode() || !solver.maneuverNodes.Contains(curState.node)) { // get the first one if we can't find the current or it's null curState = new NodeManager(solver.maneuverNodes[0]); } else if (curState.hasNode()) { curState.updateNode(); curState = curState.nextState(); } } else { if (curState.hasNode()) { curState = new NodeManager(); curState.resizeClockWindow = true; } } processKeyInput(); } intuitiveNodeGizmosManager.OnUpdate(); }
/// <summary> /// Draws the Conics window. /// </summary> /// <param name="id">Identifier.</param> public void drawConicsWindow(int id) { PatchedConicSolver solver = NodeTools.getSolver(); Color defaultColor = GUI.backgroundColor; GUILayout.BeginVertical(); // Conics mode controls GUILayout.BeginHorizontal(); GUILayout.Label("Conics mode: ", GUILayout.Width(100)); GUIParts.drawButton("0", (options.conicsMode == 0?Color.yellow:defaultColor), delegate() { options.setConicsMode(0); }); GUIParts.drawButton("1", (options.conicsMode == 1?Color.yellow:defaultColor), delegate() { options.setConicsMode(1); }); GUIParts.drawButton("2", (options.conicsMode == 2?Color.yellow:defaultColor), delegate() { options.setConicsMode(2); }); GUIParts.drawButton("3", (options.conicsMode == 3?Color.yellow:defaultColor), delegate() { options.setConicsMode(3); }); GUIParts.drawButton("4", (options.conicsMode == 4?Color.yellow:defaultColor), delegate() { options.setConicsMode(4); }); GUILayout.EndHorizontal(); // conics patch limit editor. GUILayout.BeginHorizontal(); GUILayout.Label("Change Conics Samples", GUILayout.Width(200)); GUIParts.drawButton("-", Color.red, delegate() { solver.DecreasePatchLimit(); }); GUIParts.drawButton("+", Color.red, delegate() { solver.IncreasePatchLimit(); }); GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUI.DragWindow(); }
public override void OnInitialize() { if (!HighLogic.LoadedSceneIsFlight || FlightGlobals.ActiveVessel == null || this.vessel == null) { return; } else if (this.vessel.patchedConicSolver == null) { return; } PatchedConicSolver p = this.vessel.patchedConicSolver; // don't load if we've already got nodes. if (p.maneuverNodes.Count > 0) { return; } foreach (NodeState n in nodes.nodes) { // make sure we have a UT here and that it's in the future if (n.UT > Planetarium.GetUniversalTime()) { n.createManeuverNode(p); } } }
private static double GetLowestPeA(PatchedConicSolver s, CelestialBody tgt, Orbit startPatch) { double Pe = double.MaxValue; int l = s.flightPlan.Count; for (int i = 0; i < l; i++) { Orbit o = s.flightPlan[i]; if (o == null) { continue; } if (o.StartUT < startPatch.StartUT) { continue; } //if (!o.activePatch) // continue; if (o.timeToPe > 0 && o.referenceBody == tgt && (o.StartUT + o.timeToPe < o.EndUT) && o.PeR > o.referenceBody.Radius && o.PeR < o.referenceBody.sphereOfInfluence) { if (Pe > o.PeA) { Pe = o.PeA; _closestTime = o.StartUT + o.timeToPe; } } } return(Pe); }
/// <summary> /// Gets the time until the next maneuver node, in seconds. -1 if none. /// </summary> /// <returns></returns> private static int SecondsUntilNode() { Vessel vessel = FlightGlobals.ActiveVessel; if (vessel == null) { return(-1); } PatchedConicSolver solver = vessel.patchedConicSolver; if (solver == null) { return(-1); } if ((solver.maneuverNodes == null) || (solver.maneuverNodes.Count == 0)) { return(-1); } ManeuverNode node = solver.maneuverNodes[0]; if (node == null) { return(-1); } double timeUntil = node.UT - Planetarium.GetUniversalTime(); if (timeUntil < 0) { return(-1); } return((int)timeUntil); }
private static double GetLowestPeA(PatchedConicSolver s) { double Pe = double.MaxValue; for (int i = _patchLimit - 1; i >= 0; i--) { Orbit o = s.patches[i]; if (o == null) { continue; } if (!o.activePatch) { continue; } if (o.timeToPe > 0 && o.referenceBody == _targetBody && (o.StartUT + o.timeToPe < o.EndUT) && o.PeR > o.referenceBody.Radius && o.PeR < o.referenceBody.sphereOfInfluence) { if (Pe > o.PeA) { Pe = o.PeA; _closestTime = o.StartUT + o.timeToPe; } } } return(Pe); }
/// <summary> /// Delete all the maneuver nodes for the active vessel. /// </summary> public static void ClearManeuverNodes() { PatchedConicSolver solver = FlightGlobals.ActiveVessel.patchedConicSolver; while (solver.maneuverNodes.Count > 0) { solver.maneuverNodes.First().RemoveSelf(); } }
private static Orbit GetReferencePatch(OrbitTargeter o, PatchedConicSolver s, CelestialBody tgt, CelestialBody tgtParent, bool vessel) { if (vessel) { for (int i = s.patchesAhead; i >= 0; i--) { Orbit patch = s.patches[i]; if (patch == null) { continue; } if (!patch.activePatch) { continue; } if (patch.referenceBody != tgt) { continue; } return(patch); } } else { for (int i = s.patchesAhead; i >= 0; i--) { Orbit patch = s.patches[i]; if (patch == null) { continue; } if (!patch.activePatch) { continue; } if (patch.referenceBody == tgt && i > 0) { return(s.patches[i - 1]); } else if (patch.referenceBody == tgtParent) { return(patch); } } } return(null); }
private void drawTripWindow() { PatchedConicSolver solver = NodeTools.getSolver(); GUILayout.BeginVertical(); if (solver.maneuverNodes.Count < 1) { GUILayout.BeginHorizontal(); GUILayout.Label("No nodes to show.", GUILayout.Width(200)); GUILayout.EndHorizontal(); } else { double total = 0.0; double timeNow = Planetarium.GetUniversalTime(); GUILayout.BeginHorizontal(); GUILayout.Label("", GUILayout.Width(60)); GUILayout.Label("Δv", GUILayout.Width(90)); GUILayout.Label("Time Until", GUILayout.Width(200)); GUILayout.Label("", GUILayout.Width(120)); GUILayout.EndHorizontal(); foreach (ManeuverNode curNode in solver.maneuverNodes) { int idx = solver.maneuverNodes.IndexOf(curNode); double timeDiff = curNode.UT - timeNow; GUILayout.BeginHorizontal(); GUILayout.Label("Node " + (idx + 1), GUILayout.Width(60)); GUILayout.Label(curNode.DeltaV.magnitude.ToString("F2") + " m/s", GUILayout.Width(90)); GUILayout.Label(timeDiff.convertUTtoHumanDuration(), GUILayout.Width(200)); if (idx > 0) { GUIParts.drawButton("▲ Merge", Color.white, () => { // schedule for next layout pass to not mess up maneuver nodes while iterating over them scheduledForLayout.Add(() => { solver.maneuverNodes[idx].mergeNodeDown(); }); }); } GUILayout.EndHorizontal(); total += curNode.DeltaV.magnitude; } GUILayout.BeginHorizontal(); GUILayout.Label("Total", GUILayout.Width(60)); GUILayout.Label(total.ToString("F2") + " m/s", GUILayout.Width(90)); GUILayout.Label("", GUILayout.Width(200)); GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUI.DragWindow(); }
// calculation function for mergeNodeDown private static Orbit findPreviousOrbit(this ManeuverNode n) { PatchedConicSolver p = NodeTools.getSolver(); int idx = p.maneuverNodes.IndexOf(n); if (idx > 0) { return(p.maneuverNodes[idx - 1].patch); } else { return(FlightGlobals.ActiveVessel.orbit); } }
public void drawTripWindow(int id) { PatchedConicSolver solver = NodeTools.getSolver(); GUILayout.BeginVertical(); if (solver.maneuverNodes.Count < 1) { GUILayout.BeginHorizontal(); GUILayout.Label("No nodes to show.", GUILayout.Width(200)); GUILayout.EndHorizontal(); } else { double total = 0.0; double timeNow = Planetarium.GetUniversalTime(); GUILayout.BeginHorizontal(); GUILayout.Label("", GUILayout.Width(60)); GUILayout.Label("Δv", GUILayout.Width(90)); GUILayout.Label("Time Until", GUILayout.Width(200)); GUILayout.Label("", GUILayout.Width(120)); GUILayout.EndHorizontal(); foreach (ManeuverNode curNode in solver.maneuverNodes) { int idx = solver.maneuverNodes.IndexOf(curNode); double timeDiff = curNode.UT - timeNow; GUILayout.BeginHorizontal(); GUILayout.Label("Node " + idx, GUILayout.Width(60)); GUILayout.Label(curNode.DeltaV.magnitude.ToString("F2") + "m/s", GUILayout.Width(90)); GUILayout.Label(NodeTools.convertUTtoHumanDuration(timeDiff), GUILayout.Width(200)); // these will be scheduled for during the next layout pass if (idx > 0) { GUIParts.drawButton("merge ▲", Color.white, delegate() { scheduledForLayout.Add(new Action(() => { NodeTools.mergeNodeDown(solver.maneuverNodes[idx]); })); }); } GUILayout.EndHorizontal(); total += curNode.DeltaV.magnitude; } GUILayout.BeginHorizontal(); GUILayout.Label("Total", GUILayout.Width(60)); GUILayout.Label(total.ToString("F2") + "m/s", GUILayout.Width(90)); GUILayout.Label("", GUILayout.Width(200)); GUILayout.EndHorizontal(); } GUILayout.EndVertical(); GUI.DragWindow(); }
private void drawManeuverPager() { PatchedConicSolver solver = NodeTools.getSolver(); int idx = solver.maneuverNodes.IndexOf(curState.node); int count = solver.maneuverNodes.Count; GUILayout.BeginHorizontal(); GUI.enabled = count > 1; if (GUILayout.Button("◀")) { if (idx > 0) { curState.nextNode = solver.maneuverNodes[idx - 1]; } else { curState.nextNode = solver.maneuverNodes[count - 1]; } curState.clearMemory(); } GUI.enabled = true; if (GUILayout.Button("Node " + (idx + 1))) { MapView.MapCamera.SetTarget(curState.node.scaledSpaceTarget); } GUIParts.drawButton("Del", Color.red, () => { curState.node.RemoveSelf(); //solver.RemoveManeuverNode(curState.node); curState.clearMemory(); }); GUI.enabled = count > 1; if (GUILayout.Button("▶")) { if (idx < (count - 1)) { curState.nextNode = solver.maneuverNodes[idx + 1]; } else { curState.nextNode = solver.maneuverNodes[0]; } curState.clearMemory(); } GUI.enabled = true; GUILayout.EndHorizontal(); }
public static Orbit getRefPatch(double UT, PatchedConicSolver pcs) { if (pcs == null) { return(null); } if (pcs.flightPlan.Count <= 0) { return(pcs.FindPatchContainingUT(UT)); } int l = pcs.flightPlan.Count; int start = 0; for (int i = 0; i < l; i++) { Orbit patch = pcs.flightPlan[i]; if (patch.patchStartTransition != Orbit.PatchTransitionType.MANEUVER) { continue; } start = i; break; } for (int i = start; i < l; i++) { Orbit patch = pcs.flightPlan[i]; double nextStart = patch.nextPatch == null ? patch.EndUT : patch.nextPatch.StartUT; //ManeuverController.maneuverLog("Patch: {0} - Start UT: {1:F2} - End UT: {2:F2} - Next Start UT: {3:F2}", logLevels.log, i, patch.StartUT, patch.EndUT, nextStart); if (UT >= patch.StartUT && UT < nextStart) { return(patch); } else if (patch.patchEndTransition == Orbit.PatchTransitionType.FINAL) { return(patch); } } return(null); }
internal void FixedUpdate() { if (!FlightDriver.Pause) { PatchedConicSolver solver = NodeTools.getSolver(); if (options.removeUsedNodes && solver.maneuverNodes.Count > 0) { ManeuverNode node = solver.maneuverNodes[0]; if (node.GetBurnVector(FlightGlobals.ActiveVessel.orbit).magnitude < options.usedNodeThreshold) { solver.RemoveManeuverNode(node); //TODO: Clean up states after removing the node. } } } }
private void UpdateIntuitiveManeuverHandlersList() { PatchedConicSolver solver = NodeTools.getSolver(); if (solver != null) { List <ManeuverNode> nodes = solver.maneuverNodes; for (int i = 0; i < nodes.Count; i++) { ManeuverNode node = nodes[i]; if ((node.attachedGizmo != null) && !isHandled(node)) { this.maneuverGizmoHandlers.Add(new IntuitiveNodeGizmoHandler(this, node, options)); } } } }
public static void drawManeuverPager(NodeManager curState) { PatchedConicSolver solver = NodeTools.getSolver(); GUILayout.BeginHorizontal(); if (GUILayout.Button("<")) { int count = solver.maneuverNodes.Count; if (count > 1) { // get the previous or last node int idx = solver.maneuverNodes.IndexOf(curState.node); if (idx == 0) { curState.nextNode = solver.maneuverNodes[--count]; } else { curState.nextNode = solver.maneuverNodes[--idx]; } } } if (GUILayout.Button("Editing Node " + (solver.maneuverNodes.IndexOf(curState.node) + 1))) { MapView.MapCamera.SetTarget(curState.node.scaledSpaceTarget); } if (GUILayout.Button(">")) { int count = solver.maneuverNodes.Count; if (count > 1) { // get the previous or last node int idx = solver.maneuverNodes.IndexOf(curState.node); if (idx == count - 1) { curState.nextNode = solver.maneuverNodes[0]; } else { curState.nextNode = solver.maneuverNodes[++idx]; } } } GUILayout.EndHorizontal(); }
/// <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); }
internal static void drawConicsControls(PreciseNodeOptions options) { PatchedConicSolver solver = NodeTools.getSolver(); Color defaultColor = GUI.backgroundColor; // Conics mode controls GUILayout.BeginHorizontal(); GUILayout.Label("Conics mode: ", GUILayout.Width(100)); for (int mode = 0; mode <= 4; mode++) { drawButton(mode.ToString(), (options.conicsMode == mode) ? Color.yellow : defaultColor, () => { options.setConicsMode(mode); }); } GUILayout.EndHorizontal(); // conics patch limit editor. GUILayout.BeginHorizontal(); GUILayout.Label("Change conics samples:", GUILayout.Width(200)); drawPlusMinusButtons(solver.IncreasePatchLimit, solver.DecreasePatchLimit); GUILayout.EndHorizontal(); }
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); } }
public void RunCalculations( Vessel vessel, Quaternion gymbal) { ManeuverPresent = false; // Calculations thanks to Mechjeb Vector3d CoM = vessel.findWorldCenterOfMass(); Vector3d velocityVesselOrbit = vessel.orbit.GetVel(); Vector3d velocityVesselOrbitUnit = velocityVesselOrbit.normalized; Vector3d velocityVesselSurface = velocityVesselOrbit - vessel.mainBody.getRFrmVel(CoM); Vector3d velocityVesselSurfaceUnit = velocityVesselSurface.normalized; ProgradeOrbit = gymbal * velocityVesselOrbitUnit; ProgradeSurface = gymbal * velocityVesselSurfaceUnit; PatchedConicSolver patchedConicSolver = vessel.patchedConicSolver; if (patchedConicSolver == null) { return; } if (patchedConicSolver.maneuverNodes == null) { return; } if (patchedConicSolver.maneuverNodes.Count > 0) { var manuever = patchedConicSolver.maneuverNodes[0]; ManeuverApplied = manuever.DeltaV != Vector3d.zero; Vector3d burnVector = manuever.GetBurnVector(vessel.orbit); ManeuverPlus = gymbal * burnVector.normalized; ManeuverPresent = true; } }
public static void Update() { _update = false; if (FlightGlobals.ActiveVessel == null || FlightGlobals.ActiveVessel.targetObject == null || FlightGlobals.ActiveVessel.targetObject.GetOrbit() == null || FlightGlobals.ActiveVessel.targetObject.GetOrbit().referenceBody == null || FlightGlobals.ActiveVessel.orbit == null || FlightGlobals.ActiveVessel.orbit.referenceBody == null) { _updated = false; return; } _updated = true; _targetOrbit = FlightGlobals.ActiveVessel.targetObject.GetOrbit(); Orbit active = FlightGlobals.ActiveVessel.orbit; _trueShipOrbit = active; if (active.referenceBody == Planetarium.fetch.Sun || active.referenceBody == FlightGlobals.ActiveVessel.targetObject.GetOrbit().referenceBody) { _shipOrbit = active; } else { _shipOrbit = FlightGlobals.ActiveVessel.orbit.referenceBody.orbit; } Vessel.Situations sit = FlightGlobals.ActiveVessel.situation; if ((sit |= Vessel.Situations.LANDED | Vessel.Situations.SPLASHED | Vessel.Situations.PRELAUNCH) == 0) { _vesselIntersect = false; _bodyIntersect = false; } else { if (!_isVessel && !_isCelestial) { _vesselIntersect = false; _bodyIntersect = false; } else { OrbitTargeter oTargeter = FlightGlobals.ActiveVessel.orbitTargeter; PatchedConicSolver solver = FlightGlobals.ActiveVessel.patchedConicSolver; if (oTargeter == null || solver == null) { _vesselIntersect = false; _bodyIntersect = false; } else if (!MapView.MapIsEnabled) { if (_isVessel) { _bodyIntersect = false; Orbit _refPatch = null; if (solver.maneuverNodes.Count > 0) { _refPatch = GetReferencePatch(oTargeter, solver, _targetOrbit.referenceBody, null, true); } else { _refPatch = BasicOrbitReflection.GetRefPatch(oTargeter); } Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter); _vesselIntersect = GetClosestVessel(_refPatch, _tgtRefPatch); } else { _vesselIntersect = false; double Pe = GetLowestPeA(solver); if (Pe < double.MaxValue - 1000) { _closestDist = Pe; _bodyIntersect = true; } else { Orbit _refPatch = null; if (solver.maneuverNodes.Count > 0) { _refPatch = GetReferencePatch(oTargeter, solver, _targetBody, _targetOrbit.referenceBody, false); } else { _refPatch = BasicOrbitReflection.GetRefPatch(oTargeter); } Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter); _bodyIntersect = GetClosestCelestial(_refPatch, _tgtRefPatch); } } } else { if (_markers == null || _markers.Count <= 0) { _markers = BasicOrbitReflection.GetOrbitMarkers(oTargeter); } if (_markers == null || _markers.Count <= 0) { _vesselIntersect = false; _bodyIntersect = false; } else if (_isVessel) { _bodyIntersect = false; if (solver.maneuverNodes.Count > 0) { Orbit _refPatch = GetReferencePatch(oTargeter, solver, _targetOrbit.referenceBody, null, true); Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter); _vesselIntersect = GetClosestVessel(_refPatch, _tgtRefPatch); } else { OrbitTargeter.ISectMarker _intersectOne = null; OrbitTargeter.ISectMarker _intersectTwo = null; for (int i = _markers.Count - 1; i >= 0; i--) { OrbitTargeter.Marker m = _markers[i]; if (m == null) { continue; } if (!(m is OrbitTargeter.ISectMarker)) { continue; } int num = ((OrbitTargeter.ISectMarker)m).num; if (num == 1) { _intersectOne = m as OrbitTargeter.ISectMarker; } else if (num == 2) { _intersectTwo = m as OrbitTargeter.ISectMarker; } } OrbitTargeter.ISectMarker _closestIntersect = null; if (_intersectOne != null && _intersectTwo != null) { _closestIntersect = _intersectOne.separation > _intersectTwo.separation ? _intersectTwo : _intersectOne; } else if (_intersectOne != null) { _closestIntersect = _intersectOne; } else if (_intersectTwo != null) { _closestIntersect = _intersectTwo; } else { _closestIntersect = null; } if (_closestIntersect == null) { _vesselIntersect = false; } else { _vesselIntersect = true; _closestDist = _closestIntersect.separation * 1000; _closestRelVel = _closestIntersect.relSpeed; _closestTime = _closestIntersect.UT; } } } else { _vesselIntersect = false; double Pe = GetLowestPeA(solver); if (Pe < double.MaxValue - 1000) { _closestDist = Pe; _bodyIntersect = true; } else { if (solver.maneuverNodes.Count > 0) { Orbit _refPatch = GetReferencePatch(oTargeter, solver, _targetBody, _targetOrbit.referenceBody, false); Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter); _bodyIntersect = GetClosestCelestial(_refPatch, _tgtRefPatch); } else { OrbitTargeter.ClApprMarker _approach = null; for (int i = _markers.Count - 1; i >= 0; i--) { OrbitTargeter.Marker m = _markers[i]; if (m == null) { continue; } if (!(m is OrbitTargeter.ClApprMarker)) { continue; } _approach = m as OrbitTargeter.ClApprMarker; } if (_approach == null) { _bodyIntersect = false; } else { _bodyIntersect = true; _closestDist = _approach.separation * 1000; _closestTime = (_approach.dT * -1) + Planetarium.GetUniversalTime(); } } } } } } } }
/// <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(); }
private void Update() { if (!FlightGlobals.ready) { return; } if (orbitHUD == null || targetHUD == null || maneuverHUD == null) { return; } Vessel v = FlightGlobals.ActiveVessel; if (v == null) { return; } bool jumper = v.isEVA || v.vesselType == VesselType.Rover; bool highRadar = v.isEVA ? v.radarAltitude > 10 : v.radarAltitude > 5; if (orbitHUD.IsVisible) { if (OrbitTimer < 4) { OrbitTimer++; } else { OrbitTimer = 0; bool pqs = v.mainBody != null && v.mainBody.pqsController != null; switch (v.situation) { case Vessel.Situations.LANDED: case Vessel.Situations.PRELAUNCH: vesselName.IsActive = true; apo.IsActive = apo.AlwaysShow; peri.IsActive = peri.AlwaysShow; inc.IsActive = inc.AlwaysShow; eqNode.IsActive = eqNode.AlwaysShow; ecc.IsActive = ecc.AlwaysShow; LAN.IsActive = LAN.AlwaysShow; AoPE.IsActive = AoPE.AlwaysShow; SMA.IsActive = SMA.AlwaysShow; period.IsActive = period.AlwaysShow; altitude.IsActive = altitude.AlwaysShow; radar.IsActive = radar.AlwaysShow; velocity.IsActive = true; location.IsActive = true; terrain.IsActive = pqs || terrain.AlwaysShow; break; case Vessel.Situations.SPLASHED: vesselName.IsActive = true; apo.IsActive = apo.AlwaysShow; peri.IsActive = peri.AlwaysShow; inc.IsActive = inc.AlwaysShow; eqNode.IsActive = eqNode.AlwaysShow; ecc.IsActive = ecc.AlwaysShow; LAN.IsActive = LAN.AlwaysShow; AoPE.IsActive = AoPE.AlwaysShow; SMA.IsActive = SMA.AlwaysShow; period.IsActive = period.AlwaysShow; altitude.IsActive = altitude.AlwaysShow; velocity.IsActive = true; location.IsActive = true; radar.IsActive = pqs || radar.AlwaysShow; terrain.IsActive = pqs || terrain.AlwaysShow; break; case Vessel.Situations.FLYING: vesselName.IsActive = true; apo.IsActive = apo.AlwaysShow || (v.orbit.eccentricity < 1 && (!jumper || highRadar)); radar.IsActive = radar.AlwaysShow || (pqs && (!jumper || highRadar)); terrain.IsActive = terrain.AlwaysShow || pqs; location.IsActive = true; velocity.IsActive = true; inc.IsActive = inc.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 3; eqNode.IsActive = eqNode.AlwaysShow || (v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 3 && (Math.Abs(v.orbit.inclination) > 0.0001 && Math.Abs(v.orbit.inclination) < 179.9999)); altitude.IsActive = altitude.AlwaysShow || (!pqs && (!jumper || highRadar)); LAN.IsActive = LAN.AlwaysShow; AoPE.IsActive = AoPE.AlwaysShow; SMA.IsActive = SMA.AlwaysShow; ecc.IsActive = ecc.AlwaysShow; peri.IsActive = peri.AlwaysShow || (v.orbit.PeA > 0 && ((!jumper || highRadar))); period.IsActive = period.AlwaysShow; break; case Vessel.Situations.SUB_ORBITAL: vesselName.IsActive = true; apo.IsActive = apo.AlwaysShow || (v.orbit.eccentricity < 1 && (!jumper || highRadar)); inc.IsActive = inc.AlwaysShow || !jumper || highRadar; eqNode.IsActive = eqNode.AlwaysShow || ((!jumper || highRadar) && (Math.Abs(v.orbit.inclination) > 0.0001 && Math.Abs(v.orbit.inclination) < 179.9999)); ecc.IsActive = ecc.AlwaysShow || !jumper || highRadar; location.IsActive = true; velocity.IsActive = true; radar.IsActive = radar.AlwaysShow || (pqs && (!jumper || highRadar)); terrain.IsActive = terrain.AlwaysShow || pqs; altitude.IsActive = altitude.AlwaysShow || (!pqs && (!jumper || highRadar)); if (v.orbit.PeA < 0) { peri.IsActive = peri.AlwaysShow || ((Math.Abs(v.orbit.PeA) < v.mainBody.Radius || (v.orbit.eccentricity >= 1 && v.orbit.timeToPe > 0)) && (!jumper || highRadar)); } else { peri.IsActive = peri.AlwaysShow || ((v.orbit.eccentricity < 1 || v.orbit.timeToPe > 0) && (!jumper || highRadar)); } LAN.IsActive = LAN.AlwaysShow; AoPE.IsActive = AoPE.AlwaysShow; SMA.IsActive = SMA.AlwaysShow; period.IsActive = period.AlwaysShow; break; default: vesselName.IsActive = true; apo.IsActive = apo.AlwaysShow || v.orbit.eccentricity < 1; peri.IsActive = peri.AlwaysShow || v.orbit.eccentricity < 1 || v.orbit.timeToPe > 0; inc.IsActive = true; eqNode.IsActive = eqNode.AlwaysShow || (Math.Abs(v.orbit.inclination) > 0.0001 && Math.Abs(v.orbit.inclination) < 179.9999); ecc.IsActive = true; LAN.IsActive = true; AoPE.IsActive = true; SMA.IsActive = true; period.IsActive = period.AlwaysShow || v.orbit.eccentricity < 1; altitude.IsActive = true; velocity.IsActive = velocity.AlwaysShow; location.IsActive = location.AlwaysShow; radar.IsActive = (v.altitude < (v.mainBody.minOrbitalDistance - v.mainBody.Radius) && pqs) || radar.AlwaysShow; terrain.IsActive = (v.altitude < (v.mainBody.minOrbitalDistance - v.mainBody.Radius) && pqs) || terrain.AlwaysShow; break; } } if ((terrain.IsActive && terrain.IsVisible) || (radar.IsActive && radar.IsVisible)) { BasicOrbiting.Update(); } } bool targetFlag = true; if (targetHUD.IsVisible) { if (!BasicTargetting.TargetValid()) { targetName.IsActive = false; closest.IsActive = false; distance.IsActive = false; relInc.IsActive = false; relVel.IsActive = false; angToPro.IsActive = false; closestVel.IsActive = false; phaseAngle.IsActive = false; targetFlag = false; BasicTargetting.UpdateOn = false; } else { if (TargetTimer < 3) { TargetTimer++; BasicTargetting.UpdateOn = false; } else { TargetTimer = 0; switch (v.situation) { case Vessel.Situations.LANDED: case Vessel.Situations.PRELAUNCH: case Vessel.Situations.SPLASHED: targetName.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; angToPro.IsActive = angToPro.AlwaysShow && BasicTargetting.ShowAngle && BasicTargetting.IsCelestial; phaseAngle.IsActive = phaseAngle.AlwaysShow && BasicTargetting.ShowPhasing; closest.IsActive = closest.AlwaysShow && ((BasicTargetting.IsCelestial && BasicTargetting.BodyIntersect) || (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect)); closestVel.IsActive = closestVel.AlwaysShow && BasicTargetting.IsVessel && BasicTargetting.VesselIntersect; distance.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; relVel.IsActive = relVel.AlwaysShow && (BasicTargetting.IsCelestial || BasicTargetting.IsVessel); relInc.IsActive = relInc.AlwaysShow && (BasicTargetting.IsCelestial || BasicTargetting.IsVessel); break; case Vessel.Situations.FLYING: targetName.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; angToPro.IsActive = (angToPro.AlwaysShow && BasicTargetting.ShowAngle && BasicTargetting.IsCelestial) && (!jumper || highRadar); phaseAngle.IsActive = (phaseAngle.AlwaysShow && BasicTargetting.ShowPhasing) && (!jumper || highRadar); closest.IsActive = ((BasicTargetting.IsCelestial && BasicTargetting.BodyIntersect) || (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect)) && (closest.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold); closestVel.IsActive = (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect) && (closestVel.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold); distance.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; relVel.IsActive = (BasicTargetting.IsCelestial || BasicTargetting.IsVessel) && (relVel.AlwaysShow || !jumper || highRadar); relInc.IsActive = (BasicTargetting.IsCelestial || BasicTargetting.IsVessel) && (relInc.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 3); break; default: targetName.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; angToPro.IsActive = (BasicTargetting.ShowAngle && (BasicTargetting.IsCelestial || BasicTargetting.IsVessel)) && (angToPro.AlwaysShow || !jumper || highRadar); phaseAngle.IsActive = BasicTargetting.ShowPhasing && (phaseAngle.AlwaysShow || !jumper || highRadar); closest.IsActive = ((BasicTargetting.IsCelestial && BasicTargetting.BodyIntersect) || (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect)) && (closest.AlwaysShow || !jumper || highRadar); closestVel.IsActive = (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect) && (closestVel.AlwaysShow || !jumper || highRadar); distance.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; relVel.IsActive = (BasicTargetting.IsCelestial || BasicTargetting.IsVessel) && (relVel.AlwaysShow || !jumper || highRadar); relInc.IsActive = (BasicTargetting.IsCelestial || BasicTargetting.IsVessel) && (relInc.AlwaysShow || !jumper || highRadar); break; } if (AnyTargetActive()) { BasicTargetting.UpdateOn = true; } else { BasicTargetting.UpdateOn = false; } } } } else { BasicTargetting.UpdateOn = false; } if (BasicTargetting.UpdateOn) { BasicTargetting.Update(); } if (maneuverHUD.IsVisible) { if (!targetHUD.IsVisible) { if (!BasicTargetting.TargetValid()) { targetFlag = false; } } PatchedConicSolver solver = v.patchedConicSolver; if (solver == null || solver.maneuverNodes.Count <= 0) { maneuver.IsActive = false; burnTime.IsActive = false; maneuverApoapsis.IsActive = false; maneuverPeriapsis.IsActive = false; maneuverInclination.IsActive = false; maneuverEccentricity.IsActive = false; maneuverAngleToPro.IsActive = false; maneuverPhaseAngle.IsActive = false; maneuverCloseApproach.IsActive = false; maneuverCloseRelVel.IsActive = false; BasicManeuvering.Updated = false; BasicManeuvering.UpdateOn = false; } else { if (ManeuverTimer < 3) { ManeuverTimer++; BasicManeuvering.UpdateOn = false; } else { ManeuverTimer = 0; switch (v.situation) { case Vessel.Situations.LANDED: case Vessel.Situations.PRELAUNCH: case Vessel.Situations.SPLASHED: maneuver.IsActive = maneuver.AlwaysShow; burnTime.IsActive = burnTime.AlwaysShow; maneuverApoapsis.IsActive = maneuverApoapsis.AlwaysShow; maneuverPeriapsis.IsActive = maneuverPeriapsis.AlwaysShow; maneuverInclination.IsActive = maneuverInclination.AlwaysShow; maneuverEccentricity.IsActive = maneuverEccentricity.AlwaysShow; maneuverAngleToPro.IsActive = targetFlag && maneuverAngleToPro.AlwaysShow && BasicManeuvering.ShowAngle && BasicTargetting.IsCelestial; maneuverPhaseAngle.IsActive = targetFlag && maneuverPhaseAngle.AlwaysShow && BasicManeuvering.ShowPhasing; maneuverCloseApproach.IsActive = targetFlag && maneuverCloseApproach.AlwaysShow && ((BasicTargetting.IsCelestial && BasicManeuvering.BodyIntersect) || (BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect)); maneuverCloseRelVel.IsActive = targetFlag && maneuverCloseRelVel.AlwaysShow && BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect; break; case Vessel.Situations.FLYING: maneuver.IsActive = maneuver.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2; burnTime.IsActive = burnTime.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2; maneuverApoapsis.IsActive = maneuverApoapsis.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2; maneuverPeriapsis.IsActive = maneuverPeriapsis.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2; maneuverInclination.IsActive = maneuverInclination.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2; maneuverEccentricity.IsActive = maneuverEccentricity.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2; maneuverAngleToPro.IsActive = (targetFlag && maneuverAngleToPro.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2) && BasicManeuvering.ShowAngle && BasicTargetting.IsCelestial; maneuverPhaseAngle.IsActive = (targetFlag && maneuverPhaseAngle.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2) && BasicManeuvering.ShowPhasing; maneuverCloseApproach.IsActive = targetFlag && ((BasicTargetting.IsCelestial && BasicManeuvering.BodyIntersect) || (BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect)) && (maneuverCloseApproach.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2); maneuverCloseRelVel.IsActive = targetFlag && BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect && (maneuverCloseRelVel.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2); break; default: Orbit nextPatch = solver.maneuverNodes[0].nextPatch; maneuver.IsActive = maneuver.AlwaysShow || !jumper || highRadar; burnTime.IsActive = burnTime.AlwaysShow || !jumper || highRadar; maneuverApoapsis.IsActive = maneuverApoapsis.AlwaysShow || ((nextPatch != null && nextPatch.eccentricity < 1) && (!jumper || highRadar)); maneuverPeriapsis.IsActive = maneuverPeriapsis.AlwaysShow || ((nextPatch != null && (nextPatch.eccentricity < 1 || nextPatch.timeToPe > 0)) && (!jumper || highRadar)); maneuverInclination.IsActive = maneuverInclination.AlwaysShow || !jumper || highRadar; maneuverEccentricity.IsActive = maneuverEccentricity.AlwaysShow || !jumper || highRadar; maneuverAngleToPro.IsActive = (targetFlag && BasicManeuvering.ShowAngle && (BasicTargetting.IsCelestial || BasicTargetting.IsVessel)) && (maneuverAngleToPro.AlwaysShow || !jumper || highRadar); maneuverPhaseAngle.IsActive = (targetFlag && BasicManeuvering.ShowPhasing) && (maneuverPhaseAngle.AlwaysShow || !jumper || highRadar); maneuverCloseApproach.IsActive = (targetFlag && ((BasicTargetting.IsCelestial && BasicManeuvering.BodyIntersect) || (BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect))) && (maneuverCloseApproach.AlwaysShow || !jumper || highRadar); maneuverCloseRelVel.IsActive = (targetFlag && BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect) && (maneuverCloseRelVel.AlwaysShow || !jumper || highRadar); break; } if (AnyManeuverActive()) { BasicManeuvering.UpdateOn = true; } else { BasicManeuvering.UpdateOn = false; } } } } else { BasicManeuvering.UpdateOn = false; } if (BasicManeuvering.UpdateOn) { BasicManeuvering.Update(targetFlag); } }
private void Update() { if (!FlightGlobals.ready) { return; } if (orbitHUD == null || targetHUD == null || maneuverHUD == null) { return; } Vessel v = FlightGlobals.ActiveVessel; if (v == null) { return; } if (orbitHUD.IsVisible) { switch (v.situation) { case Vessel.Situations.LANDED: case Vessel.Situations.PRELAUNCH: apo.IsActive = apo.AlwaysShow; peri.IsActive = peri.AlwaysShow; inc.IsActive = inc.AlwaysShow; ecc.IsActive = ecc.AlwaysShow; LAN.IsActive = LAN.AlwaysShow; AoPE.IsActive = AoPE.AlwaysShow; SMA.IsActive = SMA.AlwaysShow; period.IsActive = period.AlwaysShow; altitude.IsActive = altitude.AlwaysShow; radar.IsActive = radar.AlwaysShow; location.IsActive = true; terrain.IsActive = true; break; case Vessel.Situations.SPLASHED: apo.IsActive = apo.AlwaysShow; peri.IsActive = peri.AlwaysShow; inc.IsActive = inc.AlwaysShow; ecc.IsActive = ecc.AlwaysShow; LAN.IsActive = LAN.AlwaysShow; AoPE.IsActive = AoPE.AlwaysShow; SMA.IsActive = SMA.AlwaysShow; period.IsActive = period.AlwaysShow; altitude.IsActive = altitude.AlwaysShow; location.IsActive = true; radar.IsActive = true; terrain.IsActive = true; break; case Vessel.Situations.FLYING: apo.IsActive = apo.AlwaysShow || v.orbit.eccentricity < 1; radar.IsActive = true; terrain.IsActive = true; location.IsActive = true; inc.IsActive = inc.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 3; altitude.IsActive = altitude.AlwaysShow; LAN.IsActive = LAN.AlwaysShow; AoPE.IsActive = AoPE.AlwaysShow; SMA.IsActive = SMA.AlwaysShow; ecc.IsActive = ecc.AlwaysShow; peri.IsActive = v.orbit.PeA > 0; period.IsActive = period.AlwaysShow; break; case Vessel.Situations.SUB_ORBITAL: apo.IsActive = apo.AlwaysShow || v.orbit.eccentricity < 1; radar.IsActive = true; inc.IsActive = true; ecc.IsActive = true; location.IsActive = true; if (v.orbit.PeA < 0) { peri.IsActive = peri.AlwaysShow || Math.Abs(v.orbit.PeA) < v.mainBody.Radius / 5 || (v.orbit.eccentricity >= 1 && v.orbit.timeToPe > 0); } else { peri.IsActive = peri.AlwaysShow || v.orbit.eccentricity < 1 || v.orbit.timeToPe > 0; } altitude.IsActive = altitude.AlwaysShow; LAN.IsActive = LAN.AlwaysShow; AoPE.IsActive = AoPE.AlwaysShow; SMA.IsActive = SMA.AlwaysShow; period.IsActive = period.AlwaysShow; terrain.IsActive = terrain.AlwaysShow; break; default: apo.IsActive = apo.AlwaysShow || v.orbit.eccentricity < 1; peri.IsActive = peri.AlwaysShow || v.orbit.eccentricity < 1 || v.orbit.timeToPe > 0; inc.IsActive = true; ecc.IsActive = true; LAN.IsActive = true; AoPE.IsActive = true; SMA.IsActive = true; period.IsActive = period.AlwaysShow || v.orbit.eccentricity < 1; altitude.IsActive = true; location.IsActive = location.AlwaysShow; radar.IsActive = radar.AlwaysShow; terrain.IsActive = terrain.AlwaysShow; break; } } bool targetFlag = true; if (targetHUD.IsVisible) { if (!BasicTargetting.TargetValid()) { targetName.IsActive = false; closest.IsActive = false; distance.IsActive = false; relInc.IsActive = false; relVel.IsActive = false; angToPro.IsActive = false; closestVel.IsActive = false; targetFlag = false; BasicTargetting.UpdateOn = false; } else { switch (v.situation) { case Vessel.Situations.LANDED: case Vessel.Situations.PRELAUNCH: case Vessel.Situations.SPLASHED: targetName.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; angToPro.IsActive = angToPro.AlwaysShow && (BasicTargetting.IsCelestial && FlightGlobals.currentMainBody.referenceBody != null && FlightGlobals.currentMainBody.referenceBody != FlightGlobals.currentMainBody); closest.IsActive = closest.AlwaysShow && ((BasicTargetting.IsCelestial && BasicTargetting.BodyIntersect) || (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect)); closestVel.IsActive = closestVel.AlwaysShow && BasicTargetting.IsVessel && BasicTargetting.VesselIntersect; distance.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; relVel.IsActive = relVel.AlwaysShow && (BasicTargetting.IsCelestial || BasicTargetting.IsVessel); relInc.IsActive = relInc.AlwaysShow && (BasicTargetting.IsCelestial || BasicTargetting.IsVessel); break; case Vessel.Situations.FLYING: targetName.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; angToPro.IsActive = angToPro.AlwaysShow && (BasicTargetting.IsCelestial && FlightGlobals.currentMainBody.referenceBody != null && FlightGlobals.currentMainBody.referenceBody != FlightGlobals.currentMainBody); closest.IsActive = ((BasicTargetting.IsCelestial && BasicTargetting.BodyIntersect) || (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect)) && (closest.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold); closestVel.IsActive = (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect) && (closestVel.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold); distance.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; relVel.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; relInc.IsActive = (BasicTargetting.IsCelestial || BasicTargetting.IsVessel) && (relInc.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 3); break; default: targetName.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; angToPro.IsActive = BasicTargetting.IsCelestial && FlightGlobals.currentMainBody.referenceBody != null && FlightGlobals.currentMainBody.referenceBody != FlightGlobals.currentMainBody; closest.IsActive = (BasicTargetting.IsCelestial && BasicTargetting.BodyIntersect) || (BasicTargetting.IsVessel && BasicTargetting.VesselIntersect); closestVel.IsActive = BasicTargetting.IsVessel && BasicTargetting.VesselIntersect; distance.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; relVel.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; relInc.IsActive = BasicTargetting.IsCelestial || BasicTargetting.IsVessel; break; } BasicTargetting.UpdateOn = true; } } else { BasicTargetting.UpdateOn = false; } if (BasicTargetting.UpdateOn) { BasicTargetting.Update(); } if (maneuverHUD.IsVisible) { if (!targetHUD.IsVisible) { if (!BasicTargetting.TargetValid()) { targetFlag = false; } } PatchedConicSolver solver = v.patchedConicSolver; if (solver == null || solver.maneuverNodes.Count <= 0) { maneuver.IsActive = false; burnTime.IsActive = false; maneuverCloseApproach.IsActive = false; maneuverCloseRelVel.IsActive = false; BasicManeuvering.UpdateOn = false; } else { switch (v.situation) { case Vessel.Situations.LANDED: case Vessel.Situations.PRELAUNCH: case Vessel.Situations.SPLASHED: maneuver.IsActive = maneuver.AlwaysShow; burnTime.IsActive = burnTime.AlwaysShow; maneuverCloseApproach.IsActive = targetFlag && maneuverCloseApproach.AlwaysShow && ((BasicTargetting.IsCelestial && BasicManeuvering.BodyIntersect) || (BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect)); maneuverCloseRelVel.IsActive = targetFlag && maneuverCloseRelVel.AlwaysShow && BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect; break; case Vessel.Situations.FLYING: maneuver.IsActive = maneuver.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2; burnTime.IsActive = burnTime.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2; maneuverCloseApproach.IsActive = targetFlag && ((BasicTargetting.IsCelestial && BasicManeuvering.BodyIntersect) || (BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect)) && (maneuverCloseApproach.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2); maneuverCloseRelVel.IsActive = targetFlag && BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect && (maneuverCloseRelVel.AlwaysShow || v.altitude > v.mainBody.scienceValues.flyingAltitudeThreshold / 2); break; default: maneuver.IsActive = true; burnTime.IsActive = true; maneuverCloseApproach.IsActive = targetFlag && ((BasicTargetting.IsCelestial && BasicManeuvering.BodyIntersect) || (BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect)); maneuverCloseRelVel.IsActive = targetFlag && BasicTargetting.IsVessel && BasicManeuvering.VesselIntersect; break; } BasicManeuvering.UpdateOn = true; } } else { BasicManeuvering.UpdateOn = false; } if (BasicManeuvering.UpdateOn) { BasicManeuvering.Update(); } }
// Show exit orbital predictions private void ShowExitOrbit(Vessel nearObject, Vessel farObject) { // Recenter map, save previous state. wasInMapView = MapView.MapIsEnabled; if (!MapView.MapIsEnabled) { MapView.EnterMapView(); } MapObject mapObject = FindVesselBody(farObject); if ((UnityEngine.Object)mapObject != (UnityEngine.Object)null) { MapView.MapCamera.SetTarget(mapObject); } Vector3 mapCamPos = ScaledSpace.ScaledToLocalSpace(MapView.MapCamera.transform.position); Vector3 farTarPos = ScaledSpace.ScaledToLocalSpace(mapObject.transform.position); float dirScalar = Vector3.Distance(mapCamPos, farTarPos); //log.Debug("Initializing, camera distance is " + dirScalar); if (!IsPatchedConicsAvailable) { HideExitOrbit(); } else { predictionsDrawn = true; Vector3d vel = ESLDBeacon.GetJumpVelOffset(nearObject, farObject); if (predictionGameObject != null) { Destroy(predictionGameObject); } predictionGameObject = new GameObject("OrbitRendererGameObject"); predictionOrbitDriver = predictionGameObject.AddComponent <OrbitDriver>(); predictionOrbitDriver.orbit.referenceBody = farObject.mainBody; predictionOrbitDriver.orbit = new Orbit(); predictionOrbitDriver.referenceBody = farObject.mainBody; predictionOrbitDriver.upperCamVsSmaRatio = 999999f; // Took forever to figure this out - this sets at what zoom level the orbit appears. Was causing it not to appear at small bodies. predictionOrbitDriver.lowerCamVsSmaRatio = 0.0001f; predictionOrbitDriver.orbit.UpdateFromStateVectors(farObject.orbit.pos, vel, farObject.mainBody, Planetarium.GetUniversalTime()); predictionOrbitDriver.orbit.Init(); Vector3d relativePositionAtUT = predictionOrbitDriver.orbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()); Vector3d orbitalVelocityAtUT = predictionOrbitDriver.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()); predictionOrbitDriver.orbit.h = Vector3d.Cross(relativePositionAtUT, orbitalVelocityAtUT); predictionOrbitDriver.updateMode = OrbitDriver.UpdateMode.TRACK_Phys; predictionOrbitDriver.orbitColor = Color.red; predictionOrbitRenderer = predictionGameObject.AddComponent <OrbitRenderer>(); predictionOrbitRenderer.SetColor(Color.red); predictionOrbitRenderer.vessel = vessel; predictionOrbitDriver.vessel = vessel; predictionOrbitRenderer.upperCamVsSmaRatio = 999999f; predictionOrbitRenderer.lowerCamVsSmaRatio = 0.0001f; predictionOrbitRenderer.celestialBody = farObject.mainBody; predictionOrbitRenderer.driver = predictionOrbitDriver; predictionOrbitDriver.Renderer = predictionOrbitRenderer; if (true) { // This draws the full Patched Conics prediction. predictionPatchedConicSolver = predictionGameObject.AddComponent <PatchedConicSolver>(); predictionPatchedConicRenderer = predictionGameObject.AddComponent <PatchedConicRenderer>(); predictionOrbitRenderer.drawIcons = OrbitRendererBase.DrawIcons.NONE; predictionOrbitRenderer.drawMode = OrbitRendererBase.DrawMode.OFF; } #if false else { // This draws just the first patch, similar to a Level 1 tracking station. predictionOrbitRenderer.driver.drawOrbit = true; predictionOrbitRenderer.drawIcons = OrbitRenderer.DrawIcons.OBJ_PE_AP; predictionOrbitRenderer.drawMode = OrbitRenderer.DrawMode.REDRAW_AND_RECALCULATE; predictionOrbitRenderer.enabled = true; } #endif base.StartCoroutine(NullOrbitDriverVessels()); // Splash some color on it. // Directional indicator. /* * float baseWidth = 20.0f; * double baseStart = 10; * double baseEnd = 50; * oDirObj = new GameObject("Indicator"); * oDirObj.layer = 10; // Map layer! * oDirection = oDirObj.AddComponent<LineRenderer>(); * oDirection.useWorldSpace = false; * oOrigin = null; * foreach (Transform sstr in ScaledSpace.Instance.scaledSpaceTransforms) * { * if (sstr.name == far.mainBody.name) * { * oOrigin = sstr; * log.debug("Found origin: " + sstr.name); * break; * } * } * oDirection.transform.parent = oOrigin; * oDirection.transform.position = ScaledSpace.LocalToScaledSpace(far.transform.position); * oDirection.material = new Material(Shader.Find("Particles/Additive")); * oDirection.SetColors(Color.clear, Color.red); * if (dirScalar / 325000 > baseWidth) baseWidth = dirScalar / 325000f; * oDirection.SetWidth(baseWidth, 0.01f); * log.debug("Base Width set to " + baseWidth); * oDirection.SetVertexCount(2); * if (dirScalar / 650000 > baseStart) baseStart = dirScalar / 650000; * if (dirScalar / 130000 > baseEnd) baseEnd = dirScalar / 130000; * log.debug("Base Start set to " + baseStart); * log.debug("Base End set to " + baseEnd); * oDirection.SetPosition(0, Vector3d.zero + exitTraj.xzy.normalized * baseStart); * oDirection.SetPosition(1, exitTraj.xzy.normalized * baseEnd); * oDirection.enabled = true; */ } }
internal void createManeuverNode(PatchedConicSolver p) { ManeuverNode newnode = p.AddManeuverNode(UT); newnode.OnGizmoUpdated(deltaV, UT); }
private void OnVesselChange(Vessel vessel) { Logging.Log("Vessel changed to " + vessel.vesselName); solver = vessel.patchedConicSolver; }
public static void Update(bool target) { _update = false; if (FlightGlobals.ActiveVessel == null || FlightGlobals.ActiveVessel.patchedConicSolver == null) { _updated = false; return; } PatchedConicSolver solver = FlightGlobals.ActiveVessel.patchedConicSolver; _node = solver.maneuverNodes[0]; if (_node != null || _node.patch == null) { _maneuverTotal = _node.DeltaV.magnitude; _maneuverRemaining = _node.GetBurnVector(_node.patch).magnitude; if (BasicOrbitReflection.BetterBurnTimeLoaded) { if (_bbVesselModule == null || _bbVesselReference != FlightGlobals.ActiveVessel) { for (int i = FlightGlobals.ActiveVessel.vesselModules.Count - 1; i >= 0; i--) { VesselModule vMod = FlightGlobals.ActiveVessel.vesselModules[i]; if (vMod == null) { continue; } if (vMod.GetType().Name != _bbModuleName) { continue; } _bbVesselModule = vMod; _bbVesselReference = FlightGlobals.ActiveVessel; break; } } if (_bbVesselModule != null) { string type = _bbVesselModule.Fields[_bbTypeName].GetValue(_bbVesselModule).ToString(); if (type == "Maneuver") { _burnLength = _bbVesselModule.Fields[_bbLengthName].GetValue <double>(_bbVesselModule); _burnTime = _bbVesselModule.Fields[_bbTimeName].GetValue <double>(_bbVesselModule); if (double.IsNaN(_burnLength) || double.IsNaN(_burnTime)) { _bbTimeLoaded = false; _burnTime = _node.UT; _burnLength = 0; } else { double half = _burnLength / 2; _burnTime -= half; _bbTimeLoaded = true; } } else { _bbTimeLoaded = false; _burnTime = _node.UT; } } else { _bbTimeLoaded = false; _burnTime = _node.UT; } } else { _burnTime = _node.UT; } _showAngle = false; _showPhasing = false; _targetInclination = false; if (target) { if (!BasicTargetting.IsVessel && !BasicTargetting.IsCelestial) { _vesselIntersect = false; _bodyIntersect = false; } else { Orbit targetOrbit = FlightGlobals.ActiveVessel.targetObject.GetOrbit(); Orbit active = FlightGlobals.ActiveVessel.orbit; _targetPhasingOrbit = null; if (active.referenceBody == targetOrbit.referenceBody) { _phasingNodePatch = active; _targetPhasingOrbit = targetOrbit; _targetInclination = true; } else { if (active.referenceBody != Planetarium.fetch.Sun) { _showAngle = true; } _showPhasing = true; DrillDownOrbits(_node.patch, targetOrbit); } Vessel.Situations sit = FlightGlobals.ActiveVessel.situation; if ((sit |= Vessel.Situations.LANDED | Vessel.Situations.SPLASHED | Vessel.Situations.PRELAUNCH) == 0) { _vesselIntersect = false; _bodyIntersect = false; } else { OrbitTargeter oTargeter = FlightGlobals.ActiveVessel.orbitTargeter; if (oTargeter == null || solver == null) { _vesselIntersect = false; _bodyIntersect = false; } else if (!MapView.MapIsEnabled) { if (BasicTargetting.IsVessel) { _bodyIntersect = false; Vessel tgt = FlightGlobals.ActiveVessel.targetObject.GetVessel(); if (tgt == null || tgt.LandedOrSplashed) { _vesselIntersect = false; return; } Orbit _refPatch = BasicOrbitReflection.GetRefPatch(oTargeter); Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter); _vesselIntersect = GetClosestVessel(_refPatch, _tgtRefPatch); } else { _vesselIntersect = false; double Pe = GetLowestPeA(solver, BasicTargetting.TargetBody, _node.patch); if (Pe < BasicExtensions.AlmostMaxValue) { _closestDist = Pe; _bodyIntersect = true; } else { Orbit _refPatch = BasicOrbitReflection.GetRefPatch(oTargeter); Orbit _tgtRefPatch = BasicOrbitReflection.GetTargetRefPatch(oTargeter); if (_refPatch != null && _refPatch.closestTgtApprUT <= 0) { _bodyIntersect = false; return; } _bodyIntersect = GetClosestCelestial(_refPatch, _tgtRefPatch); } } } else { if (BasicTargetting.Markers == null || BasicTargetting.Markers.Count <= 0) { BasicTargetting.Markers = BasicOrbitReflection.GetOrbitMarkers(oTargeter); } if (BasicTargetting.IsVessel) { _bodyIntersect = false; OrbitTargeter.ISectMarker _intersectOne = null; OrbitTargeter.ISectMarker _intersectTwo = null; for (int i = BasicTargetting.Markers.Count - 1; i >= 0; i--) { OrbitTargeter.Marker m = BasicTargetting.Markers[i]; if (m == null) { continue; } if (!(m is OrbitTargeter.ISectMarker)) { continue; } int num = ((OrbitTargeter.ISectMarker)m).num; if (num == 1) { _intersectOne = m as OrbitTargeter.ISectMarker; } else if (num == 2) { _intersectTwo = m as OrbitTargeter.ISectMarker; } } OrbitTargeter.ISectMarker _closestIntersect = null; if (_intersectOne != null && _intersectTwo != null) { _closestIntersect = _intersectOne.separation > _intersectTwo.separation ? _intersectTwo : _intersectOne; } else if (_intersectOne != null) { _closestIntersect = _intersectOne; } else if (_intersectTwo != null) { _closestIntersect = _intersectTwo; } else { _closestIntersect = null; } if (_closestIntersect == null) { _vesselIntersect = false; } else { _vesselIntersect = true; _closestDist = _closestIntersect.separation * 1000; _closestRelVel = _closestIntersect.relSpeed; _closestTime = _closestIntersect.UT; } } else { _vesselIntersect = false; double Pe = GetLowestPeA(solver, BasicTargetting.TargetBody, _node.patch); if (Pe < BasicExtensions.AlmostMaxValue) { _closestDist = Pe; _bodyIntersect = true; } else { OrbitTargeter.ClApprMarker _approach = null; for (int i = BasicTargetting.Markers.Count - 1; i >= 0; i--) { OrbitTargeter.Marker m = BasicTargetting.Markers[i]; if (m == null) { continue; } if (!(m is OrbitTargeter.ClApprMarker)) { continue; } _approach = m as OrbitTargeter.ClApprMarker; } if (_approach == null) { _bodyIntersect = false; } else { _bodyIntersect = true; _closestDist = _approach.separation * 1000; _closestTime = (_approach.dT * -1) + Planetarium.GetUniversalTime(); } } } } } } } _updated = true; } }
/// <summary> /// Draws the Node Editor window. /// </summary> /// <param name="id">Identifier.</param> public void drawMainWindow(int id) { Color defaultColor = GUI.backgroundColor; Color contentColor = GUI.contentColor; Color curColor = defaultColor; PatchedConicSolver solver = NodeTools.getSolver(); // Options button if (showOptions) { GUI.backgroundColor = Color.green; } if (GUI.Button(new Rect(options.mainWindowPos.width - 48, 2, 22, 18), "O")) { showOptions = !showOptions; } GUI.backgroundColor = defaultColor; // Keymapping button if (showKeymapper) { GUI.backgroundColor = Color.green; } if (GUI.Button(new Rect(options.mainWindowPos.width - 24, 2, 22, 18), "K")) { showKeymapper = !showKeymapper; } GUI.backgroundColor = defaultColor; GUILayout.BeginVertical(); if (options.showManeuverPager) { GUIParts.drawManeuverPager(curState); } // Human-readable time GUIParts.drawDoubleLabel("Time:", 100, NodeTools.convertUTtoHumanTime(curState.currentUT()), 130); // Increment buttons GUILayout.BeginHorizontal(); GUILayout.Label("Increment:", GUILayout.Width(100)); GUIParts.drawButton("0.01", (options.increment == 0.01?Color.yellow:defaultColor), delegate() { options.increment = 0.01; }); GUIParts.drawButton("0.1", (options.increment == 0.1?Color.yellow:defaultColor), delegate() { options.increment = 0.1; }); GUIParts.drawButton("1", (options.increment == 1?Color.yellow:defaultColor), delegate() { options.increment = 1; }); GUIParts.drawButton("10", (options.increment == 10?Color.yellow:defaultColor), delegate() { options.increment = 10; }); GUIParts.drawButton("100", (options.increment == 100?Color.yellow:defaultColor), delegate() { options.increment = 100; }); GUILayout.EndHorizontal(); drawTimeControls(contentColor); drawProgradeControls(contentColor); drawNormalControls(contentColor); drawRadialControls(contentColor); // total delta-V display GUIParts.drawDoubleLabel("Total delta-V:", 100, curState.currentMagnitude().ToString("0.##") + "m/s", 130); drawEAngle(); drawEncounter(defaultColor); // Conics mode controls GUILayout.BeginHorizontal(); GUILayout.Label("Conics mode: ", GUILayout.Width(100)); GUIParts.drawButton("0", (options.conicsMode == 0?Color.yellow:defaultColor), delegate() { options.setConicsMode(0); }); GUIParts.drawButton("1", (options.conicsMode == 1?Color.yellow:defaultColor), delegate() { options.setConicsMode(1); }); GUIParts.drawButton("2", (options.conicsMode == 2?Color.yellow:defaultColor), delegate() { options.setConicsMode(2); }); GUIParts.drawButton("3", (options.conicsMode == 3?Color.yellow:defaultColor), delegate() { options.setConicsMode(3); }); GUIParts.drawButton("4", (options.conicsMode == 4?Color.yellow:defaultColor), delegate() { options.setConicsMode(4); }); GUILayout.EndHorizontal(); // conics patch limit editor. GUILayout.BeginHorizontal(); GUILayout.Label("Change Conics Samples", GUILayout.Width(200)); GUIParts.drawButton("-", Color.red, delegate() { solver.DecreasePatchLimit(); }); GUIParts.drawButton("+", Color.red, delegate() { solver.IncreasePatchLimit(); }); GUILayout.EndHorizontal(); // trip info button and vessel focus buttons GUILayout.BeginHorizontal(); GUIParts.drawButton("Trip Info", (options.showTrip?Color.yellow:defaultColor), delegate() { options.showTrip = !options.showTrip; }); GUIParts.drawButton("Focus on Vessel", defaultColor, delegate() { MapView.MapCamera.SetTarget(FlightGlobals.ActiveVessel.vesselName); }); GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUI.DragWindow(); }
/// <summary> /// Draws the Node Editor window. /// </summary> private void drawMainWindow() { Color defaultColor = GUI.backgroundColor; Color contentColor = GUI.contentColor; Color curColor = defaultColor; PatchedConicSolver solver = NodeTools.getSolver(); // Options button if (showOptions) { GUI.backgroundColor = Color.green; } if (GUI.Button(new Rect(options.mainWindowPos.width - 48, 2, 22, 18), "O")) { showOptions = !showOptions; } GUI.backgroundColor = defaultColor; // Keymapping button if (showKeymapper) { GUI.backgroundColor = Color.green; } if (GUI.Button(new Rect(options.mainWindowPos.width - 24, 2, 22, 18), "K")) { showKeymapper = !showKeymapper; } GUI.backgroundColor = defaultColor; GUILayout.BeginVertical(); if (options.showManeuverPager) { drawManeuverPager(); } // Human-readable time GUIParts.drawDoubleLabel("Time:", 100, curState.currentUT().convertUTtoHumanTime(), 150); // Increment buttons GUILayout.BeginHorizontal(); GUILayout.Label("Increment:", GUILayout.Width(100)); GUIParts.drawButton("0.01", (options.increment == 0.01?Color.yellow:defaultColor), () => { options.increment = 0.01; }); GUIParts.drawButton("0.1", (options.increment == 0.1?Color.yellow:defaultColor), () => { options.increment = 0.1; }); GUIParts.drawButton("1", (options.increment == 1?Color.yellow:defaultColor), () => { options.increment = 1; }); GUIParts.drawButton("10", (options.increment == 10?Color.yellow:defaultColor), () => { options.increment = 10; }); GUIParts.drawButton("100", (options.increment == 100?Color.yellow:defaultColor), () => { options.increment = 100; }); GUILayout.EndHorizontal(); drawTimeControls(contentColor); GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); drawProgradeControls(contentColor); drawNormalControls(contentColor); drawRadialControls(contentColor); GUILayout.EndVertical(); GUILayout.BeginVertical(GUILayout.ExpandHeight(true)); GUIParts.drawButton("MS", defaultColor, () => { curState.memorize(); }, GUILayout.ExpandHeight(true)); GUI.enabled = curState.HasMemorized; GUIParts.drawButton("MR", defaultColor, () => { curState.recallMemory(); }, GUILayout.ExpandHeight(true)); GUI.enabled = true; GUILayout.EndVertical(); GUILayout.EndHorizontal(); // total delta-V display GUIParts.drawDoubleLabel("Total Δv:", 100, curState.currentMagnitude().ToString("0.##") + " m/s", 130); drawEAngle(); drawEncounter(defaultColor); // Conics mode controls if (options.showConics) { GUIParts.drawConicsControls(options); } // trip info button and vessel focus buttons GUILayout.BeginHorizontal(); GUIParts.drawButton("Trip Info", (options.showTrip?Color.yellow:defaultColor), () => { options.showTrip = !options.showTrip; }); GUIParts.drawButton("Focus on Vessel", defaultColor, () => { MapObject mapObject = PlanetariumCamera.fetch.targets.Find(o => (o.vessel != null) && o.vessel.Equals(FlightGlobals.ActiveVessel)); MapView.MapCamera.SetTarget(mapObject); }); GUILayout.EndHorizontal(); GUILayout.EndVertical(); GUI.DragWindow(); }