public MainWindow(PrincipiaPluginAdapter adapter, FlightPlanner flight_planner, ReferenceFrameSelector plotting_frame_selector, PredictedVessel predicted_vessel) : base(adapter) { adapter_ = adapter; flight_planner_ = flight_planner; plotting_frame_selector_ = plotting_frame_selector; predicted_vessel_ = predicted_vessel; Show(); }
public BurnEditor(PrincipiaPluginAdapter adapter, Vessel vessel, double initial_time, int index, Func <int, BurnEditor> get_burn_at_index) { adapter_ = adapter; vessel_ = vessel; initial_time_ = initial_time; this.index = index; get_burn_at_index_ = get_burn_at_index; Δv_tangent_ = new DifferentialSlider( label: L10N.CacheFormat("#Principia_BurnEditor_ΔvTangent"), unit: L10N.CacheFormat("#Principia_BurnEditor_SpeedUnit"), log10_lower_rate: log10_Δv_lower_rate, log10_upper_rate: log10_Δv_upper_rate, text_colour: Style.Tangent); Δv_normal_ = new DifferentialSlider( label: L10N.CacheFormat("#Principia_BurnEditor_ΔvNormal"), unit: L10N.CacheFormat("#Principia_BurnEditor_SpeedUnit"), log10_lower_rate: log10_Δv_lower_rate, log10_upper_rate: log10_Δv_upper_rate, text_colour: Style.Normal); Δv_binormal_ = new DifferentialSlider( label: L10N.CacheFormat("#Principia_BurnEditor_ΔvBinormal"), unit: L10N.CacheFormat("#Principia_BurnEditor_SpeedUnit"), log10_lower_rate: log10_Δv_lower_rate, log10_upper_rate: log10_Δv_upper_rate, text_colour: Style.Binormal); previous_coast_duration_ = new DifferentialSlider( label: L10N.CacheFormat("#Principia_BurnEditor_InitialTime"), unit: null, log10_lower_rate: log10_time_lower_rate, log10_upper_rate: log10_time_upper_rate, // We cannot have a coast of length 0, so let's make it very // short: that will be indistinguishable. zero_value: 0.001, min_value: 0, formatter: FormatPreviousCoastDuration, parser: TryParsePreviousCoastDuration, field_width: 7) { value = initial_time_ - time_base }; reference_frame_selector_ = new ReferenceFrameSelector( adapter_, ReferenceFrameChanged, L10N.CacheFormat("#Principia_BurnEditor_ManœuvringFrame")); reference_frame_selector_.SetFrameParameters( adapter_.plotting_frame_selector_.FrameParameters()); ComputeEngineCharacteristics(); }
public BurnEditor(PrincipiaPluginAdapter adapter, Vessel vessel, double initial_time, int index, BurnEditor previous_burn) { adapter_ = adapter; vessel_ = vessel; initial_time_ = initial_time; index_ = index; previous_burn_ = previous_burn; Δv_tangent_ = new DifferentialSlider(label: "Δv tangent", unit: "m / s", log10_lower_rate: Log10ΔvLowerRate, log10_upper_rate: Log10ΔvUpperRate, text_colour: Style.Tangent); Δv_normal_ = new DifferentialSlider(label: "Δv normal", unit: "m / s", log10_lower_rate: Log10ΔvLowerRate, log10_upper_rate: Log10ΔvUpperRate, text_colour: Style.Normal); Δv_binormal_ = new DifferentialSlider(label: "Δv binormal", unit: "m / s", log10_lower_rate: Log10ΔvLowerRate, log10_upper_rate: Log10ΔvUpperRate, text_colour: Style.Binormal); previous_coast_duration_ = new DifferentialSlider( label: "t initial", unit: null, log10_lower_rate: Log10TimeLowerRate, log10_upper_rate: Log10TimeUpperRate, // We cannot have a coast of length 0, so let's make it very // short: that will be indistinguishable. zero_value: 0.001, min_value: 0, formatter: FormatPreviousCoastDuration, parser: TryParsePreviousCoastDuration, field_width: 7) { value = initial_time_ - time_base }; reference_frame_selector_ = new ReferenceFrameSelector( adapter_, ReferenceFrameChanged, "Manœuvring frame"); reference_frame_selector_.SetFrameParameters( adapter_.plotting_frame_selector_.FrameParameters()); ComputeEngineCharacteristics(); }
public BurnEditor(PrincipiaPluginAdapter adapter, IntPtr plugin, Vessel vessel, double initial_time) { Δv_tangent_ = new DifferentialSlider(label : "Δv tangent", unit : "m / s", log10_lower_rate : Log10ΔvLowerRate, log10_upper_rate : Log10ΔvUpperRate, text_colour : XKCDColors.NeonYellow); Δv_normal_ = new DifferentialSlider(label : "Δv normal", unit : "m / s", log10_lower_rate : Log10ΔvLowerRate, log10_upper_rate : Log10ΔvUpperRate, text_colour : XKCDColors.AquaBlue); Δv_binormal_ = new DifferentialSlider(label : "Δv binormal", unit : "m / s", log10_lower_rate : Log10ΔvLowerRate, log10_upper_rate : Log10ΔvUpperRate, text_colour : XKCDColors.PurplePink); initial_time_ = new DifferentialSlider( label : "t initial", unit : null, log10_lower_rate : Log10TimeLowerRate, log10_upper_rate : Log10TimeUpperRate, min_value : 0, max_value : double.PositiveInfinity, formatter : value => FlightPlanner.FormatTimeSpan( TimeSpan.FromSeconds( Planetarium.GetUniversalTime() - value))); initial_time_.value = initial_time; reference_frame_selector_ = new ReferenceFrameSelector( adapter, plugin, ReferenceFrameChanged, "Manœuvring frame"); plugin_ = plugin; vessel_ = vessel; adapter_ = adapter; reference_frame_selector_.Reset( adapter_.plotting_frame_selector_.get().FrameParameters()); ComputeEngineCharacteristics(); }
public BurnEditor(PrincipiaPluginAdapter adapter, IntPtr plugin, Vessel vessel, double initial_time) { Δv_tangent_ = new DifferentialSlider(label: "Δv tangent", unit: "m / s", log10_lower_rate: Log10ΔvLowerRate, log10_upper_rate: Log10ΔvUpperRate, text_colour: XKCDColors.NeonYellow); Δv_normal_ = new DifferentialSlider(label: "Δv normal", unit: "m / s", log10_lower_rate: Log10ΔvLowerRate, log10_upper_rate: Log10ΔvUpperRate, text_colour: XKCDColors.AquaBlue); Δv_binormal_ = new DifferentialSlider(label: "Δv binormal", unit: "m / s", log10_lower_rate: Log10ΔvLowerRate, log10_upper_rate: Log10ΔvUpperRate, text_colour: XKCDColors.PurplePink); initial_time_ = new DifferentialSlider( label: "t initial", unit: null, log10_lower_rate: Log10TimeLowerRate, log10_upper_rate: Log10TimeUpperRate, min_value: 0, max_value: double.PositiveInfinity, formatter: value => FlightPlanner.FormatTimeSpan( TimeSpan.FromSeconds( Planetarium.GetUniversalTime() - value))); initial_time_.value = initial_time; reference_frame_selector_ = new ReferenceFrameSelector( adapter, plugin, ReferenceFrameChanged, "Manœuvring frame"); plugin_ = plugin; vessel_ = vessel; adapter_ = adapter; reference_frame_selector_.Reset( adapter_.plotting_frame_selector_.get().FrameParameters()); ComputeEngineCharacteristics(); }
public void RenderMarkers(DisposableIterator apsis_iterator, MapObject.ObjectType type, NodeSource source, ReferenceFrameSelector reference_frame) { MapObject associated_map_object; UnityEngine.Color colour; switch (type) { case MapObject.ObjectType.Apoapsis: case MapObject.ObjectType.Periapsis: CelestialBody fixed_body = reference_frame.selected_celestial; associated_map_object = fixed_body.MapObject; colour = fixed_body.orbit == null ? XKCDColors.SunshineYellow : fixed_body.orbitDriver.Renderer.nodeColor; break; case MapObject.ObjectType.ApproachIntersect: associated_map_object = reference_frame.target_override.mapObject; colour = XKCDColors.Chartreuse; break; case MapObject.ObjectType.AscendingNode: case MapObject.ObjectType.DescendingNode: if (!reference_frame.target_override && (reference_frame.frame_type == ReferenceFrameSelector.FrameType.BODY_CENTRED_NON_ROTATING || reference_frame.frame_type == ReferenceFrameSelector.FrameType.BODY_SURFACE)) { // In one-body frames, the apsides are shown with the colour of the // body. // The nodes are with respect to the equator, rather than with respect // to an orbit. We show the nodes in a different (but arbitrary) // colour so that they can be distinguished easily. associated_map_object = reference_frame.selected_celestial.MapObject; colour = XKCDColors.Chartreuse; } else { // In two-body frames, if apsides are shown, they are shown with the // colour of the secondary (or in XKCD chartreuse if the secondary is // a vessel). // The nodes are with respect to the orbit of the secondary around the // primary. We show the nodes with the colour of the primary. CelestialBody primary = reference_frame.target_override ? reference_frame.selected_celestial : reference_frame.selected_celestial.referenceBody; associated_map_object = primary.MapObject; colour = primary.orbit == null ? XKCDColors.SunshineYellow : primary.orbitDriver.Renderer.nodeColor; } break; default: throw Log.Fatal($"Unexpected type {type}"); } colour.a = 1; for (int i = 0; i < MaxRenderedNodes && !apsis_iterator.IteratorAtEnd(); ++i, apsis_iterator.IteratorIncrement()) { QP apsis = apsis_iterator.IteratorGetDiscreteTrajectoryQP(); MapNodeProperties node_properties = new MapNodeProperties { visible = true, object_type = type, colour = colour, reference_frame = reference_frame, world_position = (Vector3d)apsis.q, velocity = (Vector3d)apsis.p, source = source, time = apsis_iterator.IteratorGetDiscreteTrajectoryTime(), associated_map_object = associated_map_object, }; if (type == MapObject.ObjectType.Periapsis && reference_frame.selected_celestial.GetAltitude( node_properties.world_position) < 0) { node_properties.object_type = MapObject.ObjectType.PatchTransition; node_properties.colour = XKCDColors.Orange; } if (pool_index_ == nodes_.Count) { nodes_.Add(MakePoolNode()); } else if (properties_[nodes_[pool_index_]].object_type != node_properties.object_type || properties_[nodes_[pool_index_]].colour != node_properties.colour) { // KSP attaches labels to its map nodes, but never detaches them. // If the node changes type, we end up with an arbitrary combination of // labels Ap, Pe, AN, DN. // Similarly, if the node changes colour, the colour of the icon label // is not updated to match the icon (making it unreadable in some // cases). Recreating the node entirely takes a long time // (approximately 𝑁 * 70 μs, where 𝑁 is the total number of map nodes // in existence), instead we manually get rid of the labels. foreach (var component in nodes_[pool_index_].transform.GetComponentsInChildren < TMPro.TextMeshProUGUI>()) { if (component.name == "iconLabel(Clone)") { UnityEngine.Object.Destroy(component.gameObject); } } // Ensure that KSP thinks the type changed, and reattaches icon // labels next time around, otherwise we might end up with no labels. // Null nodes do not have a label, so inducing a type change through // Null does not result in spurious labels. Note that the type is // updated only if the node is visible. properties_[nodes_[pool_index_]].visible = true; properties_[nodes_[pool_index_]].object_type = MapObject.ObjectType.Null; nodes_[pool_index_].NodeUpdate(); } properties_[nodes_[pool_index_++]] = node_properties; } }
public void RenderMarkers(DisposableIterator apsis_iterator, Provenance provenance, ReferenceFrameSelector reference_frame) { if (!nodes_.ContainsKey(provenance)) { nodes_.Add(provenance, new SingleProvenancePool()); } var pool = nodes_[provenance]; MapObject associated_map_object; UnityEngine.Color colour; switch (provenance.type) { case MapObject.ObjectType.Apoapsis: case MapObject.ObjectType.Periapsis: CelestialBody fixed_body = reference_frame.Centre(); associated_map_object = fixed_body.MapObject; colour = fixed_body.orbit == null ? XKCDColors.SunshineYellow : fixed_body.orbitDriver.Renderer.nodeColor; break; case MapObject.ObjectType.ApproachIntersect: associated_map_object = reference_frame.target.mapObject; colour = XKCDColors.Chartreuse; break; case MapObject.ObjectType.AscendingNode: case MapObject.ObjectType.DescendingNode: if (reference_frame.Centre() == null) { // In two-body frames, if apsides are shown, they are shown with the // colour of the secondary (or in XKCD chartreuse if the secondary is // a vessel). // The nodes are with respect to the orbit of the secondary around the // primary. We show the nodes with the colour of the primary. CelestialBody primary = reference_frame.OrientingBody(); associated_map_object = primary.MapObject; colour = primary.orbit == null ? XKCDColors.SunshineYellow : primary.orbitDriver.Renderer.nodeColor; } else { // In one-body frames, the apsides are shown with the colour of the // body. // The nodes are with respect to the equator, rather than with respect // to an orbit. We show the nodes in a different (but arbitrary) // colour so that they can be distinguished easily. associated_map_object = reference_frame.Centre().MapObject; colour = XKCDColors.Chartreuse; } break; default: throw Log.Fatal($"Unexpected type {provenance.type}"); } colour.a = 1; for (int i = 0; i < MaxNodesPerProvenance && !apsis_iterator.IteratorAtEnd(); ++i, apsis_iterator.IteratorIncrement()) { QP apsis = apsis_iterator.IteratorGetDiscreteTrajectoryQP(); MapNodeProperties node_properties = new MapNodeProperties { visible = true, object_type = provenance.type, colour = colour, reference_frame = reference_frame, world_position = (Vector3d)apsis.q, velocity = (Vector3d)apsis.p, source = provenance.source, time = apsis_iterator.IteratorGetDiscreteTrajectoryTime(), associated_map_object = associated_map_object, }; if (provenance.type == MapObject.ObjectType.Periapsis && reference_frame.Centre().GetAltitude( node_properties.world_position) < 0) { node_properties.object_type = MapObject.ObjectType.PatchTransition; node_properties.colour = XKCDColors.Orange; } if (pool.nodes_used == pool.nodes.Count) { pool.nodes.Add(MakePoolNode()); } properties_[pool.nodes[pool.nodes_used++]] = node_properties; } }