Esempio n. 1
0
		//Draw the orbit overlay
		internal static void drawOrbit(Rect maprect, SCANmap map, Vessel vessel, CelestialBody body)
		{
			if (vessel == null) return;
			if (vessel.mainBody != body) return;
			int eqh = 16;

			if (vessel.LandedOrSplashed)
				return;
			bool lite = maprect.width < 400;
			Orbit o = vessel.orbit;
			double startUT = Planetarium.GetUniversalTime();
			double UT = startUT;
			int steps = 80; // increase for neater lines, decrease for better speed indication
			bool ath = false;
			if (vessel.mainBody.atmosphere)
			{
				if (vessel.mainBody.atmosphereDepth >= vessel.altitude)
				{
					ath = true;
				}
			}
			Rect r = new Rect(0, 0, 70f, 50f);
			Color col;
			// project the last and the current orbital period onto the map
			for (int i = -steps; i < steps; ++i)
			{
				if (i < 0)
					UT = startUT - (steps + i) * (o.period / steps);
				else
					UT = startUT + i * o.period * 1f / steps;
				if (double.IsNaN(UT))
					continue;
				if (UT < o.StartUT && o.StartUT != startUT)
					continue;
				if (UT > o.EndUT)
					continue;
				if (double.IsNaN(o.getObtAtUT(UT)))
					continue;
				Vector3d pos = o.getPositionAtUT(UT);
				double rotation = 0;
				if (vessel.mainBody.rotates)
				{
					rotation = (360 * ((UT - startUT) / vessel.mainBody.rotationPeriod)) % 360;
				}
				double alt = (vessel.mainBody.GetAltitude(pos));
				if (alt < 0)
				{
					if (i < 0)
					{
						i = 0;
						continue;
					}
					break;
				}
				double lo = (vessel.mainBody.GetLongitude(pos) - rotation);
				double la = (vessel.mainBody.GetLatitude(pos));
				double lon = (map.projectLongitude(lo, la) + 180) % 360;
				double lat = (map.projectLatitude(lo, la) + 90) % 180;
				lat = map.scaleLatitude(lat);
				lon = map.scaleLongitude(lon);
				if (lat < 0 || lon < 0 || lat > 180 || lon > 360)
					continue;
				lon = lon * maprect.width / 360f;
				lat = maprect.height - lat * maprect.height / 180f;
				r.x = maprect.x + (float)lon;
				r.y = maprect.y + (float)lat;
				col = palette.cb_skyBlue;
				if (i < 0)
				{
					col = palette.cb_orange;
				}
				else
				{
					if (vessel.mainBody.atmosphere)
					{
						if (vessel.mainBody.atmosphereDepth >= alt)
						{
							if (!ath)
							{
								ath = true;
								// do something when it flips?
							}
							col = palette.cb_reddishPurple;
						}
					}
				}
				SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.Planet, col, 8, false);
			}

			// show apoapsis and periapsis
			if (o.ApA > 0 && mapPosAtT(maprect, map, ref r, vessel, o, o.timeToAp, startUT))
			{
				SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.Ap, palette.cb_skyBlue, 32, true);
				r.x += 24;
				r.y -= 12;
				if (!lite)
					drawLabel(r, o.ApA.ToString("N0"), true, true, true);
			}
			if (o.PeA > 0 && mapPosAtT(maprect, map, ref r, vessel, o, o.timeToPe, startUT))
			{
				SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.Pe, palette.cb_skyBlue, 32, true);
				r.x += 24;
				r.y -= 12;
				if (!lite)
					drawLabel(r, o.PeA.ToString("N0"), true, true, true);
			}

			if (lite)
				return;

			// show first maneuver node
			if (vessel.patchedConicSolver != null)
			{
				if (vessel.patchedConicSolver.maneuverNodes.Count > 0)
				{
					ManeuverNode n = vessel.patchedConicSolver.maneuverNodes[0];
					if (n.patch == vessel.orbit && n.nextPatch != null && n.nextPatch.activePatch && n.UT > startUT - o.period && mapPosAtT(maprect, map, ref r, vessel, o, n.UT - startUT, startUT))
					{
						col = palette.cb_reddishPurple;
						if (SCANcontroller.controller.colours != 1)
							col = palette.xkcd_PurplyPink;
						SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.ManeuverNode, col, 32, true);
						Orbit nuo = n.nextPatch;
						for (int i = 0; i < steps; ++i)
						{
							double T = n.UT - startUT + i * nuo.period / steps;
							if (T + startUT > nuo.EndUT)
								break;
							if (mapPosAtT(maprect, map, ref r, vessel, nuo, T, startUT))
							{
								SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.Planet, col, 8, false);
							}
						}
						if (nuo.patchEndTransition == Orbit.PatchTransitionType.ESCAPE)
						{
							SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.Exit, col, 32, true);
						}
						else if (nuo.patchEndTransition == Orbit.PatchTransitionType.ENCOUNTER)
						{
							SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.Encounter, col, 32, true);
						}
						if (nuo.timeToAp > 0 && n.UT + nuo.timeToAp < nuo.EndUT && mapPosAtT(maprect, map, ref r, vessel, nuo, n.UT - startUT + nuo.timeToAp, startUT))
						{
							SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.Ap, col, 32, true);
						}
						if (nuo.timeToPe > 0 && n.UT + nuo.timeToPe < nuo.EndUT && mapPosAtT(maprect, map, ref r, vessel, nuo, n.UT - startUT + nuo.timeToPe, startUT))
						{
							SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.OrbitIcon.Pe, col, 32, true);
						}
					}
				}
			}

			if (o.PeA < 0)
				return;
			if (map.Projection == MapProjection.Polar)
				return;

			if (SCANBigMap.eq_frame <= 0)
			{
				// predict equatorial crossings for the next 100 loops
				double TAAN = 360f - o.argumentOfPeriapsis;	// true anomaly at ascending node
				double TADN = (TAAN + 180) % 360;			// true anomaly at descending node
				double MAAN = meanForTrue(TAAN, o.eccentricity);
				double MADN = meanForTrue(TADN, o.eccentricity);
				double tAN = (((MAAN - o.meanAnomaly * Mathf.Rad2Deg + 360) % 360) / 360f * o.period + startUT);
				double tDN = (((MADN - o.meanAnomaly * Mathf.Rad2Deg + 360) % 360) / 360f * o.period + startUT);

				if (SCANBigMap.eq_an_map == null || SCANBigMap.eq_dn_map == null || SCANBigMap.eq_an_map.Length != maprect.width)
				{
					SCANBigMap.eq_an_map = new int[(int)maprect.width];
					SCANBigMap.eq_dn_map = new int[(int)maprect.width];
				}
				if (SCANBigMap.eq_map == null || SCANBigMap.eq_map.width != SCANBigMap.eq_an_map.Length)
				{
					SCANBigMap.eq_map = new Texture2D(SCANBigMap.eq_an_map.Length, eqh, TextureFormat.ARGB32, false);
				}
				for (int i = 0; i < SCANBigMap.eq_an_map.Length; ++i)
				{
					SCANBigMap.eq_an_map[i] = 0;
					SCANBigMap.eq_dn_map[i] = 0;
				}
				for (int i = 0; i < 100; ++i)
				{
					double UTAN = tAN + o.period * i;
					double UTDN = tDN + o.period * i;
					if (double.IsNaN(UTAN) || double.IsNaN(UTDN))
						continue;
					Vector3d pAN = o.getPositionAtUT(UTAN);
					Vector3d pDN = o.getPositionAtUT(UTDN);
					double rotAN = 0, rotDN = 0;
					if (vessel.mainBody.rotates)
					{
						rotAN = ((360 * ((UTAN - startUT) / vessel.mainBody.rotationPeriod)) % 360);
						rotDN = ((360 * ((UTDN - startUT) / vessel.mainBody.rotationPeriod)) % 360);
					}
					double loAN = vessel.mainBody.GetLongitude(pAN) - rotAN;
					double loDN = vessel.mainBody.GetLongitude(pDN) - rotDN;
					int lonAN = (int)(((map.projectLongitude(loAN, 0) + 180) % 360) * SCANBigMap.eq_an_map.Length / 360f);
					int lonDN = (int)(((map.projectLongitude(loDN, 0) + 180) % 360) * SCANBigMap.eq_dn_map.Length / 360f);
					if (lonAN >= 0 && lonAN < SCANBigMap.eq_an_map.Length)
						SCANBigMap.eq_an_map[lonAN] += 1;
					if (lonDN >= 0 && lonDN < SCANBigMap.eq_dn_map.Length)
						SCANBigMap.eq_dn_map[lonDN] += 1;
				}
				Color[] pix = SCANBigMap.eq_map.GetPixels(0, 0, SCANBigMap.eq_an_map.Length, eqh);
				Color cAN = palette.cb_skyBlue, cDN = palette.cb_orange;
				for (int y = 0; y < eqh; ++y)
				{
					Color lc = palette.clear;
					for (int x = 0; x < SCANBigMap.eq_an_map.Length; ++x)
					{
						Color c = palette.clear;
						float scale = 0;
						if (y < eqh / 2)
						{
							c = cDN;
							scale = SCANBigMap.eq_dn_map[x];
						}
						else
						{
							c = cAN;
							scale = SCANBigMap.eq_an_map[x];
						}
						if (scale >= 1)
						{
							if (y == 0 || y == eqh - 1)
							{
								c = palette.black;
							}
							else
							{
								if (lc == palette.clear)
									pix[y * SCANBigMap.eq_an_map.Length + x - 1] = palette.black;
								scale = Mathf.Clamp(scale - 1, 0, 10) / 10f;
								c = palette.lerp(c, palette.white, scale);
							}
						}
						else
						{
							c = palette.clear;
							if (lc != palette.clear && lc != palette.black)
								c = palette.black;
						}
						pix[y * SCANBigMap.eq_an_map.Length + x] = c;
						lc = c;
					}
				}
				SCANBigMap.eq_map.SetPixels(0, 0, SCANBigMap.eq_an_map.Length, eqh, pix);
				SCANBigMap.eq_map.Apply();
				SCANBigMap.eq_frame = 4;
			}
			else
			{
				SCANBigMap.eq_frame -= 1;
			}

			if (SCANBigMap.eq_map != null)
			{
				r.x = maprect.x;
				r.y = maprect.y + maprect.height / 2 + -SCANBigMap.eq_map.height / 2;
				r.width = SCANBigMap.eq_map.width;
				r.height = SCANBigMap.eq_map.height;
				GUI.DrawTexture(r, SCANBigMap.eq_map);
			}
		}
