Example #1
0
        private double getDistance(Coordinates coords1, Coordinates coords2, CelestialBody body)
        {
            double   altitude = body.TerrainAltitude(coords1.latitude, coords1.longitude);
            Vector3d pos1     = body.GetWorldSurfacePosition(coords1.latitude, coords1.longitude, altitude);

            altitude = body.TerrainAltitude(coords2.latitude, coords2.longitude);
            Vector3d pos2 = body.GetWorldSurfacePosition(coords2.latitude, coords2.longitude, altitude);

            return(Vector3d.Distance(pos1, pos2));
        }
Example #2
0
        static void Highest(CelestialBody body, double delta, IEnumerable <LLA> ALL)
        {
            if (delta > 0.001)
            {
                List <LLA> BEST = new List <LLA>();

                int n = ALL.Count();

                for (int i = 0; i < n; i++)
                {
                    LLA LatLon = ALL.ElementAt(i);

                    for (double LON = LatLon.lon - delta / 2; LON <= LatLon.lon + delta / 2; LON += delta / 10)
                    {
                        for (double LAT = LatLon.lat - delta / 2; LAT <= LatLon.lat + delta / 2; LAT += delta / 10)
                        {
                            double ALT = body.TerrainAltitude(LAT, LON, true);
                            BEST.Add(new LLA(LAT, LON, ALT));
                        }
                    }
                }

                Highest(body, delta / 10, BEST.OrderByDescending(v => v.alt).Take(100));
            }
            else
            {
                LLA BEST = ALL.OrderByDescending(v => v.alt).FirstOrDefault();

                text[5] = "Highest Point";
                text[6] = "LAT = " + BEST.lat;
                text[7] = "LON = " + BEST.lon;
                text[8] = "ALT = " + BEST.alt;
                text[9] = "";
            }
        }
Example #3
0
        void Highest(CelestialBody body, Vector2d LatLon)
        {
            double altitude  = double.MinValue;
            double latitude  = LatLon.x;
            double longitude = LatLon.y;

            for (double LON = LatLon.y - 0.1; LON <= LatLon.y + 0.1; LON += 0.001)
            {
                for (double LAT = LatLon.x - 0.1; LAT <= LatLon.x + 0.1; LAT += 0.001)
                {
                    double ALT = body.TerrainAltitude(LAT, LON, true);
                    if (ALT > altitude)
                    {
                        latitude  = LAT;
                        longitude = LON;
                        altitude  = ALT;
                    }
                }
            }

            info[5] = "Highest Point";
            info[6] = "LAT = " + latitude;
            info[7] = "LON = " + longitude;
            info[8] = "ALT = " + altitude;

            string path = "GameData/Sigma/Cartographer/PluginData/" + body.transform.name + "/";

            Directory.CreateDirectory(path);
            File.WriteAllLines(path + "Info.txt", info);
        }
Example #4
0
 public TargetInfo(MechJebModuleTargetController target)
 {
     this.mainBody    = target.mainBody;
     this.target      = target;
     targetAlt        = mainBody.TerrainAltitude(target.targetLatitude, target.targetLongitude, !mainBody.ocean);
     this.vesselState = target.vesselState;
 }
Example #5
0
        internal bool isAtLocation(Vessel vessel)
        {
            if (vessel.getCurrentBody().Equals(body))
            {
                if (circle)
                {
                    CelestialBody celestialBody = body.getCelestialBody();
                    double        altitude      = celestialBody.TerrainAltitude(latitude, longitude);
                    Vector3d      pos           = celestialBody.GetWorldSurfacePosition(latitude, longitude, altitude);

                    celestialBody = vessel.getCurrentBody().getCelestialBody();
                    Vector3d vesselPos = celestialBody.GetWorldSurfacePosition(vessel.latitude, vessel.longitude, vessel.altitude);

                    double distance = Vector3d.Distance(pos, vesselPos);

                    return(distance <= radius);
                }
                else
                {
                    // FIXME: does only work for rectangles where a side is exactly parallel to the equator
                    return(MuUtils.ClampDegrees180(vessel.latitude).between(latitude, latitude2) &&
                           MuUtils.ClampDegrees180(vessel.longitude).between(longitude, longitude2));
                }
            }
            else
            {
                return(false);
            }
        }
