protected void DrawWaypoint(WaypointData wpd) { // Not our planet CelestialBody celestialBody = FlightGlobals.currentMainBody; if (celestialBody == null || wpd.waypoint.celestialName != celestialBody.name) { return; } // Check if the waypoint should be visible if (!wpd.waypoint.visible) { return; } // Figure out waypoint label string label = wpd.waypoint.name + (wpd.waypoint.isClustered ? (" " + StringUtilities.IntegerToGreek(wpd.waypoint.index)) : ""); // Set the alpha and do a nice fade wpd.SetAlpha(); // Decide whether to actually draw the waypoint if (FlightGlobals.ActiveVessel != null) { // Figure out the distance to the waypoint Vessel v = FlightGlobals.ActiveVessel; // Only change alpha if the waypoint isn't the nav point if (!Util.IsNavPoint(wpd.waypoint)) { // Get the distance to the waypoint at the current speed double speed = v.srfSpeed < MIN_SPEED ? MIN_SPEED : v.srfSpeed; double directTime = Util.GetStraightDistance(wpd) / speed; // More than two minutes away if (directTime > MIN_TIME || Config.waypointDisplay != Config.WaypointDisplay.ALL) { return; } else if (directTime >= MIN_TIME - FADE_TIME) { wpd.currentAlpha = (float)((MIN_TIME - directTime) / FADE_TIME) * Config.opacity; } } // Draw the distance information to the nav point else { // Draw the distance to waypoint text if (Event.current.type == EventType.Repaint) { if (asb == null) { asb = UnityEngine.Object.FindObjectOfType <AltimeterSliderButtons>(); } if (referenceUISize != ScreenSafeUI.VerticalRatio || !referenceSet) { referencePos = ScreenSafeUI.referenceCam.ViewportToScreenPoint(asb.transform.position).y; referenceUISize = ScreenSafeUI.VerticalRatio; // Need two consistent numbers in a row to set the reference if (lastPos == referencePos) { referenceSet = true; } else { lastPos = referencePos; } } float ybase = (referencePos - ScreenSafeUI.referenceCam.ViewportToScreenPoint(asb.transform.position).y + Screen.height / 11.67f) / ScreenSafeUI.VerticalRatio; string timeToWP = GetTimeToWaypoint(wpd); if (Config.hudDistance) { GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Distance to " + label + ":", nameStyle); GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f), v.state != Vessel.State.DEAD ? Util.PrintDistance(wpd) : "N/A", valueStyle); ybase += 18f; } if (timeToWP != null && Config.hudTime) { GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "ETA to " + label + ":", nameStyle); GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f), v.state != Vessel.State.DEAD ? timeToWP : "N/A", valueStyle); ybase += 18f; } if (Config.hudHeading) { GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Heading to " + label + ":", nameStyle); GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f), v.state != Vessel.State.DEAD ? wpd.heading.ToString("N1") : "N/A", valueStyle); ybase += 18f; } if (Config.hudAngle && v.mainBody == wpd.celestialBody) { double distance = Util.GetLateralDistance(wpd); double heightDist = wpd.waypoint.altitude + wpd.waypoint.height - v.altitude; double angle = Math.Atan2(heightDist, distance) * 180.0 / Math.PI; GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Angle to " + label + ":", nameStyle); GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f), v.state != Vessel.State.DEAD ? angle.ToString("N2") : "N/A", valueStyle); ybase += 18f; if (v.srfSpeed >= 0.1) { double velAngle = 90 - Math.Acos(Vector3d.Dot(v.srf_velocity.normalized, v.upAxis)) * 180.0 / Math.PI; GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 20f), "Velocity pitch angle:", nameStyle); GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 20f), v.state != Vessel.State.DEAD ? velAngle.ToString("N2") : "N/A", valueStyle); ybase += 18f; } } if (Config.hudCoordinates && v.mainBody == wpd.celestialBody) { ybase += 9; GUI.Label(new Rect((float)Screen.width / 2.0f - 188f, ybase, 240f, 38f), "Coordinates of " + label + ":", nameStyle); GUI.Label(new Rect((float)Screen.width / 2.0f + 60f, ybase, 120f, 38f), v.state != Vessel.State.DEAD ? string.Format("{0}\r\n{1}", Util.DecimalDegreesToDMS(wpd.waypoint.latitude, true), Util.DecimalDegreesToDMS(wpd.waypoint.longitude, false)) : "N/A", valueStyle); ybase += 18f; } } } } // Don't draw the waypoint if (Config.waypointDisplay == Config.WaypointDisplay.NONE) { return; } // Translate to scaled space Vector3d localSpacePoint = celestialBody.GetWorldSurfacePosition(wpd.waypoint.latitude, wpd.waypoint.longitude, wpd.waypoint.height + wpd.waypoint.altitude); Vector3d scaledSpacePoint = ScaledSpace.LocalToScaledSpace(localSpacePoint); // Don't draw if it's behind the camera if (Vector3d.Dot(MapView.MapCamera.camera.transform.forward, scaledSpacePoint.normalized) < 0.0) { return; } // Translate to screen position Vector3 screenPos = MapView.MapCamera.camera.WorldToScreenPoint(new Vector3((float)scaledSpacePoint.x, (float)scaledSpacePoint.y, (float)scaledSpacePoint.z)); // Draw the marker at half-resolution (30 x 45) - that seems to match the one in the map view Rect markerRect = new Rect(screenPos.x - 15f, (float)Screen.height - screenPos.y - 45.0f, 30f, 45f); // Set the window position relative to the selected waypoint if (selectedWaypoint == wpd.waypoint) { windowPos = new Rect(markerRect.xMin - 97, markerRect.yMax + 12, 224, 60); } // Handling clicking on the waypoint if (Event.current.type == EventType.MouseUp && Event.current.button == 0) { if (markerRect.Contains(Event.current.mousePosition)) { selectedWaypoint = wpd.waypoint; windowPos = new Rect(markerRect.xMin - 97, markerRect.yMax + 12, 224, 60); waypointName = label; newClick = false; } else if (newClick) { selectedWaypoint = null; } } // Only handle on repaint events if (Event.current.type == EventType.Repaint) { // Half-res for the icon too (16 x 16) Rect iconRect = new Rect(screenPos.x - 8f, (float)Screen.height - screenPos.y - 39.0f, 16f, 16f); // Draw the marker Graphics.DrawTexture(markerRect, GameDatabase.Instance.GetTexture("Squad/Contracts/Icons/marker", false), new Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, new Color(0.5f, 0.5f, 0.5f, 0.5f * (wpd.currentAlpha - 0.3f) / 0.7f)); // Draw the icon, but support blinking if (!Util.IsNavPoint(wpd.waypoint) || !FinePrint.WaypointManager.navWaypoint.blinking || (int)((Time.fixedTime - (int)Time.fixedTime) * 4) % 2 == 0) { Graphics.DrawTexture(iconRect, ContractDefs.textures[wpd.waypoint.id], new Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, SystemUtilities.RandomColor(wpd.waypoint.seed, wpd.currentAlpha)); } // Hint text! if (iconRect.Contains(Event.current.mousePosition)) { // Add agency to label if (wpd.waypoint.contractReference != null) { label += "\n" + wpd.waypoint.contractReference.Agent.Name; } float width = 240f; float height = hintTextStyle.CalcHeight(new GUIContent(label), width); float yoffset = height + 48.0f; GUI.Box(new Rect(screenPos.x - width / 2.0f, (float)Screen.height - screenPos.y - yoffset, width, height), label, hintTextStyle); } } }
public static void DrawWaypoint(CelestialBody targetBody, double latitude, double longitude, double altitude, string id, int seed, float alpha = -1.0f) { // Translate to scaled space Vector3d localSpacePoint = targetBody.GetWorldSurfacePosition(latitude, longitude, altitude); Vector3d scaledSpacePoint = ScaledSpace.LocalToScaledSpace(localSpacePoint); // Don't draw if it's behind the camera if (Vector3d.Dot(PlanetariumCamera.Camera.transform.forward, scaledSpacePoint.normalized) < 0.0) { return; } // Translate to screen position Vector3 screenPos = PlanetariumCamera.Camera.WorldToScreenPoint(new Vector3((float)scaledSpacePoint.x, (float)scaledSpacePoint.y, (float)scaledSpacePoint.z)); // Draw the marker at half-resolution (30 x 45) - that seems to match the one in the map view Rect markerRect = new Rect(screenPos.x - 15f, (float)Screen.height - screenPos.y - 45.0f, 30f, 45f); // Half-res for the icon too (16 x 16) Rect iconRect = new Rect(screenPos.x - 8f, (float)Screen.height - screenPos.y - 39.0f, 16f, 16f); if (alpha < 0.0f) { Vector3 cameraPos = ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.Camera.transform.position); bool occluded = WaypointData.IsOccluded(targetBody, cameraPos, localSpacePoint, altitude); float desiredAlpha = occluded ? 0.3f : 1.0f * Config.opacity; if (lastAlpha < 0.0f) { lastAlpha = desiredAlpha; } else if (lastAlpha < desiredAlpha) { lastAlpha = Mathf.Clamp(lastAlpha + Time.deltaTime * 4f, lastAlpha, desiredAlpha); } else { lastAlpha = Mathf.Clamp(lastAlpha - Time.deltaTime * 4f, desiredAlpha, lastAlpha); } alpha = lastAlpha; } // Draw the marker Graphics.DrawTexture(markerRect, GameDatabase.Instance.GetTexture("Squad/Contracts/Icons/marker", false), new Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, new Color(0.5f, 0.5f, 0.5f, 0.5f * (alpha - 0.3f) / 0.7f)); // Draw the icon Graphics.DrawTexture(iconRect, ContractDefs.sprites[id].texture, new Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, SystemUtilities.RandomColor(seed, alpha)); }
public static void OnGUI() { // Initialize icon list if (icons == null) { List <GUIContent> content = new List <GUIContent>(); // Get all the stock icons foreach (GameDatabase.TextureInfo texInfo in GameDatabase.Instance.databaseTexture.Where(t => t.name.StartsWith("Squad/Contracts/Icons/"))) { string name = texInfo.name.Replace("Squad/Contracts/Icons/", ""); if (forbiddenIcons.Contains(name)) { continue; } content.Add(new GUIContent(ContractDefs.sprites[name].texture, name)); } // Get all the directories for custom icons ConfigNode[] iconConfig = GameDatabase.Instance.GetConfigNodes("WAYPOINT_MANAGER_ICONS"); foreach (ConfigNode configNode in iconConfig) { string dir = configNode.GetValue("url"); foreach (GameDatabase.TextureInfo texInfo in GameDatabase.Instance.databaseTexture.Where(t => t.name.StartsWith(dir))) { content.Add(new GUIContent(texInfo.texture, texInfo.name)); } } // Add custom icons foreach (string icon in customIcons) { foreach (GameDatabase.TextureInfo texInfo in GameDatabase.Instance.databaseTexture) { if (texInfo.name == icon) { content.Add(new GUIContent(texInfo.texture, texInfo.name)); break; } } } icons = content.ToArray(); } // Initialize color list if (colors == null) { List <GUIContent> content = new List <GUIContent>(); foreach (int seed in seeds) { Color color = SystemUtilities.RandomColor(seed, 1.0f, 1.0f, 1.0f); Texture2D texture = new Texture2D(6, 12, TextureFormat.RGBA32, false); Color[] pixels = new Color[6 * 16]; for (int i = 0; i < pixels.Length; i++) { pixels[i] = color; } texture.SetPixels(pixels); texture.Compress(true); content.Add(new GUIContent(texture)); } colors = content.ToArray(); // Set the styles used colorWheelStyle = new GUIStyle(GUI.skin.label); colorWheelStyle.padding = new RectOffset(0, 0, 2, 2); colorWheelStyle.margin = new RectOffset(0, -1, 0, 0); colorLabelStyle = new GUIStyle(GUI.skin.label); colorLabelStyle.padding = new RectOffset(0, 0, 0, 0); colorLabelStyle.margin = new RectOffset(4, 4, 6, 6); colorLabelStyle.stretchWidth = true; colorLabelStyle.fixedHeight = 12; disabledText = new GUIStyle(GUI.skin.textField); disabledText.normal.textColor = Color.gray; } if (WaypointManager.Instance != null && WaypointManager.Instance.visible) { if (windowMode != WindowMode.None && windowMode != WindowMode.Delete) { wpWindowPos = GUILayout.Window( typeof(WaypointManager).FullName.GetHashCode() + 2, wpWindowPos, WindowGUI, windowMode.ToString() + " Waypoint", GUILayout.Height(1), GUILayout.ExpandHeight(true)); // Add the close icon if (GUI.Button(new Rect(wpWindowPos.xMax - 18, wpWindowPos.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label)) { windowMode = WindowMode.None; } if (showIconPicker) { // Default iconPicker position if (iconPickerPosition.xMin == iconPickerPosition.xMax) { iconPickerPosition = new Rect((Screen.width - ICON_PICKER_WIDTH) / 2.0f, wpWindowPos.yMax, ICON_PICKER_WIDTH, 1); } iconPickerPosition = GUILayout.Window( typeof(WaypointManager).FullName.GetHashCode() + 3, iconPickerPosition, IconPickerGUI, "Icon Selector"); // Add the close icon if (GUI.Button(new Rect(iconPickerPosition.xMax - 18, iconPickerPosition.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label)) { showIconPicker = false; } } // Reset the position of the iconPicker window if (!showIconPicker) { iconPickerPosition.xMax = iconPickerPosition.xMin; } } else if (windowMode == WindowMode.Delete) { rmWindowPos = GUILayout.Window( typeof(WaypointManager).FullName.GetHashCode() + 2, rmWindowPos, DeleteGUI, windowMode.ToString() + " Waypoint"); // Add the close icon if (GUI.Button(new Rect(rmWindowPos.xMax - 18, rmWindowPos.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label)) { windowMode = WindowMode.None; } } if (showExportDialog) { expWindowPos = GUILayout.Window( typeof(WaypointManager).FullName.GetHashCode() + 3, expWindowPos, ExportGUI, "Overwrite export file?"); // Add the close icon if (GUI.Button(new Rect(expWindowPos.xMax - 18, expWindowPos.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label)) { showExportDialog = false; } } if (mapLocationMode) { PlaceWaypointAtCursor(); // Lock the waypoint if the user clicks if (Event.current.type == EventType.MouseUp && Event.current.button == 0) { mapLocationMode = false; } } } }
/// <summary> /// Gets the contract icon for the given id and seed (color). /// </summary> /// <param name="url">URL of the icon</param> /// <param name="seed">Seed to use for generating the color</param> /// <returns>The texture</returns> public static Texture2D GetContractIcon(string url, int seed) { // Check cache for texture Texture2D texture; Color color = SystemUtilities.RandomColor(seed, 1.0f, 1.0f, 1.0f); if (!contractIcons.ContainsKey(url)) { contractIcons[url] = new Dictionary <Color, Texture2D>(); } if (!contractIcons[url].ContainsKey(color)) { Texture2D baseTexture = ContractDefs.sprites[url].texture; try { Texture2D loadedTexture = null; string path = (url.Contains('/') ? "GameData/" : "GameData/Squad/Contracts/Icons/") + url; // PNG loading if (File.Exists(path + ".png")) { path += ".png"; loadedTexture = new Texture2D(baseTexture.width, baseTexture.height, TextureFormat.RGBA32, false); loadedTexture.LoadImage(File.ReadAllBytes(path.Replace('/', Path.DirectorySeparatorChar))); } // DDS loading else if (File.Exists(path + ".dds")) { path += ".dds"; BinaryReader br = new BinaryReader(new MemoryStream(File.ReadAllBytes(path))); if (br.ReadUInt32() != DDSValues.uintMagic) { throw new Exception("Format issue with DDS texture '" + path + "'!"); } DDSHeader ddsHeader = new DDSHeader(br); if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDX10) { DDSHeaderDX10 ddsHeaderDx10 = new DDSHeaderDX10(br); } TextureFormat texFormat; if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT1) { texFormat = UnityEngine.TextureFormat.DXT1; } else if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT3) { texFormat = UnityEngine.TextureFormat.DXT1 | UnityEngine.TextureFormat.Alpha8; } else if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT5) { texFormat = UnityEngine.TextureFormat.DXT5; } else { throw new Exception("Unhandled DDS format!"); } loadedTexture = new Texture2D((int)ddsHeader.dwWidth, (int)ddsHeader.dwHeight, texFormat, false); loadedTexture.LoadRawTextureData(br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position))); } else { throw new Exception("Couldn't find file for icon '" + url + "'"); } Color[] pixels = loadedTexture.GetPixels(); for (int i = 0; i < pixels.Length; i++) { pixels[i] *= color; } texture = new Texture2D(baseTexture.width, baseTexture.height, TextureFormat.RGBA32, false); texture.SetPixels(pixels); texture.Apply(false, false); contractIcons[url][color] = texture; UnityEngine.Object.Destroy(loadedTexture); } catch (Exception e) { Debug.LogError("WaypointManager: Couldn't create texture for '" + url + "'!"); Debug.LogException(e); texture = contractIcons[url][color] = baseTexture; } } else { texture = contractIcons[url][color]; } return(texture); }
/// <summary> /// Gets the contract icon for the given id and seed (color). /// </summary> /// <param name="url">URL of the icon</param> /// <param name="seed">Seed to use for generating the color</param> /// <returns>The texture</returns> /// public static Texture2D GetContractIcon(string url, int seed) { string key = url; // Check cache for texture Texture2D texture; Color color = SystemUtilities.RandomColor(seed, 1.0f, 1.0f, 1.0f); if (!contractIcons.ContainsKey(key)) { contractIcons[key] = new Dictionary <Color, Texture2D>(); } if (!contractIcons[key].ContainsKey(color)) { if (url.EndsWith(".png")) { url = url.Substring(0, url.Length - 4); } if (url.StartsWith("GameData")) { url = url.Substring(9); } Texture2D baseTexture = ContractDefs.sprites[url].texture; url = url.Replace('\\', '/'); string url2 = url; string tmp = url; if (!tmp.Contains("PluginData")) { if (!url.StartsWith("GameData")) { tmp = "/" + url; } for (int i = 0; i < GameDatabase.Instance.databaseTexture.Count; i++) { if (GameDatabase.Instance.databaseTexture[i].file != null) { if (GameDatabase.Instance.databaseTexture[i].name.EndsWith(tmp) || GameDatabase.Instance.databaseTexture[i].name == url) { url2 = GameDatabase.Instance.databaseTexture[i].file.fullPath; } } } } else { if (!url2.StartsWith("GameData")) { url2 = KSPUtil.ApplicationRootPath + "GameData/" + url2; } } string path = url2; if (path.EndsWith(".png") || path.EndsWith(".dds")) { path = path.Substring(0, path.Length - 4); } try { Texture2D loadedTexture = null; // PNG loading if (File.Exists(path + ".png")) { path += ".png"; loadedTexture = new Texture2D(baseTexture.width, baseTexture.height, TextureFormat.RGBA32, false); loadedTexture.LoadImage(File.ReadAllBytes(path.Replace('/', Path.DirectorySeparatorChar))); } // DDS loading else { if (File.Exists(path + ".dds")) { path += ".dds"; BinaryReader br = new BinaryReader(new MemoryStream(File.ReadAllBytes(path))); if (br.ReadUInt32() != DDSValues.uintMagic) { throw new Exception("Format issue with DDS texture '" + path + "'!"); } DDSHeader ddsHeader = new DDSHeader(br); if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDX10) { DDSHeaderDX10 ddsHeaderDx10 = new DDSHeaderDX10(br); } TextureFormat texFormat; if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT1) { texFormat = UnityEngine.TextureFormat.DXT1; } #if false // Not using DXT3 anymore else if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT3) { texFormat = UnityEngine.TextureFormat.DXT1 | UnityEngine.TextureFormat.Alpha8; } #endif else if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT5) { texFormat = UnityEngine.TextureFormat.DXT5; } else { throw new Exception("Unhandled DDS format!"); } loadedTexture = new Texture2D((int)ddsHeader.dwWidth, (int)ddsHeader.dwHeight, texFormat, false); loadedTexture.LoadRawTextureData(br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position))); } else { throw new Exception("Couldn't find file for icon '" + url + "'"); } } Color[] pixels = loadedTexture.GetPixels(); for (int i = 0; i < pixels.Length; i++) { pixels[i] *= color; } //texture = new Texture2D(baseTexture.width, baseTexture.height, TextureFormat.RGBA32, false); texture = new Texture2D(loadedTexture.width, loadedTexture.height, TextureFormat.RGBA32, false); texture.SetPixels(pixels); texture.Apply(false, false); contractIcons[key][color] = texture; UnityEngine.Object.Destroy(loadedTexture); } catch (Exception e) { Log.Error("WaypointManager: Couldn't create texture for '" + url + "'!"); Log.Error("key: " + key); Log.Error("path: " + path); Debug.LogException(e); texture = contractIcons[key][color] = baseTexture; } } else { texture = contractIcons[key][color]; } return(texture); }