private void RenderPredictionSettings() { AdaptiveStepParameters? adaptive_step_parameters = null; string vessel_guid = predicted_vessel?.id.ToString(); if (vessel_guid != null) { adaptive_step_parameters = plugin.VesselGetPredictionAdaptiveStepParameters(vessel_guid); prediction_length_tolerance_index_ = Array.FindIndex( prediction_length_tolerances_, (double tolerance) => tolerance >= adaptive_step_parameters.Value.length_integration_tolerance); if (prediction_length_tolerance_index_ < 0) { prediction_length_tolerance_index_ = default_prediction_length_tolerance_index_; } prediction_steps_index_ = Array.FindIndex( prediction_steps_, (long step) => step >= adaptive_step_parameters.Value.max_steps); if (prediction_steps_index_ < 0) { prediction_steps_index_ = default_prediction_steps_index_; } } // TODO(egg): make the speed tolerance independent. if (RenderSelector(prediction_length_tolerances_, ref prediction_length_tolerance_index_, "Tolerance", "{0:0.0e0} m", enabled: adaptive_step_parameters.HasValue)) { AdaptiveStepParameters new_adaptive_step_parameters = new AdaptiveStepParameters{ integrator_kind = adaptive_step_parameters.Value.integrator_kind, max_steps = prediction_steps, length_integration_tolerance = prediction_length_tolerance, speed_integration_tolerance = prediction_length_tolerance}; plugin.VesselSetPredictionAdaptiveStepParameters( vessel_guid, new_adaptive_step_parameters); } if (RenderSelector(prediction_steps_, ref prediction_steps_index_, "Steps", "{0:0.00e0}", enabled: adaptive_step_parameters.HasValue)) { AdaptiveStepParameters new_adaptive_step_parameters = new AdaptiveStepParameters{ integrator_kind = adaptive_step_parameters.Value.integrator_kind, max_steps = prediction_steps, length_integration_tolerance = prediction_length_tolerance, speed_integration_tolerance = prediction_length_tolerance}; plugin.VesselSetPredictionAdaptiveStepParameters( vessel_guid, new_adaptive_step_parameters); } }
private void RenderPredictionSettings() { if (vessel_ != predicted_vessel_()) { vessel_ = predicted_vessel_(); string vessel_guid = vessel_?.id.ToString(); if (vessel_guid != null && plugin.HasVessel(vessel_guid)) { AdaptiveStepParameters adaptive_step_parameters = plugin.VesselGetPredictionAdaptiveStepParameters(vessel_guid); prediction_length_tolerance_index_ = Array.FindIndex( prediction_length_tolerances_, (double tolerance) => tolerance >= adaptive_step_parameters.length_integration_tolerance); if (prediction_length_tolerance_index_ < 0) { prediction_length_tolerance_index_ = default_prediction_length_tolerance_index_; } prediction_steps_index_ = Array.FindIndex( prediction_steps_, (Int64 step) => step >= adaptive_step_parameters.max_steps); if (prediction_steps_index_ < 0) { prediction_steps_index_ = default_prediction_steps_index_; } } } bool changed_settings = false; RenderSelector(prediction_length_tolerances_, ref prediction_length_tolerance_index_, "Tolerance", ref changed_settings, "{0:0.0e0} m"); RenderSelector(prediction_steps_, ref prediction_steps_index_, "Steps", ref changed_settings, "{0:0.00e0}"); }
private void RenderPlanner(int window_id) { var old_skin = UnityEngine.GUI.skin; UnityEngine.GUI.skin = null; UnityEngine.GUILayout.BeginVertical(); if (vessel_ == null || vessel_ != FlightGlobals.ActiveVessel || !plugin_.HasVessel(vessel_.id.ToString())) { Reset(); } if (vessel_ != null) { string vessel_guid = vessel_.id.ToString(); if (burn_editors_ == null) { if (plugin_.HasVessel(vessel_guid)) { if (plugin_.FlightPlanExists(vessel_guid)) { burn_editors_ = new List <BurnEditor>(); for (int i = 0; i < plugin_.FlightPlanNumberOfManoeuvres(vessel_guid); ++i) { // Dummy initial time, we call |Reset| immediately afterwards. final_time_.value = plugin_.FlightPlanGetFinalTime(vessel_guid); burn_editors_.Add( new BurnEditor(adapter_, plugin_, vessel_, initial_time: 0)); burn_editors_.Last().Reset( plugin_.FlightPlanGetManoeuvre(vessel_guid, i)); } } else { if (UnityEngine.GUILayout.Button("Create flight plan")) { plugin_.FlightPlanCreate(vessel_guid, plugin_.CurrentTime() + 1000, vessel_.GetTotalMass()); final_time_.value = plugin_.FlightPlanGetFinalTime(vessel_guid); Shrink(); } } } } else { if (final_time_.Render(enabled: true)) { plugin_.FlightPlanSetFinalTime(vessel_guid, final_time_.value); final_time_.value = plugin_.FlightPlanGetFinalTime(vessel_guid); } AdaptiveStepParameters parameters = plugin_.FlightPlanGetAdaptiveStepParameters(vessel_guid); UnityEngine.GUILayout.BeginHorizontal(); UnityEngine.GUILayout.Label("Maximal step count per segment", UnityEngine.GUILayout.Width(150)); if (parameters.max_steps <= 100) { UnityEngine.GUILayout.Button("min"); } else if (UnityEngine.GUILayout.Button("-")) { parameters.max_steps /= 10; plugin_.FlightPlanSetAdaptiveStepParameters(vessel_guid, parameters); } UnityEngine.GUILayout.TextArea(parameters.max_steps.ToString(), UnityEngine.GUILayout.Width(150)); if (parameters.max_steps >= Int64.MaxValue / 10) { UnityEngine.GUILayout.Button("max"); } else if (UnityEngine.GUILayout.Button("+")) { parameters.max_steps *= 10; plugin_.FlightPlanSetAdaptiveStepParameters(vessel_guid, parameters); } UnityEngine.GUILayout.EndHorizontal(); UnityEngine.GUILayout.BeginHorizontal(); UnityEngine.GUILayout.Label("Tolerance", UnityEngine.GUILayout.Width(150)); if (parameters.length_integration_tolerance <= 1e-6) { UnityEngine.GUILayout.Button("min"); } else if (UnityEngine.GUILayout.Button("-")) { parameters.length_integration_tolerance /= 2; parameters.speed_integration_tolerance /= 2; plugin_.FlightPlanSetAdaptiveStepParameters(vessel_guid, parameters); } UnityEngine.GUILayout.TextArea( parameters.length_integration_tolerance.ToString("0.0e0") + " m", UnityEngine.GUILayout.Width(150)); if (parameters.length_integration_tolerance >= 1e6) { UnityEngine.GUILayout.Button("max"); } else if (UnityEngine.GUILayout.Button("+")) { parameters.length_integration_tolerance *= 2; parameters.speed_integration_tolerance *= 2; plugin_.FlightPlanSetAdaptiveStepParameters(vessel_guid, parameters); } UnityEngine.GUILayout.EndHorizontal(); double Δv = (from burn_editor in burn_editors_ select burn_editor.Δv()).Sum(); UnityEngine.GUILayout.Label( "Total Δv : " + Δv.ToString("0.000") + " m/s"); if (burn_editors_.Count == 0 && UnityEngine.GUILayout.Button("Delete flight plan")) { plugin_.FlightPlanDelete(vessel_guid); Reset(); } else { if (burn_editors_.Count > 0) { RenderUpcomingEvents(); } for (int i = 0; i < burn_editors_.Count - 1; ++i) { UnityEngine.GUILayout.TextArea("Manœuvre #" + (i + 1) + ":"); burn_editors_[i].Render(enabled: false); } if (burn_editors_.Count > 0) { BurnEditor last_burn = burn_editors_.Last(); UnityEngine.GUILayout.TextArea("Editing manœuvre #" + (burn_editors_.Count) + ":"); if (last_burn.Render(enabled: true)) { plugin_.FlightPlanReplaceLast(vessel_guid, last_burn.Burn()); last_burn.Reset( plugin_.FlightPlanGetManoeuvre(vessel_guid, burn_editors_.Count - 1)); } if (UnityEngine.GUILayout.Button( "Delete last manœuvre", UnityEngine.GUILayout.ExpandWidth(true))) { plugin_.FlightPlanRemoveLast(vessel_guid); burn_editors_.Last().Close(); burn_editors_.RemoveAt(burn_editors_.Count - 1); Shrink(); } } if (UnityEngine.GUILayout.Button( "Add manœuvre", UnityEngine.GUILayout.ExpandWidth(true))) { double initial_time; if (burn_editors_.Count == 0) { initial_time = plugin_.CurrentTime() + 60; } else { initial_time = plugin_.FlightPlanGetManoeuvre( vessel_guid, burn_editors_.Count - 1).final_time + 60; } var editor = new BurnEditor(adapter_, plugin_, vessel_, initial_time); Burn candidate_burn = editor.Burn(); bool inserted = plugin_.FlightPlanAppend(vessel_guid, candidate_burn); if (inserted) { editor.Reset(plugin_.FlightPlanGetManoeuvre(vessel_guid, burn_editors_.Count)); burn_editors_.Add(editor); } Shrink(); } } } } UnityEngine.GUILayout.EndVertical(); UnityEngine.GUI.DragWindow( position: new UnityEngine.Rect(x: 0f, y: 0f, width: 10000f, height: 10000f)); UnityEngine.GUI.skin = old_skin; }
private void FixedUpdate() { if (GameSettings.ORBIT_WARP_DOWN_AT_SOI) { Log.Info("Setting GameSettings.ORBIT_WARP_DOWN_AT_SOI to false"); GameSettings.ORBIT_WARP_DOWN_AT_SOI = false; } if (PluginRunning()) { double universal_time = Planetarium.GetUniversalTime(); plugin_.SetMainBody( FlightGlobals.currentMainBody.GetValueOrDefault( FlightGlobals.GetHomeBody()).flightGlobalsIndex); if (has_inertial_physics_bubble_in_space() && (FlightGlobals.currentMainBody == previous_bubble_reference_body_ || previous_bubble_reference_body_ == null)) { ApplyToVesselsInPhysicsBubble(AddToPhysicsBubble); previous_bubble_reference_body_ = FlightGlobals.currentMainBody; } else { if (PhysicsGlobals.GraviticForceMultiplier != 1) { Log.Info("Reinstating stock gravity"); PhysicsGlobals.GraviticForceMultiplier = 1; // sic. } previous_bubble_reference_body_ = null; } Vessel active_vessel = FlightGlobals.ActiveVessel; bool ready_to_draw_active_vessel_trajectory = draw_active_vessel_trajectory() && plugin_.HasVessel(active_vessel.id.ToString()); if (ready_to_draw_active_vessel_trajectory) { // TODO(egg): make the speed tolerance independent. Also max_steps. AdaptiveStepParameters adaptive_step_parameters = new AdaptiveStepParameters { max_steps = (Int64)prediction_steps_[prediction_steps_index_], length_integration_tolerance = prediction_length_tolerances_[ prediction_length_tolerance_index_], speed_integration_tolerance = prediction_length_tolerances_[ prediction_length_tolerance_index_]}; plugin_.VesselSetPredictionAdaptiveStepParameters( active_vessel.id.ToString(), adaptive_step_parameters); plugin_.SetPredictionLength(double.PositiveInfinity); } if (ready_to_draw_active_vessel_trajectory) { plugin_.UpdatePrediction(active_vessel.id.ToString()); } plugin_.ForgetAllHistoriesBefore(universal_time - history_lengths_[history_length_index_]); if (FlightGlobals.currentMainBody != null) { FlightGlobals.currentMainBody.rotationPeriod = plugin_.CelestialRotationPeriod( FlightGlobals.currentMainBody.flightGlobalsIndex); FlightGlobals.currentMainBody.initialRotation = plugin_.CelestialInitialRotationInDegrees( FlightGlobals.currentMainBody.flightGlobalsIndex); } ApplyToBodyTree(body => UpdateBody(body, universal_time)); SetBodyFrames(); // TODO(egg): set the positions of vessels inside the physics bubble too; // Only move the universe to set the centre of mass of all loaded PileUps // at the centre of the physics bubble. ApplyToVesselsOnRailsOrInInertialPhysicsBubbleInSpace( vessel => UpdateVessel(vessel, universal_time)); if (!plugin_.PhysicsBubbleIsEmpty()) { Vector3d displacement_offset = (Vector3d)plugin_.PhysicsBubbleDisplacementCorrection( (XYZ)Planetarium.fetch.Sun.position); Vector3d velocity_offset = (Vector3d)plugin_.PhysicsBubbleVelocityCorrection( active_vessel.orbit.referenceBody.flightGlobalsIndex); if (krakensbane_ == null) { krakensbane_ = (Krakensbane)FindObjectOfType(typeof(Krakensbane)); } FloatingOrigin.SetOffset(displacement_offset); krakensbane_.FrameVel += velocity_offset; } // Now we let the game and Unity do their thing. among other things, // the FashionablyLate callbacks, including ReportNonConservativeForces, // then the FlightIntegrator's FixedUpdate will run, then the Vessel's, // and eventually the physics simulation. StartCoroutine( AdvanceTimeAndNudgeVesselsAfterPhysicsSimulation(universal_time)); } }
private void FixedUpdate() { if (GameSettings.ORBIT_WARP_DOWN_AT_SOI) { Log.Info("Setting GameSettings.ORBIT_WARP_DOWN_AT_SOI to false"); GameSettings.ORBIT_WARP_DOWN_AT_SOI = false; } if (PluginRunning()) { double universal_time = Planetarium.GetUniversalTime(); double plugin_time = plugin_.CurrentTime(); if (plugin_time > universal_time) { // TODO(Egg): Make this resistant to bad floating points up to 2ULPs, // and make it fatal again. Log.Error("Closed Timelike Curve: " + plugin_time + " > " + universal_time + " plugin-universal=" + (plugin_time - universal_time)); time_is_advancing_ = false; return; } else if (plugin_time == universal_time) { time_is_advancing_ = false; return; } time_is_advancing_ = true; if (has_inertial_physics_bubble_in_space() && (FlightGlobals.currentMainBody == previous_bubble_reference_body_ || previous_bubble_reference_body_ == null)) { ApplyToVesselsInPhysicsBubble(AddToPhysicsBubble); previous_bubble_reference_body_ = FlightGlobals.currentMainBody; } else { if (FlightIntegrator.GraviticForceMultiplier != 1) { Log.Info("Reinstating stock gravity"); FlightIntegrator.GraviticForceMultiplier = 1; // sic. } previous_bubble_reference_body_ = null; } Vessel active_vessel = FlightGlobals.ActiveVessel; bool ready_to_draw_active_vessel_trajectory = draw_active_vessel_trajectory() && plugin_.HasVessel(active_vessel.id.ToString()); if (ready_to_draw_active_vessel_trajectory) { // TODO(egg): make the speed tolerance independent. Also max_steps. AdaptiveStepParameters adaptive_step_parameters = new AdaptiveStepParameters { max_steps = (Int64)prediction_steps_[prediction_steps_index_], length_integration_tolerance = prediction_length_tolerances_[ prediction_length_tolerance_index_], speed_integration_tolerance = prediction_length_tolerances_[ prediction_length_tolerance_index_]}; plugin_.VesselSetPredictionAdaptiveStepParameters( active_vessel.id.ToString(), adaptive_step_parameters); plugin_.SetPredictionLength(double.PositiveInfinity); } plugin_.AdvanceTime(universal_time, Planetarium.InverseRotAngle); if (ready_to_draw_active_vessel_trajectory) { plugin_.UpdatePrediction(active_vessel.id.ToString()); } plugin_.ForgetAllHistoriesBefore( universal_time - history_lengths_[history_length_index_]); ApplyToBodyTree(body => UpdateBody(body, universal_time)); ApplyToVesselsOnRailsOrInInertialPhysicsBubbleInSpace( vessel => UpdateVessel(vessel, universal_time)); if (!plugin_.PhysicsBubbleIsEmpty()) { Vector3d displacement_offset = (Vector3d)plugin_.BubbleDisplacementCorrection( (XYZ)Planetarium.fetch.Sun.position); Vector3d velocity_offset = (Vector3d)plugin_.BubbleVelocityCorrection( active_vessel.orbit.referenceBody.flightGlobalsIndex); if (krakensbane_ == null) { krakensbane_ = (Krakensbane)FindObjectOfType(typeof(Krakensbane)); } krakensbane_.setOffset(displacement_offset); krakensbane_.FrameVel += velocity_offset; } } }
private void RenderPredictionSettings() { AdaptiveStepParameters?adaptive_step_parameters = null; string vessel_guid = predicted_vessel?.id.ToString(); using (new UnityEngine.GUILayout.HorizontalScope()) { UnityEngine.GUILayout.Label( L10N.CacheFormat("#Principia_MainWindow_PredictionSettings"), UnityEngine.GUILayout.ExpandWidth(true)); if (vessel_guid != null) { adaptive_step_parameters = plugin.VesselGetPredictionAdaptiveStepParameters(vessel_guid); prediction_length_tolerance_index_ = Array.FindIndex( prediction_length_tolerances_, (double tolerance) => tolerance >= adaptive_step_parameters.Value. length_integration_tolerance); if (prediction_length_tolerance_index_ < 0) { prediction_length_tolerance_index_ = default_prediction_length_tolerance_index; } prediction_steps_index_ = Array.FindIndex(prediction_steps_, (long step) => step >= adaptive_step_parameters. Value.max_steps); if (prediction_steps_index_ < 0) { prediction_steps_index_ = default_prediction_steps_index; } } if (RenderSelector(prediction_length_tolerances_, ref prediction_length_tolerance_index_, L10N.CacheFormat( "#Principia_PredictionSettings_ToleranceLabel"), (i) => prediction_length_tolerance_names_[i], enabled: adaptive_step_parameters.HasValue)) { AdaptiveStepParameters new_adaptive_step_parameters = new AdaptiveStepParameters { integrator_kind = adaptive_step_parameters.Value.integrator_kind, max_steps = prediction_steps, length_integration_tolerance = prediction_length_tolerance, speed_integration_tolerance = prediction_length_tolerance }; plugin.VesselSetPredictionAdaptiveStepParameters( vessel_guid, new_adaptive_step_parameters); } if (RenderSelector(prediction_steps_, ref prediction_steps_index_, L10N.CacheFormat("#Principia_PredictionSettings_Steps"), (i) => string.Format(Culture.culture, "{0:0.0e0}", prediction_steps_[i]), enabled: adaptive_step_parameters.HasValue)) { AdaptiveStepParameters new_adaptive_step_parameters = new AdaptiveStepParameters { integrator_kind = adaptive_step_parameters.Value.integrator_kind, max_steps = prediction_steps, length_integration_tolerance = prediction_length_tolerance, speed_integration_tolerance = prediction_length_tolerance }; plugin.VesselSetPredictionAdaptiveStepParameters( vessel_guid, new_adaptive_step_parameters); } } }