Esempio n. 2
0
		internal static Dictionary<int, List<List<Vector2d>>> drawGridLine(Rect maprect, SCANmap map)
		{
			var lineDict = new Dictionary<int, List<List<Vector2d>>>();
			var whiteLineList = new List<List<Vector2d>>();
			var blackLineList = new List<List<Vector2d>>();

			switch (map.Projection)
			{
				case MapProjection.Rectangular:
					{
						for (double lon = -150; lon <= 150; lon += 30)
						{
							List<Vector2d> points = new List<Vector2d>();
							List<Vector2d> pointsBlack = new List<Vector2d>();
							points.Add(new Vector2d((int)(map.MapScale * (lon + 180)), 0));
							points.Add(new Vector2d((int)(map.MapScale * (lon + 180)), (int)(map.MapScale * 180)));
							pointsBlack.Add(new Vector2d(points[0].x + 1, points[0].y));
							pointsBlack.Add(new Vector2d(points[1].x + 1, points[1].y));

							whiteLineList.Add(points);
							blackLineList.Add(pointsBlack);
						}
						for (double lat = -60; lat <= 60; lat += 30)
						{
							List<Vector2d> points = new List<Vector2d>();
							List<Vector2d> pointsBlack = new List<Vector2d>();
							points.Add(new Vector2d(0, (int)(map.MapScale * (lat + 90))));
							points.Add(new Vector2d((int)(map.MapScale * 360), (int)(map.MapScale * (lat + 90))));
							pointsBlack.Add(new Vector2d(points[0].x, points[0].y - 1));
							pointsBlack.Add(new Vector2d(points[1].x, points[1].y - 1));

							whiteLineList.Add(points);
							blackLineList.Add(pointsBlack);
						}
							break;
					}
				case MapProjection.KavrayskiyVII:
					{
						for (double lon = -150; lon <= 150; lon += 30)
						{
							List<Vector2d> points = new List<Vector2d>();
							List<Vector2d> pointsBlack = new List<Vector2d>();
							int i = 0;
							for (double lat = -88; lat <= 88; lat += 4)
							{
								points.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, lat) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, lat) + 90))));
								pointsBlack.Add(new Vector2d(points[i].x + 1, points[i].y));
								i++;
							}

							whiteLineList.Add(points);
							blackLineList.Add(pointsBlack);
						}
						for (double lat = -60; lat <= 60; lat += 30)
						{
							List<Vector2d> points = new List<Vector2d>();
							List<Vector2d> pointsBlack = new List<Vector2d>();
							points.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(-179, lat) + 180)), (int)(map.MapScale * (lat + 90))));
							points.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(179, lat) + 180)), (int)(map.MapScale * (lat + 90))));
							pointsBlack.Add(new Vector2d(points[0].x, points[0].y - 1));
							pointsBlack.Add(new Vector2d(points[1].x, points[1].y - 1));

							whiteLineList.Add(points);
							blackLineList.Add(pointsBlack);
						}
						break;
					}
				case MapProjection.Polar:
					{
						for (double lon = -180; lon <= 150; lon += 30)
						{
							List<Vector2d> pointsS = new List<Vector2d>();
							List<Vector2d> pointsBlackS = new List<Vector2d>();
							pointsS.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, -88) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, -88) + 90))));
							pointsS.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, -2) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, -2) + 90))));

							whiteLineList.Add(pointsS);

							List<Vector2d> pointsN = new List<Vector2d>();
							List<Vector2d> pointsBlackN = new List<Vector2d>();
							pointsN.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, 2) + 180)), (int)(map.MapScale * (map.projectLatitude (lon, 2) + 90))));
							pointsN.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, 88) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, 88) + 90))));

							whiteLineList.Add(pointsN);

							if (lon == -180 || lon == 0)
							{
								pointsBlackS.Add(new Vector2d(pointsS[0].x + 1, pointsS[0].y));
								pointsBlackS.Add(new Vector2d(pointsS[1].x + 1, pointsS[1].y));
								pointsBlackN.Add(new Vector2d(pointsN[0].x + 1, pointsN[0].y));
								pointsBlackN.Add(new Vector2d(pointsN[1].x + 1, pointsN[1].y));
							}
							else if (lon == -90 || lon == 90)
							{
								pointsBlackS.Add(new Vector2d(pointsS[0].x, pointsS[0].y - 1));
								pointsBlackS.Add(new Vector2d(pointsS[1].x, pointsS[1].y - 1));
								pointsBlackN.Add(new Vector2d(pointsN[0].x, pointsN[0].y - 1));
								pointsBlackN.Add(new Vector2d(pointsN[1].x, pointsN[1].y - 1));
							}
							else if (lon == -60 || lon == -30 || lon == 120 || lon == 150)
							{
								pointsBlackS.Add(new Vector2d(pointsS[0].x - 1, pointsS[0].y - 1));
								pointsBlackS.Add(new Vector2d(pointsS[1].x - 1, pointsS[1].y - 1));
								pointsBlackN.Add(new Vector2d(pointsN[0].x + 1, pointsN[0].y - 1));
								pointsBlackN.Add(new Vector2d(pointsN[1].x + 1, pointsN[1].y - 1));
							}
							else
							{
								pointsBlackS.Add(new Vector2d(pointsS[0].x + 1, pointsS[0].y - 1));
								pointsBlackS.Add(new Vector2d(pointsS[1].x + 1, pointsS[1].y - 1));
								pointsBlackN.Add(new Vector2d(pointsN[0].x - 1, pointsN[0].y - 1));
								pointsBlackN.Add(new Vector2d(pointsN[1].x - 1, pointsN[1].y - 1));
							}
							blackLineList.Add(pointsBlackS);
							blackLineList.Add(pointsBlackN);
						}
						for (double lat = -88; lat <= 88; lat += 2)
						{
							if (lat != 0)
							{
								if (lat % 30 == 0 || lat == -88 || lat == 88)
								{
									List<Vector2d> points = new List<Vector2d>();
									List<Vector2d> pointsBlack = new List<Vector2d>();
									for (double lon = -180; lon <= 180; lon += 4)
									{
										points.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, lat) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, lat) + 90))));
										float offset = 0;
										if (lat == 30) offset = -0.8f;
										else if (lat == -30) offset = 0.8f;
										else if (lat == 60) offset = -0.3f;
										else if (lat == -60) offset = 0.3f;
										if (lat != -88 && lat != 88)
											pointsBlack.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, lat + offset) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, lat + offset) + 90))));
									}
									whiteLineList.Add(points);
									blackLineList.Add(pointsBlack);
								}
							}
						}
						break;
					}
			}

			lineDict.Add(0, blackLineList);
			lineDict.Add(1, whiteLineList);

			return lineDict;
		}
