예제 #1
0
        public void scanFromAllVessels()
        {
            if (Time.realtimeSinceStartup - last_scan_time < 1 && Time.realtimeSinceStartup > last_scan_time)
            {
                return;
            }
            if (last_scan_frame == Time.frameCount)
            {
                return;
            }
            last_scan_frame     = Time.frameCount;
            last_scan_time      = Time.realtimeSinceStartup;
            scan_UT             = Planetarium.GetUniversalTime();
            currentActiveSensor = 0;
            currentActiveVessel = 0;
            actualPasses        = 0;
            maxRes = 0;
            foreach (SCANdata data in body_data.Values)
            {
                data.updateCoverage();
            }
            foreach (Vessel v in FlightGlobals.Vessels)
            {
                if (!knownVessels.ContainsKey(v.id))
                {
                    continue;
                }
                SCANvessel vessel = knownVessels[v.id];
                SCANdata   data   = getData(v.mainBody);
                vessel.vessel = v;

                if (!data.disabled)
                {
                    if (v.mainBody == FlightGlobals.currentMainBody || scan_background)
                    {
                        if (isVesselKnown(v))
                        {
                            doScanPass(knownVessels[v.id], scan_UT, scan_UT, vessel.lastUT, vessel.latitude, vessel.longitude);
                            ++currentActiveVessel;
                            currentActiveSensor += knownVessels[v.id].sensors.Count;
                        }
                    }
                }

                vessel.body      = v.mainBody;
                vessel.frame     = Time.frameCount;
                vessel.lastUT    = scan_UT;
                vessel.latitude  = fixLatitude(v.latitude);
                vessel.longitude = fixLongitude(v.longitude);
            }
            activeVessels = currentActiveVessel;
            activeSensors = currentActiveSensor;
        }
예제 #2
0
        public void registerSensor(Guid id, SCANdata.SCANtype sensors, double fov, double min_alt, double max_alt, double best_alt)
        {
            if (!knownVessels.ContainsKey(id))
            {
                knownVessels[id] = new SCANvessel();
            }
            SCANvessel sv = knownVessels[id];

            sv.id = id;
            foreach (SCANdata.SCANtype sensor in Enum.GetValues(typeof(SCANdata.SCANtype)))
            {
                if (countBits((int)sensor) != 1)
                {
                    continue;
                }
                if ((sensor & sensors) == SCANdata.SCANtype.Nothing)
                {
                    continue;
                }
                double this_fov = fov, this_min_alt = min_alt, this_max_alt = max_alt, this_best_alt = best_alt;
                if (this_max_alt <= 0)
                {
                    this_min_alt  = 5000;
                    this_max_alt  = 500000;
                    this_best_alt = 200000;
                    this_fov      = 5;
                    if ((sensor & SCANdata.SCANtype.AltimetryHiRes) != SCANdata.SCANtype.Nothing)
                    {
                        this_fov = 3;
                    }
                    if ((sensor & SCANdata.SCANtype.AnomalyDetail) != SCANdata.SCANtype.Nothing)
                    {
                        this_min_alt  = 0;
                        this_max_alt  = 2000;
                        this_best_alt = 0;
                        this_fov      = 1;
                    }
                }
                if (!sv.sensors.ContainsKey(sensor))
                {
                    sv.sensors[sensor] = new SCANsensor();
                }
                SCANsensor s = sv.sensors[sensor];
                s.sensor   = sensor;
                s.fov      = this_fov;
                s.min_alt  = this_min_alt;
                s.max_alt  = this_max_alt;
                s.best_alt = this_best_alt;
            }
        }
예제 #3
0
        public void unregisterSensor(Vessel v, SCANdata.SCANtype sensors)
        {
            if (!knownVessels.ContainsKey(v.id))
            {
                return;
            }
            SCANvessel sv = knownVessels[v.id];

            sv.id     = v.id;
            sv.vessel = v;
            foreach (SCANdata.SCANtype sensor in Enum.GetValues(typeof(SCANdata.SCANtype)))
            {
                if ((sensors & sensor) == SCANdata.SCANtype.Nothing)
                {
                    continue;
                }
                if (!sv.sensors.ContainsKey(sensor))
                {
                    continue;
                }
                sv.sensors.Remove(sensor);
            }
        }
