diff --git a/Source/Editor/Utilities/ViewportIconsRenderer.cpp b/Source/Editor/Utilities/ViewportIconsRenderer.cpp index 69cc1158e..657117c11 100644 --- a/Source/Editor/Utilities/ViewportIconsRenderer.cpp +++ b/Source/Editor/Utilities/ViewportIconsRenderer.cpp @@ -1,6 +1,7 @@ // Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #include "ViewportIconsRenderer.h" +#include "Engine/Core/Types/Variant.h" #include "Engine/Content/Assets/Model.h" #include "Engine/Content/Assets/MaterialInstance.h" #include "Engine/Content/Content.h" @@ -36,17 +37,20 @@ enum class IconTypes ParticleEffect, SceneAnimationPlayer, + CustomTexture, + MAX }; AssetReference QuadModel; +AssetReference CustomTextureMaterial; ModelInstanceEntries InstanceBuffers[static_cast(IconTypes::MAX)]; Dictionary ActorTypeToIconType; +Dictionary> ActorTypeToTexture; class ViewportIconsRendererService : public EngineService { public: - ViewportIconsRendererService() : EngineService(TEXT("Viewport Icons Renderer")) { @@ -86,17 +90,63 @@ void ViewportIconsRenderer::DrawIcons(RenderContext& renderContext, Actor* actor } } +void ViewportIconsRenderer::AddCustomIcon(const ScriptingTypeHandle& type, Texture* iconTexture) +{ + CHECK(type && iconTexture); + ActorTypeToTexture[type] = iconTexture; +} + +void ViewportIconsRenderer::AddActor(Actor* actor) +{ + CHECK(actor && actor->GetScene()); + actor->GetSceneRendering()->AddViewportIcon(actor); +} + +void ViewportIconsRenderer::RemoveActor(Actor* actor) +{ + CHECK(actor && actor->GetScene()); + actor->GetSceneRendering()->RemoveViewportIcon(actor); +} + void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene* scene, Mesh::DrawInfo& draw) { auto& view = renderContext.View; const BoundingFrustum frustum = view.Frustum; - auto& icons = scene->GetSceneRendering()->ViewportIcons; + const auto& icons = scene->GetSceneRendering()->ViewportIcons; Matrix m1, m2, world; + GeometryDrawStateData drawState; + draw.DrawState = &drawState; + draw.World = &world; + AssetReference texture; for (Actor* icon : icons) { BoundingSphere sphere(icon->GetPosition() - renderContext.View.Origin, ICON_RADIUS); + if (!frustum.Intersects(sphere)) + continue; IconTypes iconType; - if (frustum.Intersects(sphere) && ActorTypeToIconType.TryGet(icon->GetTypeHandle(), iconType)) + ScriptingTypeHandle typeHandle = icon->GetTypeHandle(); + draw.Buffer = nullptr; + + if (ActorTypeToTexture.TryGet(typeHandle, texture)) + { + // Use custom texture + draw.Buffer = &InstanceBuffers[static_cast(IconTypes::CustomTexture)]; + if (draw.Buffer->Count() == 0) + { + // Lazy-init (use in-built icon material with custom texture) + draw.Buffer->Setup(1); + draw.Buffer->At(0).ReceiveDecals = false; + draw.Buffer->At(0).Material = InstanceBuffers[0][0].Material->CreateVirtualInstance(); + } + draw.Buffer->At(0).Material->SetParameterValue(TEXT("Image"), Variant(texture)); + } + else if (ActorTypeToIconType.TryGet(typeHandle, iconType)) + { + // Use predefined material + draw.Buffer = &InstanceBuffers[static_cast(iconType)]; + } + + if (draw.Buffer) { // Create world matrix Matrix::Scaling(ICON_RADIUS * 2.0f, m2); @@ -106,10 +156,6 @@ void ViewportIconsRendererService::DrawIcons(RenderContext& renderContext, Scene Matrix::Multiply(m1, m2, world); // Draw icon - GeometryDrawStateData drawState; - draw.DrawState = &drawState; - draw.Buffer = &InstanceBuffers[static_cast(iconType)]; - draw.World = &world; draw.Bounds = sphere; QuadModel->Draw(renderContext, draw); } @@ -185,6 +231,7 @@ bool ViewportIconsRendererService::Init() void ViewportIconsRendererService::Dispose() { QuadModel = nullptr; + CustomTextureMaterial = nullptr; for (int32 i = 0; i < ARRAY_COUNT(InstanceBuffers); i++) InstanceBuffers[i].Release(); ActorTypeToIconType.Clear(); diff --git a/Source/Editor/Utilities/ViewportIconsRenderer.h b/Source/Editor/Utilities/ViewportIconsRenderer.h index c1d8489e9..1cf162d13 100644 --- a/Source/Editor/Utilities/ViewportIconsRenderer.h +++ b/Source/Editor/Utilities/ViewportIconsRenderer.h @@ -5,6 +5,7 @@ #include "Engine/Scripting/ScriptingType.h" struct RenderContext; +class Texture; class SceneRenderTask; class Actor; @@ -13,13 +14,32 @@ class Actor; /// API_CLASS(Static, Namespace="FlaxEditor") class ViewportIconsRenderer { -DECLARE_SCRIPTING_TYPE_NO_SPAWN(ViewportIconsRenderer); -public: + DECLARE_SCRIPTING_TYPE_NO_SPAWN(ViewportIconsRenderer); +public: /// /// Draws the icons for the actors in the given scene (or actor tree). /// /// The rendering context. /// The actor (use scene for faster rendering). API_FUNCTION() static void DrawIcons(API_PARAM(Ref) RenderContext& renderContext, Actor* actor); + + /// + /// Adds icon to the custom actor. + /// + /// The actor type. + /// The icon texture to draw. + API_FUNCTION() static void AddCustomIcon(const ScriptingTypeHandle& type, Texture* iconTexture); + + /// + /// Adds actor to the viewport icon rendering. + /// + /// The actor to register for icon drawing. + API_FUNCTION() static void AddActor(Actor* actor); + + /// + /// Removes actor from the viewport icon rendering. + /// + /// The actor to unregister for icon drawing. + API_FUNCTION() static void RemoveActor(Actor* actor); }; diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index 46c40aa67..d46b4f8a0 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -5,6 +5,7 @@ #include "Engine/Core/Collections/HashFunctions.h" #include "Engine/Core/Collections/Dictionary.h" #include "Engine/Content/Asset.h" +#include "Engine/Content/AssetReference.h" #include "Engine/Core/Log.h" #include "Engine/Core/Math/Mathd.h" #include "Engine/Core/Math/BoundingBox.h" diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h index 9d274363b..c50854707 100644 --- a/Source/Engine/Core/Types/Variant.h +++ b/Source/Engine/Core/Types/Variant.h @@ -9,6 +9,8 @@ class ScriptingObject; struct ScriptingType; struct Transform; struct CommonValue; +template +class AssetReference; /// /// Represents an object type that can be interpreted as more than one type. @@ -243,6 +245,12 @@ public: explicit Variant(const Span& v); explicit Variant(const CommonValue& v); + template + Variant(const class AssetReference& v) + : Variant(v.Get()) + { + } + ~Variant(); public: