public MyGuiScreenHudSpace() : base() { RecreateControls(true); m_markerRender = new MyHudMarkerRender(this); m_oreHudMarkerStyle = m_markerRender.AllocateMarkerStyle(MyFontEnum.White, MyHudTexturesEnum.DirectionIndicator, MyHudTexturesEnum.Target_neutral, Color.White); m_gpsHudMarkerStyle = m_markerRender.AllocateMarkerStyle(MyFontEnum.DarkBlue, MyHudTexturesEnum.DirectionIndicator, MyHudTexturesEnum.Target_me, MyHudConstants.GPS_COLOR); m_buttonPanelHudMarkerStyle = m_markerRender.AllocateMarkerStyle(MyFontEnum.DarkBlue, MyHudTexturesEnum.DirectionIndicator, MyHudTexturesEnum.Target_me, MyHudConstants.GPS_COLOR); m_tmpHudEntityParams = new MyHudEntityParams() { Text = new StringBuilder(), FlagsEnum = MyHudIndicatorFlagsEnum.SHOW_ALL, IconColor = MyHudConstants.GPS_COLOR, OffsetText = true }; }
/// <summary> /// Draws a texture based icon /// </summary> private static void DrawIcon(MyHudMarkerRender renderer, string centerIconSprite, Vector2 screenPosition, Color markerColor, float sizeScale = 1) { Vector2 iconSize = new Vector2(8, 8); // Draw icon iconSize *= sizeScale; renderer.AddTexturedQuad(centerIconSprite, screenPosition, -Vector2.UnitY, markerColor, iconSize.X, iconSize.Y); }
/// <summary> /// Draws this POI /// </summary> /// <param name="renderer">MyHudMarkerRender instance that performs the rendering.</param> public void Draw(MyHudMarkerRender renderer) { Vector2 screenPosition = Vector2.Zero; bool isBehind = false; // If it's not possible to compute a screen position, don't draw anything //ProfilerShort.Begin("Compute screen position"); if (!TryComputeScreenPoint(WorldPosition, out screenPosition, out isBehind)) { //ProfilerShort.End(); return; } Vector2 screen = new Vector2(MyGuiManager.GetSafeFullscreenRectangle().Width, MyGuiManager.GetSafeFullscreenRectangle().Height); Vector2 hudSize = MyGuiManager.GetHudSize(); Vector2 center = MyGuiManager.GetHudSizeHalf(); float yScale = screen.Y / 1080f; screenPosition *= hudSize; // Obtain POI font and colour information //ProfilerShort.BeginNextBlock("Obtain style"); Color markerColor = Color.White; Color fontColor = Color.White; MyFontEnum font = MyFontEnum.White; GetPOIColorAndFontInformation(out markerColor, out fontColor, out font); // This will bound the rectangle in circle, although it isn't real circle because we work in [0,1] dimensions, // but number of horizontal pixels is bigger, so at the end it's more elypse // It must be done when point is out of circle or behind the camera //ProfilerShort.BeginNextBlock("Bind marker"); Vector2 direction = screenPosition - center; Vector3D transformedPoint = Vector3D.Transform(WorldPosition, MySector.MainCamera.ViewMatrix); float minVal = 0.04f; float overshootVal = 0.5f - minVal; //ProfilerShort.BeginNextBlock("Draw direction or marker"); if ((screenPosition.X < minVal || screenPosition.X > hudSize.X - minVal || screenPosition.Y < minVal || screenPosition.Y > hudSize.Y - minVal || transformedPoint.Z > 0)) { // Don't render targets when they are off-screen if (POIType == PointOfInterestType.Target) return; //ProfilerShort.Begin("Draw direction"); Vector2 normalizedDir = Vector2.Normalize(direction); screenPosition = center + center * normalizedDir * 0.77f; // 0.77f clamps the arrows to the screen without overlapping the toolbar direction = screenPosition - center; if (direction.LengthSquared() > MyMathConstants.EPSILON_SQUARED) { direction.Normalize(); } else { direction = new Vector2(1f, 0f); } float arrowSize = MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE * 0.8f; arrowSize /= yScale; arrowSize /= yScale; // Draw directional arrow, offset by direction renderer.AddTexturedQuad(MyHudTexturesEnum.DirectionIndicator, screenPosition, direction, markerColor, arrowSize, arrowSize); screenPosition -= direction * MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE * 2.0f; //ProfilerShort.End(); } else { float size = MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE / yScale; size /= yScale; if (POIType == PointOfInterestType.Target) { renderer.AddTexturedQuad(MyHudTexturesEnum.TargetTurret, screenPosition, -Vector2.UnitY, Color.White, size, size); return; } //ProfilerShort.Begin("Draw marker box"); // Draw [ ] box renderer.AddTexturedQuad(MyHudTexturesEnum.Target_neutral, screenPosition, -Vector2.UnitY, markerColor, size, size); //ProfilerShort.End(); } float fullFocus = 0.03f; float focusNoText = 0.07f; float focusEdge = 0.15f; int edgeState = 0; float alphaValue = 1; float alphaValueSubtext = 1; float directionLength = direction.Length(); if (directionLength <= fullFocus) { // Inner circle alphaValue = 1; alphaValueSubtext = 1; edgeState = 0; } else if (directionLength > fullFocus && directionLength < focusNoText) { // Second circle float fadeSize = focusEdge - fullFocus; alphaValue = 1 - ((directionLength - fullFocus) / fadeSize); alphaValue = alphaValue * alphaValue; fadeSize = focusNoText - fullFocus; alphaValueSubtext = 1 - ((directionLength - fullFocus) / fadeSize); alphaValueSubtext = alphaValueSubtext * alphaValueSubtext; edgeState = 1; } else if (directionLength >= focusNoText && directionLength < focusEdge) { // Third circe float fadeSize = focusEdge - fullFocus; alphaValue = 1 - ((directionLength - fullFocus) / fadeSize); alphaValue = alphaValue * alphaValue; fadeSize = focusEdge - focusNoText; alphaValueSubtext = 1 - ((directionLength - focusNoText) / fadeSize); alphaValueSubtext = alphaValueSubtext * alphaValueSubtext; edgeState = 2; } else { // Outer circle alphaValue = 0; alphaValueSubtext = 0; edgeState = 2; } float iconAlpha = (directionLength - 0.2f) / 0.5f; iconAlpha = MathHelper.Clamp(iconAlpha, 0, 1); alphaValue = MyMath.Clamp(alphaValue, 0, 1); if (m_disableFading || SignalDisplayMode == SignalMode.FullDisplay || AlwaysVisible) { alphaValue = 1; alphaValueSubtext = 1; iconAlpha = 1; edgeState = 0; } // Render name, but only if visible //ProfilerShort.BeginNextBlock("Draw name"); Vector2 textLabelOffset = new Vector2(0, 24f / MyGuiManager.GetFullscreenRectangle().Width); if (SignalDisplayMode != SignalMode.NoNames || m_disableFading || AlwaysVisible) { if (alphaValue > float.Epsilon && this.Text.Length > 0) { MyHudText objectName = renderer.m_hudScreen.AllocateText(); if (objectName != null) { fontColor.A = (byte)(255f * alphaValue); objectName.Start(font, screenPosition - textLabelOffset, fontColor, 0.7f / yScale, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); objectName.Append(this.Text); } } } MyHudText distanceBuilder = null; if (POIType != PointOfInterestType.Group) { // Draw icon //ProfilerShort.BeginNextBlock("Draw regular icon"); byte oldA = markerColor.A; markerColor.A = (byte)(255 * iconAlpha); DrawIcon(renderer, POIType, Relationship, screenPosition, markerColor); markerColor.A = oldA; // Render distance, groups render their distance differently //ProfilerShort.BeginNextBlock("Draw regular distance"); distanceBuilder = renderer.m_hudScreen.AllocateText(); if (distanceBuilder != null) { StringBuilder stringBuilder = new StringBuilder(); AppendDistance(stringBuilder, Distance); fontColor.A = 255; distanceBuilder.Start(font, screenPosition + textLabelOffset * (0.7f + 0.3f * alphaValue), fontColor, (0.5f + 0.2f * alphaValue) / yScale, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); distanceBuilder.Append(stringBuilder); } // Non-group POIs end here //ProfilerShort.End(); return; } var significantPOIs = GetSignificantGroupPOIs(); //ProfilerShort.BeginNextBlock("Compute group offsets"); Vector2[] offsetsSquare = { new Vector2(-6, -4), new Vector2(6, -4), new Vector2(-6, 4), new Vector2(6, 4), new Vector2(0, 12) }; Vector2[] offsetsVertical = { new Vector2(16, -4), new Vector2(16, 4), new Vector2(16, 12), new Vector2(16, 20), new Vector2(16, 28) }; for (int i = 0; i < offsetsSquare.Length; i++) { float offsetVal = edgeState < 2 ? 1 : alphaValueSubtext; float offsetY = offsetsSquare[i].Y; offsetsSquare[i].X = ((offsetsSquare[i].X + (22 * offsetVal)) / MyGuiManager.GetFullscreenRectangle().Width); offsetsSquare[i].Y = (offsetY / 1080f) / yScale; // Correct for triple-monitor-setup if (MyVideoSettingsManager.IsTripleHead()) offsetsSquare[i].X /= 0.33f; // Fallback in case the scale is too small if (offsetsSquare[i].Y <= float.Epsilon) offsetsSquare[i].Y = offsetY / 1080f; offsetY = offsetsVertical[i].Y; offsetsVertical[i].X = (offsetsVertical[i].X / MyGuiManager.GetFullscreenRectangle().Width) / yScale; offsetsVertical[i].Y = (offsetY / 1080f) / yScale; // Correct for triple-monitor-setup if (MyVideoSettingsManager.IsTripleHead()) offsetsVertical[i].X /= 0.33f; // Fallback in case the scale is too small if (offsetsVertical[i].Y <= float.Epsilon) offsetsVertical[i].Y = offsetY / 1080f; } int index = 0; if (significantPOIs.Count > 1) { MyRelationsBetweenPlayerAndBlock[] relations = { MyRelationsBetweenPlayerAndBlock.Owner, MyRelationsBetweenPlayerAndBlock.FactionShare, MyRelationsBetweenPlayerAndBlock.Neutral, MyRelationsBetweenPlayerAndBlock.Enemies }; //ProfilerShort.BeginNextBlock("Draw group elements"); for (int i = 0; i < relations.Length; i++) { MyRelationsBetweenPlayerAndBlock relationship = relations[i]; if (!significantPOIs.ContainsKey(relationship)) continue; var poiList = significantPOIs[relationship]; if (poiList.Count == 0) continue; PointOfInterest poi = poiList[0]; if (poi == null) continue; GetColorAndFontForRelationship(relationship, out markerColor, out fontColor, out font); float offsetVal = edgeState == 0 ? 1 : alphaValueSubtext; if (edgeState >= 2) offsetVal = 0; Vector2 offset = Vector2.Lerp(offsetsSquare[index], offsetsVertical[index], offsetVal); string icon = GetIconForRelationship(relationship); DrawIcon(renderer, icon, screenPosition + offset, markerColor, 0.75f / yScale); if (IsPoiAtHighAlert(poi)) DrawIcon(renderer, "Textures\\HUD\\marker_alert.dds", screenPosition + offset, Color.White, 0.75f / yScale); if ((SignalDisplayMode != SignalMode.NoNames || m_disableFading || AlwaysVisible) && poi.Text.Length > 0) { MyHudText objectName = renderer.m_hudScreen.AllocateText(); if (objectName != null) { float alpha = 1; if (edgeState == 1) alpha = alphaValueSubtext; else if (edgeState > 1) alpha = 0; fontColor.A = (byte)(255f * alpha); Vector2 horizontalOffset = new Vector2(8f / MyGuiManager.GetFullscreenRectangle().Width, 0); horizontalOffset.X /= yScale; objectName.Start(font, screenPosition + offset + horizontalOffset, fontColor, 0.55f / yScale, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER); objectName.Append(poi.Text); } } index++; } } else { foreach (var kvp in significantPOIs) { MyRelationsBetweenPlayerAndBlock relationship = kvp.Key; if (!significantPOIs.ContainsKey(relationship)) continue; var poiList = kvp.Value; for (int i = 0; i < 4 && i < poiList.Count; i++) { PointOfInterest poi = poiList[i]; if (poi == null) continue; GetColorAndFontForRelationship(relationship, out markerColor, out fontColor, out font); float offsetVal = edgeState == 0 ? 1 : alphaValueSubtext; if (edgeState >= 2) offsetVal = 0; Vector2 offset = Vector2.Lerp(offsetsSquare[index], offsetsVertical[index], offsetVal); string icon = GetIconForRelationship(relationship); DrawIcon(renderer, icon, screenPosition + offset, markerColor, 0.75f / yScale); if (IsPoiAtHighAlert(poi)) DrawIcon(renderer, "Textures\\HUD\\marker_alert.png", screenPosition + offset, Color.White, 0.75f / yScale); if ((SignalDisplayMode != SignalMode.NoNames || m_disableFading || AlwaysVisible) && poi.Text.Length > 0) { MyHudText objectName = renderer.m_hudScreen.AllocateText(); if (objectName != null) { float alpha = 1; if (edgeState == 1) alpha = alphaValueSubtext; else if (edgeState > 1) alpha = 0; fontColor.A = (byte)(255f * alpha); Vector2 horizontalOffset = new Vector2(8f / MyGuiManager.GetFullscreenRectangle().Width, 0); horizontalOffset.X /= yScale; objectName.Start(font, screenPosition + offset + horizontalOffset, fontColor, 0.55f / yScale, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER); objectName.Append(poi.Text); } } index++; } } } //ProfilerShort.BeginNextBlock("Group GetPOIColorAndFontInformation"); GetPOIColorAndFontInformation(out markerColor, out fontColor, out font); // Render distance //ProfilerShort.BeginNextBlock("Compute group distance label"); float distanceOffset = edgeState == 0 ? 1 : alphaValueSubtext; if (edgeState >= 2) distanceOffset = 0; Vector2 distancePos = Vector2.Lerp(offsetsSquare[4], offsetsVertical[index], distanceOffset); Vector2 horizontalDistanceOffset = Vector2.Lerp(Vector2.Zero, new Vector2((24f / 1080f) / yScale, (4f / 1080f) / yScale), distanceOffset); //ProfilerShort.BeginNextBlock("Draw group distance"); distanceBuilder = renderer.m_hudScreen.AllocateText(); if (distanceBuilder != null) { StringBuilder stringBuilder = new StringBuilder(); AppendDistance(stringBuilder, Distance); fontColor.A = 255; distanceBuilder.Start(font, screenPosition + distancePos + horizontalDistanceOffset, fontColor, (0.5f + 0.2f * alphaValue) / yScale, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); distanceBuilder.Append(stringBuilder); } //ProfilerShort.End(); }
/// <summary> /// Draws an icon for the POI /// </summary> private static void DrawIcon(MyHudMarkerRender renderer, PointOfInterestType poiType, MyRelationsBetweenPlayerAndBlock relationship, Vector2 screenPosition, Color markerColor, float sizeScale = 1) { MyHudTexturesEnum centerIcon = MyHudTexturesEnum.corner; string centerIconSprite = string.Empty; Vector2 iconSize = new Vector2(12, 12); switch (poiType) { default: // Groups don't have an icon case PointOfInterestType.Group: return; case PointOfInterestType.Hack: centerIcon = MyHudTexturesEnum.hit_confirmation; break; case PointOfInterestType.Target: centerIcon = MyHudTexturesEnum.TargetTurret; break; case PointOfInterestType.Ore: centerIcon = MyHudTexturesEnum.HudOre; break; case PointOfInterestType.Character: case PointOfInterestType.SmallEntity: case PointOfInterestType.LargeEntity: case PointOfInterestType.StaticEntity: case PointOfInterestType.Unknown: case PointOfInterestType.UnknownEntity: { string icon = GetIconForRelationship(relationship); DrawIcon(renderer, icon, screenPosition, markerColor); return; } case PointOfInterestType.GPS: { string icon = "Textures\\HUD\\marker_gps.dds"; DrawIcon(renderer, icon, screenPosition, markerColor); return; } } // Draw icon if (!string.IsNullOrWhiteSpace(centerIconSprite)) { iconSize *= sizeScale; renderer.AddTexturedQuad(centerIconSprite, screenPosition, -Vector2.UnitY, markerColor, iconSize.X, iconSize.Y); } else { float indicatorSize = MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE * 0.8f * sizeScale; renderer.AddTexturedQuad(centerIcon, screenPosition, -Vector2.UnitY, markerColor, indicatorSize, indicatorSize); } }