예제 #4
0
        protected void doScanPass(SCANvessel vessel, double UT, double startUT, double lastUT, double llat, double llon)
        {
            Vessel v = vessel.vessel;
            SCANdata data = getData(v.mainBody);
            double soi_radius = v.mainBody.sphereOfInfluence - v.mainBody.Radius;
            double alt = v.altitude, lat = fixLatitude(v.latitude), lon = fixLongitude(v.longitude);
            double res = 0;
            Orbit o = v.orbit;
            bool uncovered;

            if(scanQueue == null) scanQueue = new Queue<double>();
            if(scanQueue.Count != 0) scanQueue.Clear();

            loop: // don't look at me like that, I just unrolled the recursion
            if(res > 0) {
                if(double.IsNaN(UT)) goto dequeue;
                if(o.ObT <= 0) goto dequeue;
                if(double.IsNaN(o.getObtAtUT(UT))) goto dequeue;
                Vector3d pos = o.getPositionAtUT(UT);
                double rotation = 0;
                if(v.mainBody.rotates) {
                    rotation = (360 * ((UT - scan_UT) / v.mainBody.rotationPeriod)) % 360;
                }
                alt = v.mainBody.GetAltitude(pos);
                lat = fixLatitude(v.mainBody.GetLatitude(pos));
                lon = fixLongitude(v.mainBody.GetLongitude(pos) - rotation);
                if(alt < 0) alt = 0;
                if(res > maxRes) maxRes = (int)res;
            } else {
                alt = v.heightFromTerrain;
                if(alt < 0) alt = v.altitude;
            }

            if(Math.Abs(lat - llat) < 1 && Math.Abs(lon - llon) < 1 && res > 0) goto dequeue;
            actualPasses++;

            uncovered = res <= 0;
            foreach(SCANsensor sensor in knownVessels[v.id].sensors.Values) {
                if(res <= 0) {
                    if(data.getCoverage(sensor.sensor) > 0) uncovered = false;
                }

                sensor.inRange = false;
                sensor.bestRange = false;
                if(alt < sensor.min_alt) continue;
                if(alt > Math.Min(sensor.max_alt, soi_radius)) continue;
                sensor.inRange = true;

                double fov = sensor.fov;
                double ba = Math.Min(sensor.best_alt, soi_radius);
                if(alt < ba) fov = (alt / ba) * fov;
                else sensor.bestRange = true;

                double surfscale = 600000d/v.mainBody.Radius;
                if(surfscale < 1) surfscale = 1;
                surfscale = Math.Sqrt(surfscale);
                fov *= surfscale;
                if(fov > 20) fov = 20;

                int f = (int)Math.Truncate(fov);
                int f1 = f + (int)Math.Round(fov - f);
                for(int x=-f; x<=f1; ++x) {
                    for(int y=-f; y<=f1; ++y) {
                        data.registerPass(lon + x, lat + y, sensor.sensor);
                    }
                }
            }
            if(uncovered) return;
            /*
            if(v.mainBody == FlightGlobals.currentMainBody) {
                if(res > 0) data.map_small.SetPixel((int)Math.Round(lon) + 180, (int)Math.Round(lat) + 90, Color.magenta);
                else data.map_small.SetPixel((int)Math.Round(lon) + 180, (int)Math.Round(lat) + 90, Color.yellow);
            }
            */

            if(vessel.lastUT <= 0) return;
            if(vessel.frame <= 0) return;
            if(v.LandedOrSplashed) return;
            if(res >= timeWarpResolution) goto dequeue;

            if(startUT > UT) {
                scanQueue.Enqueue((startUT + UT) / 2);
                scanQueue.Enqueue(startUT);
                scanQueue.Enqueue(UT);
                scanQueue.Enqueue(lat);
                scanQueue.Enqueue(lon);
                scanQueue.Enqueue(res + 1);
            }
            startUT = UT;
            UT = (lastUT + UT) / 2;
            llat = lat;
            llon = lon;
            res = res + 1;
            goto loop;

            dequeue:
            if(scanQueue.Count <= 0) return;
            UT = scanQueue.Dequeue();
            startUT = scanQueue.Dequeue();
            lastUT = scanQueue.Dequeue();
            llat = scanQueue.Dequeue();
            llon = scanQueue.Dequeue();
            res = scanQueue.Dequeue();
            goto loop;
        }
