Merge remote-tracking branch 'origin/master' into gi
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
Custom fork: [https://github.com/FlaxEngine/mono](https://github.com/FlaxEngine/mono) with custom features for C# assemblies hot-reloading at runtime without domain unload (more: [https://flaxengine.com/blog/flax-facts-16-scripts-hot-reload/](https://flaxengine.com/blog/flax-facts-16-scripts-hot-reload/)).
|
||||
|
||||
Startup docs about building mono: [https://www.mono-project.com/docs/compiling-mono/](https://www.mono-project.com/docs/compiling-mono/)
|
||||
|
||||
### Notes
|
||||
|
||||
Some useful notes and tips for devs:
|
||||
|
||||
@@ -221,6 +221,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
|
||||
{
|
||||
const auto settings = WindowsPlatformSettings::Get();
|
||||
const bool modified =
|
||||
Settings.Windows.SupportDX12 != settings->SupportDX12 ||
|
||||
Settings.Windows.SupportDX11 != settings->SupportDX11 ||
|
||||
Settings.Windows.SupportDX10 != settings->SupportDX10 ||
|
||||
Settings.Windows.SupportVulkan != settings->SupportVulkan;
|
||||
@@ -1025,6 +1026,7 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
#if PLATFORM_TOOLS_WINDOWS
|
||||
{
|
||||
const auto settings = WindowsPlatformSettings::Get();
|
||||
cache.Settings.Windows.SupportDX12 = settings->SupportDX12;
|
||||
cache.Settings.Windows.SupportDX11 = settings->SupportDX11;
|
||||
cache.Settings.Windows.SupportDX10 = settings->SupportDX10;
|
||||
cache.Settings.Windows.SupportVulkan = settings->SupportVulkan;
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool SupportDX12;
|
||||
bool SupportDX11;
|
||||
bool SupportDX10;
|
||||
bool SupportVulkan;
|
||||
|
||||
@@ -891,10 +891,10 @@ namespace FlaxEditor
|
||||
if (asset == null)
|
||||
throw new ArgumentNullException(nameof(asset));
|
||||
if (asset.WaitForLoaded())
|
||||
throw new FlaxException("Failed to load asset.");
|
||||
throw new Exception("Failed to load asset.");
|
||||
var source = Internal_GetShaderAssetSourceCode(FlaxEngine.Object.GetUnmanagedPtr(asset));
|
||||
if (source == null)
|
||||
throw new FlaxException("Failed to get source code.");
|
||||
throw new Exception("Failed to get source code.");
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
base.Initialize(layout);
|
||||
|
||||
var instance = (AnimEvent)Values[0];
|
||||
if (instance == null)
|
||||
return;
|
||||
var scriptType = TypeUtils.GetObjectType(instance);
|
||||
var editor = CustomEditorsUtil.CreateEditor(scriptType, false);
|
||||
layout.Object(Values, editor);
|
||||
@@ -125,6 +127,52 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
}
|
||||
}
|
||||
|
||||
internal void InitMissing(string typeName, byte[] data)
|
||||
{
|
||||
Type = ScriptType.Null;
|
||||
IsContinuous = false;
|
||||
CanDelete = true;
|
||||
CanSplit = false;
|
||||
CanResize = false;
|
||||
TooltipText = $"Missing Anim Event Type '{typeName}'";
|
||||
Instance = null;
|
||||
BackgroundColor = Color.Red;
|
||||
_instanceTypeName = typeName;
|
||||
_instanceData = data;
|
||||
}
|
||||
|
||||
internal void Load(BinaryReader stream)
|
||||
{
|
||||
StartFrame = (int)stream.ReadSingle();
|
||||
DurationFrames = (int)stream.ReadSingle();
|
||||
var typeName = stream.ReadStrAnsi(13);
|
||||
var type = TypeUtils.GetType(typeName);
|
||||
if (type == ScriptType.Null)
|
||||
{
|
||||
InitMissing(typeName, stream.ReadJsonBytes());
|
||||
return;
|
||||
}
|
||||
Init(type);
|
||||
stream.ReadJson(Instance);
|
||||
}
|
||||
|
||||
internal void Save(BinaryWriter stream)
|
||||
{
|
||||
stream.Write((float)StartFrame);
|
||||
stream.Write((float)DurationFrames);
|
||||
if (Type != ScriptType.Null)
|
||||
{
|
||||
stream.WriteStrAnsi(Type.TypeName, 13);
|
||||
stream.WriteJson(Instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing
|
||||
stream.WriteStrAnsi(_instanceTypeName, 13);
|
||||
stream.WriteJsonBytes(_instanceData);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnDurationFramesChanged()
|
||||
{
|
||||
@@ -137,6 +185,8 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
_instanceData = null;
|
||||
_instanceTypeName = null;
|
||||
Type = ScriptType.Null;
|
||||
Object.Destroy(ref Instance);
|
||||
if (_isRegisteredForScriptsReload)
|
||||
@@ -181,14 +231,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var m = (AnimationEventMedia)e.Media[i];
|
||||
m.StartFrame = (int)stream.ReadSingle();
|
||||
m.DurationFrames = (int)stream.ReadSingle();
|
||||
var typeName = stream.ReadStrAnsi(13);
|
||||
var type = TypeUtils.GetType(typeName);
|
||||
if (type == ScriptType.Null)
|
||||
throw new Exception($"Unknown type {typeName}.");
|
||||
m.Init(type);
|
||||
stream.ReadJson(m.Instance);
|
||||
m.Load(stream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,10 +243,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var m = (AnimationEventMedia)e.Media[i];
|
||||
stream.Write((float)m.StartFrame);
|
||||
stream.Write((float)m.DurationFrames);
|
||||
stream.WriteStrAnsi(m.Type.TypeName, 13);
|
||||
stream.WriteJson(m.Instance);
|
||||
m.Save(stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -631,7 +631,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
}
|
||||
}
|
||||
if (spriteIndex == -1)
|
||||
throw new FlaxException();
|
||||
throw new Exception();
|
||||
atlas.Count++;
|
||||
_atlases[atlasIndex] = atlas;
|
||||
var sprite = new SpriteHandle(atlas.Texture, spriteIndex);
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace FlaxEditor.Modules
|
||||
|
||||
// Call backend
|
||||
if (PrefabManager.Internal_ApplyAll(FlaxEngine.Object.GetUnmanagedPtr(instance)))
|
||||
throw new FlaxException("Failed to apply the prefab. See log to learn more.");
|
||||
throw new Exception("Failed to apply the prefab. See log to learn more.");
|
||||
|
||||
PrefabApplied?.Invoke(prefab, instance);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using FlaxEditor.CustomEditors.Editors;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.Scripting;
|
||||
@@ -421,13 +422,23 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
TryParseText = (string filterText, out object[] data) =>
|
||||
{
|
||||
data = null;
|
||||
if (!filterText.StartsWith("#"))
|
||||
return false;
|
||||
if (Color.TryParseHex(filterText, out var color))
|
||||
if (filterText.StartsWith("#") && Color.TryParseHex(filterText, out var color))
|
||||
{
|
||||
// Color constant from hex
|
||||
data = new object[] { color };
|
||||
return true;
|
||||
}
|
||||
if (filterText.Length > 2)
|
||||
{
|
||||
var fieldName = char.ToUpperInvariant(filterText[0]) + filterText.Substring(1).ToLowerInvariant();
|
||||
var field = typeof(Color).GetField(fieldName, BindingFlags.Public | BindingFlags.Static);
|
||||
if (field != null && fieldName != "Zero")
|
||||
{
|
||||
// Color constant in-built
|
||||
data = new object[] { field.GetValue(null) };
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using FlaxEditor.Tools.Terrain.Brushes;
|
||||
using FlaxEngine;
|
||||
|
||||
@@ -129,9 +130,7 @@ namespace FlaxEditor.Tools.Terrain.Paint
|
||||
// Get the patch data (cached internally by the c++ core in editor)
|
||||
var sourceData = TerrainTools.GetSplatMapData(terrain, ref patch.PatchCoord, splatmapIndex);
|
||||
if (sourceData == null)
|
||||
{
|
||||
throw new FlaxException("Cannot modify terrain. Loading splatmap failed. See log for more info.");
|
||||
}
|
||||
throw new Exception("Cannot modify terrain. Loading splatmap failed. See log for more info.");
|
||||
|
||||
// Record patch data before editing it
|
||||
if (!gizmo.CurrentEditUndoAction.HashPatch(ref patch.PatchCoord))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using FlaxEditor.Tools.Terrain.Brushes;
|
||||
using FlaxEngine;
|
||||
|
||||
@@ -128,9 +129,7 @@ namespace FlaxEditor.Tools.Terrain.Sculpt
|
||||
float* sourceHeights = EditHoles ? null : TerrainTools.GetHeightmapData(terrain, ref patch.PatchCoord);
|
||||
byte* sourceHoles = EditHoles ? TerrainTools.GetHolesMaskData(terrain, ref patch.PatchCoord) : null;
|
||||
if (sourceHeights == null && sourceHoles == null)
|
||||
{
|
||||
throw new FlaxException("Cannot modify terrain. Loading heightmap failed. See log for more info.");
|
||||
}
|
||||
throw new Exception("Cannot modify terrain. Loading heightmap failed. See log for more info.");
|
||||
|
||||
// Record patch data before editing it
|
||||
if (!gizmo.CurrentEditUndoAction.HashPatch(ref patch.PatchCoord))
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace FlaxEditor.Tools.Terrain.Undo
|
||||
var offset = Int2.Zero;
|
||||
var size = new Int2((int)Mathf.Sqrt(_heightmapLength));
|
||||
if (TerrainTools.ModifyHeightMap(Terrain, ref patchCoord, (float*)data, ref offset, ref size))
|
||||
throw new FlaxException("Failed to modify the heightmap.");
|
||||
throw new Exception("Failed to modify the heightmap.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace FlaxEditor.Tools.Terrain.Undo
|
||||
var offset = Int2.Zero;
|
||||
var size = new Int2((int)Mathf.Sqrt(_heightmapLength));
|
||||
if (TerrainTools.ModifyHolesMask(Terrain, ref patchCoord, (byte*)data, ref offset, ref size))
|
||||
throw new FlaxException("Failed to modify the terrain holes.");
|
||||
throw new Exception("Failed to modify the terrain holes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace FlaxEditor.Tools.Terrain.Undo
|
||||
var offset = Int2.Zero;
|
||||
var size = new Int2((int)Mathf.Sqrt(_heightmapLength));
|
||||
if (TerrainTools.ModifySplatMap(Terrain, ref patchCoord, (int)tag, (Color32*)data, ref offset, ref size))
|
||||
throw new FlaxException("Failed to modify the splatmap.");
|
||||
throw new Exception("Failed to modify the splatmap.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace FlaxEditor.Actions
|
||||
if (actor == null)
|
||||
throw new ArgumentNullException(nameof(actor));
|
||||
if (!actor.HasPrefabLink)
|
||||
throw new FlaxException("Cannot register missing prefab link.");
|
||||
throw new Exception("Cannot register missing prefab link.");
|
||||
return new BreakPrefabLinkAction(false, actor);
|
||||
}
|
||||
|
||||
@@ -102,11 +102,11 @@ namespace FlaxEditor.Actions
|
||||
private void DoLink()
|
||||
{
|
||||
if (_prefabObjectIds == null)
|
||||
throw new FlaxException("Cannot link prefab. Missing objects Ids mapping.");
|
||||
throw new Exception("Cannot link prefab. Missing objects Ids mapping.");
|
||||
|
||||
var actor = Object.Find<Actor>(ref _actorId);
|
||||
if (actor == null)
|
||||
throw new FlaxException("Cannot link prefab. Missing actor.");
|
||||
throw new Exception("Cannot link prefab. Missing actor.");
|
||||
|
||||
// Restore cached links
|
||||
foreach (var e in _prefabObjectIds)
|
||||
@@ -149,9 +149,9 @@ namespace FlaxEditor.Actions
|
||||
{
|
||||
var actor = Object.Find<Actor>(ref _actorId);
|
||||
if (actor == null)
|
||||
throw new FlaxException("Cannot break prefab link. Missing actor.");
|
||||
throw new Exception("Cannot break prefab link. Missing actor.");
|
||||
if (!actor.HasPrefabLink)
|
||||
throw new FlaxException("Cannot break missing prefab link.");
|
||||
throw new Exception("Cannot break missing prefab link.");
|
||||
|
||||
if (_prefabObjectIds == null)
|
||||
_prefabObjectIds = new Dictionary<Guid, Guid>(1024);
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace FlaxEditor.Utilities
|
||||
if (Level.UnloadAllScenes())
|
||||
{
|
||||
Profiler.EndEvent();
|
||||
throw new FlaxException("Failed to unload scenes.");
|
||||
throw new Exception("Failed to unload scenes.");
|
||||
}
|
||||
FlaxEngine.Scripting.FlushRemovedObjects();
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace FlaxEditor.Utilities
|
||||
if (noScenes != null && noScenes.Length != 0)
|
||||
{
|
||||
Profiler.EndEvent();
|
||||
throw new FlaxException("Failed to unload scenes.");
|
||||
throw new Exception("Failed to unload scenes.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace FlaxEditor.Utilities
|
||||
if (scene == null)
|
||||
{
|
||||
Profiler.EndEvent();
|
||||
throw new FlaxException("Failed to deserialize scene");
|
||||
throw new Exception("Failed to deserialize scene");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace FlaxEditor.Utilities
|
||||
if (Level.UnloadAllScenes())
|
||||
{
|
||||
Profiler.EndEvent();
|
||||
throw new FlaxException("Failed to unload scenes.");
|
||||
throw new Exception("Failed to unload scenes.");
|
||||
}
|
||||
FlaxEngine.Scripting.FlushRemovedObjects();
|
||||
Profiler.EndEvent();
|
||||
@@ -154,7 +154,7 @@ namespace FlaxEditor.Utilities
|
||||
if (scene == null)
|
||||
{
|
||||
Profiler.EndEvent();
|
||||
throw new FlaxException("Failed to deserialize scene");
|
||||
throw new Exception("Failed to deserialize scene");
|
||||
}
|
||||
|
||||
// Restore `dirty` state
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using FlaxEngine;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
namespace FlaxEditor.Viewport.Previews
|
||||
{
|
||||
@@ -39,7 +41,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
|
||||
// Wait for base (don't want to async material parameters set due to async loading)
|
||||
if (baseMaterial == null || baseMaterial.WaitForLoaded())
|
||||
throw new FlaxException("Cannot load IES Profile preview material.");
|
||||
throw new Exception("Cannot load IES Profile preview material.");
|
||||
|
||||
// Create preview material (virtual)
|
||||
_previewMaterial = baseMaterial.CreateVirtualInstance();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using FlaxEngine;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
@@ -54,7 +55,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
if (instance == null)
|
||||
{
|
||||
_prefab = null;
|
||||
throw new FlaxException("Failed to spawn a prefab for the preview.");
|
||||
throw new Exception("Failed to spawn a prefab for the preview.");
|
||||
}
|
||||
|
||||
// Set instance
|
||||
|
||||
@@ -319,10 +319,10 @@ namespace FlaxEditor.Viewport.Previews
|
||||
// Create preview material (virtual)
|
||||
var baseMaterial = FlaxEngine.Content.LoadAsyncInternal<Material>("Editor/TexturePreviewMaterial");
|
||||
if (baseMaterial == null)
|
||||
throw new FlaxException("Cannot load texture preview material.");
|
||||
throw new Exception("Cannot load texture preview material.");
|
||||
_previewMaterial = baseMaterial.CreateVirtualInstance();
|
||||
if (_previewMaterial == null)
|
||||
throw new FlaxException("Failed to create virtual material instance for preview material.");
|
||||
throw new Exception("Failed to create virtual material instance for preview material.");
|
||||
|
||||
// Add widgets
|
||||
if (useWidgets)
|
||||
|
||||
@@ -482,7 +482,6 @@ namespace FlaxEditor.Windows
|
||||
continue;
|
||||
|
||||
var startIndex = _textBuffer.Length;
|
||||
|
||||
switch (_timestampsFormats)
|
||||
{
|
||||
case InterfaceOptions.TimestampsFormats.Utc:
|
||||
@@ -496,12 +495,12 @@ namespace FlaxEditor.Windows
|
||||
_textBuffer.AppendFormat("[ {0:00}:{1:00}:{2:00}.{3:000} ]: ", diff.Hours, diff.Minutes, diff.Seconds, diff.Milliseconds);
|
||||
break;
|
||||
}
|
||||
|
||||
if (_showLogType)
|
||||
{
|
||||
_textBuffer.AppendFormat("[{0}] ", entry.Level);
|
||||
}
|
||||
|
||||
var prefixLength = _textBuffer.Length - startIndex;
|
||||
if (entry.Message.IndexOf('\r') != -1)
|
||||
entry.Message = entry.Message.Replace("\r", "");
|
||||
_textBuffer.Append(entry.Message);
|
||||
@@ -548,7 +547,13 @@ namespace FlaxEditor.Windows
|
||||
if (textBlock.Range.Length > 0)
|
||||
{
|
||||
// Parse compilation error/warning
|
||||
var match = _compileRegex.Match(entryText, line.FirstCharIndex, textBlock.Range.Length);
|
||||
var regexStart = line.FirstCharIndex;
|
||||
if (j == 0)
|
||||
regexStart += prefixLength;
|
||||
var regexLength = line.LastCharIndex - regexStart;
|
||||
if (regexLength > 0)
|
||||
{
|
||||
var match = _compileRegex.Match(entryText, regexStart, regexLength);
|
||||
if (match.Success)
|
||||
{
|
||||
switch (match.Groups["level"].Value)
|
||||
@@ -570,6 +575,7 @@ namespace FlaxEditor.Windows
|
||||
// TODO: parsing hyperlinks with link
|
||||
// TODO: parsing file paths with link
|
||||
}
|
||||
}
|
||||
|
||||
prevBlockBottom += line.Size.Y;
|
||||
_textBlocks.Add(textBlock);
|
||||
|
||||
@@ -417,7 +417,7 @@ namespace FlaxEditor.Windows
|
||||
public override DragDropEffect OnDragEnter(ref Vector2 location, DragData data)
|
||||
{
|
||||
var result = base.OnDragEnter(ref location, data);
|
||||
if (result == DragDropEffect.None && Editor.StateMachine.CurrentState.CanEditScene)
|
||||
if (Editor.StateMachine.CurrentState.CanEditScene)
|
||||
{
|
||||
if (_dragHandlers == null)
|
||||
_dragHandlers = new DragHandlers();
|
||||
@@ -426,14 +426,14 @@ namespace FlaxEditor.Windows
|
||||
_dragAssets = new DragAssets(ValidateDragAsset);
|
||||
_dragHandlers.Add(_dragAssets);
|
||||
}
|
||||
if (_dragAssets.OnDragEnter(data))
|
||||
if (_dragAssets.OnDragEnter(data) && result == DragDropEffect.None)
|
||||
return _dragAssets.Effect;
|
||||
if (_dragActorType == null)
|
||||
{
|
||||
_dragActorType = new DragActorType(ValidateDragActorType);
|
||||
_dragHandlers.Add(_dragActorType);
|
||||
}
|
||||
if (_dragActorType.OnDragEnter(data))
|
||||
if (_dragActorType.OnDragEnter(data) && result == DragDropEffect.None)
|
||||
return _dragActorType.Effect;
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -281,9 +281,10 @@ bool JsonAsset::CreateInstance()
|
||||
|
||||
void JsonAsset::DeleteInstance()
|
||||
{
|
||||
ASSERT_LOW_LAYER(Instance && _dtor);
|
||||
InstanceType = ScriptingTypeHandle();
|
||||
if (!Instance || !_dtor)
|
||||
return;
|
||||
_dtor(Instance);
|
||||
InstanceType = ScriptingTypeHandle();
|
||||
Allocator::Free(Instance);
|
||||
Instance = nullptr;
|
||||
_dtor = nullptr;
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Flax exception object.
|
||||
/// </summary>
|
||||
/// <seealso cref="System.SystemException" />
|
||||
[Serializable]
|
||||
public class FlaxException : SystemException
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FlaxException"/> class.
|
||||
/// </summary>
|
||||
public FlaxException()
|
||||
: base("A Flax runtime error occurred!")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FlaxException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
public FlaxException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FlaxException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception. If the <paramref name="innerException" /> parameter is not a null reference (Nothing in Visual Basic), the current exception is raised in a catch block that handles the inner exception.</param>
|
||||
public FlaxException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ namespace FlaxEngine
|
||||
uv,
|
||||
colors
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -201,7 +201,7 @@ namespace FlaxEngine
|
||||
Utils.ExtractArrayFromList(uv),
|
||||
Utils.ExtractArrayFromList(colors)
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -247,7 +247,7 @@ namespace FlaxEngine
|
||||
uv,
|
||||
colors
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -294,7 +294,7 @@ namespace FlaxEngine
|
||||
Utils.ExtractArrayFromList(uv),
|
||||
Utils.ExtractArrayFromList(colors)
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -341,7 +341,7 @@ namespace FlaxEngine
|
||||
uv,
|
||||
colors
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -388,7 +388,7 @@ namespace FlaxEngine
|
||||
Utils.ExtractArrayFromList(uv),
|
||||
Utils.ExtractArrayFromList(colors)
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -412,7 +412,7 @@ namespace FlaxEngine
|
||||
triangles.Length / 3,
|
||||
triangles
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -436,7 +436,7 @@ namespace FlaxEngine
|
||||
triangles.Count / 3,
|
||||
Utils.ExtractArrayFromList(triangles)
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -460,7 +460,7 @@ namespace FlaxEngine
|
||||
triangles.Length / 3,
|
||||
triangles
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -484,7 +484,7 @@ namespace FlaxEngine
|
||||
triangles.Count / 3,
|
||||
Utils.ExtractArrayFromList(triangles)
|
||||
))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
internal enum InternalBufferType
|
||||
@@ -506,7 +506,7 @@ namespace FlaxEngine
|
||||
var vertices = VertexCount;
|
||||
var result = new Vertex0[vertices];
|
||||
if (Internal_DownloadBuffer(__unmanagedPtr, forceGpu, result, (int)InternalBufferType.VB0))
|
||||
throw new FlaxException("Failed to download mesh data.");
|
||||
throw new Exception("Failed to download mesh data.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@ namespace FlaxEngine
|
||||
var vertices = VertexCount;
|
||||
var result = new Vertex1[vertices];
|
||||
if (Internal_DownloadBuffer(__unmanagedPtr, forceGpu, result, (int)InternalBufferType.VB1))
|
||||
throw new FlaxException("Failed to download mesh data.");
|
||||
throw new Exception("Failed to download mesh data.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ namespace FlaxEngine
|
||||
var vertices = VertexCount;
|
||||
var result = new Vertex2[vertices];
|
||||
if (Internal_DownloadBuffer(__unmanagedPtr, forceGpu, result, (int)InternalBufferType.VB2))
|
||||
throw new FlaxException("Failed to download mesh data.");
|
||||
throw new Exception("Failed to download mesh data.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ namespace FlaxEngine
|
||||
var triangles = TriangleCount;
|
||||
var result = new uint[triangles * 3];
|
||||
if (Internal_DownloadBuffer(__unmanagedPtr, forceGpu, result, (int)InternalBufferType.IB32))
|
||||
throw new FlaxException("Failed to download mesh data.");
|
||||
throw new Exception("Failed to download mesh data.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -612,7 +612,7 @@ namespace FlaxEngine
|
||||
var triangles = TriangleCount;
|
||||
var result = new ushort[triangles * 3];
|
||||
if (Internal_DownloadBuffer(__unmanagedPtr, forceGpu, result, (int)InternalBufferType.IB16))
|
||||
throw new FlaxException("Failed to download mesh data.");
|
||||
throw new Exception("Failed to download mesh data.");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace FlaxEngine
|
||||
throw new ArgumentOutOfRangeException(nameof(uv));
|
||||
|
||||
if (Internal_UpdateMeshUInt(__unmanagedPtr, vertices, triangles, blendIndices, blendWeights, normals, tangents, uv))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -167,7 +167,7 @@ namespace FlaxEngine
|
||||
throw new ArgumentOutOfRangeException(nameof(uv));
|
||||
|
||||
if (Internal_UpdateMeshUInt(__unmanagedPtr, vertices, triangles, blendIndices, blendWeights, normals, tangents, uv))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -203,7 +203,7 @@ namespace FlaxEngine
|
||||
throw new ArgumentOutOfRangeException(nameof(uv));
|
||||
|
||||
if (Internal_UpdateMeshUShort(__unmanagedPtr, vertices, triangles, blendIndices, blendWeights, normals, tangents, uv))
|
||||
throw new FlaxException("Failed to update mesh data.");
|
||||
throw new Exception("Failed to update mesh data.");
|
||||
}
|
||||
|
||||
internal enum InternalBufferType
|
||||
@@ -223,7 +223,7 @@ namespace FlaxEngine
|
||||
var vertices = VertexCount;
|
||||
var result = new Vertex0[vertices];
|
||||
if (Internal_DownloadBuffer(__unmanagedPtr, forceGpu, result, (int)InternalBufferType.VB0))
|
||||
throw new FlaxException("Failed to download mesh data.");
|
||||
throw new Exception("Failed to download mesh data.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ namespace FlaxEngine
|
||||
var triangles = TriangleCount;
|
||||
var result = new uint[triangles * 3];
|
||||
if (Internal_DownloadBuffer(__unmanagedPtr, forceGpu, result, (int)InternalBufferType.IB32))
|
||||
throw new FlaxException("Failed to download mesh data.");
|
||||
throw new Exception("Failed to download mesh data.");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ namespace FlaxEngine
|
||||
var triangles = TriangleCount;
|
||||
var result = new ushort[triangles * 3];
|
||||
if (Internal_DownloadBuffer(__unmanagedPtr, forceGpu, result, (int)InternalBufferType.IB16))
|
||||
throw new FlaxException("Failed to download mesh data.");
|
||||
throw new Exception("Failed to download mesh data.");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace FlaxEngine
|
||||
|
||||
// Call backend
|
||||
if (Internal_Init(__unmanagedPtr, new IntPtr(&t)))
|
||||
throw new FlaxException("Failed to init texture data.");
|
||||
throw new Exception("Failed to init texture data.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -266,6 +266,20 @@ bool GPUDeviceDX11::Init()
|
||||
}
|
||||
UpdateOutputs(adapter);
|
||||
|
||||
ComPtr<IDXGIFactory5> factory5;
|
||||
_factoryDXGI->QueryInterface(IID_PPV_ARGS(&factory5));
|
||||
if (factory5)
|
||||
{
|
||||
BOOL allowTearing;
|
||||
if (SUCCEEDED(factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing)))
|
||||
&& allowTearing
|
||||
#if PLATFORM_WINDOWS
|
||||
&& GetModuleHandleA("renderdoc.dll") == nullptr // Disable tearing with RenderDoc (prevents crashing)
|
||||
#endif
|
||||
)
|
||||
AllowTearing = true;
|
||||
}
|
||||
|
||||
// Get flags and device type base on current configuration
|
||||
uint32 flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
#if GPU_ENABLE_DIAGNOSTICS
|
||||
@@ -276,18 +290,7 @@ bool GPUDeviceDX11::Init()
|
||||
// Create DirectX device
|
||||
D3D_FEATURE_LEVEL createdFeatureLevel = static_cast<D3D_FEATURE_LEVEL>(0);
|
||||
auto targetFeatureLevel = GetD3DFeatureLevel();
|
||||
VALIDATE_DIRECTX_RESULT(D3D11CreateDevice(
|
||||
adapter,
|
||||
D3D_DRIVER_TYPE_UNKNOWN,
|
||||
NULL,
|
||||
flags,
|
||||
&targetFeatureLevel,
|
||||
1,
|
||||
D3D11_SDK_VERSION,
|
||||
&_device,
|
||||
&createdFeatureLevel,
|
||||
&_imContext
|
||||
));
|
||||
VALIDATE_DIRECTX_RESULT(D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, &targetFeatureLevel, 1, D3D11_SDK_VERSION, &_device, &createdFeatureLevel, &_imContext));
|
||||
|
||||
// Validate result
|
||||
ASSERT(_device);
|
||||
|
||||
@@ -50,6 +50,10 @@ public:
|
||||
GPUDeviceDX11(IDXGIFactory* dxgiFactory, GPUAdapterDX* adapter);
|
||||
~GPUDeviceDX11();
|
||||
|
||||
public:
|
||||
|
||||
bool AllowTearing = false;
|
||||
|
||||
public:
|
||||
|
||||
// Gets DX11 device
|
||||
|
||||
@@ -17,6 +17,8 @@ GPUSwapChainDX11::GPUSwapChainDX11(GPUDeviceDX11* device, Window* window)
|
||||
#endif
|
||||
, _swapChain(nullptr)
|
||||
, _backBuffer(nullptr)
|
||||
, _allowTearing(false)
|
||||
, _isFullscreen(false)
|
||||
{
|
||||
ASSERT(_windowHandle);
|
||||
_window = window;
|
||||
@@ -108,6 +110,18 @@ void GPUSwapChainDX11::SetFullscreen(bool isFullscreen)
|
||||
{
|
||||
LOG(Warning, "Cannot change fullscreen mode for '{0}' to {1}.", ToString(), isFullscreen);
|
||||
}
|
||||
|
||||
_isFullscreen = isFullscreen;
|
||||
|
||||
// Buffers must be resized in flip presentation model
|
||||
if (swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ||
|
||||
swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD)
|
||||
{
|
||||
const int32 width = _width;
|
||||
const int32 height = _height;
|
||||
_width = _height = 0;
|
||||
Resize(width, height);
|
||||
}
|
||||
}
|
||||
#else
|
||||
LOG(Info, "Cannot change fullscreen mode on this platform");
|
||||
@@ -123,7 +137,14 @@ void GPUSwapChainDX11::Present(bool vsync)
|
||||
{
|
||||
// Present frame
|
||||
ASSERT(_swapChain);
|
||||
const HRESULT result = _swapChain->Present(vsync ? 1 : 0, 0);
|
||||
UINT presentFlags = 0;
|
||||
#if PLATFORM_WINDOWS
|
||||
if (!vsync && !_isFullscreen && _allowTearing)
|
||||
{
|
||||
presentFlags |= DXGI_PRESENT_ALLOW_TEARING;
|
||||
}
|
||||
#endif
|
||||
const HRESULT result = _swapChain->Present(vsync ? 1 : 0, presentFlags);
|
||||
LOG_DIRECTX_RESULT(result);
|
||||
|
||||
// Base
|
||||
@@ -140,6 +161,9 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height)
|
||||
|
||||
_device->WaitForGPU();
|
||||
GPUDeviceLock lock(_device);
|
||||
#if PLATFORM_WINDOWS
|
||||
_allowTearing = _device->AllowTearing;
|
||||
#endif
|
||||
_format = GPU_BACK_BUFFER_PIXEL_FORMAT;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
@@ -177,6 +201,11 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height)
|
||||
swapChainDesc.Windowed = TRUE;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
if (_allowTearing)
|
||||
{
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapChainDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
}
|
||||
#else
|
||||
swapChainDesc.Width = width;
|
||||
swapChainDesc.Height = height;
|
||||
@@ -202,7 +231,7 @@ bool GPUSwapChainDX11::Resize(int32 width, int32 height)
|
||||
ASSERT(_swapChain);
|
||||
|
||||
// Disable DXGI changes to the window
|
||||
VALIDATE_DIRECTX_RESULT(dxgi->MakeWindowAssociation(_windowHandle, 0));
|
||||
VALIDATE_DIRECTX_RESULT(dxgi->MakeWindowAssociation(_windowHandle, DXGI_MWA_NO_ALT_ENTER));
|
||||
#else
|
||||
auto dxgiFactory = (IDXGIFactory2*)_device->GetDXGIFactory();
|
||||
VALIDATE_DIRECTX_RESULT(dxgiFactory->CreateSwapChainForCoreWindow(_device->GetDevice(), static_cast<IUnknown*>(_windowHandle), &swapChainDesc, nullptr, &_swapChain));
|
||||
|
||||
@@ -23,6 +23,7 @@ private:
|
||||
#if PLATFORM_WINDOWS
|
||||
HWND _windowHandle;
|
||||
IDXGISwapChain* _swapChain;
|
||||
bool _allowTearing, _isFullscreen;
|
||||
#else
|
||||
IUnknown* _windowHandle;
|
||||
IDXGISwapChain1* _swapChain;
|
||||
|
||||
@@ -264,18 +264,20 @@ bool GPUDeviceDX12::Init()
|
||||
return true;
|
||||
}
|
||||
UpdateOutputs(adapter);
|
||||
{
|
||||
|
||||
ComPtr<IDXGIFactory5> factory5;
|
||||
_factoryDXGI->QueryInterface(IID_PPV_ARGS(&factory5));
|
||||
if (factory5)
|
||||
{
|
||||
BOOL allowTearing;
|
||||
if (SUCCEEDED(factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing))) && allowTearing)
|
||||
{
|
||||
if (SUCCEEDED(factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allowTearing, sizeof(allowTearing)))
|
||||
&& allowTearing
|
||||
#if PLATFORM_WINDOWS
|
||||
&& GetModuleHandleA("renderdoc.dll") == nullptr // Disable tearing with RenderDoc (prevents crashing)
|
||||
#endif
|
||||
)
|
||||
AllowTearing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create DirectX device
|
||||
VALIDATE_DIRECTX_RESULT(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_device)));
|
||||
|
||||
@@ -51,6 +51,8 @@ GPUSwapChainDX12::GPUSwapChainDX12(GPUDeviceDX12* device, Window* window)
|
||||
, _windowHandle(static_cast<HWND>(window->GetNativePtr()))
|
||||
, _swapChain(nullptr)
|
||||
, _currentFrameIndex(0)
|
||||
, _allowTearing(false)
|
||||
, _isFullscreen(false)
|
||||
{
|
||||
ASSERT(_windowHandle);
|
||||
_window = window;
|
||||
@@ -135,6 +137,16 @@ void GPUSwapChainDX12::SetFullscreen(bool isFullscreen)
|
||||
}
|
||||
|
||||
_isFullscreen = isFullscreen;
|
||||
|
||||
// Buffers must be resized in flip presentation model
|
||||
if (swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ||
|
||||
swapChainDesc.SwapEffect == DXGI_SWAP_EFFECT_FLIP_DISCARD)
|
||||
{
|
||||
const int32 width = _width;
|
||||
const int32 height = _height;
|
||||
_width = _height = 0;
|
||||
Resize(width, height);
|
||||
}
|
||||
}
|
||||
#else
|
||||
LOG(Info, "Cannot change fullscreen mode on this platform");
|
||||
@@ -217,7 +229,7 @@ bool GPUSwapChainDX12::Resize(int32 width, int32 height)
|
||||
_backBuffers.Resize(swapChainDesc.BufferCount);
|
||||
|
||||
// Disable DXGI changes to the window
|
||||
dxgiFactory->MakeWindowAssociation(_windowHandle, 0);
|
||||
VALIDATE_DIRECTX_RESULT(dxgiFactory->MakeWindowAssociation(_windowHandle, DXGI_MWA_NO_ALT_ENTER));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef IGraphicsUnknown IDXGISwapChain3;
|
||||
#include <D3D11.h>
|
||||
#include <d3d11_1.h>
|
||||
#include <dxgi1_3.h>
|
||||
#include <dxgi1_5.h>
|
||||
#endif
|
||||
#if GRAPHICS_API_DIRECTX12
|
||||
#include <dxgi1_5.h>
|
||||
|
||||
@@ -1358,7 +1358,7 @@ bool Actor::HasActorInChildren(Actor* a) const
|
||||
|
||||
bool Actor::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
|
||||
{
|
||||
return GetBox().Intersects(ray, distance, normal);
|
||||
return _box.Intersects(ray, distance, normal);
|
||||
}
|
||||
|
||||
Actor* Actor::Intersects(const Ray& ray, float& distance, Vector3& normal)
|
||||
|
||||
@@ -76,7 +76,8 @@ void AnimatedModel::SetupSkinningData()
|
||||
|
||||
void AnimatedModel::PreInitSkinningData()
|
||||
{
|
||||
ASSERT(SkinnedModel && SkinnedModel->IsLoaded());
|
||||
if (!SkinnedModel || !SkinnedModel->IsLoaded())
|
||||
return;
|
||||
|
||||
ScopeLock lock(SkinnedModel->Locker);
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "PhysicsActor.h"
|
||||
#include "../PhysicsBackend.h"
|
||||
|
||||
PhysicsActor::PhysicsActor(const SpawnParams& params)
|
||||
: Actor(params)
|
||||
, _cachedScale(1.0f)
|
||||
, _isUpdatingTransform(false)
|
||||
{
|
||||
}
|
||||
|
||||
void PhysicsActor::OnActiveTransformChanged()
|
||||
{
|
||||
// Change actor transform (but with locking)
|
||||
ASSERT(!_isUpdatingTransform);
|
||||
_isUpdatingTransform = true;
|
||||
Transform transform;
|
||||
PhysicsBackend::GetRigidActorPose(GetPhysicsActor(), transform.Translation, transform.Orientation);
|
||||
transform.Scale = _transform.Scale;
|
||||
if (_parent)
|
||||
{
|
||||
_parent->GetTransform().WorldToLocal(transform, _localTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
_localTransform = transform;
|
||||
}
|
||||
OnTransformChanged();
|
||||
_isUpdatingTransform = false;
|
||||
}
|
||||
|
||||
void PhysicsActor::OnTransformChanged()
|
||||
{
|
||||
// Base
|
||||
Actor::OnTransformChanged();
|
||||
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void PhysicsActor::UpdateBounds()
|
||||
{
|
||||
void* actor = GetPhysicsActor();
|
||||
if (actor)
|
||||
PhysicsBackend::GetActorBounds(actor, _box);
|
||||
else
|
||||
_box = BoundingBox(_transform.Translation);
|
||||
BoundingSphere::FromBox(_box, _sphere);
|
||||
}
|
||||
|
||||
bool PhysicsActor::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
|
||||
{
|
||||
return _box.Intersects(ray, distance, normal);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Level/Actor.h"
|
||||
#include "Engine/Physics/Types.h"
|
||||
#include "IPhysicsActor.h"
|
||||
|
||||
/// <summary>
|
||||
/// A base class for all physical actors.
|
||||
/// </summary>
|
||||
/// <seealso cref="Actor" />
|
||||
API_CLASS(Abstract) class FLAXENGINE_API PhysicsActor : public Actor, public IPhysicsActor
|
||||
{
|
||||
DECLARE_SCENE_OBJECT_ABSTRACT(PhysicsActor);
|
||||
protected:
|
||||
|
||||
Vector3 _cachedScale;
|
||||
bool _isUpdatingTransform;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Updates the bounding box.
|
||||
/// </summary>
|
||||
void UpdateBounds();
|
||||
|
||||
public:
|
||||
|
||||
// [Actor]
|
||||
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
||||
|
||||
// [IPhysicsActor]
|
||||
void OnActiveTransformChanged() override;
|
||||
|
||||
protected:
|
||||
|
||||
// [Actor]
|
||||
void OnTransformChanged() override;
|
||||
};
|
||||
@@ -8,8 +8,9 @@
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
|
||||
RigidBody::RigidBody(const SpawnParams& params)
|
||||
: PhysicsActor(params)
|
||||
: Actor(params)
|
||||
, _actor(nullptr)
|
||||
, _cachedScale(1.0f)
|
||||
, _mass(1.0f)
|
||||
, _linearDamping(0.01f)
|
||||
, _angularDamping(0.05f)
|
||||
@@ -24,6 +25,7 @@ RigidBody::RigidBody(const SpawnParams& params)
|
||||
, _startAwake(true)
|
||||
, _updateMassWhenScaleChanges(false)
|
||||
, _overrideMass(false)
|
||||
, _isUpdatingTransform(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -224,13 +226,13 @@ bool RigidBody::IsSleeping() const
|
||||
void RigidBody::Sleep() const
|
||||
{
|
||||
if (_actor && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy())
|
||||
PhysicsBackend::GetRigidActorSleep(_actor);
|
||||
PhysicsBackend::RigidDynamicActorSleep(_actor);
|
||||
}
|
||||
|
||||
void RigidBody::WakeUp() const
|
||||
{
|
||||
if (_actor && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy())
|
||||
PhysicsBackend::GetRigidDynamicActorWakeUp(_actor);
|
||||
PhysicsBackend::RigidDynamicActorWakeUp(_actor);
|
||||
}
|
||||
|
||||
void RigidBody::UpdateMass()
|
||||
@@ -323,6 +325,16 @@ void RigidBody::OnColliderChanged(Collider* c)
|
||||
// WakeUp();
|
||||
}
|
||||
|
||||
void RigidBody::UpdateBounds()
|
||||
{
|
||||
void* actor = GetPhysicsActor();
|
||||
if (actor && PhysicsBackend::GetRigidActorShapesCount(actor) != 0)
|
||||
PhysicsBackend::GetActorBounds(actor, _box);
|
||||
else
|
||||
_box = BoundingBox(_transform.Translation);
|
||||
BoundingSphere::FromBox(_box, _sphere);
|
||||
}
|
||||
|
||||
void RigidBody::UpdateScale()
|
||||
{
|
||||
const Vector3 scale = GetScale();
|
||||
@@ -339,7 +351,7 @@ void RigidBody::UpdateScale()
|
||||
void RigidBody::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::Serialize(stream, otherObj);
|
||||
Actor::Serialize(stream, otherObj);
|
||||
|
||||
SERIALIZE_GET_OTHER_OBJ(RigidBody);
|
||||
|
||||
@@ -364,7 +376,7 @@ void RigidBody::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
void RigidBody::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::Deserialize(stream, modifier);
|
||||
Actor::Deserialize(stream, modifier);
|
||||
|
||||
DESERIALIZE_BIT_MEMBER(OverrideMass, _overrideMass);
|
||||
DESERIALIZE_MEMBER(Mass, _mass);
|
||||
@@ -389,6 +401,26 @@ void* RigidBody::GetPhysicsActor() const
|
||||
return _actor;
|
||||
}
|
||||
|
||||
void RigidBody::OnActiveTransformChanged()
|
||||
{
|
||||
// Change actor transform (but with locking)
|
||||
ASSERT(!_isUpdatingTransform);
|
||||
_isUpdatingTransform = true;
|
||||
Transform transform;
|
||||
PhysicsBackend::GetRigidActorPose(GetPhysicsActor(), transform.Translation, transform.Orientation);
|
||||
transform.Scale = _transform.Scale;
|
||||
if (_parent)
|
||||
{
|
||||
_parent->GetTransform().WorldToLocal(transform, _localTransform);
|
||||
}
|
||||
else
|
||||
{
|
||||
_localTransform = transform;
|
||||
}
|
||||
OnTransformChanged();
|
||||
_isUpdatingTransform = false;
|
||||
}
|
||||
|
||||
void RigidBody::BeginPlay(SceneBeginData* data)
|
||||
{
|
||||
// Create rigid body
|
||||
@@ -441,13 +473,13 @@ void RigidBody::BeginPlay(SceneBeginData* data)
|
||||
UpdateBounds();
|
||||
|
||||
// Base
|
||||
PhysicsActor::BeginPlay(data);
|
||||
Actor::BeginPlay(data);
|
||||
}
|
||||
|
||||
void RigidBody::EndPlay()
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::EndPlay();
|
||||
Actor::EndPlay();
|
||||
|
||||
if (_actor)
|
||||
{
|
||||
@@ -462,7 +494,7 @@ void RigidBody::EndPlay()
|
||||
void RigidBody::OnActiveInTreeChanged()
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::OnActiveInTreeChanged();
|
||||
Actor::OnActiveInTreeChanged();
|
||||
|
||||
if (_actor)
|
||||
{
|
||||
@@ -480,24 +512,19 @@ void RigidBody::OnActiveInTreeChanged()
|
||||
|
||||
void RigidBody::OnTransformChanged()
|
||||
{
|
||||
// Base
|
||||
Actor::OnTransformChanged();
|
||||
|
||||
// Update physics is not during physics state synchronization
|
||||
if (!_isUpdatingTransform && _actor)
|
||||
{
|
||||
// Base (skip PhysicsActor call to optimize)
|
||||
Actor::OnTransformChanged();
|
||||
|
||||
const bool kinematic = GetIsKinematic() && GetEnableSimulation();
|
||||
PhysicsBackend::SetRigidActorPose(_actor, _transform.Translation, _transform.Orientation, kinematic, true);
|
||||
|
||||
UpdateScale();
|
||||
}
|
||||
|
||||
UpdateBounds();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::OnTransformChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void RigidBody::OnPhysicsSceneChanged(PhysicsScene* previous)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PhysicsActor.h"
|
||||
#include "Engine/Level/Actor.h"
|
||||
#include "Engine/Physics/Types.h"
|
||||
#include "Engine/Physics/Actors/IPhysicsActor.h"
|
||||
#include "Engine/Physics/Collisions.h"
|
||||
|
||||
class PhysicsColliderActor;
|
||||
@@ -11,8 +13,8 @@ class Collider;
|
||||
/// <summary>
|
||||
/// Physics simulation driven object.
|
||||
/// </summary>
|
||||
/// <seealso cref="PhysicsActor" />
|
||||
API_CLASS() class FLAXENGINE_API RigidBody : public PhysicsActor
|
||||
/// <seealso cref="Actor" />
|
||||
API_CLASS() class FLAXENGINE_API RigidBody : public Actor, public IPhysicsActor
|
||||
{
|
||||
DECLARE_SCENE_OBJECT(RigidBody);
|
||||
protected:
|
||||
@@ -35,6 +37,7 @@ protected:
|
||||
int32 _startAwake : 1;
|
||||
int32 _updateMassWhenScaleChanges : 1;
|
||||
int32 _overrideMass : 1;
|
||||
int32 _isUpdatingTransform : 1;
|
||||
|
||||
public:
|
||||
|
||||
@@ -537,7 +540,10 @@ public:
|
||||
// Called when collider gets detached from this rigidbody or activated/deactivated. Used to update rigidbody mass.
|
||||
virtual void OnColliderChanged(Collider* c);
|
||||
|
||||
protected:
|
||||
/// <summary>
|
||||
/// Updates the bounding box.
|
||||
/// </summary>
|
||||
void UpdateBounds();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the rigidbody scale dependent properties like mass (may be modified when actor transformation changes).
|
||||
@@ -546,14 +552,17 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
// [PhysicsActor]
|
||||
// [Actor]
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
|
||||
// [IPhysicsActor]
|
||||
void* GetPhysicsActor() const override;
|
||||
void OnActiveTransformChanged() override;
|
||||
|
||||
protected:
|
||||
|
||||
// [PhysicsActor]
|
||||
// [Actor]
|
||||
void BeginPlay(SceneBeginData* data) override;
|
||||
void EndPlay() override;
|
||||
void OnActiveInTreeChanged() override;
|
||||
|
||||
@@ -1607,6 +1607,12 @@ void PhysicsBackend::GetActorBounds(void* actor, BoundingBox& bounds)
|
||||
bounds = P2C(actorPhysX->getWorldBounds(boundsScale));
|
||||
}
|
||||
|
||||
int32 PhysicsBackend::GetRigidActorShapesCount(void* actor)
|
||||
{
|
||||
auto actorPhysX = (PxRigidActor*)actor;
|
||||
return actorPhysX->getNbShapes();
|
||||
}
|
||||
|
||||
void* PhysicsBackend::CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation)
|
||||
{
|
||||
const PxTransform trans(C2P(position), C2P(orientation));
|
||||
@@ -1749,13 +1755,13 @@ bool PhysicsBackend::GetRigidDynamicActorIsSleeping(void* actor)
|
||||
return actorPhysX->isSleeping();
|
||||
}
|
||||
|
||||
void PhysicsBackend::GetRigidActorSleep(void* actor)
|
||||
void PhysicsBackend::RigidDynamicActorSleep(void* actor)
|
||||
{
|
||||
auto actorPhysX = (PxRigidDynamic*)actor;
|
||||
actorPhysX->putToSleep();
|
||||
}
|
||||
|
||||
void PhysicsBackend::GetRigidDynamicActorWakeUp(void* actor)
|
||||
void PhysicsBackend::RigidDynamicActorWakeUp(void* actor)
|
||||
{
|
||||
auto actorPhysX = (PxRigidDynamic*)actor;
|
||||
actorPhysX->wakeUp();
|
||||
|
||||
@@ -131,6 +131,7 @@ public:
|
||||
static ActorFlags GetActorFlags(void* actor);
|
||||
static void SetActorFlags(void* actor, ActorFlags value);
|
||||
static void GetActorBounds(void* actor, BoundingBox& bounds);
|
||||
static int32 GetRigidActorShapesCount(void* actor);
|
||||
static void* CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
||||
static void* CreateRigidStaticActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
||||
static RigidDynamicFlags GetRigidDynamicActorFlags(void* actor);
|
||||
@@ -148,8 +149,8 @@ public:
|
||||
static Vector3 GetRigidDynamicActorCenterOfMass(void* actor);
|
||||
static void SetRigidDynamicActorCenterOfMassOffset(void* actor, const Vector3& value);
|
||||
static bool GetRigidDynamicActorIsSleeping(void* actor);
|
||||
static void GetRigidActorSleep(void* actor);
|
||||
static void GetRigidDynamicActorWakeUp(void* actor);
|
||||
static void RigidDynamicActorSleep(void* actor);
|
||||
static void RigidDynamicActorWakeUp(void* actor);
|
||||
static float GetRigidDynamicActorSleepThreshold(void* actor);
|
||||
static void SetRigidDynamicActorSleepThreshold(void* actor, float value);
|
||||
static float GetRigidDynamicActorMaxDepenetrationVelocity(void* actor);
|
||||
|
||||
@@ -1031,6 +1031,10 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
// In this case, we don't resize yet -- we wait until the user stops dragging, and a WM_EXITSIZEMOVE message comes.
|
||||
UpdateRegion();
|
||||
}
|
||||
else if (_isSwitchingFullScreen)
|
||||
{
|
||||
// Ignored
|
||||
}
|
||||
else
|
||||
{
|
||||
// This WM_SIZE come from resizing the window via an API like SetWindowPos() so resize
|
||||
@@ -1090,6 +1094,12 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
Close(ClosingReason::User);
|
||||
return 0;
|
||||
}
|
||||
if (wParam == VK_RETURN)
|
||||
{
|
||||
LOG(Info, "Alt+Enter pressed");
|
||||
SetIsFullscreen(!IsFullscreen());
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_POWERBROADCAST:
|
||||
switch (wParam)
|
||||
|
||||
@@ -1331,7 +1331,7 @@ void Render2D::DrawText(Font* font, const StringView& text, const Color& color,
|
||||
{
|
||||
// Calculate character size and atlas coordinates
|
||||
const float x = pointer.X + entry.OffsetX * scale;
|
||||
const float y = pointer.Y + (font->GetHeight() + font->GetDescender() - entry.OffsetY) * scale;
|
||||
const float y = pointer.Y - entry.OffsetY * scale + Math::Ceil((font->GetHeight() + font->GetDescender()) * scale);
|
||||
|
||||
Rectangle charRect(x, y, entry.UVSize.X * scale, entry.UVSize.Y * scale);
|
||||
charRect.Offset(layout.Bounds.Location);
|
||||
|
||||
@@ -541,7 +541,7 @@ void RenderInner(SceneRenderTask* task, RenderContext& renderContext)
|
||||
renderContext.List->RunMaterialPostFxPass(context, renderContext, MaterialPostFxLocation::AfterAntiAliasingPass, frameBuffer, tempBuffer);
|
||||
|
||||
// PostFx -> (up-scaling) -> Back Buffer
|
||||
if (Math::IsOne(task->RenderingPercentage))
|
||||
if (task->RenderingPercentage >= 1.0f)
|
||||
{
|
||||
PROFILE_GPU("Copy frame");
|
||||
context->SetRenderTarget(task->GetOutputView());
|
||||
|
||||
@@ -260,7 +260,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
int32 _firstManagedTypeIndex;
|
||||
int32 _firstManagedTypeIndex = 0;
|
||||
Array<void*> _managedMemoryBlocks;
|
||||
|
||||
public:
|
||||
|
||||
@@ -352,6 +352,7 @@ bool MAssembly::LoadWithImage(const String& assemblyPath)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: load pdbs for custom third-party libs referenced by game assemblies for debugging
|
||||
#if 0
|
||||
// Hack to load debug information for Newtonsoft.Json (enable it to debug C# code of json lib)
|
||||
if (assemblyPath.EndsWith(TEXT("FlaxEngine.CSharp.dll")))
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "MCore.h"
|
||||
#include "MDomain.h"
|
||||
#include "MClass.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Engine/Core/Types/DateTime.h"
|
||||
@@ -353,6 +352,9 @@ bool MCore::LoadEngine()
|
||||
PROFILE_CPU();
|
||||
ASSERT(Globals::MonoPath.IsANSI());
|
||||
|
||||
// Debugging Mono GC
|
||||
//Platform::SetEnvironmentVariable(TEXT("MONO_GC_DEBUG"), TEXT("6:gc-log.txt,check-remset-consistency,nursery-canaries"));
|
||||
|
||||
#if 0
|
||||
// Override memory allocation callback
|
||||
// TODO: use ENABLE_OVERRIDABLE_ALLOCATORS when building Mono to support memory callbacks or use counters for memory profiling
|
||||
|
||||
@@ -114,7 +114,7 @@ MonoString* MUtils::ToString(const String& str)
|
||||
MonoString* MUtils::ToString(const String& str, MonoDomain* domain)
|
||||
{
|
||||
if (str.IsEmpty())
|
||||
return mono_string_empty(mono_domain_get());
|
||||
return mono_string_empty(domain);
|
||||
return mono_string_new_utf16(domain, (const mono_unichar2*)*str, str.Length());
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "ManagedCLR/MMethod.h"
|
||||
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
|
||||
|
||||
void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, MonoObject* object)
|
||||
void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, MObject* object)
|
||||
{
|
||||
if (!object)
|
||||
{
|
||||
@@ -47,7 +47,7 @@ void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, Mon
|
||||
mono_free(invokeResultChars);
|
||||
}
|
||||
|
||||
void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream, MonoObject* object, MonoObject* other)
|
||||
void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream, MObject* object, MObject* other)
|
||||
{
|
||||
if (!object || !other)
|
||||
{
|
||||
@@ -85,7 +85,7 @@ void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream,
|
||||
mono_free(invokeResultChars);
|
||||
}
|
||||
|
||||
void ManagedSerialization::Deserialize(ISerializable::DeserializeStream& stream, MonoObject* object)
|
||||
void ManagedSerialization::Deserialize(ISerializable::DeserializeStream& stream, MObject* object)
|
||||
{
|
||||
if (!object)
|
||||
return;
|
||||
@@ -98,7 +98,7 @@ void ManagedSerialization::Deserialize(ISerializable::DeserializeStream& stream,
|
||||
Deserialize(StringAnsiView(buffer.GetString(), (int32)buffer.GetSize()), object);
|
||||
}
|
||||
|
||||
void ManagedSerialization::Deserialize(const StringAnsiView& data, MonoObject* object)
|
||||
void ManagedSerialization::Deserialize(const StringAnsiView& data, MObject* object)
|
||||
{
|
||||
const char* str = data.Get();
|
||||
const int32 len = data.Length();
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="stream">The output stream.</param>
|
||||
/// <param name="object">The object to serialize.</param>
|
||||
static void Serialize(ISerializable::SerializeStream& stream, MonoObject* object);
|
||||
static void Serialize(ISerializable::SerializeStream& stream, MObject* object);
|
||||
|
||||
/// <summary>
|
||||
/// Serializes managed object difference to JSON.
|
||||
@@ -26,20 +26,20 @@ public:
|
||||
/// <param name="stream">The output stream.</param>
|
||||
/// <param name="object">The object to serialize.</param>
|
||||
/// <param name="other">The reference object to serialize diff compared to it.</param>
|
||||
static void SerializeDiff(ISerializable::SerializeStream& stream, MonoObject* object, MonoObject* other);
|
||||
static void SerializeDiff(ISerializable::SerializeStream& stream, MObject* object, MObject* other);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes managed object from the JSON.
|
||||
/// </summary>
|
||||
/// <param name="stream">The input stream.</param>
|
||||
/// <param name="object">The object to deserialize.</param>
|
||||
static void Deserialize(ISerializable::DeserializeStream& stream, MonoObject* object);
|
||||
static void Deserialize(ISerializable::DeserializeStream& stream, MObject* object);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes managed object from the JSON.
|
||||
/// </summary>
|
||||
/// <param name="data">The input data.</param>
|
||||
/// <param name="object">The object to deserialize.</param>
|
||||
static void Deserialize(const StringAnsiView& data, MonoObject* object);
|
||||
static void Deserialize(const StringAnsiView& data, MObject* object);
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace FlaxEngine
|
||||
{
|
||||
Internal_ManagedInstanceCreated(this);
|
||||
if (__unmanagedPtr == IntPtr.Zero)
|
||||
throw new FlaxException($"Failed to create native instance for object of type {GetType().FullName} (assembly: {GetType().Assembly.FullName}).");
|
||||
throw new Exception($"Failed to create native instance for object of type {GetType().FullName} (assembly: {GetType().Assembly.FullName}).");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,8 +170,12 @@ namespace FlaxEngine
|
||||
private static void OnLocalizationChanged()
|
||||
{
|
||||
var currentThread = Thread.CurrentThread;
|
||||
currentThread.CurrentUICulture = Localization.CurrentLanguage;
|
||||
currentThread.CurrentCulture = Localization.CurrentCulture;
|
||||
var language = Localization.CurrentLanguage;
|
||||
if (language != null)
|
||||
currentThread.CurrentUICulture = language;
|
||||
var culture = Localization.CurrentCulture;
|
||||
if (culture != null)
|
||||
currentThread.CurrentCulture = culture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -188,7 +188,7 @@ namespace FlaxEngine.Json
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.TokenType != JsonToken.Comment)
|
||||
throw new FlaxException("Additional text found in JSON string after finishing deserializing object.");
|
||||
throw new Exception("Additional text found in JSON string after finishing deserializing object.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +226,7 @@ namespace FlaxEngine.Json
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.TokenType != JsonToken.Comment)
|
||||
throw new FlaxException("Additional text found in JSON string after finishing deserializing object.");
|
||||
throw new Exception("Additional text found in JSON string after finishing deserializing object.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace FlaxEngine.Json
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.TokenType != JsonToken.Comment)
|
||||
throw new FlaxException("Additional text found in JSON string after finishing deserializing object.");
|
||||
throw new Exception("Additional text found in JSON string after finishing deserializing object.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ namespace FlaxEngine.Json
|
||||
while (jsonReader.Read())
|
||||
{
|
||||
if (jsonReader.TokenType != JsonToken.Comment)
|
||||
throw new FlaxException("Additional text found in JSON string after finishing deserializing object.");
|
||||
throw new Exception("Additional text found in JSON string after finishing deserializing object.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -357,6 +357,14 @@ namespace FlaxEngine
|
||||
return new Matrix(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle());
|
||||
}
|
||||
|
||||
internal static byte[] ReadJsonBytes(this BinaryReader stream)
|
||||
{
|
||||
// ReadStream::ReadJson
|
||||
var engineBuild = stream.ReadInt32();
|
||||
var size = stream.ReadInt32();
|
||||
return stream.ReadBytes(size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes object from Json by reading it as a raw data (ver+length+bytes).
|
||||
/// </summary>
|
||||
@@ -569,6 +577,19 @@ namespace FlaxEngine
|
||||
stream.Write(value.M44);
|
||||
}
|
||||
|
||||
internal static void WriteJsonBytes(this BinaryWriter stream, byte[] bytes)
|
||||
{
|
||||
// WriteStream::WriteJson
|
||||
stream.Write(Globals.EngineBuildNumber);
|
||||
if (bytes != null)
|
||||
{
|
||||
stream.Write(bytes.Length);
|
||||
stream.Write(bytes);
|
||||
}
|
||||
else
|
||||
stream.Write(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes object to Json and writes it as a raw data (ver+length+bytes).
|
||||
/// </summary>
|
||||
|
||||
@@ -156,6 +156,10 @@ void ShaderGenerator::ProcessGroupMath(Box* box, Node* node, Value& value)
|
||||
Box* b2 = node->GetBox(1);
|
||||
Value v1 = tryGetValue(b1, 0, Value::Zero);
|
||||
Value v2 = tryGetValue(b2, 1, Value::Zero);
|
||||
if (b1->HasConnection())
|
||||
v2 = v2.Cast(v1.Type);
|
||||
else
|
||||
v1 = v1.Cast(v2.Type);
|
||||
Char op = '?';
|
||||
switch (node->TypeID)
|
||||
{
|
||||
|
||||
@@ -154,8 +154,13 @@ void VisjectExecutor::ProcessGroupMath(Box* box, Node* node, Value& value)
|
||||
case 40:
|
||||
case 41:
|
||||
{
|
||||
Value v1 = tryGetValue(node->GetBox(0), 0, Value::Zero);
|
||||
Value v2 = tryGetValue(node->GetBox(1), 1, Value::Zero).Cast(v1.Type);
|
||||
auto b1 = node->GetBox(0);
|
||||
Value v1 = tryGetValue(b1, 0, Value::Zero);
|
||||
Value v2 = tryGetValue(node->GetBox(1), 1, Value::Zero);
|
||||
if (b1->HasConnection())
|
||||
v2 = v2.Cast(v1.Type);
|
||||
else
|
||||
v1 = v1.Cast(v2.Type);
|
||||
GraphUtilities::ApplySomeMathHere(node->TypeID, value, v1, v2);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace Flax.Build
|
||||
|
||||
// Prefer installed Roslyn C# compiler over Mono one
|
||||
monoPath = null;
|
||||
cscPath = Path.Combine(Path.GetDirectoryName(Deploy.VCEnvironment.MSBuildPath), "Roslyn", "csc.exe");
|
||||
cscPath = Path.Combine(Path.GetDirectoryName(VCEnvironment.MSBuildPath), "Roslyn", "csc.exe");
|
||||
|
||||
if (!File.Exists(cscPath))
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2020 Flax Engine. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Flax.Build;
|
||||
@@ -219,7 +220,8 @@ namespace Flax.Deploy
|
||||
/// <param name="solutionFile">Path to the solution file</param>
|
||||
/// <param name="buildConfig">Configuration to build.</param>
|
||||
/// <param name="buildPlatform">Platform to build.</param>
|
||||
public static void BuildSolution(string solutionFile, string buildConfig, string buildPlatform)
|
||||
/// <param name="props">Custom build properties mapping (property=value).</param>
|
||||
public static void BuildSolution(string solutionFile, string buildConfig, string buildPlatform, Dictionary<string, string> props = null)
|
||||
{
|
||||
var msBuild = MSBuildPath;
|
||||
if (string.IsNullOrEmpty(msBuild))
|
||||
@@ -233,6 +235,11 @@ namespace Flax.Deploy
|
||||
}
|
||||
|
||||
string cmdLine = string.Format("\"{0}\" /m /t:Build /p:Configuration=\"{1}\" /p:Platform=\"{2}\" {3} /nologo", solutionFile, buildConfig, buildPlatform, Verbosity);
|
||||
if (props != null)
|
||||
{
|
||||
foreach (var e in props)
|
||||
cmdLine += string.Format(" /p:{0}={1}", e.Key, e.Value);
|
||||
}
|
||||
int result = Utilities.Run(msBuild, cmdLine);
|
||||
if (result != 0)
|
||||
{
|
||||
|
||||
@@ -99,6 +99,18 @@ namespace Flax.Deps
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clones the directory.
|
||||
/// </summary>
|
||||
/// <param name="src">The source folder path.</param>
|
||||
/// <param name="dst">The destination folder path.</param>
|
||||
public static void CloneDirectory(string src, string dst)
|
||||
{
|
||||
if (Directory.Exists(dst))
|
||||
Utilities.DirectoryDelete(dst);
|
||||
Utilities.DirectoryCopy(src, dst);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clones the git repository from the remote url (full repository).
|
||||
/// </summary>
|
||||
@@ -275,30 +287,76 @@ namespace Flax.Deps
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <param name="workspace">The workspace folder.</param>
|
||||
/// <param name="envVars">Custom environment variables to pass to the child process.</param>
|
||||
public static void RunCygwin(string path, string workspace = null, Dictionary<string, string> envVars = null)
|
||||
public static void RunCygwin(string path, string workspace = null)
|
||||
{
|
||||
RunBash(path, string.Empty, workspace);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the bash script (executes natively on Unix platforms, uses Cygwin on Windows).
|
||||
/// </summary>
|
||||
/// <param name="path">The script or command path.</param>
|
||||
/// <param name="args">The arguments.</param>
|
||||
/// <param name="workspace">The workspace folder.</param>
|
||||
/// <param name="envVars">Custom environment variables to pass to the child process.</param>
|
||||
public static void RunBash(string path, string args = null, string workspace = null, Dictionary<string, string> envVars = null)
|
||||
{
|
||||
string app;
|
||||
switch (BuildPlatform)
|
||||
{
|
||||
case TargetPlatform.Windows:
|
||||
{
|
||||
// Find Cygwin
|
||||
var cygwinFolder = Environment.GetEnvironmentVariable("CYGWIN");
|
||||
if (string.IsNullOrEmpty(cygwinFolder) || !Directory.Exists(cygwinFolder))
|
||||
{
|
||||
cygwinFolder = "C:\\cygwin";
|
||||
if (!Directory.Exists(cygwinFolder))
|
||||
{
|
||||
cygwinFolder = "C:\\cygwin64";
|
||||
if (!Directory.Exists(cygwinFolder))
|
||||
throw new Exception("Missing Cygwin. Install Cygwin64 to C:\\cygwin or set CYGWIN env variable to install location folder.");
|
||||
}
|
||||
app = Path.Combine(cygwinFolder, "bin\\bash.exe");
|
||||
}
|
||||
var cygwinBinFolder = Path.Combine(cygwinFolder, "bin");
|
||||
|
||||
// Ensure that Cygwin binaries folder is in a PATH
|
||||
string envPath = null;
|
||||
envVars?.TryGetValue("PATH", out envPath);
|
||||
if (envPath == null || envPath.IndexOf(cygwinBinFolder, StringComparison.OrdinalIgnoreCase) == -1)
|
||||
{
|
||||
if (envVars == null)
|
||||
envVars = new Dictionary<string, string>();
|
||||
envVars["PATH"] = cygwinBinFolder;
|
||||
if (envPath != null)
|
||||
envVars["PATH"] += ";" + envPath;
|
||||
}
|
||||
|
||||
// Get the executable file path
|
||||
if (path.EndsWith(".sh", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Bash script
|
||||
if (args == null)
|
||||
args = path.Replace('\\', '/');
|
||||
else
|
||||
args = path.Replace('\\', '/') + " " + args;
|
||||
path = Path.Combine(cygwinBinFolder, "bash.exe");
|
||||
}
|
||||
else if (File.Exists(Path.Combine(cygwinBinFolder, path + ".exe")))
|
||||
{
|
||||
// Tool (eg. make)
|
||||
path = Path.Combine(cygwinBinFolder, path + ".exe");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Cannot execute command " + path + " with args " + args);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TargetPlatform.Linux:
|
||||
app = "bash";
|
||||
break;
|
||||
case TargetPlatform.Mac: break;
|
||||
default: throw new InvalidPlatformException(BuildPlatform);
|
||||
}
|
||||
Utilities.Run(app, path, null, workspace, Utilities.RunOptions.None, envVars);
|
||||
Utilities.Run(path, args, null, workspace, Utilities.RunOptions.ThrowExceptionOnError, envVars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,6 +244,26 @@ namespace Flax.Build
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the directories inside a directory.
|
||||
/// </summary>
|
||||
/// <param name="directoryPath">The directory path.</param>
|
||||
/// <param name="searchPattern">The custom filter for the directories to delete. Can be used to select files to delete. Null if unused.</param>
|
||||
/// <param name="withSubdirs">if set to <c>true</c> with sub-directories (recursive delete operation).</param>
|
||||
public static void DirectoriesDelete(string directoryPath, string searchPattern = null, bool withSubdirs = true)
|
||||
{
|
||||
if (!Directory.Exists(directoryPath))
|
||||
return;
|
||||
if (searchPattern == null)
|
||||
searchPattern = "*";
|
||||
|
||||
var directories = Directory.GetDirectories(directoryPath, searchPattern, withSubdirs ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
|
||||
for (int i = 0; i < directories.Length; i++)
|
||||
{
|
||||
DirectoryDelete(directories[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The process run options.
|
||||
/// </summary>
|
||||
@@ -355,14 +375,14 @@ namespace Flax.Build
|
||||
Stopwatch stopwatch = Stopwatch.StartNew();
|
||||
if (!options.HasFlag(RunOptions.NoLoggingOfRunCommand))
|
||||
{
|
||||
Log.Verbose("Running: " + app + " " + (string.IsNullOrEmpty(commandLine) ? "" : commandLine));
|
||||
Log.Verbose("Running: " + app + (string.IsNullOrEmpty(commandLine) ? "" : " " + commandLine));
|
||||
}
|
||||
|
||||
bool redirectStdOut = (options & RunOptions.NoStdOutRedirect) != RunOptions.NoStdOutRedirect;
|
||||
|
||||
Process proc = new Process();
|
||||
proc.StartInfo.FileName = app;
|
||||
proc.StartInfo.Arguments = string.IsNullOrEmpty(commandLine) ? "" : commandLine;
|
||||
proc.StartInfo.Arguments = commandLine != null ? commandLine : "";
|
||||
proc.StartInfo.UseShellExecute = false;
|
||||
proc.StartInfo.RedirectStandardInput = input != null;
|
||||
proc.StartInfo.CreateNoWindow = true;
|
||||
@@ -386,7 +406,7 @@ namespace Flax.Build
|
||||
{
|
||||
if (env.Key == "PATH")
|
||||
{
|
||||
proc.StartInfo.EnvironmentVariables[env.Key] = proc.StartInfo.EnvironmentVariables[env.Key] + ';' + env.Value;
|
||||
proc.StartInfo.EnvironmentVariables[env.Key] = env.Value + ';' + proc.StartInfo.EnvironmentVariables[env.Key];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user