Example #6
0
        // Credits to https://github.com/jrossignol/WaypointManager/blob/master/source/WaypointManager/CustomWaypointGUI.cs
        // for this code
        public static bool GetBodyRayIntersect(CelestialBody targetBody, bool map, out double latitude, out double longitude, out double altitude)
        {
            latitude  = 0;
            longitude = 0;
            altitude  = 0;
            if (targetBody.pqsController == null)
            {
                return(false);
            }

            Ray mouseRay = map ? PlanetariumCamera.Camera.ScreenPointToRay(Input.mousePosition) : FlightCamera.fetch.mainCamera.ScreenPointToRay(Input.mousePosition);

            if (map) // use scaled space
            {
                mouseRay.origin = ScaledSpace.ScaledToLocalSpace(mouseRay.origin);
            }
            var    bodyToOrigin = mouseRay.origin - targetBody.position;
            double curRadius    = targetBody.pqsController.radiusMax;
            double lastRadius   = 0;
            int    loops        = 0;

            while (loops < 10)
            {
                Vector3d relSurfacePosition;
                if (PQS.LineSphereIntersection(bodyToOrigin, mouseRay.direction, curRadius, out relSurfacePosition))
                {
                    var    surfacePoint = targetBody.position + relSurfacePosition;
                    double alt          = targetBody.pqsController.GetSurfaceHeight(
                        QuaternionD.AngleAxis(targetBody.GetLongitude(surfacePoint), Vector3d.down) * QuaternionD.AngleAxis(targetBody.GetLatitude(surfacePoint), Vector3d.forward) * Vector3d.right);
                    double error = Math.Abs(curRadius - alt);
                    if (error < (targetBody.pqsController.radiusMax - targetBody.pqsController.radiusMin) / 500)
                    {
                        latitude  = targetBody.GetLatitude(surfacePoint);
                        longitude = targetBody.GetLongitude(surfacePoint);
                        altitude  = targetBody.TerrainAltitude(latitude, longitude);
                        return(true);
                    }
                    else
                    {
                        lastRadius = curRadius;
                        curRadius  = 0.5 * alt + 0.5 * curRadius;
                        loops++;
                    }
                }
                else
                {
                    if (loops == 0)
                    {
                        break;
                    }
                    // Went too low, needs to try higher
                    else
                    {
                        curRadius = (lastRadius * 9 + curRadius) / 10;
                        loops++;
                    }
                }
            }
            return(true);
        }
Example #7
0
        void FirstPass(CelestialBody body)
        {
            double lowest  = double.MaxValue;
            double highest = double.MinValue;

            Vector2d LatLonLo = new Vector2d();
            Vector2d LatLonHi = new Vector2d();

            for (double LON = -180; LON < 180; LON += 0.1)
            {
                for (double LAT = -90; LAT <= 90; LAT += 0.1)
                {
                    double ALT = body.TerrainAltitude(LAT, LON, true);

                    if (ALT < lowest)
                    {
                        lowest   = ALT;
                        LatLonLo = new Vector2d(LAT, LON);
                    }
                    if (ALT > highest)
                    {
                        highest  = ALT;
                        LatLonHi = new Vector2d(LAT, LON);
                    }
                }
            }
            Lowest(body, LatLonLo);
            Highest(body, LatLonHi);
        }
Example #8
0
        void Lowest(CelestialBody body, Vector2d LatLon)
        {
            double altitude  = double.MaxValue;
            double latitude  = LatLon.x;
            double longitude = LatLon.y;

            for (double LON = LatLon.y - 0.1; LON <= LatLon.y + 0.1; LON += 0.001)
            {
                for (double LAT = LatLon.x - 0.1; LAT <= LatLon.x + 0.1; LAT += 0.001)
                {
                    double ALT = body.TerrainAltitude(LAT, LON, true);
                    if (ALT < altitude)
                    {
                        latitude  = LAT;
                        longitude = LON;
                        altitude  = ALT;
                    }
                }
            }

            info[0] = "Lowest Point";
            info[1] = "LAT = " + latitude;
            info[2] = "LON = " + longitude;
            info[3] = "ALT = " + altitude;
            info[4] = "";
        }
Example #9
0
 public Cell(Coords coords, Vector3 geoPos, bool traversable, CelestialBody body)
 {
     Coords      = coords;
     GeoPos      = geoPos;
     GeoPos.z    = (float)body.TerrainAltitude(GeoPos.x, GeoPos.y);
     Traversable = traversable;
     this.body   = body;
 }
Example #10
0
 private float getCornerAlt(Coords coords)
 {
     if (!cornerAlts.TryGetValue(coords, out float alt))
     {
         var geo = gridToGeo(coords.X - 0.5f, coords.Y - 0.5f);
         alt = (float)body.TerrainAltitude(geo.x, geo.y, true);
         cornerAlts[coords] = alt;
     }
     return(alt);
 }
        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));
        }
