Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Early detection of NaN in terrain computation #4042

Merged
merged 3 commits into from
Jul 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 47 additions & 10 deletions ksp_plugin_adapter/ksp_plugin_adapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using UnityEngine.Profiling;
using static principia.ksp_plugin_adapter.FrameType;

Expand Down Expand Up @@ -94,6 +95,7 @@ internal IntPtr Plugin() {
// EulerSolver.
CelestialBody last_main_body_;
private int main_body_change_countdown_ = 1;
private bool celestial_terrains_were_validated_ = false;

private PlanetariumCameraAdjuster planetarium_camera_adjuster_;

Expand Down Expand Up @@ -720,6 +722,37 @@ public static void LoadTextureOrDie(out UnityEngine.Texture texture,
}
}

public static double RadiusAt(CelestialBody centre,
double latitude,
double longitude) {
double altitude = centre.TerrainAltitude(
latitude,
longitude,
allowNegative: !centre.ocean);
if (double.IsNaN(altitude)) {
Log.Fatal("Terrain system returned NaN for altitude at latitude " +
latitude +
", longitude " +
longitude +
" for celestial " +
centre.name);
}
if (double.IsNaN(centre.Radius)) {
Log.Fatal("Radius is NaN for celestial " + centre.name);
}
return altitude + centre.Radius;
}

[MethodImpl(MethodImplOptions.NoOptimization)]
public static void ValidateCelestialTerrain(CelestialBody centre,
Random random) {
for (int i = 0; i < 5; ++i) {
double latitude = random.NextDouble() * 360.0 - 180.0;
double longitude = random.NextDouble() * 360.0 - 180.0;
RadiusAt(centre, latitude: latitude, longitude: longitude);
}
}

#region ScenarioModule lifecycle

// These functions override virtual ones from |ScenarioModule|, but it seems
Expand Down Expand Up @@ -1804,6 +1837,14 @@ private void BetterLateThanNever() {
}

private void BetterLateThanNeverLateUpdate() {
if (!celestial_terrains_were_validated_) {
var random = new Random();
foreach (CelestialBody celestial in FlightGlobals.Bodies) {
ValidateCelestialTerrain(celestial, random);
}
celestial_terrains_were_validated_ = true;
}

// While we draw the trajectories directly (and thus do so after everything
// else has been rendered), we rely on the game to render its map nodes.
// Since the screen position is determined in |MapNode.NodeUpdate|, it must
Expand Down Expand Up @@ -2327,11 +2368,9 @@ private void RenderManœuvreMarkers() {
return null;
}
}
executor.CollisionSetRadius(centre.TerrainAltitude(
trial_latitude,
trial_longitude,
allowNegative: !centre.ocean) +
centre.Radius);
executor.CollisionSetRadius(RadiusAt(centre,
latitude: trial_latitude,
longitude: trial_longitude));
}
}

Expand All @@ -2355,11 +2394,9 @@ private void RenderManœuvreMarkers() {
return null;
}
}
executor.CollisionSetRadius(centre.TerrainAltitude(
trial_latitude,
trial_longitude,
allowNegative: !centre.ocean) +
centre.Radius);
executor.CollisionSetRadius(RadiusAt(centre,
latitude: trial_latitude,
longitude: trial_longitude));
}
}

Expand Down