Add viewport icons scale relative to the distance and editor control over it

#2944 #2644
This commit is contained in:
Wojtek Figat
2025-06-03 14:50:47 +02:00
parent 55b441e9fa
commit f2aaad0048
4 changed files with 43 additions and 7 deletions

View File

@@ -35,7 +35,8 @@ namespace FlaxEditor.SceneGraph
return false;
}
BoundingSphere sphere = new BoundingSphere(Transform.Translation, 7.0f);
var center = _actor.Transform.Translation;
ViewportIconsRenderer.GetBounds(ref center, ref ray.Ray.Position, out var sphere);
return CollisionsHelper.RayIntersectsSphere(ref ray.Ray, ref sphere, out distance);
}
}

View File

@@ -23,8 +23,6 @@
#include "Engine/Level/Actors/SpotLight.h"
#include "Engine/Video/VideoPlayer.h"
#define ICON_RADIUS 7.0f
enum class IconTypes
{
PointLight,
@@ -66,6 +64,16 @@ public:
};
ViewportIconsRendererService ViewportIconsRendererServiceInstance;
float ViewportIconsRenderer::Scale = 1.0f;
void ViewportIconsRenderer::GetBounds(const Vector3& position, const Vector3& viewPosition, BoundingSphere& bounds)
{
constexpr float minSize = 7.0f;
constexpr float maxSize = 30.0f;
Real scale = Math::Square(Vector3::Distance(position, viewPosition) / 1000.0f);
Real radius = minSize + Math::Min(scale, 1.0f) * (maxSize - minSize);
bounds = BoundingSphere(position, radius * Scale);
}
void ViewportIconsRenderer::DrawIcons(RenderContext& renderContext, Actor* actor)
{
@@ -133,7 +141,8 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene
AssetReference<Texture> texture;
for (Actor* icon : icons)
{
BoundingSphere sphere(icon->GetPosition() - renderContext.View.Origin, ICON_RADIUS);
BoundingSphere sphere;
ViewportIconsRenderer::GetBounds(icon->GetPosition() - renderContext.View.Origin, renderContext.View.Position, sphere);
if (!frustum.Intersects(sphere))
continue;
IconTypes iconType;
@@ -173,7 +182,7 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene
if (draw.Buffer)
{
// Create world matrix
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
Matrix::Scaling(sphere.Radius * 2.0f, m2);
Matrix::RotationY(PI, world);
Matrix::Multiply(m2, world, m1);
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);
@@ -193,14 +202,15 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Actor
auto& view = renderContext.View;
const BoundingFrustum frustum = view.Frustum;
Matrix m1, m2, world;
BoundingSphere sphere(actor->GetPosition() - renderContext.View.Origin, ICON_RADIUS);
BoundingSphere sphere;
ViewportIconsRenderer::GetBounds(actor->GetPosition() - renderContext.View.Origin, renderContext.View.Position, sphere);
IconTypes iconType;
AssetReference<Texture> texture;
if (frustum.Intersects(sphere) && ActorTypeToIconType.TryGet(actor->GetTypeHandle(), iconType))
{
// Create world matrix
Matrix::Scaling(ICON_RADIUS * 2.0f, m2);
Matrix::Scaling(sphere.Radius * 2.0f, m2);
Matrix::RotationY(PI, world);
Matrix::Multiply(m2, world, m1);
Matrix::Billboard(sphere.Center, view.Position, Vector3::Up, view.Direction, m2);

View File

@@ -17,6 +17,19 @@ API_CLASS(Static, Namespace="FlaxEditor") class FLAXENGINE_API ViewportIconsRend
DECLARE_SCRIPTING_TYPE_NO_SPAWN(ViewportIconsRenderer);
public:
/// <summary>
/// Global scale of the icons.
/// </summary>
API_FIELD() static float Scale;
/// <summary>
/// Draws the icons for the actors in the given scene (or actor tree).
/// </summary>
/// <param name="position">The icon position.</param>
/// <param name="viewPosition">The viewer position.</param>
/// <param name="bounds">The computed bounds for the icon.</param>
API_FUNCTION() static void GetBounds(API_PARAM(Ref) const Vector3& position, API_PARAM(Ref) const Vector3& viewPosition, API_PARAM(Out) BoundingSphere& bounds);
/// <summary>
/// Draws the icons for the actors in the given scene (or actor tree).
/// </summary>

View File

@@ -1002,6 +1002,18 @@ namespace FlaxEditor.Viewport
ViewWidgetButtonMenu.VisibleChanged += control => resolutionValue.Value = ResolutionScale;
}
// Icons Scale
{
var icons = ViewWidgetButtonMenu.AddButton("Icons");
icons.CloseMenuOnClick = false;
var iconsValue = new FloatValueBox(ViewportIconsRenderer.Scale, xLocationForExtras, 2, 70.0f, 0.01f, 100.0f, 0.001f)
{
Parent = icons
};
iconsValue.ValueChanged += () => ViewportIconsRenderer.Scale = iconsValue.Value;
ViewWidgetButtonMenu.VisibleChanged += control => iconsValue.Value = ViewportIconsRenderer.Scale;
}
#endregion View mode widget
}