Example #12
0
        static void FirstPass(CelestialBody body)
        {
            List <LLA> ALL = new List <LLA>();

            double terrain    = 0;
            double surface    = 0;
            double underwater = 0;

            for (double LON = -180 + definition / 2; LON < 180; LON += definition)
            {
                for (double LAT = -90 + definition / 2; LAT < 90; LAT += definition)
                {
                    double ALT = body.TerrainAltitude(LAT, LON, true);

                    ALL.Add(new LLA(LAT, LON, ALT));

                    if (ALT == 0)
                    {
                        continue;
                    }

                    double area = Math.PI * (Math.Cos((LAT - definition / 2) / 180 * Math.PI) + Math.Cos((LAT + definition / 2) / 180 * Math.PI)) / (4 * 180 / definition * 360 / definition);

                    terrain += ALT * area;

                    if (ALT > 0)
                    {
                        surface += ALT * area;
                    }
                    else
                    {
                        underwater += area;
                    }
                }
            }

            Lowest(body, definition, ALL.OrderBy(v => v.alt).Take(100));
            Highest(body, definition, ALL.OrderByDescending(v => v.alt).Take(100));
            Print(body, terrain, surface, underwater);
        }
 public Vector3d GetPositionTargetPosition()
 {
     return(targetBody.GetWorldSurfacePosition(targetLatitude, targetLongitude, targetBody.TerrainAltitude(targetLatitude, targetLongitude)) - targetBody.position);
 }
Example #14
0
 /// <summary>
 /// Get the altitude of terrain below/above a point.
 /// </summary>
 /// <param name="position">World position, not geo position (use VectorUtils.GetWorldSurfacePostion to convert lat,long,alt to world position)</param>
 /// <param name="body">usually vessel.MainBody</param>
 /// <returns>terrain height</returns>
 public static float GetTerrainAltitude(Vector3 position, CelestialBody body, bool underwater = true)
 {
     return((float)body.TerrainAltitude(body.GetLatitude(position), body.GetLongitude(position), underwater));
 }
