diff --git a/Content/Editor/IconsAtlas.flax b/Content/Editor/IconsAtlas.flax
index cd1c745a2..01baadfed 100644
--- a/Content/Editor/IconsAtlas.flax
+++ b/Content/Editor/IconsAtlas.flax
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2248c3069f16a3b1eb62aa4660c81427fd6effa364f8f0694ba751be8e60114c
-size 5612622
+oid sha256:c2a7d0c6969a180d59a32fbc908fe432bddb393437e9c5b64ddb25737e4aab94
+size 5609840
diff --git a/Content/Editor/IconsAtlas.psd b/Content/Editor/IconsAtlas.psd
new file mode 100644
index 000000000..b062fc0fa
--- /dev/null
+++ b/Content/Editor/IconsAtlas.psd
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0ee4e46c2b39cf6def6be079a898204e283253bf5841ccf3985fa9d49834b9a0
+size 2766306
diff --git a/Source/Editor/Content/Import/AudioImportSettings.cs b/Source/Editor/Content/Import/AudioImportSettings.cs
index b645c1509..a0af8c154 100644
--- a/Source/Editor/Content/Import/AudioImportSettings.cs
+++ b/Source/Editor/Content/Import/AudioImportSettings.cs
@@ -12,7 +12,7 @@ namespace FlaxEngine.Tools
{
partial struct Options
{
- private bool ShowBtiDepth => Format != AudioFormat.Vorbis;
+ private bool ShowBitDepth => Format != AudioFormat.Vorbis;
}
}
}
diff --git a/Source/Editor/Content/Import/ModelImportEntry.cs b/Source/Editor/Content/Import/ModelImportEntry.cs
index 5e17d7ecf..eed8db6ba 100644
--- a/Source/Editor/Content/Import/ModelImportEntry.cs
+++ b/Source/Editor/Content/Import/ModelImportEntry.cs
@@ -19,6 +19,7 @@ namespace FlaxEngine.Tools
private bool ShowRootMotion => ShowAnimation && RootMotion != RootMotionMode.None;
private bool ShowSmoothingNormalsAngle => ShowGeometry && CalculateNormals;
private bool ShowSmoothingTangentsAngle => ShowGeometry && CalculateTangents;
+ private bool ShowGenerateLODs => ShowGeometry && GenerateLODs;
private bool ShowFramesRange => ShowAnimation && Duration == AnimationDuration.Custom;
private bool ShowSplitting => Type != ModelType.Prefab;
}
diff --git a/Source/Editor/Content/Items/AssetItem.cs b/Source/Editor/Content/Items/AssetItem.cs
index eaa93561a..78519b400 100644
--- a/Source/Editor/Content/Items/AssetItem.cs
+++ b/Source/Editor/Content/Items/AssetItem.cs
@@ -98,12 +98,12 @@ namespace FlaxEditor.Content
}
///
- /// Reloads the asset (if it's loaded).
+ /// Reloads the asset (if it's loaded or failed to load).
///
public void Reload()
{
var asset = FlaxEngine.Content.GetAsset(ID);
- if (asset != null && asset.IsLoaded)
+ if (asset != null && (asset.IsLoaded || asset.LastLoadFailed))
{
asset.Reload();
}
diff --git a/Source/Editor/Content/Proxy/MaterialBaseProxy.cs b/Source/Editor/Content/Proxy/MaterialBaseProxy.cs
new file mode 100644
index 000000000..83c98ee6e
--- /dev/null
+++ b/Source/Editor/Content/Proxy/MaterialBaseProxy.cs
@@ -0,0 +1,109 @@
+// Copyright (c) Wojciech Figat. All rights reserved.
+
+using FlaxEditor.Content.Thumbnails;
+using FlaxEditor.GUI.ContextMenu;
+using FlaxEditor.Viewport.Previews;
+using FlaxEngine;
+using FlaxEngine.GUI;
+
+namespace FlaxEditor.Content
+{
+ ///
+ /// A base class for asset proxy object.
+ ///
+ ///
+ public abstract class MaterialBaseProxy : BinaryAssetProxy
+ {
+ ///
+ /// The material preview drawer.
+ ///
+ protected MaterialPreview _preview;
+
+ ///
+ public override bool CanCreate(ContentFolder targetLocation)
+ {
+ return targetLocation.CanHaveAssets;
+ }
+
+ ///
+ public override void OnContentWindowContextMenu(ContextMenu menu, ContentItem item)
+ {
+ base.OnContentWindowContextMenu(menu, item);
+
+ if (item is BinaryAssetItem binaryAssetItem)
+ {
+ var button = menu.AddButton("Create Material Instance", CreateMaterialInstanceClicked);
+ button.Tag = binaryAssetItem;
+ }
+ }
+
+ private void CreateMaterialInstanceClicked(ContextMenuButton button)
+ {
+ var binaryAssetItem = (BinaryAssetItem)button.Tag;
+ CreateMaterialInstance(binaryAssetItem);
+ }
+
+ ///
+ /// Creates the material instance from the given material.
+ ///
+ /// The material item to use as a base material.
+ public static void CreateMaterialInstance(BinaryAssetItem materialItem)
+ {
+ var materialInstanceName = materialItem.ShortName + " Instance";
+ var materialInstanceProxy = Editor.Instance.ContentDatabase.GetProxy();
+ Editor.Instance.Windows.ContentWin.NewItem(materialInstanceProxy, null, item => OnMaterialInstanceCreated(item, materialItem), materialInstanceName);
+ }
+
+ private static void OnMaterialInstanceCreated(ContentItem item, BinaryAssetItem materialItem)
+ {
+ var assetItem = (AssetItem)item;
+ var materialInstance = FlaxEngine.Content.LoadAsync(assetItem.ID);
+ if (materialInstance == null || materialInstance.WaitForLoaded())
+ {
+ Editor.LogError("Failed to load created material instance.");
+ return;
+ }
+ materialInstance.BaseMaterial = FlaxEngine.Content.LoadAsync(materialItem.ID);
+ materialInstance.Save();
+ }
+
+ ///
+ public override void OnThumbnailDrawPrepare(ThumbnailRequest request)
+ {
+ if (_preview == null)
+ {
+ _preview = new MaterialPreview(false);
+ InitAssetPreview(_preview);
+ }
+ }
+
+ ///
+ public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context)
+ {
+ _preview.Material = (MaterialBase)request.Asset;
+ _preview.Parent = guiRoot;
+ _preview.SyncBackbufferSize();
+
+ _preview.Task.OnDraw();
+ }
+
+ ///
+ public override void OnThumbnailDrawEnd(ThumbnailRequest request, ContainerControl guiRoot)
+ {
+ _preview.Material = null;
+ _preview.Parent = null;
+ }
+
+ ///
+ public override void Dispose()
+ {
+ if (_preview != null)
+ {
+ _preview.Dispose();
+ _preview = null;
+ }
+
+ base.Dispose();
+ }
+ }
+}
diff --git a/Source/Editor/Content/Proxy/MaterialInstanceProxy.cs b/Source/Editor/Content/Proxy/MaterialInstanceProxy.cs
index fc4fcdbc1..212417e9f 100644
--- a/Source/Editor/Content/Proxy/MaterialInstanceProxy.cs
+++ b/Source/Editor/Content/Proxy/MaterialInstanceProxy.cs
@@ -2,23 +2,18 @@
using System;
using FlaxEditor.Content.Thumbnails;
-using FlaxEditor.Viewport.Previews;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
-using FlaxEngine.GUI;
namespace FlaxEditor.Content
{
///
/// A asset proxy object.
///
- ///
[ContentContextMenu("New/Material/Material Instance")]
- public class MaterialInstanceProxy : BinaryAssetProxy
+ public class MaterialInstanceProxy : MaterialBaseProxy
{
- private MaterialPreview _preview;
-
///
public override string Name => "Material Instance";
@@ -34,12 +29,6 @@ namespace FlaxEditor.Content
///
public override Type AssetType => typeof(MaterialInstance);
- ///
- public override bool CanCreate(ContentFolder targetLocation)
- {
- return targetLocation.CanHaveAssets;
- }
-
///
public override void Create(string outputPath, object arg)
{
@@ -47,49 +36,10 @@ namespace FlaxEditor.Content
throw new Exception("Failed to create new asset.");
}
- ///
- public override void OnThumbnailDrawPrepare(ThumbnailRequest request)
- {
- if (_preview == null)
- {
- _preview = new MaterialPreview(false);
- InitAssetPreview(_preview);
- }
- }
-
///
public override bool CanDrawThumbnail(ThumbnailRequest request)
{
return _preview.HasLoadedAssets && ThumbnailsModule.HasMinimumQuality((MaterialInstance)request.Asset);
}
-
- ///
- public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context)
- {
- _preview.Material = (MaterialInstance)request.Asset;
- _preview.Parent = guiRoot;
- _preview.SyncBackbufferSize();
-
- _preview.Task.OnDraw();
- }
-
- ///
- public override void OnThumbnailDrawEnd(ThumbnailRequest request, ContainerControl guiRoot)
- {
- _preview.Material = null;
- _preview.Parent = null;
- }
-
- ///
- public override void Dispose()
- {
- if (_preview != null)
- {
- _preview.Dispose();
- _preview = null;
- }
-
- base.Dispose();
- }
}
}
diff --git a/Source/Editor/Content/Proxy/MaterialProxy.cs b/Source/Editor/Content/Proxy/MaterialProxy.cs
index 4769ca548..58d34299c 100644
--- a/Source/Editor/Content/Proxy/MaterialProxy.cs
+++ b/Source/Editor/Content/Proxy/MaterialProxy.cs
@@ -2,24 +2,18 @@
using System;
using FlaxEditor.Content.Thumbnails;
-using FlaxEditor.GUI.ContextMenu;
-using FlaxEditor.Viewport.Previews;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
-using FlaxEngine.GUI;
namespace FlaxEditor.Content
{
///
/// A asset proxy object.
///
- ///
[ContentContextMenu("New/Material/Material")]
- public class MaterialProxy : BinaryAssetProxy
+ public class MaterialProxy : MaterialBaseProxy
{
- private MaterialPreview _preview;
-
///
public override string Name => "Material";
@@ -35,12 +29,6 @@ namespace FlaxEditor.Content
///
public override Type AssetType => typeof(Material);
- ///
- public override bool CanCreate(ContentFolder targetLocation)
- {
- return targetLocation.CanHaveAssets;
- }
-
///
public override void Create(string outputPath, object arg)
{
@@ -48,92 +36,10 @@ namespace FlaxEditor.Content
throw new Exception("Failed to create new asset.");
}
- ///
- public override void OnContentWindowContextMenu(ContextMenu menu, ContentItem item)
- {
- base.OnContentWindowContextMenu(menu, item);
-
- if (item is BinaryAssetItem binaryAssetItem)
- {
- var button = menu.AddButton("Create Material Instance", CreateMaterialInstanceClicked);
- button.Tag = binaryAssetItem;
- }
- }
-
- private void CreateMaterialInstanceClicked(ContextMenuButton obj)
- {
- var binaryAssetItem = (BinaryAssetItem)obj.Tag;
- CreateMaterialInstance(binaryAssetItem);
- }
-
- ///
- /// Creates the material instance from the given material.
- ///
- /// The material item to use as a base material.
- public static void CreateMaterialInstance(BinaryAssetItem materialItem)
- {
- var materialInstanceName = materialItem.ShortName + " Instance";
- var materialInstanceProxy = Editor.Instance.ContentDatabase.GetProxy();
- Editor.Instance.Windows.ContentWin.NewItem(materialInstanceProxy, null, item => OnMaterialInstanceCreated(item, materialItem), materialInstanceName);
- }
-
- private static void OnMaterialInstanceCreated(ContentItem item, BinaryAssetItem materialItem)
- {
- var assetItem = (AssetItem)item;
- var materialInstance = FlaxEngine.Content.LoadAsync(assetItem.ID);
- if (materialInstance == null || materialInstance.WaitForLoaded())
- {
- Editor.LogError("Failed to load created material instance.");
- return;
- }
-
- materialInstance.BaseMaterial = FlaxEngine.Content.LoadAsync(materialItem.ID);
- materialInstance.Save();
- }
-
- ///
- public override void OnThumbnailDrawPrepare(ThumbnailRequest request)
- {
- if (_preview == null)
- {
- _preview = new MaterialPreview(false);
- InitAssetPreview(_preview);
- }
- }
-
///
public override bool CanDrawThumbnail(ThumbnailRequest request)
{
return _preview.HasLoadedAssets && ThumbnailsModule.HasMinimumQuality((Material)request.Asset);
}
-
- ///
- public override void OnThumbnailDrawBegin(ThumbnailRequest request, ContainerControl guiRoot, GPUContext context)
- {
- _preview.Material = (Material)request.Asset;
- _preview.Parent = guiRoot;
- _preview.SyncBackbufferSize();
-
- _preview.Task.OnDraw();
- }
-
- ///
- public override void OnThumbnailDrawEnd(ThumbnailRequest request, ContainerControl guiRoot)
- {
- _preview.Material = null;
- _preview.Parent = null;
- }
-
- ///
- public override void Dispose()
- {
- if (_preview != null)
- {
- _preview.Dispose();
- _preview = null;
- }
-
- base.Dispose();
- }
}
}
diff --git a/Source/Editor/Cooker/Platform/Web/WebPlatformTools.cpp b/Source/Editor/Cooker/Platform/Web/WebPlatformTools.cpp
index a2c35f38f..e38a7310c 100644
--- a/Source/Editor/Cooker/Platform/Web/WebPlatformTools.cpp
+++ b/Source/Editor/Cooker/Platform/Web/WebPlatformTools.cpp
@@ -191,7 +191,7 @@ bool WebPlatformTools::OnPostProcess(CookingData& data)
FileSystem::GetChildDirectories(pythons, emscriptenSdk / TEXT("/python"));
if (pythons.HasItems())
{
- procSettings.Arguments = procSettings.FileName + TEXT(".py ") + procSettings.Arguments;
+ procSettings.Arguments = String::Format(TEXT("\"{}.py\" {}"), procSettings.FileName, procSettings.Arguments);
#if PLATFORM_WINDOWS
procSettings.FileName = pythons[0] / TEXT("/python.exe");
#else
diff --git a/Source/Editor/GUI/ItemsListContextMenu.cs b/Source/Editor/GUI/ItemsListContextMenu.cs
index 50c08e9ba..5f09342c7 100644
--- a/Source/Editor/GUI/ItemsListContextMenu.cs
+++ b/Source/Editor/GUI/ItemsListContextMenu.cs
@@ -589,6 +589,8 @@ namespace FlaxEditor.GUI
// Get the next item
bool controlDown = Root.GetKey(KeyboardKeys.Control);
var items = GetVisibleItems(!controlDown);
+ if (items.Count == 0)
+ return true;
var focusedIndex = items.IndexOf(focusedItem);
int delta = key == KeyboardKeys.ArrowDown ? -1 : 1;
diff --git a/Source/Editor/GUI/Timeline/Timeline.cs b/Source/Editor/GUI/Timeline/Timeline.cs
index 1fb19e9ec..861bd7e44 100644
--- a/Source/Editor/GUI/Timeline/Timeline.cs
+++ b/Source/Editor/GUI/Timeline/Timeline.cs
@@ -229,6 +229,7 @@ namespace FlaxEditor.GUI.Timeline
private List