public static void DoAirlaunch(AirlaunchParams launchParams) { CelestialBody body = FlightGlobals.currentMainBody; Vessel vessel = FlightGlobals.ActiveVessel; // SpaceCenter.Instance.transform doesn't work correctly with RSS + KSCSwitcher installed PQSCity ksc = KCT_Utilities.FindKSC(body); Vector3d kscPosition = ksc.transform.position - body.position; Vector3d kscUp = kscPosition.normalized; Vector3d kscEast = Vector3d.Cross(body.angularVelocity, kscPosition).normalized; Vector3d kscNorth = Vector3d.Cross(kscEast, kscUp); double kscAltitude = kscPosition.magnitude - body.Radius; // From https://www.movable-type.co.uk/scripts/latlong-vectors.html#midpoint var δ = launchParams.KscDistance / body.Radius; var d = kscNorth * Math.Cos(Mathf.Deg2Rad * launchParams.KscAzimuth) + kscEast * Math.Sin(Mathf.Deg2Rad * launchParams.KscAzimuth); var teleportPosition = kscPosition * Math.Cos(δ) + body.Radius * d * Math.Sin(δ); teleportPosition += teleportPosition.normalized * (launchParams.Altitude - kscAltitude); Vector3d up = teleportPosition.normalized; Vector3d east = Vector3d.Cross(body.angularVelocity, teleportPosition).normalized; Vector3d north = Vector3d.Cross(east, up); Vector3d teleportVelocity = Vector3d.Cross(body.angularVelocity, teleportPosition); teleportVelocity += (Math.Sin(Mathf.Deg2Rad * launchParams.LaunchAzimuth) * east + Math.Cos(Mathf.Deg2Rad * launchParams.LaunchAzimuth) * north) * launchParams.Velocity; // counter for the momentary fall when on rails teleportVelocity += up * (body.gravParameter / teleportPosition.sqrMagnitude / 2); teleportPosition = teleportPosition.xzy; teleportVelocity = teleportVelocity.xzy; Vector3d to = teleportPosition.xzy.normalized; Quaternion rotation = Quaternion.LookRotation(-to); rotation *= Quaternion.AngleAxis((float)launchParams.LaunchAzimuth, Vector3.back); Orbit orbit = vessel.orbitDriver.orbit.Clone(); orbit.UpdateFromStateVectors(teleportPosition, teleportVelocity, body, Planetarium.GetUniversalTime()); vessel.SetOrbit(orbit); vessel.SetRotation(rotation); ResetGroundContact(vessel); }