public static void UpdatePositionValues(this ProtoVessel protoVessel, VesselPositionUpdate update) { if (protoVessel == null) { return; } protoVessel.latitude = update.LatLonAlt[0]; protoVessel.longitude = update.LatLonAlt[1]; protoVessel.altitude = update.LatLonAlt[2]; protoVessel.height = update.HeightFromTerrain; protoVessel.normal[0] = update.Normal[0]; protoVessel.normal[1] = update.Normal[1]; protoVessel.normal[2] = update.Normal[2]; protoVessel.rotation[0] = update.SrfRelRotation[0]; protoVessel.rotation[1] = update.SrfRelRotation[1]; protoVessel.rotation[2] = update.SrfRelRotation[2]; protoVessel.rotation[3] = update.SrfRelRotation[3]; protoVessel.orbitSnapShot.inclination = update.Orbit[0]; protoVessel.orbitSnapShot.eccentricity = update.Orbit[1]; protoVessel.orbitSnapShot.semiMajorAxis = update.Orbit[2]; protoVessel.orbitSnapShot.LAN = update.Orbit[3]; protoVessel.orbitSnapShot.argOfPeriapsis = update.Orbit[4]; protoVessel.orbitSnapShot.meanAnomalyAtEpoch = update.Orbit[5]; protoVessel.orbitSnapShot.epoch = update.Orbit[6]; protoVessel.orbitSnapShot.ReferenceBodyIndex = (int)update.Orbit[7]; }
public static void SetVesselPosition(this Vessel vessel, VesselPositionUpdate update, VesselPositionUpdate target, float percentage) { if (vessel == null || update == null || target == null) { return; } var lerpedBody = percentage < 0.5 ? update.Body : target.Body; ApplyOrbitInterpolation(vessel, update, target, lerpedBody, percentage); //Do not use CoM. It's not needed and it generate issues when you patch the protovessel with it as it generate weird commnet lines //It's important to set the static pressure as otherwise the vessel situation is not updated correctly when //Vessel.updateSituation() is called in the Vessel.LateUpdate(). Same applies for landed and splashed vessel.staticPressurekPa = FlightGlobals.getStaticPressure(target.LatLonAlt[2], lerpedBody); vessel.heightFromTerrain = target.HeightFromTerrain; if (!vessel.loaded) { //DO NOT lerp the latlonalt as otherwise if you are in orbit you will see landed vessels in the map view with weird jittering vessel.latitude = target.LatLonAlt[0]; vessel.longitude = target.LatLonAlt[1]; vessel.altitude = target.LatLonAlt[2]; if (vessel.LandedOrSplashed) { vessel.SetPosition(lerpedBody.GetWorldSurfacePosition(vessel.latitude, vessel.longitude, vessel.altitude)); } } else { ApplyInterpolationsToLoadedVessel(vessel, update, target, lerpedBody, percentage); } }
private static void ApplyOrbitInterpolation(Vessel vessel, VesselPositionUpdate update, VesselPositionUpdate target, CelestialBody lerpedBody, float percentage) { var startTime = Planetarium.GetUniversalTime(); var targetTime = Planetarium.GetUniversalTime(); //Uncomment this if you want to show the other vessels as in their PAST positions //This is the old way of how LMP handled the vessels positions when YOUR vessel is in the future //Now the vessel positions are advanced and "projected" //startTime = _startOrbit.epoch; //targetTime = _endOrbit.epoch; var currentPos = update.KspOrbit.getRelativePositionAtUT(startTime); var targetPos = target.KspOrbit.getRelativePositionAtUT(targetTime); var currentVel = update.KspOrbit.getOrbitalVelocityAtUT(startTime); var targetVel = target.KspOrbit.getOrbitalVelocityAtUT(targetTime); var lerpedPos = Vector3d.Lerp(currentPos, targetPos, percentage); var lerpedVel = Vector3d.Lerp(currentVel, targetVel, percentage); var updateTime = Planetarium.GetUniversalTime(); //Uncomment this if you want to show the other vessels as in their PAST positions //updateTime = LunaMath.Lerp(startTime, targetTime, percentage); vessel.orbit.UpdateFromStateVectors(lerpedPos, lerpedVel, lerpedBody, updateTime); }
private static void ApplyOrbitInterpolation(Vessel vessel, VesselPositionUpdate update, VesselPositionUpdate target, CelestialBody lerpedBody, float percentage) { var currentPos = update.KspOrbit.getRelativePositionAtUT(TimeSyncSystem.UniversalTime); var targetPos = target.KspOrbit.getRelativePositionAtUT(TimeSyncSystem.UniversalTime); var currentVel = update.KspOrbit.getOrbitalVelocityAtUT(TimeSyncSystem.UniversalTime); var targetVel = target.KspOrbit.getOrbitalVelocityAtUT(TimeSyncSystem.UniversalTime); var lerpedPos = Vector3d.Lerp(currentPos, targetPos, percentage); var lerpedVel = Vector3d.Lerp(currentVel, targetVel, percentage); vessel.orbit.UpdateFromStateVectors(lerpedPos, lerpedVel, lerpedBody, TimeSyncSystem.UniversalTime); }
private static void ApplyOrbitInterpolation(Vessel vessel, VesselPositionUpdate update, VesselPositionUpdate target, CelestialBody lerpedBody, float percentage) { var currentPos = update.KspOrbit.getRelativePositionAtUT(TimeSyncSystem.UniversalTime); var targetPos = target.KspOrbit.getRelativePositionAtUT(TimeSyncSystem.UniversalTime); var currentVel = update.KspOrbit.getOrbitalVelocityAtUT(TimeSyncSystem.UniversalTime); var targetVel = target.KspOrbit.getOrbitalVelocityAtUT(TimeSyncSystem.UniversalTime); var lerpedPos = Vector3d.Lerp(currentPos, targetPos, percentage); var lerpedVel = Vector3d.Lerp(currentVel, targetVel, percentage); //This call will update the orbit PARAMETERS (ecc, sma, inc, etc) based on the vectors you pass as parameters //Bear in mind that this method will NOT reposition the vessel!! vessel.orbit.UpdateFromStateVectors(lerpedPos, lerpedVel, lerpedBody, TimeSyncSystem.UniversalTime); }
private static void ApplyInterpolationsToLoadedVessel(Vessel vessel, VesselPositionUpdate update, VesselPositionUpdate target, CelestialBody lerpedBody, float percentage) { //Do not call vessel.orbitDriver.updateFromParameters()!! //It will set the vessel at the CURRENT position and ignore that the orbit is from the PAST! var currentSurfaceRelRotation = Quaternion.Slerp(update.SurfaceRelRotation, target.SurfaceRelRotation, percentage); //If you don't set srfRelRotation and vessel is packed it won't change it's rotation vessel.srfRelRotation = currentSurfaceRelRotation; vessel.SetRotation((Quaternion)lerpedBody.rotation * currentSurfaceRelRotation, true); vessel.Landed = percentage < 0.5 ? update.Landed : target.Landed; vessel.Splashed = percentage < 0.5 ? update.Splashed : target.Splashed; vessel.latitude = LunaMath.Lerp(update.LatLonAlt[0], target.LatLonAlt[0], percentage); vessel.longitude = LunaMath.Lerp(update.LatLonAlt[1], target.LatLonAlt[1], percentage); vessel.altitude = LunaMath.Lerp(update.LatLonAlt[2], target.LatLonAlt[2], percentage); //var startLatLonAltPos = update.Body.GetWorldSurfacePosition(update.LatLonAlt[0], update.LatLonAlt[1], update.LatLonAlt[2]); //var targetLatLonAltPos = target.Body.GetWorldSurfacePosition(target.LatLonAlt[0], target.LatLonAlt[1], target.LatLonAlt[2]); //var startOrbitPos = startOrbit.getPositionAtUT(startOrbit.epoch); //var endOrbitPos = endOrbit.getPositionAtUT(endOrbit.epoch); vessel.SetPosition(vessel.orbit.getPositionAtUT(Planetarium.GetUniversalTime())); if (vessel.situation <= Vessel.Situations.PRELAUNCH) { vessel.SetPosition(lerpedBody.GetWorldSurfacePosition(vessel.latitude, vessel.longitude, vessel.altitude)); } //Always run this at the end!! //Otherwise during docking, the orbital speeds are not displayed correctly and you won't be able to dock if (!vessel.packed) { var velBeforeCorrection = vessel.rootPart.rb.velocity; vessel.rootPart.ResumeVelocity(); if (velBeforeCorrection != vessel.rootPart.rb.velocity) { foreach (var part in vessel.Parts) { part.ResumeVelocity(); } } } }
public static void SetVesselPosition(this Vessel vessel, VesselPositionUpdate update, VesselPositionUpdate target, float percentage) { if (vessel == null || update == null || target == null) { return; } var lerpedBody = percentage < 0.5 ? update.Body : target.Body; ApplyOrbitInterpolation(vessel, update, target, lerpedBody, percentage); //Do not use CoM. It's not needed and it generate issues when you patch the protovessel with it as it generate weird commnet lines //It's important to set the static pressure as otherwise the vessel situation is not updated correctly when //Vessel.updateSituation() is called in the Vessel.LateUpdate(). Same applies for landed and splashed vessel.staticPressurekPa = FlightGlobals.getStaticPressure(target.LatLonAlt[2], lerpedBody); vessel.heightFromTerrain = target.HeightFromTerrain; ApplyInterpolationsToVessel(vessel, update, target, lerpedBody, percentage); }
public static void UpdateVesselProtoPosition(VesselPositionUpdate vesselPositionUpdate) { if (vesselPositionUpdate == null) { return; } if (AllPlayerVessels.TryGetValue(vesselPositionUpdate.VesselId, out var vesselProtoUpd)) { if (vesselProtoUpd.ProtoVessel == null) { return; } vesselProtoUpd.ProtoVessel.latitude = vesselPositionUpdate.LatLonAlt[0]; vesselProtoUpd.ProtoVessel.longitude = vesselPositionUpdate.LatLonAlt[1]; vesselProtoUpd.ProtoVessel.altitude = vesselPositionUpdate.LatLonAlt[2]; vesselProtoUpd.ProtoVessel.height = vesselPositionUpdate.HeightFromTerrain; vesselProtoUpd.ProtoVessel.normal.x = (float)vesselPositionUpdate.NormalVector[0]; vesselProtoUpd.ProtoVessel.normal.y = (float)vesselPositionUpdate.NormalVector[1]; vesselProtoUpd.ProtoVessel.normal.z = (float)vesselPositionUpdate.NormalVector[2]; vesselProtoUpd.ProtoVessel.rotation.x = vesselPositionUpdate.SrfRelRotation[0]; vesselProtoUpd.ProtoVessel.rotation.y = vesselPositionUpdate.SrfRelRotation[1]; vesselProtoUpd.ProtoVessel.rotation.z = vesselPositionUpdate.SrfRelRotation[2]; vesselProtoUpd.ProtoVessel.rotation.w = vesselPositionUpdate.SrfRelRotation[3]; if (vesselProtoUpd.ProtoVessel.orbitSnapShot != null) { vesselProtoUpd.ProtoVessel.orbitSnapShot.inclination = vesselPositionUpdate.Orbit[0]; vesselProtoUpd.ProtoVessel.orbitSnapShot.eccentricity = vesselPositionUpdate.Orbit[1]; vesselProtoUpd.ProtoVessel.orbitSnapShot.semiMajorAxis = vesselPositionUpdate.Orbit[2]; vesselProtoUpd.ProtoVessel.orbitSnapShot.LAN = vesselPositionUpdate.Orbit[3]; vesselProtoUpd.ProtoVessel.orbitSnapShot.argOfPeriapsis = vesselPositionUpdate.Orbit[4]; vesselProtoUpd.ProtoVessel.orbitSnapShot.meanAnomalyAtEpoch = vesselPositionUpdate.Orbit[5]; vesselProtoUpd.ProtoVessel.orbitSnapShot.epoch = vesselPositionUpdate.Orbit[6]; vesselProtoUpd.ProtoVessel.orbitSnapShot.ReferenceBodyIndex = (int)vesselPositionUpdate.Orbit[7]; } } }
private static void ApplyInterpolationsToVessel(Vessel vessel, VesselPositionUpdate update, VesselPositionUpdate target, CelestialBody lerpedBody, float percentage) { var currentSurfaceRelRotation = Quaternion.Slerp(update.SurfaceRelRotation, target.SurfaceRelRotation, percentage); //If you don't set srfRelRotation and vessel is packed it won't change it's rotation vessel.srfRelRotation = currentSurfaceRelRotation; vessel.Landed = percentage < 0.5 ? update.Landed : target.Landed; vessel.Splashed = percentage < 0.5 ? update.Splashed : target.Splashed; vessel.latitude = LunaMath.Lerp(update.LatLonAlt[0], target.LatLonAlt[0], percentage); vessel.longitude = LunaMath.Lerp(update.LatLonAlt[1], target.LatLonAlt[1], percentage); vessel.altitude = LunaMath.Lerp(update.LatLonAlt[2], target.LatLonAlt[2], percentage); var rotation = (Quaternion)lerpedBody.rotation * currentSurfaceRelRotation; var position = vessel.situation <= Vessel.Situations.SUB_ORBITAL ? lerpedBody.GetWorldSurfacePosition(vessel.latitude, vessel.longitude, vessel.altitude) : vessel.orbit.getPositionAtUT(TimeSyncSystem.UniversalTime); SetVesselPositionAndRotation(vessel, position, rotation); }