Bug #13195
Vessel.GetWorldPos3D() return sun position in certain conditions
Status:
New
Severity:
Low
Assignee:
-
Category:
Physics
Target version:
-
Start date:
11/06/2016
% Done:
0%
Language:
English (US)
Mod Related:
No
Votes:
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()); } }