Merge branch 'master' into Visject-ConvertConstantToParameter
This commit is contained in:
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
Binary file not shown.
@@ -15,7 +15,7 @@ if errorlevel 1 goto BuildToolFailed
|
||||
|
||||
:: Build bindings for all editor configurations
|
||||
echo Building C# bindings...
|
||||
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor,FlaxGame
|
||||
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
||||
|
||||
popd
|
||||
echo Done!
|
||||
|
||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
||||
# Build bindings for all editor configurations
|
||||
echo Building C# bindings...
|
||||
# TODO: Detect the correct architecture here
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor,FlaxGame
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
||||
|
||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Linux/CallBuildTool.sh --genproject "$@"
|
||||
# Build bindings for all editor configurations
|
||||
echo Building C# bindings...
|
||||
# TODO: Detect the correct architecture here
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor,FlaxGame
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor
|
||||
|
||||
@@ -30,6 +30,12 @@ namespace FlaxEditor.Content
|
||||
return item is SceneItem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool AcceptsAsset(string typeName, string path)
|
||||
{
|
||||
return (typeName == Scene.AssetTypename || typeName == Scene.EditorPickerTypename) && path.EndsWith(FileExtension, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanCreate(ContentFolder targetLocation)
|
||||
{
|
||||
|
||||
@@ -406,18 +406,16 @@ namespace FlaxEditor.Content.Thumbnails
|
||||
for (int i = 0; i < maxChecks; i++)
|
||||
{
|
||||
var request = _requests[i];
|
||||
|
||||
try
|
||||
{
|
||||
if (request.IsReady)
|
||||
{
|
||||
return request;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Editor.LogWarning(ex);
|
||||
Editor.LogWarning($"Failed to prepare thumbnail rendering for {request.Item.ShortName}.");
|
||||
Editor.LogWarning(ex);
|
||||
_requests.RemoveAt(i--);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,7 +513,6 @@ namespace FlaxEditor.Content.Thumbnails
|
||||
for (int i = 0; i < checks; i++)
|
||||
{
|
||||
var request = _requests[i];
|
||||
|
||||
try
|
||||
{
|
||||
if (request.IsReady)
|
||||
@@ -529,8 +526,9 @@ namespace FlaxEditor.Content.Thumbnails
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Editor.LogWarning(ex);
|
||||
Editor.LogWarning($"Failed to prepare thumbnail rendering for {request.Item.ShortName}.");
|
||||
Editor.LogWarning(ex);
|
||||
_requests.RemoveAt(i--);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -811,10 +811,9 @@ namespace FlaxEditor.Modules
|
||||
{
|
||||
if (node == null)
|
||||
return;
|
||||
|
||||
// Temporary data
|
||||
var folder = node.Folder;
|
||||
var path = folder.Path;
|
||||
var canHaveAssets = node.CanHaveAssets;
|
||||
|
||||
if (_isDuringFastSetup)
|
||||
{
|
||||
@@ -833,20 +832,38 @@ namespace FlaxEditor.Modules
|
||||
var child = folder.Children[i];
|
||||
if (!child.Exists)
|
||||
{
|
||||
// Send info
|
||||
// Item doesn't exist anymore
|
||||
Editor.Log(string.Format($"Content item \'{child.Path}\' has been removed"));
|
||||
|
||||
// Destroy it
|
||||
Delete(child, false);
|
||||
|
||||
i--;
|
||||
}
|
||||
else if (canHaveAssets && child is AssetItem childAsset)
|
||||
{
|
||||
// Check if asset type doesn't match the item proxy (eg. item reimported as Material Instance instead of Material)
|
||||
if (FlaxEngine.Content.GetAssetInfo(child.Path, out var assetInfo))
|
||||
{
|
||||
bool changed = assetInfo.ID != childAsset.ID;
|
||||
if (!changed && assetInfo.TypeName != childAsset.TypeName)
|
||||
{
|
||||
// Use proxy check (eg. scene asset might accept different typename than AssetInfo reports)
|
||||
var proxy = GetAssetProxy(childAsset.TypeName, child.Path);
|
||||
if (proxy == null)
|
||||
proxy = GetAssetProxy(assetInfo.TypeName, child.Path);
|
||||
changed = !proxy.AcceptsAsset(assetInfo.TypeName, child.Path);
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
OnAssetTypeInfoChanged(childAsset, ref assetInfo);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find files
|
||||
var files = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);
|
||||
if (node.CanHaveAssets)
|
||||
if (canHaveAssets)
|
||||
{
|
||||
LoadAssets(node, files);
|
||||
}
|
||||
@@ -1157,19 +1174,8 @@ namespace FlaxEditor.Modules
|
||||
// For eg. change texture to sprite atlas on reimport
|
||||
if (binaryAssetItem.TypeName != assetInfo.TypeName)
|
||||
{
|
||||
// Asset type has been changed!
|
||||
Editor.LogWarning(string.Format("Asset \'{0}\' changed type from {1} to {2}", item.Path, binaryAssetItem.TypeName, assetInfo.TypeName));
|
||||
Editor.Windows.CloseAllEditors(item);
|
||||
|
||||
// Remove this item from the database and some related data
|
||||
var toRefresh = binaryAssetItem.ParentFolder;
|
||||
binaryAssetItem.Dispose();
|
||||
toRefresh.Children.Remove(binaryAssetItem);
|
||||
if (!binaryAssetItem.HasDefaultThumbnail)
|
||||
{
|
||||
// Delete old thumbnail and remove it from the cache
|
||||
Editor.Instance.Thumbnails.DeletePreview(binaryAssetItem);
|
||||
}
|
||||
OnAssetTypeInfoChanged(binaryAssetItem, ref assetInfo);
|
||||
|
||||
// Refresh the parent folder to find the new asset (it should have different type or some other format)
|
||||
RefreshFolder(toRefresh, false);
|
||||
@@ -1186,6 +1192,23 @@ namespace FlaxEditor.Modules
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAssetTypeInfoChanged(AssetItem assetItem, ref AssetInfo assetInfo)
|
||||
{
|
||||
// Asset type has been changed!
|
||||
Editor.LogWarning(string.Format("Asset \'{0}\' changed type from {1} to {2}", assetItem.Path, assetItem.TypeName, assetInfo.TypeName));
|
||||
Editor.Windows.CloseAllEditors(assetItem);
|
||||
|
||||
// Remove this item from the database and some related data
|
||||
assetItem.Dispose();
|
||||
assetItem.ParentFolder.Children.Remove(assetItem);
|
||||
|
||||
// Delete old thumbnail and remove it from the cache
|
||||
if (!assetItem.HasDefaultThumbnail)
|
||||
{
|
||||
Editor.Instance.Thumbnails.DeletePreview(assetItem);
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnDirectoryEvent(MainContentTreeNode node, FileSystemEventArgs e)
|
||||
{
|
||||
// Ensure to be ready for external events
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using FlaxEditor.Gizmo;
|
||||
using FlaxEditor.GUI;
|
||||
@@ -11,7 +10,6 @@ using FlaxEditor.GUI.Dialogs;
|
||||
using FlaxEditor.GUI.Input;
|
||||
using FlaxEditor.Progress.Handlers;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEditor.SceneGraph.Actors;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEditor.Viewport.Cameras;
|
||||
using FlaxEditor.Windows;
|
||||
@@ -208,6 +206,7 @@ namespace FlaxEditor.Modules
|
||||
_toolStripScale.Checked = gizmoMode == TransformGizmoBase.Mode.Scale;
|
||||
//
|
||||
_toolStripBuildScenes.Enabled = (canEditScene && !isPlayMode) || Editor.StateMachine.BuildingScenesState.IsActive;
|
||||
_toolStripBuildScenes.Visible = Editor.Options.Options.General.BuildActions?.Length != 0;
|
||||
_toolStripCook.Enabled = Editor.Windows.GameCookerWin.CanBuild(Platform.PlatformType) && !GameCooker.IsRunning;
|
||||
//
|
||||
var play = _toolStripPlay;
|
||||
@@ -653,7 +652,7 @@ namespace FlaxEditor.Modules
|
||||
cm.AddButton("Information about Flax", () => new AboutDialog().Show());
|
||||
}
|
||||
|
||||
private void OnOptionsChanged(FlaxEditor.Options.EditorOptions options)
|
||||
private void OnOptionsChanged(EditorOptions options)
|
||||
{
|
||||
var inputOptions = options.Input;
|
||||
|
||||
@@ -688,6 +687,8 @@ namespace FlaxEditor.Modules
|
||||
_menuToolsTakeScreenshot.ShortKeys = inputOptions.TakeScreenshot.ToString();
|
||||
|
||||
MainMenuShortcutKeysUpdated?.Invoke();
|
||||
|
||||
UpdateToolstrip();
|
||||
}
|
||||
|
||||
private void InitToolstrip(RootControl mainWindow)
|
||||
@@ -709,11 +710,11 @@ namespace FlaxEditor.Modules
|
||||
_toolStripScale = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Scale32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale).LinkTooltip($"Change Gizmo tool mode to Scale ({inputOptions.ScaleMode})");
|
||||
ToolStrip.AddSeparator();
|
||||
|
||||
// Cook scenes
|
||||
// Build 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 ({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 ({inputOptions.Play})");
|
||||
_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.CookAndRun})");
|
||||
_toolStripCook.ContextMenu = new ContextMenu();
|
||||
_toolStripCook.ContextMenu.AddButton("Run cooked game", Editor.Windows.GameCookerWin.RunCooked);
|
||||
_toolStripCook.ContextMenu.AddSeparator();
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Gets or sets the sequence of actions to perform when using Build Scenes button. Can be used to configure this as button (eg. compile code or just update navmesh).
|
||||
/// </summary>
|
||||
[EditorDisplay("General"), EditorOrder(200), Tooltip("The sequence of actions to perform when using Build Scenes button. Can be used to configure this as button (eg. compile code or just update navmesh).")]
|
||||
[EditorDisplay("General"), EditorOrder(200), ExpandGroups, Tooltip("The sequence of actions to perform when using Build Scenes button. Can be used to configure this as button (eg. compile code or just update navmesh).")]
|
||||
public BuildAction[] BuildActions { get; set; } =
|
||||
{
|
||||
BuildAction.CSG,
|
||||
|
||||
@@ -388,14 +388,16 @@ namespace FlaxEditor.Windows.Assets
|
||||
protected override void OnShow()
|
||||
{
|
||||
// Check if has no asset (but has item linked)
|
||||
if (_asset == null && _item != null)
|
||||
var item = _item;
|
||||
if (_asset == null && item != null)
|
||||
{
|
||||
// Load asset
|
||||
_asset = LoadAsset();
|
||||
if (_asset == null)
|
||||
{
|
||||
Editor.LogError(string.Format("Cannot load asset \'{0}\' ({1})", _item.Path, typeof(T)));
|
||||
Editor.LogError(string.Format("Cannot load asset \'{0}\' ({1})", item.Path, typeof(T)));
|
||||
Close();
|
||||
Editor.ContentDatabase.RefreshFolder(item, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -521,8 +521,11 @@ namespace FlaxEditor.Windows.Assets
|
||||
/// <inheritdoc />
|
||||
protected override void OnClose()
|
||||
{
|
||||
// Discard unsaved changes
|
||||
_properties.DiscardChanges();
|
||||
if (Asset)
|
||||
{
|
||||
// Discard unsaved changes
|
||||
_properties.DiscardChanges();
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
_undo.Clear();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Engine/ShadersCompilation/Config.h"
|
||||
#if BUILD_DEBUG
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Scripting/BinaryModule.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -256,7 +257,9 @@ Asset::LoadResult Material::load()
|
||||
|
||||
#if BUILD_DEBUG && USE_EDITOR
|
||||
// Dump generated material source to the temporary file
|
||||
BinaryModule::Locker.Lock();
|
||||
source.SaveToFile(Globals::ProjectCacheFolder / TEXT("material.txt"));
|
||||
BinaryModule::Locker.Unlock();
|
||||
#endif
|
||||
|
||||
// Encrypt source code
|
||||
|
||||
@@ -124,7 +124,8 @@ CreateAssetResult ImportModelFile::Import(CreateAssetContext& context)
|
||||
// Import model file
|
||||
ModelData modelData;
|
||||
String errorMsg;
|
||||
String autoImportOutput = String(StringUtils::GetDirectoryName(context.TargetAssetPath)) / StringUtils::GetFileNameWithoutExtension(context.InputPath);
|
||||
String autoImportOutput(StringUtils::GetDirectoryName(context.TargetAssetPath));
|
||||
autoImportOutput /= options.SubAssetFolder.HasChars() ? options.SubAssetFolder.TrimTrailing() : String(StringUtils::GetFileNameWithoutExtension(context.InputPath));
|
||||
if (ModelTool::ImportModel(context.InputPath, modelData, options, errorMsg, autoImportOutput))
|
||||
{
|
||||
LOG(Error, "Cannot import model file. {0}", errorMsg);
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
int32 _chunkIndex;
|
||||
int32 _index;
|
||||
|
||||
Iterator(ChunkedArray const* collection, const int32 index)
|
||||
Iterator(const ChunkedArray* collection, const int32 index)
|
||||
: _collection(const_cast<ChunkedArray*>(collection))
|
||||
, _chunkIndex(index / ChunkSize)
|
||||
, _index(index % ChunkSize)
|
||||
@@ -122,29 +122,29 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
FORCE_INLINE ChunkedArray* GetChunkedArray() const
|
||||
Iterator(Iterator&& i)
|
||||
: _collection(i._collection)
|
||||
, _chunkIndex(i._chunkIndex)
|
||||
, _index(i._index)
|
||||
{
|
||||
return _collection;
|
||||
}
|
||||
|
||||
public:
|
||||
FORCE_INLINE int32 Index() const
|
||||
{
|
||||
return _chunkIndex * ChunkSize + _index;
|
||||
}
|
||||
|
||||
public:
|
||||
bool IsEnd() const
|
||||
FORCE_INLINE bool IsEnd() const
|
||||
{
|
||||
return Index() == _collection->Count();
|
||||
return (_chunkIndex * ChunkSize + _index) == _collection->_count;
|
||||
}
|
||||
|
||||
bool IsNotEnd() const
|
||||
FORCE_INLINE bool IsNotEnd() const
|
||||
{
|
||||
return Index() != _collection->Count();
|
||||
return (_chunkIndex * ChunkSize + _index) != _collection->_count;
|
||||
}
|
||||
|
||||
public:
|
||||
FORCE_INLINE T& operator*() const
|
||||
{
|
||||
return _collection->_chunks[_chunkIndex]->At(_index);
|
||||
@@ -155,7 +155,6 @@ public:
|
||||
return &_collection->_chunks[_chunkIndex]->At(_index);
|
||||
}
|
||||
|
||||
public:
|
||||
FORCE_INLINE bool operator==(const Iterator& v) const
|
||||
{
|
||||
return _collection == v._collection && _chunkIndex == v._chunkIndex && _index == v._index;
|
||||
@@ -166,17 +165,22 @@ public:
|
||||
return _collection != v._collection || _chunkIndex != v._chunkIndex || _index != v._index;
|
||||
}
|
||||
|
||||
public:
|
||||
Iterator& operator=(const Iterator& v)
|
||||
{
|
||||
_collection = v._collection;
|
||||
_chunkIndex = v._chunkIndex;
|
||||
_index = v._index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator& operator++()
|
||||
{
|
||||
// Check if it is not at end
|
||||
const int32 end = _collection->Count();
|
||||
if (Index() != end)
|
||||
if ((_chunkIndex * ChunkSize + _index) != _collection->_count)
|
||||
{
|
||||
// Move forward within chunk
|
||||
_index++;
|
||||
|
||||
// Check if need to change chunk
|
||||
if (_index == ChunkSize && _chunkIndex < _collection->_chunks.Count() - 1)
|
||||
{
|
||||
// Move to next chunk
|
||||
@@ -189,9 +193,9 @@ public:
|
||||
|
||||
Iterator operator++(int)
|
||||
{
|
||||
Iterator temp = *this;
|
||||
++temp;
|
||||
return temp;
|
||||
Iterator i = *this;
|
||||
++i;
|
||||
return i;
|
||||
}
|
||||
|
||||
Iterator& operator--()
|
||||
@@ -199,7 +203,6 @@ public:
|
||||
// Check if it's not at beginning
|
||||
if (_index != 0 || _chunkIndex != 0)
|
||||
{
|
||||
// Check if need to change chunk
|
||||
if (_index == 0)
|
||||
{
|
||||
// Move to previous chunk
|
||||
@@ -217,9 +220,9 @@ public:
|
||||
|
||||
Iterator operator--(int)
|
||||
{
|
||||
Iterator temp = *this;
|
||||
--temp;
|
||||
return temp;
|
||||
Iterator i = *this;
|
||||
--i;
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -294,7 +297,7 @@ public:
|
||||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
ASSERT(i.GetChunkedArray() == this);
|
||||
ASSERT(i._collection == this);
|
||||
ASSERT(i._chunkIndex < _chunks.Count() && i._index < ChunkSize);
|
||||
ASSERT(i.Index() < Count());
|
||||
|
||||
@@ -432,11 +435,31 @@ public:
|
||||
|
||||
Iterator End() const
|
||||
{
|
||||
return Iterator(this, Count());
|
||||
return Iterator(this, _count);
|
||||
}
|
||||
|
||||
Iterator IteratorAt(int32 index) const
|
||||
{
|
||||
return Iterator(this, index);
|
||||
}
|
||||
|
||||
FORCE_INLINE Iterator begin()
|
||||
{
|
||||
return Iterator(this, 0);
|
||||
}
|
||||
|
||||
FORCE_INLINE Iterator end()
|
||||
{
|
||||
return Iterator(this, _count);
|
||||
}
|
||||
|
||||
FORCE_INLINE const Iterator begin() const
|
||||
{
|
||||
return Iterator(this, 0);
|
||||
}
|
||||
|
||||
FORCE_INLINE const Iterator end() const
|
||||
{
|
||||
return Iterator(this, _count);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -107,6 +107,26 @@ public:
|
||||
ASSERT(index >= 0 && index < _length);
|
||||
return _data[index];
|
||||
}
|
||||
|
||||
FORCE_INLINE T* begin()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
FORCE_INLINE T* end()
|
||||
{
|
||||
return _data + _length;
|
||||
}
|
||||
|
||||
FORCE_INLINE const T* begin() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
FORCE_INLINE const T* end() const
|
||||
{
|
||||
return _data + _length;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -634,15 +634,12 @@ void Foliage::RemoveFoliageType(int32 index)
|
||||
int32 Foliage::GetFoliageTypeInstancesCount(int32 index) const
|
||||
{
|
||||
PROFILE_CPU();
|
||||
|
||||
int32 result = 0;
|
||||
|
||||
for (auto i = Instances.Begin(); i.IsNotEnd(); i++)
|
||||
for (auto i = Instances.Begin(); i.IsNotEnd(); ++i)
|
||||
{
|
||||
if (i->Type == index)
|
||||
result++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.h"
|
||||
#if BUILD_DEBUG
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Scripting/BinaryModule.h"
|
||||
#endif
|
||||
#endif
|
||||
#if COMPILE_WITH_GPU_PARTICLES
|
||||
@@ -185,7 +186,9 @@ Asset::LoadResult ParticleEmitter::load()
|
||||
|
||||
#if BUILD_DEBUG && USE_EDITOR
|
||||
// Dump generated shader source to the temporary file
|
||||
BinaryModule::Locker.Lock();
|
||||
source.SaveToFile(Globals::ProjectCacheFolder / TEXT("particle_emitter.txt"));
|
||||
BinaryModule::Locker.Unlock();
|
||||
#endif
|
||||
|
||||
// Encrypt source code
|
||||
|
||||
@@ -47,10 +47,16 @@ int32 SpriteAtlas::GetSpritesCount() const
|
||||
|
||||
Sprite SpriteAtlas::GetSprite(int32 index) const
|
||||
{
|
||||
CHECK_RETURN(index >= 0 && index < Sprites.Count(), Sprite())
|
||||
CHECK_RETURN(index >= 0 && index < Sprites.Count(), Sprite());
|
||||
return Sprites.Get()[index];
|
||||
}
|
||||
|
||||
void SpriteAtlas::GetSpriteArea(int32 index, Rectangle& result) const
|
||||
{
|
||||
CHECK(index >= 0 && index < Sprites.Count());
|
||||
result = Sprites.Get()[index].Area;
|
||||
}
|
||||
|
||||
void SpriteAtlas::SetSprite(int32 index, const Sprite& value)
|
||||
{
|
||||
CHECK(index >= 0 && index < Sprites.Count());
|
||||
|
||||
@@ -70,7 +70,13 @@ namespace FlaxEngine
|
||||
[NoSerialize]
|
||||
public Float2 Size
|
||||
{
|
||||
get => Area.Size * Atlas.Size;
|
||||
get
|
||||
{
|
||||
if (Atlas == null)
|
||||
throw new InvalidOperationException("Cannot use invalid sprite.");
|
||||
Atlas.GetSpriteArea(Index, out var area);
|
||||
return area.Size * Atlas.Size;
|
||||
}
|
||||
set
|
||||
{
|
||||
var area = Area;
|
||||
@@ -89,7 +95,8 @@ namespace FlaxEngine
|
||||
{
|
||||
if (Atlas == null)
|
||||
throw new InvalidOperationException("Cannot use invalid sprite.");
|
||||
return Atlas.GetSprite(Index).Area;
|
||||
Atlas.GetSpriteArea(Index, out var area);
|
||||
return area;
|
||||
}
|
||||
set
|
||||
{
|
||||
|
||||
@@ -120,6 +120,14 @@ public:
|
||||
/// <returns>The sprite data.</returns>
|
||||
API_FUNCTION() Sprite GetSprite(int32 index) const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sprite area.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <param name="result">The output sprite area.</param>
|
||||
/// <returns>The sprite data.</returns>
|
||||
API_FUNCTION() void GetSpriteArea(int32 index, API_PARAM(Out) Rectangle& result) const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sprite data.
|
||||
/// </summary>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "Engine/Core/Types/DateTime.h"
|
||||
#include "Engine/Core/Types/TimeSpan.h"
|
||||
#include "Engine/Core/Types/Pair.h"
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Graphics/Models/SkeletonUpdater.h"
|
||||
#include "Engine/Graphics/Models/SkeletonMapping.h"
|
||||
#include "Engine/Core/Utilities.h"
|
||||
@@ -396,6 +397,7 @@ void ModelTool::Options::Serialize(SerializeStream& stream, const void* otherObj
|
||||
SERIALIZE(SDFResolution);
|
||||
SERIALIZE(SplitObjects);
|
||||
SERIALIZE(ObjectIndex);
|
||||
SERIALIZE(SubAssetFolder);
|
||||
}
|
||||
|
||||
void ModelTool::Options::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
@@ -441,6 +443,7 @@ void ModelTool::Options::Deserialize(DeserializeStream& stream, ISerializeModifi
|
||||
DESERIALIZE(SDFResolution);
|
||||
DESERIALIZE(SplitObjects);
|
||||
DESERIALIZE(ObjectIndex);
|
||||
DESERIALIZE(SubAssetFolder);
|
||||
|
||||
// [Deprecated on 23.11.2021, expires on 21.11.2023]
|
||||
int32 AnimationIndex = -1;
|
||||
@@ -744,6 +747,32 @@ void MeshOptDeallocate(void* ptr)
|
||||
Allocator::Free(ptr);
|
||||
}
|
||||
|
||||
void TrySetupMaterialParameter(MaterialInstance* instance, Span<const Char*> paramNames, const Variant& value, MaterialParameterType type)
|
||||
{
|
||||
for (const Char* name : paramNames)
|
||||
{
|
||||
for (MaterialParameter& param : instance->Params)
|
||||
{
|
||||
const MaterialParameterType paramType = param.GetParameterType();
|
||||
if (type != paramType)
|
||||
{
|
||||
if (type == MaterialParameterType::Color)
|
||||
{
|
||||
if (paramType != MaterialParameterType::Vector3 ||
|
||||
paramType != MaterialParameterType::Vector4)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
if (StringUtils::CompareIgnoreCase(name, param.GetName().Get()) != 0)
|
||||
continue;
|
||||
param.SetValue(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& options, String& errorMsg, const String& autoImportOutput)
|
||||
{
|
||||
LOG(Info, "Importing model from \'{0}\'", path);
|
||||
@@ -1014,9 +1043,18 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
|
||||
{
|
||||
// Create material instance
|
||||
AssetsImportingManager::Create(AssetsImportingManager::CreateMaterialInstanceTag, assetPath, material.AssetID);
|
||||
if (MaterialInstance* materialInstance = Content::Load<MaterialInstance>(assetPath))
|
||||
if (auto* materialInstance = Content::Load<MaterialInstance>(assetPath))
|
||||
{
|
||||
materialInstance->SetBaseMaterial(options.InstanceToImportAs);
|
||||
|
||||
// Customize base material based on imported material (blind guess based on the common names used in materials)
|
||||
const Char* diffuseColorNames[] = { TEXT("color"), TEXT("col"), TEXT("diffuse"), TEXT("basecolor"), TEXT("base color") };
|
||||
TrySetupMaterialParameter(materialInstance, ToSpan(diffuseColorNames, ARRAY_COUNT(diffuseColorNames)), material.Diffuse.Color, MaterialParameterType::Color);
|
||||
const Char* emissiveColorNames[] = { TEXT("emissive"), TEXT("emission"), TEXT("light") };
|
||||
TrySetupMaterialParameter(materialInstance, ToSpan(emissiveColorNames, ARRAY_COUNT(emissiveColorNames)), material.Emissive.Color, MaterialParameterType::Color);
|
||||
const Char* opacityValueNames[] = { TEXT("opacity"), TEXT("alpha") };
|
||||
TrySetupMaterialParameter(materialInstance, ToSpan(opacityValueNames, ARRAY_COUNT(opacityValueNames)), material.Opacity.Value, MaterialParameterType::Float);
|
||||
|
||||
materialInstance->Save();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -370,6 +370,12 @@ public:
|
||||
API_FIELD(Attributes="EditorOrder(2010), EditorDisplay(\"Splitting\")")
|
||||
int32 ObjectIndex = -1;
|
||||
|
||||
public: // Other
|
||||
|
||||
// If specified, will be used as sub-directory name for automatically imported sub assets such as textures and materials. Set to whitespace (single space) to import to the same directory.
|
||||
API_FIELD(Attributes="EditorOrder(3030), EditorDisplay(\"Other\")")
|
||||
String SubAssetFolder = TEXT("");
|
||||
|
||||
// Runtime data for objects splitting during import (used internally)
|
||||
void* SplitContext = nullptr;
|
||||
Function<bool(Options& splitOptions, const String& objectName)> OnSplitImport;
|
||||
|
||||
@@ -211,7 +211,7 @@ float SampleSDF(uint3 voxelCoordMip, int3 offset)
|
||||
float result = GlobalSDFTex[voxelCoordMip].r;
|
||||
|
||||
// Extend by distance to the sampled texel location
|
||||
float distanceInWorldUnits = length(offset) * (MaxDistance / (float)GenerateMipTexResolution);
|
||||
float distanceInWorldUnits = length((float3)offset) * (MaxDistance / (float)GenerateMipTexResolution);
|
||||
float distanceToVoxel = distanceInWorldUnits / MaxDistance;
|
||||
result = CombineDistanceToSDF(result, distanceToVoxel);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user