Example #15
0
        public void Update()
        {
            timeSpentInIllumination  = TimeSpan.Zero;
            timeSpentInTextureUpdate = TimeSpan.Zero;
            DateTime      start  = DateTime.UtcNow;
            CelestialBody kerbin = FlightGlobals.GetHomeBody();

            if (reset)
            {
                reset          = false;
                kerbin_imaging = null;
                lastUpdateUT   = null;
                window.width   = 0;
                window.height  = 0;
                return;
            }
            if (pause)
            {
                return;
            }
            if (kerbin_imaging == null)
            {
                UnityEngine.Debug.LogWarning("Rebuilding map...");
                x_size         = small ? 256 : 512;
                y_size         = small ? 128 : 256;
                kerbin_imaging = new ImagingParallel[y_size];
                minimap        = new UnityEngine.Texture2D(x_size, y_size);
                for (int y = 0; y < y_size; ++y)
                {
                    // Mollweide on [-2, 2] × [-1, 1].
                    double y_normalized = 2.0 * y / y_size - 1;
                    double θ            = Math.Asin(y_normalized);
                    double sinφ         = (2 * θ + Math.Sin(2 * θ)) / Math.PI;
                    double φ            = Math.Asin(sinφ);
                    double φ_deg        = φ * (180 / Math.PI);
                    var    parallel     = kerbin_imaging[y] = new ImagingParallel
                    {
                        cosLatitude = Math.Cos(φ),
                        sinLatitude = sinφ,
                        map         = new MapPoint[x_size],
                        midInfrared = new ImagingStatus[x_size],
                        nightVisNIR = new ImagingStatus[x_size],
                        unglintedReflectiveVisNIR = new ImagingStatus[x_size],
                        glintedReflectiveVisNIR   = new ImagingStatus[x_size],
                        sun     = new SunSurfaceGeometry[x_size],
                        surface = new SurfacePoint[x_size]
                    };
                    bool entered_map = false;
                    parallel.x_end = x_size;
                    for (int x = 0; x < x_size; ++x)
                    {
                        double x_normalized = 4.0 * x / x_size - 2;
                        double λ            = Math.PI * x_normalized / (2 * Math.Cos(θ));
                        double λ_deg        = λ * (180 / Math.PI);

                        if (double.IsNaN(φ) || double.IsNaN(λ) || Math.Abs(λ) > Math.PI)
                        {
                            parallel.map[x].on_map = false;
                            if (entered_map && parallel.x_end == x_size)
                            {
                                parallel.x_end = x;
                            }
                        }
                        else
                        {
                            parallel.map[x].on_map = true;
                            if (!entered_map)
                            {
                                parallel.x_begin = x;
                            }
                            entered_map = true;
                            double altitude = kerbin.TerrainAltitude(φ_deg, λ_deg);
                            parallel.surface[x] = new SurfacePoint(
                                kerbin.scaledBody.transform.rotation.Inverse() *
                                (kerbin.GetWorldSurfacePosition(φ_deg, λ_deg, altitude) - kerbin.position));
                            parallel.map[x].ocean = altitude == 0;
                            parallel.midInfrared[x].lastImagingTime               = new double[resolutionThresholds.Length];
                            parallel.nightVisNIR[x].lastImagingTime               = new double[resolutionThresholds.Length];
                            parallel.glintedReflectiveVisNIR[x].lastImagingTime   = new double[resolutionThresholds.Length];
                            parallel.unglintedReflectiveVisNIR[x].lastImagingTime = new double[resolutionThresholds.Length];
                            for (int i = 0; i < resolutionThresholds.Length; ++i)
                            {
                                parallel.midInfrared[x].lastImagingTime[i]               = double.NegativeInfinity;
                                parallel.nightVisNIR[x].lastImagingTime[i]               = double.NegativeInfinity;
                                parallel.glintedReflectiveVisNIR[x].lastImagingTime[i]   = double.NegativeInfinity;
                                parallel.unglintedReflectiveVisNIR[x].lastImagingTime[i] = double.NegativeInfinity;
                            }
                        }
                    }
                }
            }
            var    imagers = activeImagers.ToArray();
            double Δt      = 30;

            if (lastUpdateUT == null || kerbin.scaledBody.transform.rotation == null)
            {
                lastUpdateUT       = Planetarium.GetUniversalTime();
                lastKerbinRotation = kerbin.scaledBody.transform.rotation;
            }
            var current_kerbin_to_world = kerbin.scaledBody.transform.rotation;

            for (int n = (int)Math.Floor((Planetarium.GetUniversalTime() - lastUpdateUT.Value) / Δt); n >= 0; --n)
            {
                double t = Planetarium.GetUniversalTime() - n * Δt;
                // TODO(egg): This will fail hilariously if the interval between updates is greater than half a day.
                // It is probably broken in other ways.
                var kerbin_to_world = UnityEngine.Quaternion.Slerp(
                    lastKerbinRotation.Value, current_kerbin_to_world,
                    (float)((t - lastUpdateUT) / (Planetarium.GetUniversalTime() - lastUpdateUT)));
                var      world_to_kerbin       = kerbin_to_world.Inverse();
                double   kerbin_radius         = kerbin.Radius;
                var      kerbin_world_position = kerbin.orbit.getPositionAtUT(t);
                Vector3d sunInSurfaceFrame     = world_to_kerbin *
                                                 (kerbin.referenceBody.getPositionAtUT(t) - kerbin_world_position);
                Vector3d sunDirection = sunInSurfaceFrame.normalized;
                for (int y = 0; y != y_size; ++y)
                {
                    var parallel = kerbin_imaging[y];
                    for (int x = parallel.x_begin; x != parallel.x_end; ++x)
                    {
                        if (solarParallax)
                        {
                            parallel.sun[x] = SunSurfaceGeometry.FromSunPosition(
                                parallel.surface[x],
                                sunInSurfaceFrame);
                        }
                        else
                        {
                            parallel.sun[x] = SunSurfaceGeometry.FromSunDirection(
                                parallel.surface[x],
                                sunDirection);
                        }
                    }
                }
                foreach (var imager in imagers)
                {
                    Vessel           platform = FlightGlobals.FindVessel(imager.Key);
                    ImagingProduct[] products = imager.Value;
                    Vector3d         vesselFromKerbinInWorld;
                    Vector3d         kerbinCentredVesselVelocityInWorld;
                    if (platform.orbit.referenceBody == kerbin)
                    {
                        var vesselFromKerbinInAlice            = platform.orbit.getRelativePositionAtUT(t);
                        var kerbinCentredVesselVelocityInAlice = platform.orbit.getOrbitalVelocityAtUT(t);
                        vesselFromKerbinInWorld            = vesselFromKerbinInAlice.xzy;
                        kerbinCentredVesselVelocityInWorld = kerbinCentredVesselVelocityInAlice.xzy;
                    }
                    else
                    {
                        Vector3d vesselFromSunInAlice = Vector3d.zero;
                        Vector3d kerbinFromSunInAlice = Vector3d.zero;
                        Vector3d heliocentricVesselVelocityInAlice = Vector3d.zero;
                        Vector3d heliocentricKerbinVelocityInAlice = Vector3d.zero;
                        for (var orbit = platform.orbit; orbit != null; orbit = orbit.referenceBody?.orbit)
                        {
                            vesselFromSunInAlice += orbit.getRelativePositionAtUT(t);
                            heliocentricVesselVelocityInAlice += orbit.getOrbitalVelocityAtUT(t);
                        }
                        for (var orbit = kerbin.orbit; orbit != null; orbit = orbit.referenceBody?.orbit)
                        {
                            kerbinFromSunInAlice += orbit.getRelativePositionAtUT(t);
                            heliocentricKerbinVelocityInAlice += orbit.getOrbitalVelocityAtUT(t);
                        }
                        vesselFromKerbinInWorld            = (vesselFromSunInAlice - kerbinFromSunInAlice).xzy;
                        kerbinCentredVesselVelocityInWorld =
                            (heliocentricVesselVelocityInAlice - heliocentricKerbinVelocityInAlice).xzy;
                    }
                    Vector3d swathNormal;
                    if (platform.loaded)
                    {
                        // The rotation transforms from part coordinates to
                        // world coordinates.
                        // TODO(egg): that products[0] is a hack.
                        swathNormal = world_to_kerbin *
                                      (products[0].part.rb.rotation * Vector3d.up);
                    }
                    else
                    {
                        // TODO(egg): Fetch from Principia if available.
                        swathNormal = world_to_kerbin * kerbinCentredVesselVelocityInWorld.normalized;
                    }
                    Vector3d             vesselInSurfaceFrame = world_to_kerbin * vesselFromKerbinInWorld;
                    UnityEngine.Vector2d subsatellitePoint    = kerbin.GetLatitudeAndLongitude(
                        kerbin.position + current_kerbin_to_world * world_to_kerbin * vesselFromKerbinInWorld);
                    double latitude  = subsatellitePoint.x;
                    double longitude = subsatellitePoint.y;
                    double xVessel   = (0.5 + longitude / 360) % 1;
                    double yVessel   = (0.5 + latitude / 180) % 1;
                    for (int y = (int)(yVessel * y_size); y < y_size; ++y)
                    {
                        var parallel = kerbin_imaging[y];
                        UpdateParallel(
                            t, parallel, vesselInSurfaceFrame, swathNormal, products,
                            out bool parallelVisibleAtRelevantResolution);
                        if (!parallelVisibleAtRelevantResolution)
                        {
                            break;
                        }
                    }
                    for (int y = (int)(yVessel * y_size) - 1; y >= 0; --y)
                    {
                        var parallel = kerbin_imaging[y];
                        UpdateParallel(
                            t, parallel, vesselInSurfaceFrame, swathNormal, products,
                            out bool parallelVisibleAtRelevantResolution);
                        if (!parallelVisibleAtRelevantResolution)
                        {
                            break;
                        }
                    }
                }
                lastUpdateUT       = t;
                lastKerbinRotation = current_kerbin_to_world;
            }

            RefreshMap();

            minimap.Apply(updateMipmaps: false);
            timeSpentInUpdate = DateTime.UtcNow - start;
        }
 public void Update(CelestialBody body, double latitude, double longitude)
 {
     double altitude = body.TerrainAltitude(latitude, longitude);
     Update(body, latitude, longitude, altitude);
 }
 public double SurfaceAlt(CelestialBody body, bool underwater = false)
 {
     return(body.TerrainAltitude(Lat, Lon, underwater || !body.ocean));
 }
 public double Alt(CelestialBody body)
 {
     return body.TerrainAltitude(Lat, Lon);
 }
 public double Alt(CelestialBody body)
 {
     return(body.TerrainAltitude(Lat, Lon));
 }
 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 double TerrainAltitude(this CelestialBody body, Vector3d worldPosition)
 {
     return(body.TerrainAltitude(body.GetLatitude(worldPosition), body.GetLongitude(worldPosition)));
 }
        public void Update(CelestialBody body, double latitude, double longitude)
        {
            double altitude = body.TerrainAltitude(latitude, longitude);

            Update(body, latitude, longitude, altitude);
        }