diff --git a/Source/Editor/Editor.cs b/Source/Editor/Editor.cs index 7f0359331..06a6f0979 100644 --- a/Source/Editor/Editor.cs +++ b/Source/Editor/Editor.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; @@ -13,6 +14,7 @@ using FlaxEditor.Content.Thumbnails; using FlaxEditor.Modules; using FlaxEditor.Modules.SourceCodeEditing; using FlaxEditor.Options; +using FlaxEditor.SceneGraph.Actors; using FlaxEditor.States; using FlaxEditor.Windows; using FlaxEditor.Windows.Assets; @@ -1274,6 +1276,69 @@ namespace FlaxEditor Scene.MarkSceneEdited(scenes); } + /// + /// Bakes all environmental probes in the scene. + /// + public void BakeAllEnvProbes() + { + Scene.ExecuteOnGraph(node => + { + if (node is EnvironmentProbeNode envProbeNode && envProbeNode.IsActive) + { + ((EnvironmentProbe)envProbeNode.Actor).Bake(); + node.ParentScene.IsEdited = true; + } + else if (node is SkyLightNode skyLightNode && skyLightNode.IsActive && skyLightNode.Actor is SkyLight skyLight && skyLight.Mode == SkyLight.Modes.CaptureScene) + { + skyLight.Bake(); + node.ParentScene.IsEdited = true; + } + + return node.IsActive; + }); + } + + /// + /// Builds CSG for all open scenes. + /// + public void BuildCSG() + { + var scenes = Level.Scenes; + scenes.ToList().ForEach(x => x.BuildCSG(0)); + Scene.MarkSceneEdited(scenes); + } + + /// + /// Builds Nav mesh for all open scenes. + /// + public void BuildNavMesh() + { + var scenes = Level.Scenes; + scenes.ToList().ForEach(x => Navigation.BuildNavMesh(x, 0)); + Scene.MarkSceneEdited(scenes); + } + + /// + /// Builds SDF for all static models in the scene. + /// + public void BuildAllMeshesSDF() + { + // TODO: async maybe with progress reporting? + Scene.ExecuteOnGraph(node => + { + if (node is StaticModelNode staticModelNode && staticModelNode.Actor is StaticModel staticModel) + { + if (staticModel.DrawModes.HasFlag(DrawPass.GlobalSDF) && staticModel.Model != null && !staticModel.Model.IsVirtual && staticModel.Model.SDF.Texture == null) + { + Log("Generating SDF for " + staticModel.Model); + if (!staticModel.Model.GenerateSDF()) + staticModel.Model.Save(); + } + } + return true; + }); + } + #endregion #region Internal Calls diff --git a/Source/Editor/Modules/UIModule.cs b/Source/Editor/Modules/UIModule.cs index d54012cc3..bde2e610a 100644 --- a/Source/Editor/Modules/UIModule.cs +++ b/Source/Editor/Modules/UIModule.cs @@ -70,9 +70,10 @@ namespace FlaxEditor.Modules private ContextMenuButton _menuToolsBakeAllEnvProbes; private ContextMenuButton _menuToolsBuildCSGMesh; private ContextMenuButton _menuToolsBuildNavMesh; - private ContextMenuButton _menuToolsBuildAllMesgesSDF; + private ContextMenuButton _menuToolsBuildAllMeshesSDF; private ContextMenuButton _menuToolsCancelBuilding; private ContextMenuButton _menuToolsSetTheCurrentSceneViewAsDefault; + private ContextMenuButton _menuToolsTakeScreenshot; private ContextMenuChildMenu _menuWindowApplyWindowLayout; private ToolStripButton _toolStripSaveAll; @@ -576,14 +577,14 @@ namespace FlaxEditor.Modules MenuTools = MainMenu.AddButton("Tools"); cm = MenuTools.ContextMenu; cm.VisibleChanged += OnMenuToolsShowHide; - _menuToolsBuildScenes = cm.AddButton("Build scenes data", "Ctrl+F10", Editor.BuildScenesOrCancel); + _menuToolsBuildScenes = cm.AddButton("Build scenes data", inputOptions.BuildScenesData, Editor.BuildScenesOrCancel); cm.AddSeparator(); - _menuToolsBakeLightmaps = cm.AddButton("Bake lightmaps", Editor.BakeLightmapsOrCancel); - _menuToolsClearLightmaps = cm.AddButton("Clear lightmaps data", Editor.ClearLightmaps); - _menuToolsBakeAllEnvProbes = cm.AddButton("Bake all env probes", BakeAllEnvProbes); - _menuToolsBuildCSGMesh = cm.AddButton("Build CSG mesh", BuildCSG); - _menuToolsBuildNavMesh = cm.AddButton("Build Nav Mesh", BuildNavMesh); - _menuToolsBuildAllMesgesSDF = cm.AddButton("Build all meshes SDF", BuildAllMeshesSDF); + _menuToolsBakeLightmaps = cm.AddButton("Bake lightmaps", inputOptions.BakeLightmaps, Editor.BakeLightmapsOrCancel); + _menuToolsClearLightmaps = cm.AddButton("Clear lightmaps data", inputOptions.ClearLightmaps, Editor.ClearLightmaps); + _menuToolsBakeAllEnvProbes = cm.AddButton("Bake all env probes", inputOptions.BakeEnvProbes, Editor.BakeAllEnvProbes); + _menuToolsBuildCSGMesh = cm.AddButton("Build CSG mesh", inputOptions.BuildCSG, Editor.BuildCSG); + _menuToolsBuildNavMesh = cm.AddButton("Build Nav Mesh", inputOptions.BuildNav, Editor.BuildNavMesh); + _menuToolsBuildAllMeshesSDF = cm.AddButton("Build all meshes SDF", inputOptions.BuildSDF, Editor.BuildAllMeshesSDF); cm.AddSeparator(); cm.AddButton("Game Cooker", Editor.Windows.GameCookerWin.FocusOrShow); _menuToolsCancelBuilding = cm.AddButton("Cancel building game", () => GameCooker.Cancel()); @@ -591,7 +592,7 @@ namespace FlaxEditor.Modules cm.AddButton("Profiler", Editor.Windows.ProfilerWin.FocusOrShow); cm.AddSeparator(); _menuToolsSetTheCurrentSceneViewAsDefault = cm.AddButton("Set current scene view as project default", SetTheCurrentSceneViewAsDefault); - cm.AddButton("Take screenshot", "F12", Editor.Windows.TakeScreenshot); + _menuToolsTakeScreenshot = cm.AddButton("Take screenshot", inputOptions.TakeScreenshot, Editor.Windows.TakeScreenshot); cm.AddSeparator(); cm.AddButton("Plugins", () => Editor.Windows.PluginsWin.Show()); cm.AddButton("Options", () => Editor.Windows.EditorOptionsWin.Show()); @@ -652,6 +653,14 @@ namespace FlaxEditor.Modules _menuGameStop.ShortKeys = inputOptions.Play.ToString(); _menuGameCookAndRun.ShortKeys = inputOptions.CookAndRun.ToString(); _menuGameRunCookedGame.ShortKeys = inputOptions.RunCookedGame.ToString(); + _menuToolsBuildScenes.ShortKeys = inputOptions.BuildScenesData.ToString(); + _menuToolsBakeLightmaps.ShortKeys = inputOptions.BakeLightmaps.ToString(); + _menuToolsClearLightmaps.ShortKeys = inputOptions.ClearLightmaps.ToString(); + _menuToolsBakeAllEnvProbes.ShortKeys = inputOptions.BakeEnvProbes.ToString(); + _menuToolsBuildCSGMesh.ShortKeys = inputOptions.BuildCSG.ToString(); + _menuToolsBuildNavMesh.ShortKeys = inputOptions.BuildNav.ToString(); + _menuToolsBuildAllMeshesSDF.ShortKeys = inputOptions.BuildSDF.ToString(); + _menuToolsTakeScreenshot.ShortKeys = inputOptions.TakeScreenshot.ToString(); MainMenuShortcutKeysUpdated?.Invoke(); } @@ -676,10 +685,10 @@ namespace FlaxEditor.Modules ToolStrip.AddSeparator(); // Cook scenes - _toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build64, Editor.BuildScenesOrCancel).LinkTooltip("Build scenes data - CSG, navmesh, static lighting, env probes - configurable via Build Actions in editor options (Ctrl+F10)"); + _toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build64, Editor.BuildScenesOrCancel).LinkTooltip($"Build scenes data - CSG, navmesh, static lighting, env probes - configurable via Build Actions in editor options ({inputOptions.BuildScenesData})"); // Cook and run - _toolStripCook = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.ShipIt64, Editor.Windows.GameCookerWin.BuildAndRun).LinkTooltip("Cook & Run - build game for the current platform and run it locally"); + _toolStripCook = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.ShipIt64, Editor.Windows.GameCookerWin.BuildAndRun).LinkTooltip($"Cook & Run - build game for the current platform and run it locally ({inputOptions.Play})"); _toolStripCook.ContextMenu = new ContextMenu(); _toolStripCook.ContextMenu.AddButton("Run cooked game", Editor.Windows.GameCookerWin.RunCooked); _toolStripCook.ContextMenu.AddSeparator(); @@ -880,7 +889,7 @@ namespace FlaxEditor.Modules _menuToolsBakeLightmaps.Text = isBakingLightmaps ? "Cancel baking lightmaps" : "Bake lightmaps"; _menuToolsClearLightmaps.Enabled = canEdit; _menuToolsBakeAllEnvProbes.Enabled = canEdit; - _menuToolsBuildAllMesgesSDF.Enabled = canEdit && !isBakingLightmaps; + _menuToolsBuildAllMeshesSDF.Enabled = canEdit && !isBakingLightmaps; _menuToolsBuildCSGMesh.Enabled = canEdit; _menuToolsBuildNavMesh.Enabled = canEdit; _menuToolsCancelBuilding.Enabled = GameCooker.IsRunning; @@ -980,57 +989,6 @@ namespace FlaxEditor.Modules new Tools.Terrain.CreateTerrainDialog().Show(Editor.Windows.MainWindow); } - private void BakeAllEnvProbes() - { - Editor.Scene.ExecuteOnGraph(node => - { - if (node is EnvironmentProbeNode envProbeNode && envProbeNode.IsActive) - { - ((EnvironmentProbe)envProbeNode.Actor).Bake(); - node.ParentScene.IsEdited = true; - } - else if (node is SkyLightNode skyLightNode && skyLightNode.IsActive && skyLightNode.Actor is SkyLight skyLight && skyLight.Mode == SkyLight.Modes.CaptureScene) - { - skyLight.Bake(); - node.ParentScene.IsEdited = true; - } - - return node.IsActive; - }); - } - - private void BuildCSG() - { - var scenes = Level.Scenes; - scenes.ToList().ForEach(x => x.BuildCSG(0)); - Editor.Scene.MarkSceneEdited(scenes); - } - - private void BuildNavMesh() - { - var scenes = Level.Scenes; - scenes.ToList().ForEach(x => Navigation.BuildNavMesh(x, 0)); - Editor.Scene.MarkSceneEdited(scenes); - } - - private void BuildAllMeshesSDF() - { - // TODO: async maybe with progress reporting? - Editor.Scene.ExecuteOnGraph(node => - { - if (node is StaticModelNode staticModelNode && staticModelNode.Actor is StaticModel staticModel) - { - if (staticModel.DrawModes.HasFlag(DrawPass.GlobalSDF) && staticModel.Model != null && !staticModel.Model.IsVirtual && staticModel.Model.SDF.Texture == null) - { - Editor.Log("Generating SDF for " + staticModel.Model); - if (!staticModel.Model.GenerateSDF()) - staticModel.Model.Save(); - } - } - return true; - }); - } - private void SetTheCurrentSceneViewAsDefault() { var projectInfo = Editor.GameProject; diff --git a/Source/Editor/Options/InputOptions.cs b/Source/Editor/Options/InputOptions.cs index 27faf48a2..52d7343dd 100644 --- a/Source/Editor/Options/InputOptions.cs +++ b/Source/Editor/Options/InputOptions.cs @@ -126,22 +126,58 @@ namespace FlaxEditor.Options #endregion + #region Tools + + [DefaultValue(typeof(InputBinding), "Ctrl+F10")] + [EditorDisplay("Tools", "Build scenes data"), EditorOrder(600)] + public InputBinding BuildScenesData = new InputBinding(KeyboardKeys.F10, KeyboardKeys.Control); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Bake lightmaps"), EditorOrder(601)] + public InputBinding BakeLightmaps = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Clear lightmaps data"), EditorOrder(602)] + public InputBinding ClearLightmaps = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Bake all env probes"), EditorOrder(603)] + public InputBinding BakeEnvProbes = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Build CSG mesh"), EditorOrder(604)] + public InputBinding BuildCSG = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Build Nav Mesh"), EditorOrder(605)] + public InputBinding BuildNav = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "None")] + [EditorDisplay("Tools", "Build all meshes SDF"), EditorOrder(606)] + public InputBinding BuildSDF = new InputBinding(KeyboardKeys.None); + + [DefaultValue(typeof(InputBinding), "F12")] + [EditorDisplay("Tools", "Take screenshot"), EditorOrder(607)] + public InputBinding TakeScreenshot = new InputBinding(KeyboardKeys.F12); + + #endregion + #region Debugger [DefaultValue(typeof(InputBinding), "F5")] - [EditorDisplay("Debugger", "Continue"), EditorOrder(610)] + [EditorDisplay("Debugger", "Continue"), EditorOrder(810)] public InputBinding DebuggerContinue = new InputBinding(KeyboardKeys.F5); [DefaultValue(typeof(InputBinding), "F10")] - [EditorDisplay("Debugger", "Step Over"), EditorOrder(620)] + [EditorDisplay("Debugger", "Step Over"), EditorOrder(820)] public InputBinding DebuggerStepOver = new InputBinding(KeyboardKeys.F10); [DefaultValue(typeof(InputBinding), "F11")] - [EditorDisplay("Debugger", "Step Into"), EditorOrder(630)] + [EditorDisplay("Debugger", "Step Into"), EditorOrder(830)] public InputBinding DebuggerStepInto = new InputBinding(KeyboardKeys.F11); [DefaultValue(typeof(InputBinding), "Shift+F11")] - [EditorDisplay("Debugger", "Step Out"), EditorOrder(640)] + [EditorDisplay("Debugger", "Step Out"), EditorOrder(840)] public InputBinding DebuggerStepOut = new InputBinding(KeyboardKeys.F11, KeyboardKeys.Shift); #endregion diff --git a/Source/Editor/Windows/SceneEditorWindow.cs b/Source/Editor/Windows/SceneEditorWindow.cs index 290f02089..529eb5ebc 100644 --- a/Source/Editor/Windows/SceneEditorWindow.cs +++ b/Source/Editor/Windows/SceneEditorWindow.cs @@ -44,6 +44,14 @@ namespace FlaxEditor.Windows InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame); InputActions.Add(options => options.CookAndRun, () => Editor.Windows.GameCookerWin.BuildAndRun()); InputActions.Add(options => options.RunCookedGame, () => Editor.Windows.GameCookerWin.RunCooked()); + InputActions.Add(options => options.BuildScenesData, Editor.BuildScenesOrCancel); + InputActions.Add(options => options.BakeLightmaps, Editor.BakeLightmapsOrCancel); + InputActions.Add(options => options.ClearLightmaps, Editor.ClearLightmaps); + InputActions.Add(options => options.BakeEnvProbes, Editor.BakeAllEnvProbes); + InputActions.Add(options => options.BuildCSG, Editor.BuildCSG); + InputActions.Add(options => options.BuildNav, Editor.BuildNavMesh); + InputActions.Add(options => options.BuildSDF, Editor.BuildAllMeshesSDF); + InputActions.Add(options => options.TakeScreenshot, Editor.Windows.TakeScreenshot); } } }