diff --git a/.gitignore b/.gitignore index fd20b9666..eb51e5d1c 100644 --- a/.gitignore +++ b/.gitignore @@ -153,4 +153,4 @@ obj/ .vscode/ .idea/ *.code-workspace - +omnisharp.json 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 6f953b6f0..1b70152d6 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: diff --git a/Source/Engine/Level/Actor.h b/Source/Engine/Level/Actor.h index 3e8d5232f..e68f5ee17 100644 --- a/Source/Engine/Level/Actor.h +++ b/Source/Engine/Level/Actor.h @@ -623,7 +623,6 @@ public: API_PROPERTY() BoundingBox GetBoxWithChildren() const; #if USE_EDITOR - /// /// Gets actor bounding box (single actor, no children included) for editor tools. /// @@ -633,7 +632,6 @@ public: /// Gets actor bounding box of the actor including all child actors for editor tools. /// API_PROPERTY() BoundingBox GetEditorBoxChildren() const; - #endif /// @@ -665,17 +663,15 @@ public: virtual void Draw(RenderContextBatch& renderContextBatch); #if USE_EDITOR - /// /// Draws debug shapes for the actor and all child scripts. /// - virtual void OnDebugDraw(); + API_FUNCTION() virtual void OnDebugDraw(); /// /// Draws debug shapes for the selected actor and all child scripts. /// - virtual void OnDebugDrawSelected(); - + API_FUNCTION() virtual void OnDebugDrawSelected(); #endif public: @@ -812,9 +808,7 @@ public: if (action(this, args...)) { for (int32 i = 0; i < Children.Count(); i++) - { Children[i]->TreeExecute(action, args...); - } } } @@ -829,9 +823,7 @@ public: void TreeExecuteChildren(Function& action, Params ... args) { for (int32 i = 0; i < Children.Count(); i++) - { Children[i]->TreeExecute(action, args...); - } } public: @@ -897,12 +889,12 @@ public: /// /// Called when actor gets added to game systems. Occurs on BeginPlay event or when actor gets activated in hierarchy. Use this event to register object to other game system (eg. audio). /// - virtual void OnEnable(); + API_FUNCTION() virtual void OnEnable(); /// /// Called when actor gets removed from game systems. Occurs on EndPlay event or when actor gets inactivated in hierarchy. Use this event to unregister object from other game system (eg. audio). /// - virtual void OnDisable(); + API_FUNCTION() virtual void OnDisable(); /// /// Called when actor parent gets changed. diff --git a/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs index ec829c3f8..95bba3515 100644 --- a/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs +++ b/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs @@ -617,6 +617,22 @@ namespace Flax.Build.Projects.VisualStudioCode json.EndRootObject(); json.Save(Path.Combine(vsCodeFolder, "extensions.json")); } + + // Create OmniSharp configuration file + using (var json = new JsonWriter()) + { + json.BeginRootObject(); + + json.BeginObject("msbuild"); + { + json.AddField("enabled", true); + json.AddField("Configuration", "Editor.Debug"); + } + json.EndObject(); + + json.EndRootObject(); + json.Save(Path.Combine(solution.WorkspaceRootPath, "omnisharp.json")); + } } } }