Esempio n. 3
0
		private static void drawWaypointLabel(Rect maprect, SCANmap map, SCANwaypoint p, SCANdata data)
		{
			double lon = SCANUtil.fixLon(p.Longitude);
			double lat = SCANUtil.fixLat(p.Latitude);

			if (map != null)
			{
				lat = SCANUtil.fixLat(map.projectLatitude(p.Longitude, p.Latitude));
				lon = SCANUtil.fixLon(map.projectLongitude(p.Longitude, p.Latitude));
				lat = map.scaleLatitude(lat);
				lon = map.scaleLongitude(lon);
				if (lat < 0 || lon < 0 || lat > 180 || lon > 360)
					return;
			}
			lon = lon * maprect.width / 360f;
			lat = maprect.height - lat * maprect.height / 180f;

			Rect r = new Rect(maprect.x + (float)lon, maprect.y + (float)lat, 24, 24);

			r.x -= 12;

			if (!p.LandingTarget)
			{
				r.y -= 24;
				drawMapIcon(r, SCANskins.SCAN_WaypointIcon, true);
			}
			else
			{
				r.x += 1;
				r.y -= 13;
				drawMapIcon(r, SCANcontroller.controller.mechJebTargetSelection ? SCANskins.SCAN_MechJebIcon : SCANskins.SCAN_TargetIcon, true, SCANcontroller.controller.mechJebTargetSelection ? palette.red : palette.xkcd_PukeGreen, true);
			}
		}
Esempio n. 4
0
		//Method to draw anomaly labels on the map
		private static void drawAnomalyLabel(Rect maprect, SCANmap map, SCANanomaly anomaly)
		{
			if (!anomaly.Known)
				return;
			double lon = SCANUtil.fixLon(anomaly.Longitude);
			double lat = SCANUtil.fixLat(anomaly.Latitude);
			if (map != null)
			{
				lat = SCANUtil.fixLat(map.projectLatitude(anomaly.Longitude, anomaly.Latitude));
				lon = SCANUtil.fixLon(map.projectLongitude(anomaly.Longitude, anomaly.Latitude));
				lat = map.scaleLatitude(lat);
				lon = map.scaleLongitude(lon);
				if (lat < 0 || lon < 0 || lat > 180 || lon > 360)
					return;
			}
			lon = lon * maprect.width / 360f;
			lat = maprect.height - lat * maprect.height / 180f;
			string txt = SCANcontroller.controller.anomalyMarker + " " + anomaly.Name;
			if (!anomaly.Detail)
				txt = SCANcontroller.controller.anomalyMarker + " Anomaly";
			Rect r = new Rect(maprect.x + (float)lon, maprect.y + (float)lat, 250f, 25f);
			drawLabel(r, txt, true, true, true);
		}
Esempio n. 5
0
		//Method to actually draw vessel labels on the map
		internal static void drawVesselLabel(Rect maprect, SCANmap map, int num, Vessel vessel)
		{
			bool flash = false;
			double lon = SCANUtil.fixLon(vessel.longitude);
			double lat = SCANUtil.fixLat(vessel.latitude);
			if (map != null)
			{
				lat = SCANUtil.fixLat(map.projectLatitude(vessel.longitude, vessel.latitude));
				lon = SCANUtil.fixLon(map.projectLongitude(vessel.longitude, vessel.latitude));
				lat = map.scaleLatitude(lat);
				lon = map.scaleLongitude(lon);
				if (lat < 0 || lon < 0 || lat > 180 || lon > 360)
					return;
			}
			lon = lon * maprect.width / 360f;
			lat = maprect.height - lat * maprect.height / 180f;
			string txt = num.ToString();
			if (num == 0)
				txt = vessel.vesselName;
			else if (num < 0)
				txt = "";
			Rect r = new Rect(maprect.x + (float)lon, maprect.y + (float)lat, 250f, 25f);
			Color col = palette.white;
			if (SCANcontroller.controller.colours == 1 && vessel != FlightGlobals.ActiveVessel)
				col = palette.cb_skyBlue;
			if (vessel == FlightGlobals.ActiveVessel && (int)(Time.realtimeSinceStartup % 2) == 0)
			{
				flash = true;
				col = palette.cb_yellow;
			}
			int sz = 16;
			if (vessel.vesselType == VesselType.Flag)
				sz = 24;
			SCANicon.drawOrbitIcon((int)r.x, (int)r.y, SCANicon.orbitIconForVesselType(vessel.vesselType), col, sz, true);
			if (maprect.width < 360)
				return;
			r.x += 12;
			drawLabel(r, txt, flash, true, true);
		}
Esempio n. 6
0
		/* UI: This isn't really a UI function, so it doesn't belong here.
		 * 		This is more of a time-projection mathematical function. */
		/* FIXME: possible relocation */
		private static bool mapPosAtT(Rect maprect, SCANmap map, ref Rect r, Vessel vessel, Orbit o, double dT, double startUT)
		{
			double UT = startUT + dT;
			if (double.IsNaN(UT))
				return false;
			try
			{
				if (double.IsNaN(o.getObtAtUT(UT)))
					return false;
				Vector3d pos = o.getPositionAtUT(UT);
				double rotation = 0;
				if (vessel.mainBody.rotates)
				{
					rotation = (360 * (dT / vessel.mainBody.rotationPeriod)) % 360;
				}
				double lo = (vessel.mainBody.GetLongitude(pos) - rotation);
				double la = (vessel.mainBody.GetLatitude(pos));
				double lon = (map.projectLongitude(lo, la) + 180) % 360;
				double lat = (map.projectLatitude(lo, la) + 90) % 180;
				lat = map.scaleLatitude(lat);
				lon = map.scaleLongitude(lon);
				if (lat < 0 || lon < 0 || lat > 180 || lon > 360)
					return false;
				lon = lon * maprect.width / 360f;
				lat = maprect.height - lat * maprect.height / 180f;
				r.x = maprect.x + (float)lon;
				r.y = maprect.y + (float)lat;
				return true;
			}
			catch (Exception)
			{
				return false;
			}
		}