예제 #5
0
 public void registerSensor(Guid id, SCANdata.SCANtype sensors, double fov, double min_alt, double max_alt, double best_alt)
 {
     if(!knownVessels.ContainsKey(id)) knownVessels[id] = new SCANvessel();
     SCANvessel sv = knownVessels[id];
     sv.id = id;
     foreach(SCANdata.SCANtype sensor in Enum.GetValues(typeof(SCANdata.SCANtype))) {
         if(countBits((int)sensor) != 1) continue;
         if((sensor & sensors) == SCANdata.SCANtype.Nothing) continue;
         double this_fov = fov, this_min_alt = min_alt, this_max_alt = max_alt, this_best_alt = best_alt;
         if(this_max_alt <= 0) {
             this_min_alt = 5000;
             this_max_alt = 500000;
             this_best_alt = 200000;
             this_fov = 5;
             if((sensor & SCANdata.SCANtype.AltimetryHiRes) != SCANdata.SCANtype.Nothing) this_fov = 3;
             if((sensor & SCANdata.SCANtype.AnomalyDetail) != SCANdata.SCANtype.Nothing) {
                 this_min_alt = 0;
                 this_max_alt = 2000;
                 this_best_alt = 0;
                 this_fov = 1;
             }
         }
         if(!sv.sensors.ContainsKey(sensor)) sv.sensors[sensor] = new SCANsensor();
         SCANsensor s = sv.sensors[sensor];
         s.sensor = sensor;
         s.fov = this_fov;
         s.min_alt = this_min_alt;
         s.max_alt = this_max_alt;
         s.best_alt = this_best_alt;
     }
 }
예제 #6
0
        protected void doScanPass(SCANvessel vessel, double UT, double startUT, double lastUT, double llat, double llon)
        {
            Vessel   v = vessel.vessel;
            SCANdata data = getData(v.mainBody);
            double   soi_radius = v.mainBody.sphereOfInfluence - v.mainBody.Radius;
            double   alt = v.altitude, lat = fixLatitude(v.latitude), lon = fixLongitude(v.longitude);
            double   res = 0;
            Orbit    o   = v.orbit;
            bool     uncovered;

            if (scanQueue == null)
            {
                scanQueue = new Queue <double>();
            }
            if (scanQueue.Count != 0)
            {
                scanQueue.Clear();
            }

loop:       // don't look at me like that, I just unrolled the recursion
            if (res > 0)
            {
                if (double.IsNaN(UT))
                {
                    goto dequeue;
                }
                if (o.ObT <= 0)
                {
                    goto dequeue;
                }
                if (double.IsNaN(o.getObtAtUT(UT)))
                {
                    goto dequeue;
                }
                Vector3d pos      = o.getPositionAtUT(UT);
                double   rotation = 0;
                if (v.mainBody.rotates)
                {
                    rotation = (360 * ((UT - scan_UT) / v.mainBody.rotationPeriod)) % 360;
                }
                alt = v.mainBody.GetAltitude(pos);
                lat = fixLatitude(v.mainBody.GetLatitude(pos));
                lon = fixLongitude(v.mainBody.GetLongitude(pos) - rotation);
                if (alt < 0)
                {
                    alt = 0;
                }
                if (res > maxRes)
                {
                    maxRes = (int)res;
                }
            }
            else
            {
                alt = v.heightFromTerrain;
                if (alt < 0)
                {
                    alt = v.altitude;
                }
            }

            if (Math.Abs(lat - llat) < 1 && Math.Abs(lon - llon) < 1 && res > 0)
            {
                goto dequeue;
            }
            actualPasses++;

            uncovered = res <= 0;
            foreach (SCANsensor sensor in knownVessels[v.id].sensors.Values)
            {
                if (res <= 0)
                {
                    if (data.getCoverage(sensor.sensor) > 0)
                    {
                        uncovered = false;
                    }
                }

                sensor.inRange   = false;
                sensor.bestRange = false;
                if (alt < sensor.min_alt)
                {
                    continue;
                }
                if (alt > Math.Min(sensor.max_alt, soi_radius))
                {
                    continue;
                }
                sensor.inRange = true;

                double fov = sensor.fov;
                //double ba = Math.Min(sensor.best_alt, soi_radius);
                //if(alt < ba) fov = (alt / ba) * fov;
                //else sensor.bestRange = true;

                double surfscale = 600000d / v.mainBody.Radius;
                if (surfscale < 1)
                {
                    surfscale = 1;
                }
                surfscale = Math.Sqrt(surfscale);
                fov      *= surfscale;
                if (fov > 20)
                {
                    fov = 20;
                }

                int f  = (int)Math.Truncate(fov);
                int f1 = f + (int)Math.Round(fov - f);

                double clampLat;
                double clampLon;
                for (int x = -f; x <= f1; ++x)
                {
                    clampLon = lon + x;                         // longitude does not need clamping
                    /*if (clampLon < 0  ) clampLon = 0; */
                    /*if (clampLon > 360) clampLon = 360; */
                    for (int y = -f; y <= f1; ++y)
                    {
                        clampLat = lat + y;
                        if (clampLat > 90)
                        {
                            clampLat = 90;
                        }
                        if (clampLat < -90)
                        {
                            clampLat = -90;
                        }
                        data.registerPass(clampLon, clampLat, sensor.sensor);
                    }
                }
            }
            if (uncovered)
            {
                return;
            }

            /*
             * if(v.mainBody == FlightGlobals.currentMainBody) {
             *      if(res > 0) data.map_small.SetPixel((int)Math.Round(lon) + 180, (int)Math.Round(lat) + 90, Color.magenta);
             *      else data.map_small.SetPixel((int)Math.Round(lon) + 180, (int)Math.Round(lat) + 90, Color.yellow);
             * }
             */

            if (vessel.lastUT <= 0)
            {
                return;
            }
            if (vessel.frame <= 0)
            {
                return;
            }
            if (v.LandedOrSplashed)
            {
                return;
            }
            if (res >= timeWarpResolution)
            {
                goto dequeue;
            }

            if (startUT > UT)
            {
                scanQueue.Enqueue((startUT + UT) / 2);
                scanQueue.Enqueue(startUT);
                scanQueue.Enqueue(UT);
                scanQueue.Enqueue(lat);
                scanQueue.Enqueue(lon);
                scanQueue.Enqueue(res + 1);
            }
            startUT = UT;
            UT      = (lastUT + UT) / 2;
            llat    = lat;
            llon    = lon;
            res     = res + 1;
            goto loop;

dequeue:
            if (scanQueue.Count <= 0)
            {
                return;
            }
            UT      = scanQueue.Dequeue();
            startUT = scanQueue.Dequeue();
            lastUT  = scanQueue.Dequeue();
            llat    = scanQueue.Dequeue();
            llon    = scanQueue.Dequeue();
            res     = scanQueue.Dequeue();
            goto loop;
        }
