public static void drawLandingArea(CelestialBody body, double minLatitude, double maxLatitude, double minLongitude, double maxLongitude, Color c, double rotation = 0) { double dlat = (maxLatitude - minLatitude) / 10.0; double dlog = (maxLongitude - minLongitude) / 10.0; List <Vector3d[]> quads = new List <Vector3d[]> (); for (double lat = minLatitude; lat + dlat < maxLatitude; lat += dlat) { for (double log = minLongitude; log + dlog < maxLongitude; log += dlog) { Vector3d up1 = body.GetSurfaceNVector(lat, log); Vector3d center1 = body.position + body.Radius * up1; Vector3d up2 = body.GetSurfaceNVector(lat, log + dlog); Vector3d center2 = body.position + body.Radius * up2; Vector3d up3 = body.GetSurfaceNVector(lat + dlat, log + dlog); Vector3d center3 = body.position + body.Radius * up3; Vector3d up4 = body.GetSurfaceNVector(lat + dlat, log); Vector3d center4 = body.position + body.Radius * up4; if (!IsOccluded(center1, body)) { quads.Add(new Vector3d[] { center1, center2, center3, center4 }); } } } GLQuadMap(quads, c); }
public static void drawLandingArea(CelestialBody body, double minLatitude, double maxLatitude, double minLongitude, double maxLongitude, Color c, double rotation = 0) { double dlat = (maxLatitude - minLatitude) / 10.0; double dlog = (maxLongitude - minLongitude) / 10.0; List<Vector3d[]> quads = new List<Vector3d[]> (); for (double lat = minLatitude; lat + dlat < maxLatitude; lat += dlat) { for (double log = minLongitude; log + dlog < maxLongitude; log += dlog) { Vector3d up1 = body.GetSurfaceNVector (lat, log); Vector3d center1 = body.position + body.Radius * up1; Vector3d up2 = body.GetSurfaceNVector (lat, log + dlog); Vector3d center2 = body.position + body.Radius * up2; Vector3d up3 = body.GetSurfaceNVector (lat + dlat, log + dlog); Vector3d center3 = body.position + body.Radius * up3; Vector3d up4 = body.GetSurfaceNVector (lat + dlat, log); Vector3d center4 = body.position + body.Radius * up4; if (!IsOccluded (center1, body)) { quads.Add (new Vector3d[] { center1, center2, center3, center4}); } } } GLQuadMap (quads, c); }
public static ReferenceFrame CreateAtCurrentTime(CelestialBody referenceBody) { ReferenceFrame ret = new ReferenceFrame(); ret.lat0lon0AtStart = referenceBody.GetSurfaceNVector(0, 0); ret.lat0lon90AtStart = referenceBody.GetSurfaceNVector(0, 90); ret.lat90AtStart = referenceBody.GetSurfaceNVector(90, 0); ret.epoch = Planetarium.GetUniversalTime(); ret.referenceBody = referenceBody; return(ret); }
//Computes the time until the phase angle between the launchpad and the target equals the given angle. //The convention used is that phase angle is the angle measured starting at the target and going east until //you get to the launchpad. //The time returned will not be exactly accurate unless the target is in an exactly circular orbit. However, //the time returned will go to exactly zero when the desired phase angle is reached. public static double TimeToPhaseAngle(double phaseAngle, CelestialBody launchBody, double launchLongitude, Orbit target) { double launchpadAngularRate = 360 / launchBody.rotationPeriod; double targetAngularRate = 360.0 / target.period; if (Vector3d.Dot(target.SwappedOrbitNormal(), launchBody.angularVelocity) < 0) targetAngularRate *= -1; //retrograde target Vector3d currentLaunchpadDirection = launchBody.GetSurfaceNVector(0, launchLongitude); Vector3d currentTargetDirection = target.SwappedRelativePositionAtUT(Planetarium.GetUniversalTime()); currentTargetDirection = Vector3d.Exclude(launchBody.angularVelocity, currentTargetDirection); double currentPhaseAngle = Math.Abs(Vector3d.Angle(currentLaunchpadDirection, currentTargetDirection)); if (Vector3d.Dot(Vector3d.Cross(currentTargetDirection, currentLaunchpadDirection), launchBody.angularVelocity) < 0) { currentPhaseAngle = 360 - currentPhaseAngle; } double phaseAngleRate = launchpadAngularRate - targetAngularRate; double phaseAngleDifference = MuUtils.ClampDegrees360(phaseAngle - currentPhaseAngle); if (phaseAngleRate < 0) { phaseAngleRate *= -1; phaseAngleDifference = 360 - phaseAngleDifference; } return phaseAngleDifference / phaseAngleRate; }
//Computes the time until the phase angle between the launchpad and the target equals the given angle. //The convention used is that phase angle is the angle measured starting at the target and going east until //you get to the launchpad. //The time returned will not be exactly accurate unless the target is in an exactly circular orbit. However, //the time returned will go to exactly zero when the desired phase angle is reached. public static double TimeToPhaseAngle(double phaseAngle, CelestialBody launchBody, double launchLongitude, Orbit target) { double launchpadAngularRate = 360 / launchBody.rotationPeriod; double targetAngularRate = 360.0 / target.period; if (Vector3d.Dot(target.SwappedOrbitNormal(), launchBody.angularVelocity) < 0) { targetAngularRate *= -1; //retrograde target } Vector3d currentLaunchpadDirection = launchBody.GetSurfaceNVector(0, launchLongitude); Vector3d currentTargetDirection = target.SwappedRelativePositionAtUT(Planetarium.GetUniversalTime()); currentTargetDirection = Vector3d.Exclude(launchBody.angularVelocity, currentTargetDirection); double currentPhaseAngle = Math.Abs(Vector3d.Angle(currentLaunchpadDirection, currentTargetDirection)); if (Vector3d.Dot(Vector3d.Cross(currentTargetDirection, currentLaunchpadDirection), launchBody.angularVelocity) < 0) { currentPhaseAngle = 360 - currentPhaseAngle; } double phaseAngleRate = launchpadAngularRate - targetAngularRate; double phaseAngleDifference = MuUtils.ClampDegrees360(phaseAngle - currentPhaseAngle); if (phaseAngleRate < 0) { phaseAngleRate *= -1; phaseAngleDifference = 360 - phaseAngleDifference; } return(phaseAngleDifference / phaseAngleRate); }
//Interprets a given AbsoluteVector as a velocity, and returns the corresponding Vector3d velocity //in world coordinates. public Vector3d WorldVelocityAtCurrentTime(AbsoluteVector absolute) { double now = Planetarium.GetUniversalTime(); double unrotatedLongitude = MuUtils.ClampDegrees360(absolute.longitude - 360 * (now - absolute.UT) / referenceBody.rotationPeriod); return(absolute.radius * referenceBody.GetSurfaceNVector(absolute.latitude, unrotatedLongitude)); }
public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, Color c, double rotation = 0) { Vector3d up = body.GetSurfaceNVector(latitude, longitude); Vector3d center = body.position + body.Radius * up; if (IsOccluded(center, body)) return; Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; double radius = body.Radius / 15; GLTriangleMap(new Vector3d[]{ center, center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north) }, c); GLTriangleMap(new Vector3d[]{ center, center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north) }, c); GLTriangleMap(new Vector3d[]{ center, center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north) }, c); }
public Vector3d Up() { double lat = body.GetLatitude(center); double lon = body.GetLongitude(center); return(body.GetSurfaceNVector(lat, lon)); }
private int GetHeading() { body = staticInstance.CelestialBody; upVector = body.GetSurfaceNVector(staticInstance.RefLatitude, staticInstance.RefLongitude).normalized; north = Vector3.ProjectOnPlane(body.transform.up, upVector).normalized; east = Vector3.Cross(upVector, north).normalized; forward = Vector3.ProjectOnPlane(gameObject.transform.forward, upVector); float heading = Vector3.Angle(forward, north); if (Vector3.Dot(forward, east) < 0) { heading = 360 - heading; } heading = (heading + headingAdj + 360) % 360; if (heading % 10 > 5) { heading += 10 - heading % 10; } if (heading < 6) { heading = 360; // There are no 00 runways, they all are 36! } return((int)heading); }
public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, Color c, double rotation = 0, double radius = 0) { Vector3d up = body.GetSurfaceNVector(latitude, longitude); var height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right); if (height < body.Radius) { height = body.Radius; } Vector3d center = body.position + height * up; if (IsOccluded(center, body)) return; Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; if (radius <= 0) { radius = body.Radius / 15; } GLTriangleMap(new Vector3d[]{ center, center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north) }, c); GLTriangleMap(new Vector3d[]{ center, center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north) }, c); GLTriangleMap(new Vector3d[]{ center, center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north) }, c); }
public static Vector3 GetNorthVector(Vector3 position, CelestialBody body) { Vector3 geoPosA = VectorUtils.WorldPositionToGeoCoords(position, body); Vector3 geoPosB = new Vector3(geoPosA.x+1, geoPosA.y, geoPosA.z); Vector3 north = GetWorldSurfacePostion(geoPosB, body)-GetWorldSurfacePostion(geoPosA, body); return Vector3.ProjectOnPlane(north, body.GetSurfaceNVector(geoPosA.x, geoPosA.y)).normalized; }
public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, double radius, Color c, double rotation = 0) { Vector3d up = body.GetSurfaceNVector(latitude, longitude); Vector3d center = body.position + body.Radius * up; if (IsOccluded(center, body)) { return; } Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; //double radius = body.Radius / 15; GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north) }, c); GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north) }, c); GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north) }, c); }
public static bool DrawCBMarker(CelestialBody body, Coordinates pos, Color color, out Vector3d worldPos, Texture2D texture = null, float size = DefaultIconSize) { worldPos = Vector3d.zero; Camera camera; Vector3d point; if (MapView.MapIsEnabled) { //TODO: cache local center coordinates of the marker camera = PlanetariumCamera.Camera; worldPos = body.position + (pos.Alt + body.Radius) * body.GetSurfaceNVector(pos.Lat, pos.Lon); point = ScaledSpace.LocalToScaledSpace(worldPos); if (IsOccluded(worldPos, body)) { return(false); } } else { camera = FlightCamera.fetch.mainCamera; worldPos = body.GetWorldSurfacePosition(pos.Lat, pos.Lon, pos.Alt); point = worldPos; if (camera.transform.InverseTransformPoint(worldPos).z <= 0) { return(false); } } return(color.a > 0 && DrawMarker(camera.WorldToScreenPoint(point), color, texture, size)); }
public double GroundDistanceFromMark() { CelestialBody markBody = FlightGlobals.Bodies[markBodyIndex]; Vector3d markVector = markBody.GetSurfaceNVector(markLatitude, markLongitude); Vector3d vesselVector = vesselState.CoM - markBody.transform.position; return(markBody.Radius * Vector3d.Angle(markVector, vesselVector) * UtilMath.Deg2Rad); }
public static Vector3 GetNorthVector(Vector3 position, CelestialBody body) { Vector3 geoPosA = WorldPositionToGeoCoords(position, body); Vector3 geoPosB = new Vector3(geoPosA.x + 1, geoPosA.y, geoPosA.z); Vector3 north = GetWorldSurfacePostion(geoPosB, body) - GetWorldSurfacePostion(geoPosA, body); return(Vector3.ProjectOnPlane(north, body.GetSurfaceNVector(geoPosA.x, geoPosA.y)).normalized); }
public Vector3d GetSurfaceNormalVector() { CelestialBody body = ParentBody ? ParentBody : ParentVessel?.mainBody; if (body == null) { return(Vector3d.zero); } body.GetLatLonAlt(position, out double lat, out double lon, out double _); return(body.GetSurfaceNVector(lat, lon)); }
private static float GetHeading(Transform transform) { CelestialBody body = FlightGlobals.ActiveVessel.mainBody; Vector3 upVector = body.GetSurfaceNVector(body.GetLatitude((Vector3d)transform.position), body.GetLongitude((Vector3d)transform.position)).normalized; Vector3 north = Vector3.ProjectOnPlane(body.transform.up, upVector).normalized; Vector3 east = Vector3.Cross(upVector, north).normalized; Vector3 forward = Vector3.ProjectOnPlane(transform.forward, upVector); return(Vector3.Angle(forward, north)); }
public static DMPRaycastPair RaycastGround(double latitude, double longitude, CelestialBody body) { //We can only find the ground on bodies that actually *have* ground and if we are in flight near the origin if (!HighLogic.LoadedSceneIsFlight || FlightGlobals.fetch.activeVessel == null || body.pqsController == null) { return(new DMPRaycastPair(-1f, Vector3.up)); } //Math functions take radians. double latRadians = latitude * Mathf.Deg2Rad; double longRadians = longitude * Mathf.Deg2Rad; //Radial vector Vector3d surfaceRadial = new Vector3d(Math.Cos(latRadians) * Math.Cos(longRadians), Math.Sin(latRadians), Math.Cos(latRadians) * Math.Sin(longRadians)); double surfaceHeight = body.pqsController.GetSurfaceHeight(surfaceRadial) - body.pqsController.radius; Vector3d origin = body.GetWorldSurfacePosition(latitude, longitude, surfaceHeight + 500); //Only return the surface if it's really close. double highestHit = double.NegativeInfinity; Vector3 rotatedVector = Vector3.up; if (Vector3d.Distance(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), origin) < 2500) { //Down vector Vector3d downVector = -body.GetSurfaceNVector(latitude, longitude); //Magic numbers, comes from Vessel.GetHeightFromTerrain LayerMask groundMask = 32768; RaycastHit[] raycastHits = Physics.RaycastAll(origin, downVector, 1000f, groundMask); foreach (RaycastHit raycastHit in raycastHits) { if (raycastHit.collider == null) { //I don't think this is technically possible, but unity's weird enough that we should probably check this anyway. continue; } if (raycastHit.collider.name == body.name) { continue; } double hitAltitude = body.GetAltitude(raycastHit.point); if ((hitAltitude > highestHit) && (!body.ocean || hitAltitude > 0)) { highestHit = hitAltitude; rotatedVector = Quaternion.Inverse(body.rotation) * raycastHit.normal; } } } if (double.IsNegativeInfinity(highestHit)) { return(new DMPRaycastPair(-1f, Vector3.up)); } else { return(new DMPRaycastPair(highestHit, rotatedVector)); } }
public static void DrawGroundMarker(CelestialBody body, double latitude, double longitude, Color c, bool map, double rotation = 0, double radius = 0) { Vector3d up = body.GetSurfaceNVector(latitude, longitude); var height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right); if (height < body.Radius) { height = body.Radius; } Vector3d center = body.position + height * up; Vector3d camPos = map ? ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.Camera.transform.position) : (Vector3d)FlightCamera.fetch.mainCamera.transform.position; if (IsOccluded(center, body, camPos)) { return; } Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; if (radius <= 0) { radius = map ? body.Radius / 15 : 5; } if (!map) { Vector3 centerPoint = FlightCamera.fetch.mainCamera.WorldToViewportPoint(center); if (centerPoint.z < 0) { return; } } GLTriangle( center, center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north) , c, map); GLTriangle( center, center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north) , c, map); GLTriangle( center, center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north) , c, map); }
public static DMPRaycastPair RaycastGround(double latitude, double longitude, CelestialBody body) { //We can only find the ground on bodies that actually *have* ground and if we are in flight near the origin if (!HighLogic.LoadedSceneIsFlight || FlightGlobals.fetch.activeVessel == null || body.pqsController == null) { return new DMPRaycastPair(-1f, Vector3.up); } //Math functions take radians. double latRadians = latitude * Mathf.Deg2Rad; double longRadians = longitude * Mathf.Deg2Rad; //Radial vector Vector3d surfaceRadial = new Vector3d(Math.Cos(latRadians) * Math.Cos(longRadians), Math.Sin(latRadians), Math.Cos(latRadians) * Math.Sin(longRadians)); double surfaceHeight = body.pqsController.GetSurfaceHeight(surfaceRadial) - body.pqsController.radius; Vector3d origin = body.GetWorldSurfacePosition(latitude, longitude, surfaceHeight + 500); //Only return the surface if it's really close. double highestHit = double.NegativeInfinity; Vector3 rotatedVector = Vector3.up; if (Vector3d.Distance(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), origin) < 2500) { //Down vector Vector3d downVector = -body.GetSurfaceNVector(latitude, longitude); //Magic numbers! LayerMask groundMask = 33792; RaycastHit[] raycastHits = Physics.RaycastAll(origin, downVector, 1000f, groundMask); foreach (RaycastHit raycastHit in raycastHits) { if (raycastHit.collider == null) { //I don't think this is technically possible, but unity's weird enough that we should probably check this anyway. continue; } if (raycastHit.collider.name == body.name) { continue; } double hitAltitude = body.GetAltitude(raycastHit.point); if ((hitAltitude > highestHit) && (!body.ocean || hitAltitude > 0)) { highestHit = hitAltitude; rotatedVector = Quaternion.Inverse(body.rotation) * raycastHit.normal; } } } if (highestHit == double.NegativeInfinity) { return new DMPRaycastPair(-1f, Vector3.up); } else { return new DMPRaycastPair(highestHit, rotatedVector); } }
public static void DrawGroundMarker(CelestialBody body, double latitude, double longitude, Color c, bool map, double rotation = 0, double radius = 0) { Vector3d up = body.GetSurfaceNVector(latitude, longitude); var height = 1 + body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right); if (height < body.Radius + 1) { height = body.Radius + 1; } Vector3d center = body.position + height * up; Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; if (map) //grr { Vector3d camPos = ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.Camera.transform.position); if (IsOccluded(center, body, camPos)) { return; } } if (radius <= 0) { radius = map ? body.Radius / 50 : 15; } List <Vector3d> Verts = new List <Vector3d>(); int num = 64; for (int i = 0; i <= num; i++) { Verts.Add(center + radius * 0.85 * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north)); Verts.Add(center + radius * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north)); } GLTriangleStrip(Verts, c, map); for (int i = 0; i <= num; i++) { Verts.Add(center + radius * 0.45 * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north)); Verts.Add(center + radius * 0.6 * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north)); } GLTriangleStrip(Verts, c, map); for (int i = 0; i <= num; i++) { Verts.Add(center); Verts.Add(center + radius * 0.2 * (QuaternionD.AngleAxis(rotation + i * 360 / num, up) * north)); } GLTriangleStrip(Verts, c, map); }
protected override bool VesselMeetsCondition(Vessel vessel) { if (!triggered) { return(false); } // The following distance calculation code is from MechJebModuleFlightRecorder CelestialBody markBody = FlightGlobals.GetHomeBody(); Vector3d markVector = markBody.GetSurfaceNVector(markLatitude, markLongitude); Vector3d vesselVector = vessel.CoMD - markBody.transform.position; curDist = markBody.Radius * Vector3d.Angle(markVector, vesselVector) * UtilMath.Deg2Rad; return(curDist > distance); }
private int getHeading() { CelestialBody body = FlightGlobals.ActiveVessel.mainBody; Vector3 upVector = body.GetSurfaceNVector( FlightGlobals.ActiveVessel.latitude, FlightGlobals.ActiveVessel.longitude).normalized; Vector3 north = Vector3.ProjectOnPlane(body.transform.up, upVector).normalized; Vector3 east = Vector3.Cross(upVector, north).normalized; Vector3 forward = Vector3.ProjectOnPlane(gameObject.transform.forward, upVector); float heading = Vector3.Angle(forward, north); if (Vector3.Dot(forward, east) < 0) { heading = 360 - heading; } return((int)heading); }
public IEnumerator <YieldInstruction> Burninator() { LoggingUtil.LogDebug(this, "burninating"); while (burninating && FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.state != Vessel.State.DEAD) { Vessel v = FlightGlobals.ActiveVessel; v.srf_velocity = -jool.GetSurfaceNVector(v.latitude, v.longitude); v.externalTemperature = 1000f; v.atmDensity = 1.0f; v.speed = 3000f; v.mach = 4f; yield return(new WaitForFixedUpdate()); } LoggingUtil.LogDebug(this, "burninating done"); }
public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, Color c, double rotation = 0, double radius = 0) { Vector3d up = body.GetSurfaceNVector(latitude, longitude); var height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right); if (height < body.Radius) { height = body.Radius; } Vector3d center = body.position + height * up; if (IsOccluded(center, body)) { return; } Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; if (radius <= 0) { radius = body.Radius / 15; } GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north) }, c); GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north) }, c); GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north) }, c); }
//From MechJeb2 //Computes the time required for the given launch location to rotate under the target orbital plane. //If the latitude is too high for the launch location to ever actually rotate under the target plane, //returns the time of closest approach to the target plane. //I have a wonderful proof of this formula which this comment is too short to contain. private double[] CalcAngleToPlane(CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target) { double[] o = new double[2]; double inc = Math.Abs(Vector3d.Angle(SwappedOrbitNormal(target), launchBody.angularVelocity)); Vector3d b = Vector3d.Exclude(launchBody.angularVelocity, SwappedOrbitNormal(target)).normalized; // I don't understand the sign here, but this seems to work b *= launchBody.Radius * Math.Sin(Math.PI / 180 * launchLatitude) / Math.Tan(Math.PI / 180 * inc); Vector3d c = Vector3d.Cross(SwappedOrbitNormal(target), launchBody.angularVelocity).normalized; double cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(Math.PI / 180 * launchLatitude), 2) - b.sqrMagnitude; if (cMagnitudeSquared < 0) { cMagnitudeSquared = 0; } c *= Math.Sqrt(cMagnitudeSquared); Vector3d a1 = b + c; Vector3d a2 = b - c; Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude); double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1)); if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0) { angle1 = 360 - angle1; } double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2)); if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0) { angle2 = 360 - angle2; } o[0] = Math.Min(angle1, angle2); o[1] = Math.Max(angle1, angle2) - 360; return(o); }
public static void DrawGroundMarker(CelestialBody body, double latitude, double longitude, Color c, bool map, double rotation = 0, double radius = 0) { Vector3d up = body.GetSurfaceNVector(latitude, longitude); var height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right); if (height < body.Radius) { height = body.Radius; } Vector3d center = body.position + height * up; Vector3d camPos = map ? ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.Camera.transform.position) : (Vector3d)FlightCamera.fetch.mainCamera.transform.position; if (IsOccluded(center, body, camPos)) return; Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; if (radius <= 0) { radius = map ? body.Radius / 15 : 5; } if (!map) { Vector3 centerPoint = FlightCamera.fetch.mainCamera.WorldToViewportPoint(center); if (centerPoint.z < 0) return; } GLTriangle( center, center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north) , c, map); GLTriangle( center, center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north) , c, map); GLTriangle( center, center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north) , c, map); }
public static void DrawGroundMarker(CelestialBody body, double latitude, double longitude, double alt, Color c, bool map, double rotation = 0, double radius = 0) { Vector3d up = body.GetSurfaceNVector(latitude, longitude); Vector3d center = body.GetWorldSurfacePosition(latitude, longitude, alt + 0.5f); Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; if (!map) { Vector3 centerPoint = FlightCamera.fetch.mainCamera.WorldToViewportPoint(center); if ((centerPoint.z < 0) || (centerPoint.x < -1) || (centerPoint.x > 1) || (centerPoint.y < -1) || (centerPoint.y > 1)) { return; } } GLTriangle(center, center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north), c, map); GLTriangle(center, center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north), c, map); GLTriangle(center, center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north), c, map); }
//From MechJeb2 //Computes the time required for the given launch location to rotate under the target orbital plane. //If the latitude is too high for the launch location to ever actually rotate under the target plane, //returns the time of closest approach to the target plane. //I have a wonderful proof of this formula which this comment is too short to contain. internal static double TimeToPlane(CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target) { double inc = Math.Abs(Vector3d.Angle(target.SwappedOrbitNormal(), launchBody.angularVelocity)); Vector3d b = Vector3d.Exclude(launchBody.angularVelocity, target.SwappedOrbitNormal()).normalized; // I don't understand the sign here, but this seems to work b *= launchBody.Radius * Math.Sin(Math.PI / 180 * launchLatitude) / Math.Tan(Math.PI / 180 * inc); Vector3d c = Vector3d.Cross(target.SwappedOrbitNormal(), launchBody.angularVelocity).normalized; double cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(Math.PI / 180 * launchLatitude), 2) - b.sqrMagnitude; if (cMagnitudeSquared < 0) cMagnitudeSquared = 0; c *= Math.Sqrt(cMagnitudeSquared); Vector3d a1 = b + c; Vector3d a2 = b - c; Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude); double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1)); if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0) angle1 = 360 - angle1; double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2)); if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0) angle2 = 360 - angle2; double angle = Math.Min(angle1, angle2); return (angle / 360) * launchBody.rotationPeriod; }
//Computes the time required for the given launch location to rotate under the target orbital plane. //If the latitude is too high for the launch location to ever actually rotate under the target plane, //returns the time of closest approach to the target plane. //I have a wonderful proof of this formula which this comment is too short to contain. public static double TimeToPlane(double LANDifference, CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target) { double inc = Math.Abs(Vector3d.Angle(-target.GetOrbitNormal().Reorder(132).normalized, launchBody.angularVelocity)); Vector3d b = Vector3d.Exclude(launchBody.angularVelocity, -target.GetOrbitNormal().Reorder(132).normalized).normalized; // I don't understand the sign here, but this seems to work b *= launchBody.Radius * Math.Sin(UtilMath.Deg2Rad * launchLatitude) / Math.Tan(UtilMath.Deg2Rad * inc); Vector3d c = Vector3d.Cross(-target.GetOrbitNormal().Reorder(132).normalized, launchBody.angularVelocity).normalized; double cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(UtilMath.Deg2Rad * launchLatitude), 2) - b.sqrMagnitude; if (cMagnitudeSquared < 0) { cMagnitudeSquared = 0; } c *= Math.Sqrt(cMagnitudeSquared); Vector3d a1 = b + c; Vector3d a2 = b - c; Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude); double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1)); if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0) { angle1 = 360 - angle1; } double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2)); if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0) { angle2 = 360 - angle2; } double angle = Math.Min(angle1, angle2) - LANDifference; return((angle / 360) * launchBody.rotationPeriod); }
//Computes the time required for the given launch location to rotate under the target orbital plane. //If the latitude is too high for the launch location to ever actually rotate under the target plane, //returns the time of closest approach to the target plane. //I have a wonderful proof of this formula which this comment is too short to contain. public static double TimeToPlane(CelestialBody launchBody, double launchLatitude, double launchLongitude, Orbit target) { double inc = Math.Abs(Vector3d.Angle(target.SwappedOrbitNormal(), launchBody.angularVelocity)); Vector3d b = Vector3d.Exclude(launchBody.angularVelocity, -target.SwappedOrbitNormal()).normalized; b *= launchBody.Radius * Math.Sin(Math.PI / 180 * launchLatitude) / Math.Tan(Math.PI / 180 * inc); Vector3d c = Vector3d.Cross(target.SwappedOrbitNormal(), launchBody.angularVelocity).normalized; double cMagnitudeSquared = Math.Pow(launchBody.Radius * Math.Cos(Math.PI / 180 * launchLatitude), 2) - b.sqrMagnitude; if (cMagnitudeSquared < 0) { cMagnitudeSquared = 0; } c *= cMagnitudeSquared; Vector3d a1 = b + c; Vector3d a2 = b - c; Vector3d longitudeVector = launchBody.GetSurfaceNVector(0, launchLongitude); double angle1 = Math.Abs(Vector3d.Angle(longitudeVector, a1)); if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a1), launchBody.angularVelocity) < 0) { angle1 = 360 - angle1; } double angle2 = Math.Abs(Vector3d.Angle(longitudeVector, a2)); if (Vector3d.Dot(Vector3d.Cross(longitudeVector, a2), launchBody.angularVelocity) < 0) { angle2 = 360 - angle2; } double angle = Math.Min(angle1, angle2); return((angle / 360) * launchBody.rotationPeriod); }
public Vector3d Up(CelestialBody body) { return(body.GetSurfaceNVector(latitude, longitude)); }
public Vector3d Normal(CelestialBody body) { return(body.GetSurfaceNVector(Lat, Lon)); }
public static void updatePlanetaryResourceMap() { if (FlightGlobals.currentMainBody.flightGlobalsIndex != current_body) { loadPlanetaryResourceData(FlightGlobals.currentMainBody.flightGlobalsIndex); } if (body_resource_maps.ContainsKey(displayed_resource) && (FlightGlobals.currentMainBody.flightGlobalsIndex != map_body || displayed_resource != map_resource)) { foreach (ORSHeatMapOverlay abundance_marker in abundance_markers) { removeAbundanceSphere(abundance_marker.getPlanetarySphere()); removeAbundanceSphere(abundance_marker.getScaledSphere()); } abundance_markers.Clear(); CelestialBody celbody = FlightGlobals.currentMainBody; sphere_texture = body_resource_maps[displayed_resource].getDisplayTexturePath(); Vector2d[] abundance_points_list = body_abudnance_angles[displayed_resource]; if (abundance_points_list != null && celbody.pqsController != null) { foreach (Vector2d abundance_point in abundance_points_list) { //double theta = abundance_point.x; //double phi = abundance_point.y; Vector3d up = celbody.GetSurfaceNVector(0, 0).normalized; //double surface_height = celbody.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(0, Vector3d.down) * QuaternionD.AngleAxis(0, Vector3d.forward) * Vector3d.right); GameObject resource_prim = createAbundanceSphere(); GameObject resource_prim_scaled = createAbundanceSphere(); //Vector3d center = celbody.position + surface_height * up; Vector3d center = celbody.position; //Vector3d scaledcenter = ScaledSpace.LocalToScaledSpace(celbody.position) + surface_height * up * ScaledSpace.InverseScaleFactor; Vector3d scaledcenter = ScaledSpace.LocalToScaledSpace(celbody.position); Transform scaled_trans = ScaledSpace.Instance.scaledSpaceTransforms.Single(t => t.name == celbody.name); resource_prim_scaled.transform.position = scaledcenter; resource_prim_scaled.transform.localScale = sphere_scale_scaled * (FlightGlobals.currentMainBody.Radius / FlightGlobals.Bodies[ORSGameConstants.REF_BODY_KERBIN].Radius); resource_prim_scaled.transform.localRotation = Quaternion.identity; resource_prim_scaled.transform.parent = scaled_trans; resource_prim_scaled.layer = 10; resource_prim.transform.position = center; resource_prim.transform.parent = celbody.transform; resource_prim.transform.localScale = sphere_scale * (FlightGlobals.currentMainBody.Radius / FlightGlobals.Bodies[ORSGameConstants.REF_BODY_KERBIN].Radius); resource_prim.transform.localRotation = Quaternion.identity; ORSHeatMapOverlay abundance_marker = new ORSHeatMapOverlay(resource_prim_scaled); abundance_markers.Add(abundance_marker); } map_body = current_body; map_resource = displayed_resource; stored_scale = ScaledSpace.ScaleFactor; } } else { if (body_resource_maps.ContainsKey(displayed_resource) && FlightGlobals.currentMainBody.flightGlobalsIndex == map_body && displayed_resource == map_resource) { CelestialBody celbody = FlightGlobals.currentMainBody; foreach (ORSHeatMapOverlay abundance_marker in abundance_markers) { //if (lineOfSightToPosition(abundance_marker.getPlanetarySphere().transform.position, celbody)) //{ if (MapView.MapIsEnabled) { abundance_marker.getScaledSphere().renderer.enabled = true; abundance_marker.getPlanetarySphere().renderer.enabled = false; } else { abundance_marker.getScaledSphere().renderer.enabled = false; abundance_marker.getPlanetarySphere().renderer.enabled = true; } //} //else //{ // abundance_marker.getScaledSphere().renderer.enabled = false; // //abundance_marker.getPlanetarySphere().renderer.enabled = false; //} } } } }
static bool DrawGroundMarker(CelestialBody body, Coordinates pos, Color c, float r = IconSize, Texture2D texture = null) { Vector3d center; Camera camera; if(MapView.MapIsEnabled) { //TODO: cache local center coordinates of the marker camera = PlanetariumCamera.Camera; center = body.position + (body.TerrainAltitude(pos.Lat, pos.Lon)+body.Radius) * body.GetSurfaceNVector(pos.Lat, pos.Lon); } else { camera = FlightCamera.fetch.mainCamera; center = body.GetWorldSurfacePosition(pos.Lat, pos.Lon, body.TerrainAltitude(pos.Lat, pos.Lon)+GLB.WaypointHeight); if(camera.transform.InverseTransformPoint(center).z <= 0) return false; } return !IsOccluded(center, body) && DrawMarker(camera.WorldToScreenPoint(MapView.MapIsEnabled ? ScaledSpace.LocalToScaledSpace(center) : center), c, r, texture); }
public static ReferenceFrame CreateAtCurrentTime(CelestialBody referenceBody) { ReferenceFrame ret = new ReferenceFrame(); ret.lat0lon0AtStart = referenceBody.GetSurfaceNVector(0, 0); ret.lat0lon90AtStart = referenceBody.GetSurfaceNVector(0, 90); ret.lat90AtStart = referenceBody.GetSurfaceNVector(90, 0); ret.epoch = Planetarium.GetUniversalTime(); ret.referenceBody = referenceBody; return ret; }
protected bool CheckParameters(MonolithState paramState) { if (paramState < currentState) { return(true); } // StarJeb not active vessel if (starJeb != null && FlightGlobals.ActiveVessel != starJeb || candidate != null && FlightGlobals.ActiveVessel != candidate) { stepTime = Time.fixedTime; return(false); } // Create the velocity change handler if (velHdlr == null) { LoggingUtil.LogDebug(this, "Adding VelocityHandler"); velHdlr = MapView.MapCamera.gameObject.AddComponent <VelocityHandler>(); velHdlr.param = this; } switch (currentState) { case MonolithState.STARTED: // Look for an eva if (FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.vesselType == VesselType.EVA) { candidate = FlightGlobals.ActiveVessel; candidateName = candidate.vesselName; LoggingUtil.LogDebug(this, "Got an eva, starJeb = " + candidate.vesselName); nextState(); return(true); } return(false); case MonolithState.EVA: { Vessel discovery = ContractVesselTracker.Instance.GetAssociatedVessel("Discovery One"); float discoveryDistance = discovery == null ? 10000 : Vector3.Distance(discovery.transform.position, candidate.transform.position); if (distance < 10000 && discoveryDistance > distance && Time.fixedTime - stepTime > 10.0f || distance < MONOLITH_TOO_CLOSE) { // Store Star Jeb's name starJeb = candidate; starJebName = candidateName; PersistentDataStore.Instance.Store <string>("starJebName", starJebName); // Store Star Jeb's friend's name ProtoCrewMember protoStarJeb = candidate.GetVesselCrew().First(); if (discovery != null) { string trait = protoStarJeb.experienceTrait.TypeName == "Scientist" ? "Pilot" : "Scientist"; ProtoCrewMember notStarJeb = discovery.GetVesselCrew().Where(pcm => pcm.experienceTrait.TypeName == trait).FirstOrDefault(); if (notStarJeb != null) { PersistentDataStore.Instance.Store <string>("notStarJebName", notStarJeb.name); } } candidate = null; nextState(); // Set the right image (male vs. female) for the end sequence ConfiguredContract contract = Root as ConfiguredContract; DialogBox dialogBox = contract.Behaviours.Select(b => b as DialogBox).Where(b => b != null).FirstOrDefault(); if (dialogBox != null) { FieldInfo detailsField = typeof(DialogBox).GetFields(BindingFlags.Instance | BindingFlags.NonPublic). Where(fi => fi.FieldType == typeof(List <DialogBox.DialogDetail>)).First(); DialogBox.DialogDetail detail = ((List <DialogBox.DialogDetail>)detailsField.GetValue(dialogBox)).First(); DialogBox.ImageSection starJebImage = detail.sections.First() as DialogBox.ImageSection; starJebImage.imageURL = protoStarJeb.gender == ProtoCrewMember.Gender.Male ? "ContractPacks/AnomalySurveyor/Images/starjeb.dds.noload" : "ContractPacks/AnomalySurveyor/Images/starjeb_female.dds.noload"; } return(true); } } return(false); case MonolithState.FULL_OF_STARS1: { // Backup progress tracking progressTreeBackup = new ConfigNode("PROGRESS_TREE_BACKUP"); ProgressTracking.Instance.OnSave(progressTreeBackup); // Give the first kick away from Jool - this one using regular velocity change CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First(); // Find closest point on the jool-monolith line, and throw us away from that (so we don't hit either) Vector3 line = monolith.transform.position - jool.transform.position; float t = Vector3.Dot(line, (starJeb.transform.position - jool.transform.position)) / Vector3.Dot(line, line); Vector3 closest = jool.transform.position + line * t; velocity = (starJeb.transform.position - (t > 1.0 ? jool.transform.position : closest)).normalized; velocity += new Vector3(0.0f, 0.1f, 0.0f); velocity *= 15000; LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity); nextState(); // Camera to target jool FlightCamera.SetTarget(starJeb.transform); FlightCamera.fetch.SetCamCoordsFromPosition((starJeb.transform.position - jool.transform.position).normalized * 25.0f); } return(false); case MonolithState.FULL_OF_STARS2: if (Time.fixedTime - stepTime > 4.0f) { // Give the second kick away from Jool - these using anti-kraken velocity change CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First(); velocity = (starJeb.transform.position - jool.transform.position).normalized; velocity += new Vector3(0.0f, 0.1f, 0.0f); velocity *= 1500000; LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity); nextState(); } return(false); case MonolithState.FULL_OF_STARS3: if (Time.fixedTime - stepTime > 3.0f) { // Give the third kick away from Jool CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First(); velocity = (starJeb.transform.position - jool.transform.position).normalized; velocity *= 20000000; LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity); nextState(); } return(false); case MonolithState.FULL_OF_STARS4: if (Time.fixedTime - stepTime > 2.0f) { // Give the fourth and final kick away from Jool CelestialBody jool = FlightGlobals.Bodies.Where(b => b.name == "Jool").First(); velocity = (starJeb.transform.position - jool.transform.position).normalized; velocity *= 200000000; LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity); nextState(); } return(false); case MonolithState.FULL_OF_STARS5: if (Time.fixedTime - stepTime > 2.0f) { // Move along nextState(); } return(false); case MonolithState.FULL_OF_STARS_DRES1: { // Visit Dres CelestialBody dres = FlightGlobals.Bodies.Where(b => b.name == "Dres").First(); // Determine which side the sun is on - makes for a better show CelestialBody sun = FlightGlobals.Bodies.Where(b => b.name == "Sun").First(); Vector3 sunnySide = sun.transform.position - dres.transform.position; sunnySide.x = 0.0f; sunnySide.y = 1; // Move across the top of the planet sunnySide.z = Math.Sign(sunnySide.z); // Set position for starjeb float distance = 4.0f * (float)dres.Radius; starJeb.SetPosition(dres.transform.position + new Vector3(distance, (float)dres.Radius, (float)dres.Radius * sunnySide.z)); velocity = (dres.transform.position - starJeb.transform.position + sunnySide * ((float)dres.Radius)).normalized; velocity *= distance / 3.0f; LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity); starJeb.SetWorldVelocity(dres.getRFrmVel(starJeb.transform.position)); nextState(); } return(false); case MonolithState.FULL_OF_STARS_DRES2: { // Camera to target Dres - do this on a seperate update to allow KSP to catch up CelestialBody dres = FlightGlobals.Bodies.Where(b => b.name == "Dres").First(); FlightCamera.SetTarget(starJeb.transform); FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - dres.transform.position).normalized * 10.0f); // Make sure that the camera gets fixed if (Time.fixedTime - stepTime > 0.1f) { nextState(); } } return(false); case MonolithState.FULL_OF_STARS_DRES3: if (Time.fixedTime - stepTime > 5.5f) { // Done with Dres nextState(); } return(false); case MonolithState.FULL_OF_STARS_DUNA1: { // Start between the sun and Duna CelestialBody duna = FlightGlobals.Bodies.Where(b => b.name == "Duna").First(); CelestialBody sun = FlightGlobals.Bodies.Where(b => b.name == "Sun").First(); Vector3 sunnySide = sun.transform.position - duna.transform.position; sunnySide.Normalize(); // Set us up a nice 4 radiuses away... float distance = 4.0f * (float)duna.Radius; starJeb.SetPosition(duna.transform.position + sunnySide * distance); // Go straight at Duna velocity = (duna.transform.position - starJeb.transform.position).normalized; velocity *= distance / 3.0f; LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity); // Now offset him down so he doesn't actually hit Duna... starJeb.SetPosition(starJeb.transform.position + new Vector3(0.0f, -((float)duna.Radius + 55000), 0.0f)); starJeb.SetWorldVelocity(duna.getRFrmVel(starJeb.transform.position)); nextState(); } return(false); case MonolithState.FULL_OF_STARS_DUNA2: { // Camera to target Duna - do this on a seperate update to allow KSP to catch up CelestialBody duna = FlightGlobals.Bodies.Where(b => b.name == "Duna").First(); FlightCamera.SetTarget(starJeb.transform); FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - duna.transform.position).normalized * 25.0f); // Make sure that the camera gets fixed if (Time.fixedTime - stepTime > 0.1f) { nextState(); } } return(false); case MonolithState.FULL_OF_STARS_DUNA3: if (Time.fixedTime - stepTime > 5.5f) { // Done with Duna nextState(); } return(false); case MonolithState.FULL_OF_STARS_EELOO1: { // Start perpendicular to the sun and Eeloo CelestialBody eeloo = FlightGlobals.Bodies.Where(b => b.name == "Eeloo").First(); CelestialBody sun = FlightGlobals.Bodies.Where(b => b.name == "Sun").First(); Vector3 perp = eeloo.transform.position - sun.transform.position; float tmp = perp.x; perp.x = -perp.z; perp.z = tmp; perp.Normalize(); // Set us up a nice 4 radiuses away... float distance = 4.0f * (float)eeloo.Radius; starJeb.SetPosition(eeloo.transform.position + perp * distance); // Determine which side the sun is on - makes for a better show Vector3 sunnySide = sun.transform.position - eeloo.transform.position; sunnySide.Normalize(); // Go straight at Eeloo velocity = (eeloo.transform.position - starJeb.transform.position).normalized; velocity *= distance / 3.0f; LoggingUtil.LogDebug(this, "kick magnitude will be: " + velocity); // Now offset him down so he doesn't actually hit Eeloo... starJeb.SetPosition(starJeb.transform.position + sunnySide * ((float)eeloo.Radius * 1.5f)); starJeb.SetWorldVelocity(eeloo.getRFrmVel(starJeb.transform.position)); nextState(); } return(false); case MonolithState.FULL_OF_STARS_EELOO2: { // This time won't target directly towards Eeloo, as the player will have some idea // what is up by now. CelestialBody eeloo = FlightGlobals.Bodies.Where(b => b.name == "Eeloo").First(); CelestialBody sun = FlightGlobals.Bodies.Where(b => b.name == "Sun").First(); Vector3 awayFromSun = sun.transform.position - eeloo.transform.position; awayFromSun.Normalize(); FlightCamera.SetTarget(starJeb.transform); FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + awayFromSun * 50.0f); // Make sure that the camera gets fixed if (Time.fixedTime - stepTime > 0.1f) { nextState(); } } return(false); case MonolithState.FULL_OF_STARS_EELOO3: if (Time.fixedTime - stepTime > 5.5f) { velocity = null; // Done with Eeloo nextState(); } return(false); case MonolithState.FULL_OF_STARS_EVE1: { CelestialBody eve = FlightGlobals.Bodies.Where(b => b.name == "Eve").First(); Vector3 targetPosition = Destination.Value; Vector3 normal = eve.GetSurfaceNVector(eveLatitude, eveLongitude); startDistance = 10000000f; Vector3 start = targetPosition + normal * startDistance; starJeb.SetPosition(start); nextState(); } return(false); case MonolithState.FULL_OF_STARS_EVE2: { // Camera straight towards Eve - we're going in! CelestialBody eve = FlightGlobals.Bodies.Where(b => b.name == "Eve").First(); Vector3 awayFromEve = starJeb.transform.position - eve.transform.position; awayFromEve.Normalize(); FlightCamera.SetTarget(starJeb.transform); FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + awayFromEve * 15.0f); // Make sure that the camera gets fixed if (Time.fixedTime - stepTime > 0.1f) { nextState(); } } return(false); case MonolithState.FULL_OF_STARS_EVE3: // Wait until we've held the position for a split second if (Time.fixedTime - stepTime >= 9.3f) { nextState(); } return(false); case MonolithState.FULL_OF_STARS_EVE4: // Give the player a bit to get settled, then let the fun begins if (Time.fixedTime - stepTime >= 15.0f) { // Spawn some asteroids CelestialBody eve = FlightGlobals.Bodies.Where(b => b.name == "Eve").First(); ScenarioDiscoverableObjects asteroidSpawner = (ScenarioDiscoverableObjects)HighLogic.CurrentGame.scenarios.Find( s => s.moduleRef is ScenarioDiscoverableObjects).moduleRef; System.Random random = new System.Random(); // Spawn some more asteroids for (int i = 0; i < ASTEROID_COUNT; i++) { asteroidSpawner.SpawnAsteroid(); } nextState(); } return(false); case MonolithState.FULL_OF_STARS_EVE5: // Wait a full second after spawning the asteroids - we're not allowed to pull // them off rails until they've been active a bit if (Time.fixedTime - stepTime > 1.0f) { // Spawn some asteroids CelestialBody eve = FlightGlobals.Bodies.Where(b => b.name == "Eve").First(); System.Random random = new System.Random(); foreach (Vessel asteroid in FlightGlobals.Vessels.Where(v => v.vesselType == VesselType.SpaceObject).Reverse().Take(ASTEROID_COUNT)) { // Set the position double r = random.NextDouble() * 0.02 + 0.002; double theta = random.NextDouble() * 2.0 * Math.PI; double latitude = starJeb.latitude + r * Math.Sin(theta); double longitude = starJeb.longitude + r * Math.Cos(theta); double altitude = starJeb.altitude + 100 + random.NextDouble() * 200; asteroid.SetPosition(eve.GetWorldSurfacePosition(latitude, longitude, altitude)); asteroid.ChangeWorldVelocity(asteroid.GetSrfVelocity()); asteroid.Load(); asteroid.GoOffRails(); } nextState(); } return(false); case MonolithState.FULL_OF_STARS_EVE6: { // Determine if there's an asteroid about to kill us CelestialBody eve = FlightGlobals.Bodies.Where(b => b.name == "Eve").First(); bool killerAsteroid = FlightGlobals.Vessels.Where(v => v.mainBody == eve && v.vesselType == VesselType.SpaceObject && Vector3.Distance(starJeb.transform.position, v.transform.position) < 5.5 * ((int)v.DiscoveryInfo.objectSize + 1)).Any(); if (killerAsteroid || Time.fixedTime - stepTime > 20.0f) { foreach (Vessel asteroid in FlightGlobals.Vessels.Where(v => v.vesselType == VesselType.SpaceObject).Reverse().Take(ASTEROID_COUNT)) { asteroid.Die(); } nextState(); } } return(false); case MonolithState.FULL_OF_STARS_KERBIN1: { CheatOptions.NoCrashDamage = false; // Start between the sun and Kerbin CelestialBody kerbin = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First(); CelestialBody sun = FlightGlobals.Bodies.Where(b => b.name == "Sun").First(); Vector3 sunnySide = sun.transform.position - kerbin.transform.position; sunnySide.Normalize(); // Set us up a nice 4 radiuses away... float distance = 4.0f * (float)kerbin.Radius; starJeb.SetPosition(kerbin.transform.position + sunnySide * distance); // Orient him properly KerbalEVA keva = starJeb.FindPartModulesImplementing <KerbalEVA>().First(); MethodInfo rotationMethod = typeof(KerbalEVA).GetMethod("correctGroundedRotation", BindingFlags.Instance | BindingFlags.NonPublic); starJeb.packed = true; rotationMethod.Invoke(keva, new object[] { }); starJeb.packed = false; // Hardcode an orbital velocity, because it's late and I'm tired starJeb.SetWorldVelocity(kerbin.getRFrmVel(starJeb.transform.position).normalized * 1085); nextState(); } return(false); case MonolithState.FULL_OF_STARS_KERBIN2: { // Camera to target kerbin - do this on a seperate update to allow KSP to catch up CelestialBody kerbin = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First(); FlightCamera.SetTarget(starJeb.transform); FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized * 10.0f); starJeb.SetRotation(FlightCamera.fetch.transform.rotation * Quaternion.AngleAxis(180.0f, FlightCamera.fetch.transform.up)); // Make sure that the camera gets fixed if (Time.fixedTime - stepTime > 0.1f) { nextState(); } } return(false); case MonolithState.FULL_OF_STARS_KERBIN3: if (Time.fixedTime - stepTime > 2.0f) { // Turn into star jeb CelestialBody kerbin = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First(); starJeb.vesselName = "The Star Jeb"; Undress(starJeb.gameObject); FlightCamera.fetch.SetCamCoordsFromPosition(starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized * 1.5f); nextState(); } return(false); case MonolithState.FULL_OF_STARS_KERBIN4: if (Time.fixedTime - stepTime < 15.0f) { CelestialBody kerbin = FlightGlobals.Bodies.Where(b => b.name == "Kerbin").First(); Vector3 camDirection = starJeb.transform.position + (starJeb.transform.position - kerbin.transform.position).normalized; } else { nextState(); monolith.Die(); monolith = null; starJeb.Die(); starJeb = null; Vessel discovery = ContractVesselTracker.Instance.GetAssociatedVessel("Discovery One"); FlightGlobals.ForceSetActiveVessel(discovery); } return(false); case MonolithState.FULL_OF_STARS_FINAL: nextState(); return(true); default: return(false); } }
public void UpdateAtCurrentTime(CelestialBody body) { lat0lon0AtStart = body.GetSurfaceNVector(0, 0); lat0lon90AtStart = body.GetSurfaceNVector(0, 90); lat90AtStart = body.GetSurfaceNVector(90, 0); epoch = Planetarium.GetUniversalTime(); referenceBody = body; }
public SurfaceNode(WayPoint wp, CelestialBody body) { position = wp.GetTransform().position; up = body.GetSurfaceNVector(wp.Pos.Lat, wp.Pos.Lon); }
private bool isInSafetyBubble(Vector3d pos, CelestialBody body, double altitude) { //Assume Kerbin if body isn't supplied for some reason if (body == null) body = FlightGlobals.Bodies.Find(b => b.name == "Kerbin"); //If not at Kerbin or past ceiling we're definitely clear if (body.name != "Kerbin" || altitude > SAFETY_BUBBLE_CEILING) return false; //Cylindrical safety bubble -- project vessel position to a plane positioned at KSC with normal pointed away from surface Vector3d kscNormal = body.GetSurfaceNVector(-0.102668048654, -74.5753856554); Vector3d kscPosition = body.GetWorldSurfacePosition(-0.102668048654, -74.5753856554, 60); Vector3d landingPadPosition = body.GetWorldSurfacePosition(-0.0971978130377757, 285.44237039111, 60); Vector3d runwayPosition = body.GetWorldSurfacePosition(-0.0486001121594686, 285.275552559723, 60); double projectionDistance = Vector3d.Dot(kscNormal, (pos - kscPosition)) * -1; double landingPadDistance = Vector3d.Distance(pos, landingPadPosition); double runwayDistance = Vector3d.Distance(pos, runwayPosition); Vector3d projectedPos = pos + (Vector3d.Normalize(kscNormal) * projectionDistance); return Vector3d.Distance(kscPosition, projectedPos) < safetyBubbleRadius || runwayDistance < MIN_SAFETY_BUBBLE_DISTANCE || landingPadDistance < MIN_SAFETY_BUBBLE_DISTANCE; }
static bool DrawGroundMarker(CelestialBody body, Coordinates pos, Color c, float r = IconSize, Texture2D texture = null) { Vector3d center; Camera camera; if (MapView.MapIsEnabled) { //TODO: cache local center coordinates of the marker camera = PlanetariumCamera.Camera; center = body.position + (body.TerrainAltitude(pos.Lat, pos.Lon) + body.Radius) * body.GetSurfaceNVector(pos.Lat, pos.Lon); } else { camera = FlightCamera.fetch.mainCamera; center = body.GetWorldSurfacePosition(pos.Lat, pos.Lon, body.TerrainAltitude(pos.Lat, pos.Lon) + GLB.WaypointHeight); if (camera.transform.InverseTransformPoint(center).z <= 0) { return(false); } } return(!IsOccluded(center, body) && DrawMarker(camera.WorldToScreenPoint(MapView.MapIsEnabled ? ScaledSpace.LocalToScaledSpace(center) : center), c, r, texture)); }
/*These methods borrowed from MechJeb GLUtils: * https://github.com/MuMech/MechJeb2/blob/master/MechJeb2/GLUtils.cs * */ internal static void drawTargetOverlay(CelestialBody body, double latitude, double longitude, Color c) { double rotation = 0; double radius = 0; Vector3d up = body.GetSurfaceNVector(latitude, longitude); var height = SCANUtil.getElevation(body, longitude, latitude); if (height < body.Radius) height = body.Radius; Vector3d center = body.position + height * up; if (occluded(center, body)) return; Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized; if (radius <= 0) radius = body.Radius / 15; GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation - 55, up) * north), center + radius * (QuaternionD.AngleAxis(rotation -35, up) * north) }, c); GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation + 55, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 35, up) * north) }, c); GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation - 145, up) * north), center + radius * (QuaternionD.AngleAxis(rotation - 125, up) * north) }, c); GLTriangleMap(new Vector3d[] { center, center + radius * (QuaternionD.AngleAxis(rotation + 145, up) * north), center + radius * (QuaternionD.AngleAxis(rotation + 125, up) * north) }, c); }
private bool isInSafetyBubble(Vector3d pos, CelestialBody body, double altitude) { //Assume Kerbin if body isn't supplied for some reason if (body == null) body = FlightGlobals.Bodies.Find(b => b.name == "Kerbin"); //If KSC out of range, syncing, not at Kerbin, or past ceiling we're definitely clear if (kscPosition == Vector3d.zero || syncing || body.name != "Kerbin" || altitude > SAFETY_BUBBLE_CEILING) return false; //Cylindrical safety bubble -- project vessel position to a plane positioned at KSC with normal pointed away from surface Vector3d kscNormal = body.GetSurfaceNVector(-0.102668048654,-74.5753856554); double projectionDistance = Vector3d.Dot(kscNormal, (pos - kscPosition)) * -1; Vector3d projectedPos = pos + (Vector3d.Normalize(kscNormal)*projectionDistance); return Vector3d.Distance(kscPosition, projectedPos) < safetyBubbleRadius; }
public Vector3d BodyPositionAtCurrentTime(AbsoluteVector absolute) { return(referenceBody.position + absolute.radius * referenceBody.GetSurfaceNVector(absolute.latitude, absolute.longitude)); }