public void PlotTrajectories(DisposablePlanetarium planetarium, string main_vessel_guid, double history_length) { PlotCelestialTrajectories(planetarium, main_vessel_guid, history_length); if (main_vessel_guid == null) { return; } PlotVesselTrajectories(planetarium, main_vessel_guid, history_length); }
private void PlotCelestialTrajectories(DisposablePlanetarium planetarium, string main_vessel_guid, double history_length) { const double degree = Math.PI / 180; UnityEngine.Camera camera = PlanetariumCamera.Camera; float vertical_fov = camera.fieldOfView; float horizontal_fov = UnityEngine.Camera.VerticalToHorizontalFieldOfView( vertical_fov, camera.aspect); // The angle subtended by the pixel closest to the centre of the viewport. double tan_angular_resolution = Math.Min( Math.Tan(vertical_fov * degree / 2) / (camera.pixelHeight / 2), Math.Tan(horizontal_fov * degree / 2) / (camera.pixelWidth / 2)); PlotSubtreeTrajectories(planetarium, main_vessel_guid, history_length, Planetarium.fetch.Sun, tan_angular_resolution); }
private void PlotVesselTrajectories(DisposablePlanetarium planetarium, string main_vessel_guid, double history_length) { { planetarium.PlanetariumPlotPsychohistory( Plugin, main_vessel_guid, history_length, VertexBuffer.data, VertexBuffer.size, out int vertex_count); DrawLineMesh(psychohistory_mesh_, vertex_count, adapter_.history_colour, adapter_.history_style); } { planetarium.PlanetariumPlotPrediction( Plugin, main_vessel_guid, VertexBuffer.data, VertexBuffer.size, out int vertex_count); DrawLineMesh(prediction_mesh_, vertex_count, adapter_.prediction_colour, adapter_.prediction_style); } // Target psychohistory and prediction. string target_id = FlightGlobals.fetch.VesselTarget?.GetVessel()?.id. ToString(); if (FlightGlobals.ActiveVessel != null && !adapter_.plotting_frame_selector_.target_frame_selected && target_id != null && Plugin.HasVessel(target_id)) { { planetarium.PlanetariumPlotPsychohistory( Plugin, target_id, history_length, VertexBuffer.data, VertexBuffer.size, out int vertex_count); DrawLineMesh(target_psychohistory_mesh_, vertex_count, adapter_.target_history_colour, adapter_.target_history_style); } { planetarium.PlanetariumPlotPrediction( Plugin, target_id, VertexBuffer.data, VertexBuffer.size, out int vertex_count); DrawLineMesh(target_prediction_mesh_, vertex_count, adapter_.target_prediction_colour, adapter_.target_prediction_style); } } // Main vessel flight plan. if (Plugin.FlightPlanExists(main_vessel_guid)) { int number_of_segments = Plugin.FlightPlanNumberOfSegments(main_vessel_guid); for (int i = flight_plan_segment_meshes_.Count; i < number_of_segments; ++i) { flight_plan_segment_meshes_.Add(MakeDynamicMesh()); } for (int i = 0; i < number_of_segments; ++i) { bool is_burn = i % 2 == 1; planetarium.PlanetariumPlotFlightPlanSegment( Plugin, main_vessel_guid, i, VertexBuffer.data, VertexBuffer.size, out int vertex_count); DrawLineMesh(flight_plan_segment_meshes_[i], vertex_count, is_burn ? adapter_.burn_colour : adapter_.flight_plan_colour, is_burn ? adapter_.burn_style : adapter_.flight_plan_style); } } }
// Plots the trajectories of |root| and its natural satellites. private void PlotSubtreeTrajectories(DisposablePlanetarium planetarium, string main_vessel_guid, double history_length, CelestialBody root, double tan_angular_resolution) { CelestialTrajectories trajectories; if (!celestial_trajectory_meshes_.TryGetValue(root, out trajectories)) { trajectories = celestial_trajectory_meshes_[root] = new CelestialTrajectories(); } var colour = root.orbitDriver?.Renderer?.orbitColor ?? XKCDColors.SunshineYellow; var camera_world_position = ScaledSpace.ScaledToLocalSpace( PlanetariumCamera.fetch.transform.position); double min_distance_from_camera = (root.position - camera_world_position).magnitude; if (!adapter_.plotting_frame_selector_.FixesBody(root) && adapter_.show_celestial_trajectory(root)) { { planetarium.PlanetariumPlotCelestialPastTrajectory( Plugin, root.flightGlobalsIndex, history_length, VertexBuffer.data, VertexBuffer.size, out double min_past_distance, out int vertex_count); min_distance_from_camera = Math.Min(min_distance_from_camera, min_past_distance); DrawLineMesh(trajectories.past, vertex_count, colour, GLLines.Style.Faded); } if (main_vessel_guid != null) { planetarium.PlanetariumPlotCelestialFutureTrajectory( Plugin, root.flightGlobalsIndex, main_vessel_guid, VertexBuffer.data, VertexBuffer.size, out double min_future_distance, out int vertex_count); min_distance_from_camera = Math.Min(min_distance_from_camera, min_future_distance); DrawLineMesh(trajectories.future, vertex_count, colour, GLLines.Style.Solid); } } foreach (CelestialBody child in root.orbitingBodies) { // Plot the trajectory of an orbiting body if it could be separated from // that of its parent by a pixel of empty space, instead of merely making // the line wider; but always traverse the subtree if the current body is // hidden. if (!adapter_.show_celestial_trajectory(root) || child.orbit.ApR / min_distance_from_camera > 2 * tan_angular_resolution) { PlotSubtreeTrajectories(planetarium, main_vessel_guid, history_length, child, tan_angular_resolution); } } }