/// <summary> /// Draws location marker on screen. /// </summary> public void DrawLocationMarker(int styleHandle, Vector3D position, MyHudEntityParams hudParams, float targetDamageRatio, float targetArmorRatio, float alphaMultiplifier = 1f) { if (MySession.ControlledEntity == null) { return; } // Transform point to camera space, so Z = -1 is always forward and then do projective transformation Vector3D transformedPoint = Vector3D.Transform(position, MySector.MainCamera.ViewMatrix); Vector4D projectedPoint = Vector4D.Transform(transformedPoint, MySector.MainCamera.ProjectionMatrix); // If point is behind camera we swap X and Y (this is mirror-like transformation) if (transformedPoint.Z > 0) { projectedPoint.X *= -1; projectedPoint.Y *= -1; } if (projectedPoint.W == 0) { return; } MyMarkerStyle markerStyle = m_markerStyles[styleHandle]; double distance = Vector3D.Distance(position, MySession.ControlledEntity.Entity.WorldMatrix.Translation); float maxDistance = hudParams.MaxDistance; byte colorAlphaInByte = 255; var hudColor = MyFakes.SHOW_FACTIONS_GUI ? markerStyle.Color : Color.White; hudColor.A = (byte)(colorAlphaInByte * alphaMultiplifier); // Calculate centered coordinates in range <0..1> Vector2 projectedPoint2D = new Vector2((float)(projectedPoint.X / projectedPoint.W / 2.0f) + 0.5f, (float)(-projectedPoint.Y / projectedPoint.W) / 2.0f + 0.5f); if (MyVideoSettingsManager.IsTripleHead()) { projectedPoint2D.X = (projectedPoint2D.X - (1.0f / 3.0f)) / (1.0f / 3.0f); } float objectNameYOffset = 0.0f; //offset to direction indicator // This will bound the rectangle in circle, although it isn't real circle because we work in [1,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 Vector2 direction = projectedPoint2D - MyHudConstants.DIRECTION_INDICATOR_SCREEN_CENTER; if ((direction.Length() > MyHudConstants.DIRECTION_INDICATOR_MAX_SCREEN_DISTANCE) || (transformedPoint.Z > 0)) { if ((hudParams.FlagsEnum & MyHudIndicatorFlagsEnum.SHOW_BORDER_INDICATORS) == 0) { return; } if (direction.LengthSquared() > MyMathConstants.EPSILON_SQUARED) { direction.Normalize(); } else { direction = new Vector2(1f, 0f); } projectedPoint2D = MyHudConstants.DIRECTION_INDICATOR_SCREEN_CENTER + direction * MyHudConstants.DIRECTION_INDICATOR_MAX_SCREEN_DISTANCE; // Fix vertical scale projectedPoint2D.Y *= MyGuiManager.GetHudSize().Y; AddTexturedQuad(markerStyle.TextureDirectionIndicator, projectedPoint2D + direction * MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE * 2.5f, direction, hudColor, MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE * 1.2f, MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE * 0.8f); } else { // Fix vertical scale projectedPoint2D.Y *= MyGuiManager.GetHudSize().Y; Color rectangleColor = Color.White; rectangleColor.A = colorAlphaInByte; if ((hudParams.FlagsEnum & MyHudIndicatorFlagsEnum.SHOW_FOCUS_MARK) > 0) { Vector2 upVector = new Vector2(0, -1); if (markerStyle.TextureTargetRotationSpeed != 0) { upVector = new Vector2((float)Math.Cos(MySandboxGame.TotalGamePlayTimeInMilliseconds / 1000f * markerStyle.TextureTargetRotationSpeed * MathHelper.Pi), (float)Math.Sin(MySandboxGame.TotalGamePlayTimeInMilliseconds / 1000f * markerStyle.TextureTargetRotationSpeed * MathHelper.Pi)); } AddTexturedQuad(markerStyle.TextureTarget, projectedPoint2D, upVector, hudColor, MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE * markerStyle.TextureTargetScale, MyHudConstants.HUD_DIRECTION_INDICATOR_SIZE * markerStyle.TextureTargetScale); } objectNameYOffset = -MyHudConstants.HUD_TEXTS_OFFSET; } if (hudParams.Text != null && hudParams.Text.Length > 0 && (hudParams.FlagsEnum & MyHudIndicatorFlagsEnum.SHOW_TEXT) != 0) { // Add object's name MyHudText objectName = m_hudScreen.AllocateText(); if (objectName != null) { objectName.Start(markerStyle.Font, projectedPoint2D + new Vector2(0, hudParams.OffsetText ? objectNameYOffset : 0), hudColor, 0.8f, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); objectName.Append(hudParams.Text); } } // display hud icon if (hudParams.Icon != null && (hudParams.FlagsEnum & MyHudIndicatorFlagsEnum.SHOW_ICON) != 0) { Color iconColor = hudParams.IconColor.HasValue && MyFakes.SHOW_FACTIONS_GUI ? hudParams.IconColor.Value : Color.White; iconColor.A = (byte)(colorAlphaInByte * alphaMultiplifier); AddTexturedQuad(hudParams.Icon.Value, projectedPoint2D + hudParams.IconOffset, new Vector2(0, -1), iconColor, hudParams.IconSize.X / 2f, hudParams.IconSize.Y / 2f); } if (MyFakes.SHOW_HUD_DISTANCES && (hudParams.FlagsEnum & MyHudIndicatorFlagsEnum.SHOW_DISTANCE) != 0) { // Add distance to object MyHudText objectDistance = m_hudScreen.AllocateText(); if (objectDistance != null) { objectDistance.Start(markerStyle.Font, projectedPoint2D + new Vector2(0, MyHudConstants.HUD_TEXTS_OFFSET), hudColor, 0.8f, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); // Create string builder with distance in metres, e.g. "123m" objectDistance.AppendInt32((int)Math.Round(distance)); objectDistance.Append("m"); } } }
public void OverrideStyleForRelation(MyRelationsBetweenPlayerAndBlock relation, MyFontEnum font, MyHudTexturesEnum directionIcon, MyHudTexturesEnum targetIcon, Color color) { int handle = GetStyleForRelation(relation); m_markerStyles[handle] = new MyMarkerStyle(font, directionIcon, targetIcon, color); }