Exemple #1
0
 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();
 }
Exemple #3
0
 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();
 }
Exemple #4
0
 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();
 }
Exemple #5
0
 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();
 }
Exemple #6
0
            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;
                }
            }
Exemple #7
0
            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;
                }
            }