예제 #7
0
		private void registerSensor(Guid id, SCANtype sensors, double fov, double min_alt, double max_alt, double best_alt)
		{
			if (id == null)
				return;
			if (!knownVessels.ContainsKey(id))
				knownVessels[id] = new SCANvessel();
			SCANvessel sv = knownVessels[id];
			sv.id = id;
			sv.vessel = FlightGlobals.Vessels.FirstOrDefault(a => a.id == id);
			if (sv.vessel == null)
			{
				knownVessels.Remove(id);
				return;
			}
			foreach (SCANtype sensor in Enum.GetValues(typeof(SCANtype)))
			{
				if (SCANUtil.countBits((int)sensor) != 1)
					continue;
				if ((sensor & sensors) == SCANtype.Nothing)
					continue;
				double this_fov = fov;
				double this_min_alt = min_alt;
				double this_max_alt = max_alt;
				double this_best_alt = best_alt;
				if (this_max_alt <= 0)
				{
					this_min_alt = 5000;
					this_max_alt = 500000;
					this_best_alt = 200000;
					this_fov = 5;
					if ((sensor & SCANtype.AltimetryHiRes) != SCANtype.Nothing) this_fov = 3;
					if ((sensor & SCANtype.AnomalyDetail) != SCANtype.Nothing)
					{
						this_min_alt = 0;
						this_max_alt = 2000;
						this_best_alt = 0;
						this_fov = 1;
					}
				}
				if (!sv.sensors.ContainsKey(sensor))
					sv.sensors[sensor] = new SCANsensor();
				SCANsensor s = sv.sensors[sensor];
				s.sensor = sensor;
				s.fov = this_fov;
				s.min_alt = this_min_alt;
				s.max_alt = this_max_alt;
				s.best_alt = this_best_alt;
			}
		}