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);
                }
            }