Project

General

Profile

Bug #13195

Vessel.GetWorldPos3D() return sun position in certain conditions

Added by ShotgunNinja over 7 years ago.

Status:
New
Severity:
Low
Assignee:
-
Category:
Physics
Target version:
-
Start date:
11/06/2016
% Done:

0%

Version:
Platform:
Windows
Expansion:
Language:
English (US)
Mod Related:
No
Votes:
Arrow u r green
Arrow d r red

Description

When a vessel is orbiting the sun, and the user switch from flight to space center scene,
for a single tick the position returned by Vessel.GetWorldPos3D() is the same as the sun.
This in turn lead to bad things (tm).

For example, background simulation of solar panels will get a zero distance for a single
tick, leading to NaN amounts of ElectricCharge being added to the vessel, in turn leading
to NaN vessel mass the next time the vessel is loaded, and finally to the universe explosion.

Test case

[KSPAddon(KSPAddon.Startup.MainMenu, true)]
public sealed class TestCase : MonoBehaviour
{
  TestCase() { DontDestroyOnLoad(this); }

  public void FixedUpdate()
  {
    Vector3d sun_position = FlightGlobals.Bodies[0].position;
    foreach(Vessel v in FlightGlobals.Vessels)
    {
      Vector3d vessel_position = v.GetWorldPos3D();

      if (Vector3d.Distance(sun_position, vessel_position) <= double.Epsilon)
      {
        print("!!! BAD THING HAPPENED FOR VESSEL " + v.vesselName);
      }
    }
  }
}

Reproduction steps
  • launch a vessel, exit kerbin SOI and enter orbit around the Sun
  • go back to the space center
  • there will be a 'BAD THING HAPPENED' entry in the log, for only one thick

Workaround
This is the workaround I've been using to avoid the issue.

  public static bool Landed(Vessel v)
  {
    if (v.loaded) return v.Landed || v.Splashed;
    else return v.protoVessel.landed || v.protoVessel.splashed;
  }

  public static Vector3d VesselPosition(Vessel v)
  {
    // if loaded, or landed, or orbit is invalid
    if (v.loaded || Landed(v) || double.IsNaN(v.orbit.inclination))
    {
      return v.GetWorldPos3D();
    }
    // in all other cases
    else
    {
      // resolve the orbit position, that is reliable in all cases
      return v.orbit.getPositionAtUT(Planetarium.GetUniversalTime());
    }
  }

test case results.png (107 KB) test case results.png Running the test case lead to these results ShotgunNinja, 11/06/2016 08:57 AM
25808

Also available in: Atom PDF