Merge branch '1.9' of https://gitlab.flaxengine.com/flax/flaxengine into 1.9
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
"Major": 1,
|
"Major": 1,
|
||||||
"Minor": 9,
|
"Minor": 9,
|
||||||
"Revision": 0,
|
"Revision": 0,
|
||||||
"Build": 6603
|
"Build": 6604
|
||||||
},
|
},
|
||||||
"Company": "Flax",
|
"Company": "Flax",
|
||||||
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
|
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy fresh Gradle project template
|
// Copy fresh Gradle project template
|
||||||
if (FileSystem::CopyDirectory(data.OriginalOutputPath, platformDataPath / TEXT("Project"), true))
|
if (FileSystem::CopyDirectory(data.OriginalOutputPath, platformDataPath / TEXT("Project")))
|
||||||
{
|
{
|
||||||
LOG(Error, "Failed to deploy Gradle project to {0} from {1}", data.OriginalOutputPath, platformDataPath);
|
LOG(Error, "Failed to deploy Gradle project to {0} from {1}", data.OriginalOutputPath, platformDataPath);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ bool UWPPlatformTools::OnDeployBinaries(CookingData& data)
|
|||||||
const auto srcAssetsPath = uwpDataPath / TEXT("Assets");
|
const auto srcAssetsPath = uwpDataPath / TEXT("Assets");
|
||||||
if (!FileSystem::DirectoryExists(dstAssetsPath))
|
if (!FileSystem::DirectoryExists(dstAssetsPath))
|
||||||
{
|
{
|
||||||
if (FileSystem::CopyDirectory(dstAssetsPath, srcAssetsPath, true))
|
if (FileSystem::CopyDirectory(dstAssetsPath, srcAssetsPath))
|
||||||
{
|
{
|
||||||
data.Error(TEXT("Failed to copy Assets directory."));
|
data.Error(TEXT("Failed to copy Assets directory."));
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ bool iOSPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Copy fresh XCode project template
|
// Copy fresh XCode project template
|
||||||
if (FileSystem::CopyDirectory(data.OriginalOutputPath, platformDataPath / TEXT("Project"), true))
|
if (FileSystem::CopyDirectory(data.OriginalOutputPath, platformDataPath / TEXT("Project")))
|
||||||
{
|
{
|
||||||
LOG(Error, "Failed to deploy XCode project to {0} from {1}", data.OriginalOutputPath, platformDataPath);
|
LOG(Error, "Failed to deploy XCode project to {0} from {1}", data.OriginalOutputPath, platformDataPath);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -156,12 +156,12 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
FileSystem::CopyFile(dstDotnet / TEXT("THIRD-PARTY-NOTICES.TXT"), srcDotnet / TEXT("THIRD-PARTY-NOTICES.TXT"));
|
FileSystem::CopyFile(dstDotnet / TEXT("THIRD-PARTY-NOTICES.TXT"), srcDotnet / TEXT("THIRD-PARTY-NOTICES.TXT"));
|
||||||
if (usAOT)
|
if (usAOT)
|
||||||
{
|
{
|
||||||
failed |= EditorUtilities::CopyDirectoryIfNewer(dstDotnet, srcDotnet / TEXT("shared/Microsoft.NETCore.App") / version, true);
|
failed |= EditorUtilities::CopyDirectoryIfNewer(dstDotnet, srcDotnet / TEXT("shared/Microsoft.NETCore.App") / version);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
failed |= EditorUtilities::CopyDirectoryIfNewer(dstDotnet / TEXT("host/fxr") / version, srcDotnet / TEXT("host/fxr") / version, true);
|
failed |= EditorUtilities::CopyDirectoryIfNewer(dstDotnet / TEXT("host/fxr") / version, srcDotnet / TEXT("host/fxr") / version);
|
||||||
#else
|
#else
|
||||||
// TODO: hostfxr for target platform should be copied from nuget package location: microsoft.netcore.app.runtime.<RID>/<VERSION>/runtimes/<RID>/native/hostfxr.dll
|
// TODO: hostfxr for target platform should be copied from nuget package location: microsoft.netcore.app.runtime.<RID>/<VERSION>/runtimes/<RID>/native/hostfxr.dll
|
||||||
String dstHostfxr = dstDotnet / TEXT("host/fxr") / version;
|
String dstHostfxr = dstDotnet / TEXT("host/fxr") / version;
|
||||||
@@ -330,7 +330,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
data.Error(TEXT("Missing Mono runtime data files."));
|
data.Error(TEXT("Missing Mono runtime data files."));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (FileSystem::CopyDirectory(dstMono, srcMono, true))
|
if (FileSystem::CopyDirectory(dstMono, srcMono))
|
||||||
{
|
{
|
||||||
data.Error(TEXT("Failed to copy Mono runtime data files."));
|
data.Error(TEXT("Failed to copy Mono runtime data files."));
|
||||||
return true;
|
return true;
|
||||||
@@ -416,7 +416,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
for (auto& e : buildSettings.AdditionalAssetFolders)
|
for (auto& e : buildSettings.AdditionalAssetFolders)
|
||||||
{
|
{
|
||||||
String path = FileSystem::ConvertRelativePathToAbsolute(Globals::ProjectFolder, e);
|
String path = FileSystem::ConvertRelativePathToAbsolute(Globals::ProjectFolder, e);
|
||||||
if (FileSystem::DirectoryGetFiles(files, path, TEXT("*"), DirectorySearchOption::AllDirectories))
|
if (FileSystem::DirectoryGetFiles(files, path))
|
||||||
{
|
{
|
||||||
data.Error(TEXT("Failed to find additional assets to deploy."));
|
data.Error(TEXT("Failed to find additional assets to deploy."));
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -296,6 +296,16 @@ namespace FlaxEditor.CustomEditors
|
|||||||
_values.Set(_parent.Values, value);
|
_values.Set(_parent.Values, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool SyncParent()
|
||||||
|
{
|
||||||
|
// TODO: add attribute for types that want to sync their contents with a parent
|
||||||
|
var type = Values.Type.Type;
|
||||||
|
if (type == typeof(LocalizedString) ||
|
||||||
|
type == typeof(FontReference))
|
||||||
|
return true;
|
||||||
|
return _parent != null && !(_parent is SyncPointEditor);
|
||||||
|
}
|
||||||
|
|
||||||
internal virtual void RefreshInternal()
|
internal virtual void RefreshInternal()
|
||||||
{
|
{
|
||||||
if (_values == null)
|
if (_values == null)
|
||||||
@@ -317,7 +327,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
|
|
||||||
// Propagate values up (eg. when member of structure gets modified, also structure should be updated as a part of the other object)
|
// Propagate values up (eg. when member of structure gets modified, also structure should be updated as a part of the other object)
|
||||||
var obj = _parent;
|
var obj = _parent;
|
||||||
while (obj._parent != null && !(obj._parent is SyncPointEditor))
|
while (obj.SyncParent())
|
||||||
{
|
{
|
||||||
obj.Values.Set(obj._parent.Values, obj.Values);
|
obj.Values.Set(obj._parent.Values, obj.Values);
|
||||||
obj = obj._parent;
|
obj = obj._parent;
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ namespace FlaxEditor.CustomEditors
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
FlaxEditor.Editor.LogWarning(ex);
|
FlaxEditor.Editor.LogWarning(ex);
|
||||||
|
|
||||||
|
// Refresh layout on errors to reduce lgo spam
|
||||||
|
_presenter.BuildLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Update(deltaTime);
|
base.Update(deltaTime);
|
||||||
@@ -397,6 +400,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
Panel.DisposeChildren();
|
Panel.DisposeChildren();
|
||||||
|
|
||||||
ClearLayout();
|
ClearLayout();
|
||||||
|
_buildOnUpdate = false;
|
||||||
Editor.Setup(this);
|
Editor.Setup(this);
|
||||||
|
|
||||||
Panel.IsLayoutLocked = false;
|
Panel.IsLayoutLocked = false;
|
||||||
@@ -484,7 +488,6 @@ namespace FlaxEditor.CustomEditors
|
|||||||
{
|
{
|
||||||
if (_buildOnUpdate)
|
if (_buildOnUpdate)
|
||||||
{
|
{
|
||||||
_buildOnUpdate = false;
|
|
||||||
BuildLayout();
|
BuildLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ namespace FlaxEditor.CustomEditors
|
|||||||
return new GenericEditor();
|
return new GenericEditor();
|
||||||
if (targetType.IsArray)
|
if (targetType.IsArray)
|
||||||
{
|
{
|
||||||
|
if (targetType.Type == null)
|
||||||
|
return new ArrayEditor();
|
||||||
if (targetType.Type.GetArrayRank() != 1)
|
if (targetType.Type.GetArrayRank() != 1)
|
||||||
return new GenericEditor(); // Not-supported multidimensional array
|
return new GenericEditor(); // Not-supported multidimensional array
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using FlaxEditor.CustomEditors.Editors;
|
|||||||
using FlaxEditor.CustomEditors.Elements;
|
using FlaxEditor.CustomEditors.Elements;
|
||||||
using FlaxEditor.GUI;
|
using FlaxEditor.GUI;
|
||||||
using FlaxEditor.GUI.ContextMenu;
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
|
using FlaxEditor.GUI.Input;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
@@ -634,26 +635,29 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
LayoutElementsContainer vEl;
|
LayoutElementsContainer vEl;
|
||||||
Color axisColorX = ActorTransformEditor.AxisColorX;
|
Color axisColorX = ActorTransformEditor.AxisColorX;
|
||||||
Color axisColorY = ActorTransformEditor.AxisColorY;
|
Color axisColorY = ActorTransformEditor.AxisColorY;
|
||||||
|
FloatValueBox xV, yV, wV, hV;
|
||||||
if (xEq)
|
if (xEq)
|
||||||
{
|
{
|
||||||
xEl = UniformPanelCapsuleForObjectWithText(horUp, "X: ", xItem.GetValues(Values), axisColorX);
|
xEl = UniformPanelCapsuleForObjectWithText(horUp, "X: ", xItem.GetValues(Values), axisColorX, out xV);
|
||||||
vEl = UniformPanelCapsuleForObjectWithText(horDown, "Width: ", widthItem.GetValues(Values), axisColorX);
|
vEl = UniformPanelCapsuleForObjectWithText(horDown, "Width: ", widthItem.GetValues(Values), axisColorX, out wV);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xEl = UniformPanelCapsuleForObjectWithText(horUp, "Left: ", leftItem.GetValues(Values), axisColorX);
|
xEl = UniformPanelCapsuleForObjectWithText(horUp, "Left: ", leftItem.GetValues(Values), axisColorX, out xV);
|
||||||
vEl = UniformPanelCapsuleForObjectWithText(horDown, "Right: ", rightItem.GetValues(Values), axisColorX);
|
vEl = UniformPanelCapsuleForObjectWithText(horDown, "Right: ", rightItem.GetValues(Values), axisColorX, out wV);
|
||||||
}
|
}
|
||||||
if (yEq)
|
if (yEq)
|
||||||
{
|
{
|
||||||
yEl = UniformPanelCapsuleForObjectWithText(horUp, "Y: ", yItem.GetValues(Values), axisColorY);
|
yEl = UniformPanelCapsuleForObjectWithText(horUp, "Y: ", yItem.GetValues(Values), axisColorY, out yV);
|
||||||
hEl = UniformPanelCapsuleForObjectWithText(horDown, "Height: ", heightItem.GetValues(Values), axisColorY);
|
hEl = UniformPanelCapsuleForObjectWithText(horDown, "Height: ", heightItem.GetValues(Values), axisColorY, out hV);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
yEl = UniformPanelCapsuleForObjectWithText(horUp, "Top: ", topItem.GetValues(Values), axisColorY);
|
yEl = UniformPanelCapsuleForObjectWithText(horUp, "Top: ", topItem.GetValues(Values), axisColorY, out yV);
|
||||||
hEl = UniformPanelCapsuleForObjectWithText(horDown, "Bottom: ", bottomItem.GetValues(Values), axisColorY);
|
hEl = UniformPanelCapsuleForObjectWithText(horDown, "Bottom: ", bottomItem.GetValues(Values), axisColorY, out hV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Anchors
|
||||||
xEl.Control.AnchorMin = new Float2(0, xEl.Control.AnchorMin.Y);
|
xEl.Control.AnchorMin = new Float2(0, xEl.Control.AnchorMin.Y);
|
||||||
xEl.Control.AnchorMax = new Float2(0.5f, xEl.Control.AnchorMax.Y);
|
xEl.Control.AnchorMax = new Float2(0.5f, xEl.Control.AnchorMax.Y);
|
||||||
|
|
||||||
@@ -665,6 +669,15 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
|
|
||||||
hEl.Control.AnchorMin = new Float2(0.5f, xEl.Control.AnchorMin.Y);
|
hEl.Control.AnchorMin = new Float2(0.5f, xEl.Control.AnchorMin.Y);
|
||||||
hEl.Control.AnchorMax = new Float2(1, xEl.Control.AnchorMax.Y);
|
hEl.Control.AnchorMax = new Float2(1, xEl.Control.AnchorMax.Y);
|
||||||
|
|
||||||
|
// Navigation path
|
||||||
|
xV.NavTargetRight = yV;
|
||||||
|
yV.NavTargetRight = wV;
|
||||||
|
wV.NavTargetRight = hV;
|
||||||
|
|
||||||
|
yV.NavTargetLeft = xV;
|
||||||
|
wV.NavTargetLeft = yV;
|
||||||
|
hV.NavTargetLeft = wV;
|
||||||
}
|
}
|
||||||
|
|
||||||
private VerticalPanelElement VerticalPanelWithoutMargin(LayoutElementsContainer cont)
|
private VerticalPanelElement VerticalPanelWithoutMargin(LayoutElementsContainer cont)
|
||||||
@@ -684,17 +697,19 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CustomElementsContainer<UniformGridPanel> UniformPanelCapsuleForObjectWithText(LayoutElementsContainer el, string text, ValueContainer values, Color borderColor)
|
private CustomElementsContainer<UniformGridPanel> UniformPanelCapsuleForObjectWithText(LayoutElementsContainer el, string text, ValueContainer values, Color borderColor, out FloatValueBox valueBox)
|
||||||
{
|
{
|
||||||
|
valueBox = null;
|
||||||
var grid = UniformGridTwoByOne(el);
|
var grid = UniformGridTwoByOne(el);
|
||||||
grid.CustomControl.SlotPadding = new Margin(5, 5, 1, 1);
|
grid.CustomControl.SlotPadding = new Margin(5, 5, 1, 1);
|
||||||
var label = grid.Label(text, TextAlignment.Far);
|
var label = grid.Label(text, TextAlignment.Far);
|
||||||
var editor = grid.Object(values);
|
var editor = grid.Object(values);
|
||||||
if (editor is FloatEditor floatEditor && floatEditor.Element is FloatValueElement floatEditorElement)
|
if (editor is FloatEditor floatEditor && floatEditor.Element is FloatValueElement floatEditorElement)
|
||||||
{
|
{
|
||||||
|
valueBox = floatEditorElement.ValueBox;
|
||||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||||
floatEditorElement.ValueBox.BorderColor = Color.Lerp(borderColor, back, ActorTransformEditor.AxisGreyOutFactor);
|
valueBox.BorderColor = Color.Lerp(borderColor, back, ActorTransformEditor.AxisGreyOutFactor);
|
||||||
floatEditorElement.ValueBox.BorderSelectedColor = borderColor;
|
valueBox.BorderSelectedColor = borderColor;
|
||||||
}
|
}
|
||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var isSliding = XElement.IsSliding || YElement.IsSliding;
|
var isSliding = XElement.IsSliding || YElement.IsSliding;
|
||||||
@@ -158,7 +158,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var isSliding = XElement.IsSliding || YElement.IsSliding;
|
var isSliding = XElement.IsSliding || YElement.IsSliding;
|
||||||
@@ -247,7 +247,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var isSliding = XElement.IsSliding || YElement.IsSliding;
|
var isSliding = XElement.IsSliding || YElement.IsSliding;
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var xValue = XElement.ValueBox.Value;
|
var xValue = XElement.ValueBox.Value;
|
||||||
@@ -318,7 +318,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding;
|
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding;
|
||||||
@@ -418,7 +418,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding;
|
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding || WElement.IsSliding;
|
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding || WElement.IsSliding;
|
||||||
@@ -200,7 +200,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding || WElement.IsSliding;
|
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding || WElement.IsSliding;
|
||||||
@@ -311,7 +311,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private void OnValueChanged()
|
private void OnValueChanged()
|
||||||
{
|
{
|
||||||
if (IsSetBlocked)
|
if (IsSetBlocked || Values == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding || WElement.IsSliding;
|
var isSliding = XElement.IsSliding || YElement.IsSliding || ZElement.IsSliding || WElement.IsSliding;
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ bool Editor::CheckProjectUpgrade()
|
|||||||
FileSystem::DeleteDirectory(tempSourceSetup);
|
FileSystem::DeleteDirectory(tempSourceSetup);
|
||||||
FileSystem::CreateDirectory(tempSourceSetup);
|
FileSystem::CreateDirectory(tempSourceSetup);
|
||||||
Array<String> files;
|
Array<String> files;
|
||||||
FileSystem::DirectoryGetFiles(files, sourceFolder, TEXT("*"), DirectorySearchOption::AllDirectories);
|
FileSystem::DirectoryGetFiles(files, sourceFolder);
|
||||||
bool useEditorModule = false;
|
bool useEditorModule = false;
|
||||||
for (auto& file : files)
|
for (auto& file : files)
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ bool Editor::CheckProjectUpgrade()
|
|||||||
FileSystem::CopyFile(tempSourceFile, file);
|
FileSystem::CopyFile(tempSourceFile, file);
|
||||||
}
|
}
|
||||||
FileSystem::DeleteDirectory(sourceFolder);
|
FileSystem::DeleteDirectory(sourceFolder);
|
||||||
FileSystem::CopyDirectory(sourceFolder, tempSourceSetup, true);
|
FileSystem::CopyDirectory(sourceFolder, tempSourceSetup);
|
||||||
FileSystem::DeleteDirectory(tempSourceSetup);
|
FileSystem::DeleteDirectory(tempSourceSetup);
|
||||||
|
|
||||||
// Generate module files
|
// Generate module files
|
||||||
@@ -364,7 +364,7 @@ bool Editor::BackupProject()
|
|||||||
LOG(Info, "Backup project to \"{0}\"", dstPath);
|
LOG(Info, "Backup project to \"{0}\"", dstPath);
|
||||||
|
|
||||||
// Copy everything
|
// Copy everything
|
||||||
return FileSystem::CopyDirectory(dstPath, Globals::ProjectFolder, true);
|
return FileSystem::CopyDirectory(dstPath, Globals::ProjectFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 Editor::LoadProduct()
|
int32 Editor::LoadProduct()
|
||||||
|
|||||||
@@ -218,6 +218,13 @@ namespace FlaxEditor.GUI
|
|||||||
Render2D.FillRectangle(bounds, style.Selection);
|
Render2D.FillRectangle(bounds, style.Selection);
|
||||||
Render2D.DrawRectangle(bounds, style.SelectionBorder);
|
Render2D.DrawRectangle(bounds, style.SelectionBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Navigation focus highlight
|
||||||
|
if (IsNavFocused)
|
||||||
|
{
|
||||||
|
var bounds = new Rectangle(Float2.Zero, Size);
|
||||||
|
Render2D.DrawRectangle(bounds, style.BackgroundSelected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -286,35 +293,7 @@ namespace FlaxEditor.GUI
|
|||||||
else if (Button1Rect.Contains(location))
|
else if (Button1Rect.Contains(location))
|
||||||
{
|
{
|
||||||
Focus();
|
Focus();
|
||||||
if (Validator.AssetType != ScriptType.Null)
|
OnSubmit();
|
||||||
{
|
|
||||||
// Show asset picker popup
|
|
||||||
var popup = AssetSearchPopup.Show(this, Button1Rect.BottomLeft, Validator.IsValid, item =>
|
|
||||||
{
|
|
||||||
Validator.SelectedItem = item;
|
|
||||||
RootWindow.Focus();
|
|
||||||
Focus();
|
|
||||||
});
|
|
||||||
if (Validator.SelectedAsset != null)
|
|
||||||
{
|
|
||||||
var selectedAssetName = Path.GetFileNameWithoutExtension(Validator.SelectedAsset.Path);
|
|
||||||
popup.ScrollToAndHighlightItemByName(selectedAssetName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Show content item picker popup
|
|
||||||
var popup = ContentSearchPopup.Show(this, Button1Rect.BottomLeft, Validator.IsValid, item =>
|
|
||||||
{
|
|
||||||
Validator.SelectedItem = item;
|
|
||||||
RootWindow.Focus();
|
|
||||||
Focus();
|
|
||||||
});
|
|
||||||
if (Validator.SelectedItem != null)
|
|
||||||
{
|
|
||||||
popup.ScrollToAndHighlightItemByName(Validator.SelectedItem.ShortName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (Validator.SelectedAsset != null || Validator.SelectedItem != null)
|
else if (Validator.SelectedAsset != null || Validator.SelectedItem != null)
|
||||||
{
|
{
|
||||||
@@ -412,5 +391,41 @@ namespace FlaxEditor.GUI
|
|||||||
|
|
||||||
return DragDropEffect.Move;
|
return DragDropEffect.Move;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSubmit()
|
||||||
|
{
|
||||||
|
base.OnSubmit();
|
||||||
|
|
||||||
|
if (Validator.AssetType != ScriptType.Null)
|
||||||
|
{
|
||||||
|
// Show asset picker popup
|
||||||
|
var popup = AssetSearchPopup.Show(this, Button1Rect.BottomLeft, Validator.IsValid, item =>
|
||||||
|
{
|
||||||
|
Validator.SelectedItem = item;
|
||||||
|
RootWindow.Focus();
|
||||||
|
Focus();
|
||||||
|
});
|
||||||
|
if (Validator.SelectedAsset != null)
|
||||||
|
{
|
||||||
|
var selectedAssetName = Path.GetFileNameWithoutExtension(Validator.SelectedAsset.Path);
|
||||||
|
popup.ScrollToAndHighlightItemByName(selectedAssetName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Show content item picker popup
|
||||||
|
var popup = ContentSearchPopup.Show(this, Button1Rect.BottomLeft, Validator.IsValid, item =>
|
||||||
|
{
|
||||||
|
Validator.SelectedItem = item;
|
||||||
|
RootWindow.Focus();
|
||||||
|
Focus();
|
||||||
|
});
|
||||||
|
if (Validator.SelectedItem != null)
|
||||||
|
{
|
||||||
|
popup.ScrollToAndHighlightItemByName(Validator.SelectedItem.ShortName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,6 +155,11 @@ namespace FlaxEditor.Modules.SourceCodeEditing
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly CachedTypesCollection All = new CachedAllTypesCollection(8096, ScriptType.Null, type => true, HasAssemblyValidAnyTypes);
|
public readonly CachedTypesCollection All = new CachedAllTypesCollection(8096, ScriptType.Null, type => true, HasAssemblyValidAnyTypes);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The all types collection from all assemblies (including C# system libraries).
|
||||||
|
/// </summary>
|
||||||
|
public readonly CachedTypesCollection AllWithStd = new CachedTypesCollection(8096, ScriptType.Null, type => true, assembly => true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The all valid types collection for the Visual Script property types (includes basic types like int/float, structures, object references).
|
/// The all valid types collection for the Visual Script property types (includes basic types like int/float, structures, object references).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -574,21 +579,17 @@ namespace FlaxEditor.Modules.SourceCodeEditing
|
|||||||
private static bool HasAssemblyValidAnyTypes(Assembly assembly)
|
private static bool HasAssemblyValidAnyTypes(Assembly assembly)
|
||||||
{
|
{
|
||||||
var codeBase = Utils.GetAssemblyLocation(assembly);
|
var codeBase = Utils.GetAssemblyLocation(assembly);
|
||||||
|
if (string.IsNullOrEmpty(codeBase))
|
||||||
|
return true;
|
||||||
#if USE_NETCORE
|
#if USE_NETCORE
|
||||||
if (assembly.ManifestModule.FullyQualifiedName == "<In Memory Module>")
|
if (assembly.ManifestModule.FullyQualifiedName == "<In Memory Module>")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(codeBase))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Skip runtime related assemblies
|
// Skip runtime related assemblies
|
||||||
string repositoryUrl = assembly.GetCustomAttributes<AssemblyMetadataAttribute>().FirstOrDefault(x => x.Key == "RepositoryUrl")?.Value ?? "";
|
string repositoryUrl = assembly.GetCustomAttributes<AssemblyMetadataAttribute>().FirstOrDefault(x => x.Key == "RepositoryUrl")?.Value ?? "";
|
||||||
if (repositoryUrl != "https://github.com/dotnet/runtime")
|
if (repositoryUrl != "https://github.com/dotnet/runtime")
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
if (string.IsNullOrEmpty(codeBase))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Skip assemblies from in-build Mono directory
|
// Skip assemblies from in-build Mono directory
|
||||||
if (!codeBase.Contains("/Mono/lib/mono/"))
|
if (!codeBase.Contains("/Mono/lib/mono/"))
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -211,10 +211,10 @@ namespace FlaxEditor.Options
|
|||||||
public bool SeparateValueAndUnit { get; set; }
|
public bool SeparateValueAndUnit { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the option to put a space between numbers and units for unit formatting.
|
/// Gets or sets tree line visibility.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(true)]
|
[DefaultValue(true)]
|
||||||
[EditorDisplay("Interface"), EditorOrder(320)]
|
[EditorDisplay("Interface"), EditorOrder(320), Tooltip("Toggles tree line visibility in places like the Scene or Content Panel.")]
|
||||||
public bool ShowTreeLines { get; set; } = true;
|
public bool ShowTreeLines { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -369,7 +369,7 @@ namespace FlaxEditor.Options
|
|||||||
public int NumberOfGameClientsToLaunch = 1;
|
public int NumberOfGameClientsToLaunch = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the visject connection curvature.
|
/// Gets or sets the curvature of the line connecting to connected visject nodes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(1.0f), Range(0.0f, 2.0f)]
|
[DefaultValue(1.0f), Range(0.0f, 2.0f)]
|
||||||
[EditorDisplay("Visject"), EditorOrder(550)]
|
[EditorDisplay("Visject"), EditorOrder(550)]
|
||||||
|
|||||||
@@ -183,12 +183,6 @@ namespace VisualStudio
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Scans the running processes to find a running Visual Studio instance with the specified version and open solution.
|
|
||||||
//
|
|
||||||
// @param[in] clsID Class ID of the specific Visual Studio version we are looking for.
|
|
||||||
// @param[in] solutionPath Path to the solution the instance needs to have open.
|
|
||||||
// @return DTE object that may be used to interact with the Visual Studio instance, or null if
|
|
||||||
// not found.
|
|
||||||
static Result FindRunningInstance(ConnectionHandle connection)
|
static Result FindRunningInstance(ConnectionHandle connection)
|
||||||
{
|
{
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ namespace FlaxEditor.Surface
|
|||||||
Visible = false,
|
Visible = false,
|
||||||
Parent = this,
|
Parent = this,
|
||||||
EndEditOnClick = false, // We have to handle this ourselves, otherwise the textbox instantly loses focus when double-clicking the header
|
EndEditOnClick = false, // We have to handle this ourselves, otherwise the textbox instantly loses focus when double-clicking the header
|
||||||
|
HorizontalAlignment = TextAlignment.Center,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -448,6 +448,8 @@ namespace FlaxEditor.Surface
|
|||||||
sb.Append("virtual ");
|
sb.Append("virtual ");
|
||||||
sb.Append(valueType.Name);
|
sb.Append(valueType.Name);
|
||||||
sb.Append(' ');
|
sb.Append(' ');
|
||||||
|
if (member.IsMethod)
|
||||||
|
sb.Append(member.DeclaringType.Namespace).Append('.');
|
||||||
sb.Append(declaringType.Name);
|
sb.Append(declaringType.Name);
|
||||||
sb.Append('.');
|
sb.Append('.');
|
||||||
sb.Append(name);
|
sb.Append(name);
|
||||||
|
|||||||
@@ -140,12 +140,12 @@ namespace FlaxEditor.Surface
|
|||||||
var searchStartTime = DateTime.Now;
|
var searchStartTime = DateTime.Now;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
foreach (var scriptType in Editor.Instance.CodeEditing.All.Get())
|
foreach (var scriptType in Editor.Instance.CodeEditing.AllWithStd.Get())
|
||||||
{
|
{
|
||||||
if (!SurfaceUtils.IsValidVisualScriptType(scriptType))
|
if (SurfaceUtils.IsValidVisualScriptType(scriptType))
|
||||||
continue;
|
{
|
||||||
|
_iterator(scriptType, _cache, _version);
|
||||||
_iterator(scriptType, _cache, _version);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add group to context menu (on a main thread)
|
// Add group to context menu (on a main thread)
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ using FlaxEditor.Surface.Elements;
|
|||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
using Object = FlaxEngine.Object;
|
|
||||||
|
|
||||||
namespace FlaxEditor.Surface
|
namespace FlaxEditor.Surface
|
||||||
{
|
{
|
||||||
@@ -36,6 +35,14 @@ namespace FlaxEditor.Surface
|
|||||||
Archetypes = new List<NodeArchetype>(),
|
Archetypes = new List<NodeArchetype>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static readonly string[] _blacklistedTypeNames =
|
||||||
|
{
|
||||||
|
"Newtonsoft.Json.",
|
||||||
|
"System.Array",
|
||||||
|
"System.Linq.Expressions.",
|
||||||
|
"System.Reflection.",
|
||||||
|
};
|
||||||
|
|
||||||
private static NodesCache _nodesCache = new NodesCache(IterateNodesCache);
|
private static NodesCache _nodesCache = new NodesCache(IterateNodesCache);
|
||||||
private DragActors _dragActors;
|
private DragActors _dragActors;
|
||||||
|
|
||||||
@@ -269,8 +276,11 @@ namespace FlaxEditor.Surface
|
|||||||
{
|
{
|
||||||
// Skip Newtonsoft.Json stuff
|
// Skip Newtonsoft.Json stuff
|
||||||
var scriptTypeTypeName = scriptType.TypeName;
|
var scriptTypeTypeName = scriptType.TypeName;
|
||||||
if (scriptTypeTypeName.StartsWith("Newtonsoft.Json."))
|
for (var i = 0; i < _blacklistedTypeNames.Length; i++)
|
||||||
return;
|
{
|
||||||
|
if (scriptTypeTypeName.StartsWith(_blacklistedTypeNames[i]))
|
||||||
|
return;
|
||||||
|
}
|
||||||
var scriptTypeName = scriptType.Name;
|
var scriptTypeName = scriptType.Name;
|
||||||
|
|
||||||
// Enum
|
// Enum
|
||||||
|
|||||||
@@ -79,5 +79,5 @@ public:
|
|||||||
static bool ReplaceInFile(const StringView& file, const Dictionary<String, String, HeapAllocation>& replaceMap);
|
static bool ReplaceInFile(const StringView& file, const Dictionary<String, String, HeapAllocation>& replaceMap);
|
||||||
|
|
||||||
static bool CopyFileIfNewer(const StringView& dst, const StringView& src);
|
static bool CopyFileIfNewer(const StringView& dst, const StringView& src);
|
||||||
static bool CopyDirectoryIfNewer(const StringView& dst, const StringView& src, bool withSubDirectories);
|
static bool CopyDirectoryIfNewer(const StringView& dst, const StringView& src, bool withSubDirectories = true);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FlaxEditor.Gizmo;
|
using FlaxEditor.Gizmo;
|
||||||
using FlaxEditor.GUI.ContextMenu;
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
|
using FlaxEditor.GUI.Input;
|
||||||
using FlaxEditor.SceneGraph;
|
using FlaxEditor.SceneGraph;
|
||||||
using FlaxEditor.Viewport.Cameras;
|
using FlaxEditor.Viewport.Cameras;
|
||||||
using FlaxEditor.Viewport.Widgets;
|
using FlaxEditor.Viewport.Widgets;
|
||||||
@@ -298,9 +299,33 @@ namespace FlaxEditor.Viewport
|
|||||||
}
|
}
|
||||||
var buttonBB = translateSnappingCM.AddButton("Bounding Box").LinkTooltip("Snaps the selection based on it's bounding volume");
|
var buttonBB = translateSnappingCM.AddButton("Bounding Box").LinkTooltip("Snaps the selection based on it's bounding volume");
|
||||||
buttonBB.Tag = -1.0f;
|
buttonBB.Tag = -1.0f;
|
||||||
translateSnappingCM.ButtonClicked += button =>
|
var buttonCustom = translateSnappingCM.AddButton("Custom");
|
||||||
|
buttonCustom.LinkTooltip("Custom grid size");
|
||||||
|
const float defaultCustomTranslateSnappingValue = 250.0f;
|
||||||
|
float customTranslateSnappingValue = transformGizmo.TranslationSnapValue;
|
||||||
|
if (customTranslateSnappingValue < 0.0f)
|
||||||
|
customTranslateSnappingValue = defaultCustomTranslateSnappingValue;
|
||||||
|
foreach (var v in TranslateSnapValues)
|
||||||
{
|
{
|
||||||
var v = (float)button.Tag;
|
if (Mathf.Abs(transformGizmo.TranslationSnapValue - v) < 0.001f)
|
||||||
|
{
|
||||||
|
customTranslateSnappingValue = defaultCustomTranslateSnappingValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buttonCustom.Tag = customTranslateSnappingValue;
|
||||||
|
var customValue = new FloatValueBox(customTranslateSnappingValue, Style.Current.FontMedium.MeasureText(buttonCustom.Text).X + 5, 2, 70.0f, 0.001f, float.MaxValue, 0.1f)
|
||||||
|
{
|
||||||
|
Parent = buttonCustom
|
||||||
|
};
|
||||||
|
customValue.ValueChanged += () =>
|
||||||
|
{
|
||||||
|
buttonCustom.Tag = customValue.Value;
|
||||||
|
buttonCustom.Click();
|
||||||
|
};
|
||||||
|
translateSnappingCM.ButtonClicked += b =>
|
||||||
|
{
|
||||||
|
var v = (float)b.Tag;
|
||||||
transformGizmo.TranslationSnapValue = v;
|
transformGizmo.TranslationSnapValue = v;
|
||||||
if (v < 0.0f)
|
if (v < 0.0f)
|
||||||
translateSnapping.Text = "Bounding Box";
|
translateSnapping.Text = "Bounding Box";
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ namespace FlaxEditor.Viewport
|
|||||||
editor.SceneEditing.SelectionChanged += OnSelectionChanged;
|
editor.SceneEditing.SelectionChanged += OnSelectionChanged;
|
||||||
|
|
||||||
// Gizmo widgets
|
// Gizmo widgets
|
||||||
AddGizmoViewportWidgets(this, TransformGizmo);
|
AddGizmoViewportWidgets(this, TransformGizmo, true);
|
||||||
|
|
||||||
// Show grid widget
|
// Show grid widget
|
||||||
_showGridButton = ViewWidgetShowMenu.AddButton("Grid", () => Grid.Enabled = !Grid.Enabled);
|
_showGridButton = ViewWidgetShowMenu.AddButton("Grid", () => Grid.Enabled = !Grid.Enabled);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
_surface.ContextChanged += OnSurfaceContextChanged;
|
_surface.ContextChanged += OnSurfaceContextChanged;
|
||||||
|
|
||||||
// Toolstrip
|
// Toolstrip
|
||||||
|
SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton);
|
||||||
_toolstrip.AddSeparator();
|
_toolstrip.AddSeparator();
|
||||||
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/animation/anim-graph/index.html")).LinkTooltip("See documentation to learn more");
|
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/animation/anim-graph/index.html")).LinkTooltip("See documentation to learn more");
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Toolstrip
|
// Toolstrip
|
||||||
|
SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton);
|
||||||
_toolstrip.AddSeparator();
|
_toolstrip.AddSeparator();
|
||||||
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/graphics/materials/index.html")).LinkTooltip("See documentation to learn more");
|
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/graphics/materials/index.html")).LinkTooltip("See documentation to learn more");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Toolstrip
|
// Toolstrip
|
||||||
|
SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton);
|
||||||
_toolstrip.AddSeparator();
|
_toolstrip.AddSeparator();
|
||||||
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/particles/index.html")).LinkTooltip("See documentation to learn more");
|
_toolstrip.AddButton(editor.Icons.Docs64, () => Platform.OpenUrl(Utilities.Constants.DocsUrl + "manual/particles/index.html")).LinkTooltip("See documentation to learn more");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,14 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
{
|
{
|
||||||
var menu = new ContextMenu();
|
var menu = new ContextMenu();
|
||||||
|
|
||||||
|
var copySprite = menu.AddButton("Copy sprite");
|
||||||
|
copySprite.Tag = groupPanel.Tag;
|
||||||
|
copySprite.ButtonClicked += OnCopySpriteClicked;
|
||||||
|
|
||||||
|
var pasteSprite = menu.AddButton("Paste sprite");
|
||||||
|
pasteSprite.Tag = groupPanel.Tag;
|
||||||
|
pasteSprite.ButtonClicked += OnPasteSpriteClicked;
|
||||||
|
|
||||||
var deleteSprite = menu.AddButton("Delete sprite");
|
var deleteSprite = menu.AddButton("Delete sprite");
|
||||||
deleteSprite.Tag = groupPanel.Tag;
|
deleteSprite.Tag = groupPanel.Tag;
|
||||||
deleteSprite.ButtonClicked += OnDeleteSpriteClicked;
|
deleteSprite.ButtonClicked += OnDeleteSpriteClicked;
|
||||||
@@ -160,6 +168,24 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
menu.Show(groupPanel, location);
|
menu.Show(groupPanel, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnCopySpriteClicked(ContextMenuButton button)
|
||||||
|
{
|
||||||
|
var window = ((PropertiesProxy)ParentEditor.Values[0])._window;
|
||||||
|
var index = (int)button.Tag;
|
||||||
|
var sprite = window.Asset.GetSprite(index);
|
||||||
|
Clipboard.Text = FlaxEngine.Json.JsonSerializer.Serialize(sprite, typeof(Sprite));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPasteSpriteClicked(ContextMenuButton button)
|
||||||
|
{
|
||||||
|
var window = ((PropertiesProxy)ParentEditor.Values[0])._window;
|
||||||
|
var index = (int)button.Tag;
|
||||||
|
var sprite = window.Asset.GetSprite(index);
|
||||||
|
var pasted = FlaxEngine.Json.JsonSerializer.Deserialize<Sprite>(Clipboard.Text);
|
||||||
|
sprite.Area = pasted.Area;
|
||||||
|
window.Asset.SetSprite(index, ref sprite);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnDeleteSpriteClicked(ContextMenuButton button)
|
private void OnDeleteSpriteClicked(ContextMenuButton button)
|
||||||
{
|
{
|
||||||
var window = ((PropertiesProxy)ParentEditor.Values[0])._window;
|
var window = ((PropertiesProxy)ParentEditor.Values[0])._window;
|
||||||
|
|||||||
@@ -27,9 +27,21 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly Panel _panel;
|
protected readonly Panel _panel;
|
||||||
|
|
||||||
private readonly ToolStripButton _saveButton;
|
/// <summary>
|
||||||
private readonly ToolStripButton _undoButton;
|
/// Save button.
|
||||||
private readonly ToolStripButton _redoButton;
|
/// </summary>
|
||||||
|
protected ToolStripButton _saveButton;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Undo button.
|
||||||
|
/// </summary>
|
||||||
|
protected ToolStripButton _undoButton;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Redo button.
|
||||||
|
/// </summary>
|
||||||
|
protected ToolStripButton _redoButton;
|
||||||
|
|
||||||
private bool _showWholeGraphOnLoad = true;
|
private bool _showWholeGraphOnLoad = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -61,17 +73,12 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
protected VisjectFunctionSurfaceWindow(Editor editor, AssetItem item)
|
protected VisjectFunctionSurfaceWindow(Editor editor, AssetItem item)
|
||||||
: base(editor, item)
|
: base(editor, item)
|
||||||
{
|
{
|
||||||
var inputOptions = Editor.Options.Options.Input;
|
|
||||||
|
|
||||||
// Undo
|
// Undo
|
||||||
_undo = new Undo();
|
_undo = new Undo();
|
||||||
_undo.UndoDone += OnUndoRedo;
|
_undo.UndoDone += OnUndoRedo;
|
||||||
_undo.RedoDone += OnUndoRedo;
|
_undo.RedoDone += OnUndoRedo;
|
||||||
_undo.ActionDone += OnUndoRedo;
|
_undo.ActionDone += OnUndoRedo;
|
||||||
|
|
||||||
// Toolstrip
|
|
||||||
SurfaceUtils.PerformCommonSetup(this, _toolstrip, _surface, out _saveButton, out _undoButton, out _redoButton);
|
|
||||||
|
|
||||||
// Panel
|
// Panel
|
||||||
_panel = new Panel(ScrollBars.None)
|
_panel = new Panel(ScrollBars.None)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -146,12 +146,11 @@ namespace FlaxEditor.Windows.Profiler
|
|||||||
avgStats.TotalDataSent += e.TotalDataSent;
|
avgStats.TotalDataSent += e.TotalDataSent;
|
||||||
avgStats.TotalDataReceived += e.TotalDataReceived;
|
avgStats.TotalDataReceived += e.TotalDataReceived;
|
||||||
}
|
}
|
||||||
avgStats.TotalDataSent /= (uint)_stats.Count;
|
//avgStats.TotalDataSent /= (uint)_stats.Count;
|
||||||
avgStats.TotalDataReceived /= (uint)_stats.Count;
|
//avgStats.TotalDataReceived /= (uint)_stats.Count;
|
||||||
_dataSentRateChart.AddSample(avgStats.TotalDataSent);
|
_dataSentRateChart.AddSample(avgStats.TotalDataSent);
|
||||||
_dataReceivedRateChart.AddSample(avgStats.TotalDataReceived);
|
_dataReceivedRateChart.AddSample(avgStats.TotalDataReceived);
|
||||||
|
|
||||||
|
|
||||||
// Gather network events
|
// Gather network events
|
||||||
var events = ProfilingTools.EventsNetwork;
|
var events = ProfilingTools.EventsNetwork;
|
||||||
if (_events == null)
|
if (_events == null)
|
||||||
@@ -319,7 +318,7 @@ namespace FlaxEditor.Windows.Profiler
|
|||||||
|
|
||||||
private static string FormatCellBytes(object x)
|
private static string FormatCellBytes(object x)
|
||||||
{
|
{
|
||||||
return Utilities.Utils.FormatBytesCount((ulong)x);
|
return Utilities.Utils.FormatBytesCount((ulong)(int)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int SortRows(Control x, Control y)
|
private static int SortRows(Control x, Control y)
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ const Char* SplashScreenQuotes[] =
|
|||||||
TEXT("Drum roll please"),
|
TEXT("Drum roll please"),
|
||||||
TEXT("Good Luck Have Fun"),
|
TEXT("Good Luck Have Fun"),
|
||||||
TEXT("GG Well Played"),
|
TEXT("GG Well Played"),
|
||||||
|
TEXT("Now with documentation."),
|
||||||
};
|
};
|
||||||
|
|
||||||
SplashScreen::~SplashScreen()
|
SplashScreen::~SplashScreen()
|
||||||
|
|||||||
@@ -396,8 +396,8 @@ void BehaviorTreeMoveToNode::GetAgentSize(Actor* agent, float& outRadius, float&
|
|||||||
// Estimate actor bounds to extract capsule information
|
// Estimate actor bounds to extract capsule information
|
||||||
const BoundingBox box = agent->GetBox();
|
const BoundingBox box = agent->GetBox();
|
||||||
const BoundingSphere sphere = agent->GetSphere();
|
const BoundingSphere sphere = agent->GetSphere();
|
||||||
outRadius = sphere.Radius;
|
outRadius = (float)sphere.Radius;
|
||||||
outHeight = box.GetSize().Y;
|
outHeight = (float)box.GetSize().Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 BehaviorTreeMoveToNode::GetStateSize() const
|
int32 BehaviorTreeMoveToNode::GetStateSize() const
|
||||||
@@ -522,7 +522,7 @@ String BehaviorTreeMoveToNode::GetDebugInfo(const BehaviorUpdateContext& context
|
|||||||
goal = state->GoalLocation.ToString();
|
goal = state->GoalLocation.ToString();
|
||||||
const Vector3 agentLocation = state->Agent->GetPosition();
|
const Vector3 agentLocation = state->Agent->GetPosition();
|
||||||
const Vector3 agentLocationOnPath = agentLocation + state->AgentOffset;
|
const Vector3 agentLocationOnPath = agentLocation + state->AgentOffset;
|
||||||
float distanceLeft = state->Path.Count() > state->TargetPathIndex ? Vector3::Distance(state->Path[state->TargetPathIndex], agentLocationOnPath) : 0;
|
Real distanceLeft = state->Path.Count() > state->TargetPathIndex ? Vector3::Distance(state->Path[state->TargetPathIndex], agentLocationOnPath) : 0;
|
||||||
for (int32 i = state->TargetPathIndex; i < state->Path.Count(); i++)
|
for (int32 i = state->TargetPathIndex; i < state->Path.Count(); i++)
|
||||||
distanceLeft += Vector3::Distance(state->Path[i - 1], state->Path[i]);
|
distanceLeft += Vector3::Distance(state->Path[i - 1], state->Path[i]);
|
||||||
return String::Format(TEXT("Agent: '{}'\nGoal: '{}'\nDistance: {}"), agent, goal, (int32)distanceLeft);
|
return String::Format(TEXT("Agent: '{}'\nGoal: '{}'\nDistance: {}"), agent, goal, (int32)distanceLeft);
|
||||||
@@ -559,7 +559,7 @@ void BehaviorTreeMoveToNode::State::OnUpdate()
|
|||||||
const float acceptableHeightPercentage = 1.05f;
|
const float acceptableHeightPercentage = 1.05f;
|
||||||
const float testHeight = agentHeight * acceptableHeightPercentage;
|
const float testHeight = agentHeight * acceptableHeightPercentage;
|
||||||
const Vector3 toGoal = agentLocationOnPath - pathSegmentEnd;
|
const Vector3 toGoal = agentLocationOnPath - pathSegmentEnd;
|
||||||
const float toGoalHeightDiff = (toGoal * UpVector).SumValues();
|
const Real toGoalHeightDiff = (toGoal * UpVector).SumValues();
|
||||||
if (toGoal.Length() <= testRadius && toGoalHeightDiff <= testHeight)
|
if (toGoal.Length() <= testRadius && toGoalHeightDiff <= testHeight)
|
||||||
{
|
{
|
||||||
TargetPathIndex++;
|
TargetPathIndex++;
|
||||||
|
|||||||
@@ -465,7 +465,7 @@ namespace FlaxEngine
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A single keyframe that can be injected into linear curve.
|
/// A single keyframe that can be injected into linear curve.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
public struct Keyframe : IComparable, IComparable<Keyframe>
|
public struct Keyframe : IComparable, IComparable<Keyframe>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -720,7 +720,7 @@ namespace FlaxEngine
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A single keyframe that can be injected into Bezier curve.
|
/// A single keyframe that can be injected into Bezier curve.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
public struct Keyframe : IComparable, IComparable<Keyframe>
|
public struct Keyframe : IComparable, IComparable<Keyframe>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ void InverseKinematics::SolveTwoBoneIK(Transform& rootTransform, Transform& midJ
|
|||||||
newMidJointPos = rootTransform.Translation + projJointDist * toTargetDir + jointLineDist * bendDirection;
|
newMidJointPos = rootTransform.Translation + projJointDist * toTargetDir + jointLineDist * bendDirection;
|
||||||
}
|
}
|
||||||
// TODO: fix the new IK impl (https://github.com/FlaxEngine/FlaxEngine/pull/2421) to properly work for character from https://github.com/PrecisionRender/CharacterControllerPro
|
// TODO: fix the new IK impl (https://github.com/FlaxEngine/FlaxEngine/pull/2421) to properly work for character from https://github.com/PrecisionRender/CharacterControllerPro
|
||||||
#define OLD 0
|
#define OLD 1
|
||||||
// Update root joint orientation
|
// Update root joint orientation
|
||||||
{
|
{
|
||||||
#if OLD
|
#if OLD
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "Loading/ContentLoadingManager.h"
|
#include "Loading/ContentLoadingManager.h"
|
||||||
#include "Loading/Tasks/LoadAssetTask.h"
|
#include "Loading/Tasks/LoadAssetTask.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
|
#include "Engine/Core/LogContext.h"
|
||||||
#include "Engine/Engine/Engine.h"
|
#include "Engine/Engine/Engine.h"
|
||||||
#include "Engine/Threading/Threading.h"
|
#include "Engine/Threading/Threading.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
@@ -596,9 +597,10 @@ bool Asset::IsInternalType() const
|
|||||||
|
|
||||||
bool Asset::onLoad(LoadAssetTask* task)
|
bool Asset::onLoad(LoadAssetTask* task)
|
||||||
{
|
{
|
||||||
if (task->Asset.Get() != this || Platform::AtomicRead(&_loadingTask) == 0)
|
|
||||||
// It may fail when task is cancelled and new one was created later (don't crash but just end with an error)
|
// It may fail when task is cancelled and new one was created later (don't crash but just end with an error)
|
||||||
|
if (task->Asset.Get() != this || Platform::AtomicRead(&_loadingTask) == 0)
|
||||||
return true;
|
return true;
|
||||||
|
LogContextScope logContext(GetID());
|
||||||
|
|
||||||
Locker.Lock();
|
Locker.Lock();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "Storage/JsonStorageProxy.h"
|
#include "Storage/JsonStorageProxy.h"
|
||||||
#include "Factories/IAssetFactory.h"
|
#include "Factories/IAssetFactory.h"
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
|
#include "Engine/Core/LogContext.h"
|
||||||
#include "Engine/Core/Types/String.h"
|
#include "Engine/Core/Types/String.h"
|
||||||
#include "Engine/Core/ObjectsRemovalService.h"
|
#include "Engine/Core/ObjectsRemovalService.h"
|
||||||
#include "Engine/Engine/EngineService.h"
|
#include "Engine/Engine/EngineService.h"
|
||||||
@@ -970,6 +971,7 @@ Asset* Content::LoadAsync(const Guid& id, const ScriptingTypeHandle& type)
|
|||||||
if (IsAssetTypeIdInvalid(type, result->GetTypeHandle()) && !result->Is(type))
|
if (IsAssetTypeIdInvalid(type, result->GetTypeHandle()) && !result->Is(type))
|
||||||
{
|
{
|
||||||
LOG(Warning, "Different loaded asset type! Asset: \'{0}\'. Expected type: {1}", result->ToString(), type.ToString());
|
LOG(Warning, "Different loaded asset type! Asset: \'{0}\'. Expected type: {1}", result->ToString(), type.ToString());
|
||||||
|
LogContext::Print(LogType::Warning);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -1004,6 +1006,7 @@ Asset* Content::LoadAsync(const Guid& id, const ScriptingTypeHandle& type)
|
|||||||
if (!GetAssetInfo(id, assetInfo))
|
if (!GetAssetInfo(id, assetInfo))
|
||||||
{
|
{
|
||||||
LOG(Warning, "Invalid or missing asset ({0}, {1}).", id, type.ToString());
|
LOG(Warning, "Invalid or missing asset ({0}, {1}).", id, type.ToString());
|
||||||
|
LogContext::Print(LogType::Warning);
|
||||||
LOAD_FAILED();
|
LOAD_FAILED();
|
||||||
}
|
}
|
||||||
#if ASSETS_LOADING_EXTRA_VERIFICATION
|
#if ASSETS_LOADING_EXTRA_VERIFICATION
|
||||||
@@ -1064,7 +1067,7 @@ bool findAsset(const Guid& id, const String& directory, Array<String>& tmpCache,
|
|||||||
{
|
{
|
||||||
// Get all asset files
|
// Get all asset files
|
||||||
tmpCache.Clear();
|
tmpCache.Clear();
|
||||||
if (FileSystem::DirectoryGetFiles(tmpCache, directory, TEXT("*"), DirectorySearchOption::AllDirectories))
|
if (FileSystem::DirectoryGetFiles(tmpCache, directory))
|
||||||
{
|
{
|
||||||
if (FileSystem::DirectoryExists(directory))
|
if (FileSystem::DirectoryExists(directory))
|
||||||
LOG(Error, "Cannot query files in folder '{0}'.", directory);
|
LOG(Error, "Cannot query files in folder '{0}'.", directory);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#if COMPILE_WITH_ASSETS_IMPORTER
|
#if COMPILE_WITH_ASSETS_IMPORTER
|
||||||
|
|
||||||
#include "Engine/Core/Log.h"
|
#include "Engine/Core/Log.h"
|
||||||
|
#include "Engine/Core/Cache.h"
|
||||||
#include "Engine/Core/Collections/Sorting.h"
|
#include "Engine/Core/Collections/Sorting.h"
|
||||||
#include "Engine/Core/Collections/ArrayExtensions.h"
|
#include "Engine/Core/Collections/ArrayExtensions.h"
|
||||||
#include "Engine/Serialization/MemoryWriteStream.h"
|
#include "Engine/Serialization/MemoryWriteStream.h"
|
||||||
@@ -766,6 +767,7 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
|
|||||||
// Link with object from prefab (if reimporting)
|
// Link with object from prefab (if reimporting)
|
||||||
if (prefab)
|
if (prefab)
|
||||||
{
|
{
|
||||||
|
rapidjson_flax::StringBuffer buffer;
|
||||||
for (Actor* a : nodeActors)
|
for (Actor* a : nodeActors)
|
||||||
{
|
{
|
||||||
for (const auto& i : prefab->ObjectsCache)
|
for (const auto& i : prefab->ObjectsCache)
|
||||||
@@ -776,6 +778,32 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
|
|||||||
if (o->GetName() != a->GetName()) // Name match
|
if (o->GetName() != a->GetName()) // Name match
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Preserve local changes made in the prefab
|
||||||
|
{
|
||||||
|
// Serialize
|
||||||
|
buffer.Clear();
|
||||||
|
CompactJsonWriter writer(buffer);
|
||||||
|
writer.StartObject();
|
||||||
|
const void* defaultInstance = o->GetType().GetDefaultInstance();
|
||||||
|
o->Serialize(writer, defaultInstance);
|
||||||
|
writer.EndObject();
|
||||||
|
|
||||||
|
// Parse json
|
||||||
|
rapidjson_flax::Document document;
|
||||||
|
document.Parse(buffer.GetString(), buffer.GetSize());
|
||||||
|
|
||||||
|
// Strip unwanted data
|
||||||
|
document.RemoveMember("ID");
|
||||||
|
document.RemoveMember("ParentID");
|
||||||
|
document.RemoveMember("PrefabID");
|
||||||
|
document.RemoveMember("PrefabObjectID");
|
||||||
|
document.RemoveMember("Name");
|
||||||
|
|
||||||
|
// Deserialize object
|
||||||
|
auto modifier = Cache::ISerializeModifier.Get();
|
||||||
|
a->Deserialize(document, &*modifier);
|
||||||
|
}
|
||||||
|
|
||||||
// Mark as this object already exists in prefab so will be preserved when updating it
|
// Mark as this object already exists in prefab so will be preserved when updating it
|
||||||
a->LinkPrefab(o->GetPrefabID(), o->GetPrefabObjectID());
|
a->LinkPrefab(o->GetPrefabID(), o->GetPrefabObjectID());
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
#include "LogContext.h"
|
#include "LogContext.h"
|
||||||
|
#include "Engine/Core/Log.h"
|
||||||
#include "Engine/Core/Types/Guid.h"
|
#include "Engine/Core/Types/Guid.h"
|
||||||
#include "Engine/Core/Types/String.h"
|
#include "Engine/Core/Types/String.h"
|
||||||
|
#include "Engine/Core/Types/StringBuilder.h"
|
||||||
#include "Engine/Core/Collections/Array.h"
|
#include "Engine/Core/Collections/Array.h"
|
||||||
|
#include "Engine/Scripting/Scripting.h"
|
||||||
|
#include "Engine/Scripting/Script.h"
|
||||||
|
#include "Engine/Content/Asset.h"
|
||||||
|
#include "Engine/Content/Content.h"
|
||||||
|
#include "Engine/Level/Actor.h"
|
||||||
#include "Engine/Threading/ThreadLocal.h"
|
#include "Engine/Threading/ThreadLocal.h"
|
||||||
|
|
||||||
struct LogContextThreadData
|
struct LogContextThreadData
|
||||||
@@ -30,7 +37,7 @@ struct LogContextThreadData
|
|||||||
Count--;
|
Count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogContextData Peek()
|
LogContextData Peek() const
|
||||||
{
|
{
|
||||||
return Count > 0 ? Ptr[Count - 1] : LogContextData();
|
return Count > 0 ? Ptr[Count - 1] : LogContextData();
|
||||||
}
|
}
|
||||||
@@ -38,12 +45,58 @@ struct LogContextThreadData
|
|||||||
|
|
||||||
ThreadLocal<LogContextThreadData> GlobalLogContexts;
|
ThreadLocal<LogContextThreadData> GlobalLogContexts;
|
||||||
|
|
||||||
String LogContext::GetInfo()
|
void LogContext::Print(LogType verbosity)
|
||||||
{
|
{
|
||||||
LogContextData context = LogContext::Get();
|
auto& stack = GlobalLogContexts.Get();
|
||||||
if (context.ObjectID != Guid::Empty)
|
if (stack.Count == 0)
|
||||||
return String::Format(TEXT("(Loading source was {0})"), context.ObjectID);
|
return;
|
||||||
return String::Empty;
|
const StringView indentation(TEXT(" "));
|
||||||
|
StringBuilder msg;
|
||||||
|
for (int32 index = (int32)stack.Count - 1; index >= 0; index--)
|
||||||
|
{
|
||||||
|
// Build call hierarchy via indentation
|
||||||
|
msg.Clear();
|
||||||
|
for (uint32 i = index; i < stack.Count; i++)
|
||||||
|
msg.Append(indentation);
|
||||||
|
|
||||||
|
LogContextData& context = stack.Ptr[index];
|
||||||
|
if (context.ObjectID != Guid::Empty)
|
||||||
|
{
|
||||||
|
// Object reference context
|
||||||
|
msg.Append(TEXT(" Referenced by "));
|
||||||
|
if (ScriptingObject* object = Scripting::TryFindObject(context.ObjectID))
|
||||||
|
{
|
||||||
|
const StringAnsiView typeName(object->GetType().Fullname);
|
||||||
|
if (Asset* asset = ScriptingObject::Cast<Asset>(object))
|
||||||
|
{
|
||||||
|
msg.AppendFormat(TEXT("asset '{}' ({}, {})"), asset->GetPath(), asset->GetTypeName(), context.ObjectID);
|
||||||
|
}
|
||||||
|
else if (Actor* actor = ScriptingObject::Cast<Actor>(object))
|
||||||
|
{
|
||||||
|
msg.AppendFormat(TEXT("actor '{}' ({}, {})"), actor->GetNamePath(), String(typeName), context.ObjectID);
|
||||||
|
}
|
||||||
|
else if (Script* script = ScriptingObject::Cast<Script>(object))
|
||||||
|
{
|
||||||
|
msg.AppendFormat(TEXT("script '{}' ({}, {})"), script->GetNamePath(), String(typeName), context.ObjectID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg.AppendFormat(TEXT("object {} ({})"), String(typeName), context.ObjectID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Asset* asset = Content::GetAsset(context.ObjectID))
|
||||||
|
{
|
||||||
|
msg.AppendFormat(TEXT("asset '{}' ({}, {})"), asset->GetPath(), asset->GetTypeName(), context.ObjectID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg.AppendFormat(TEXT("object {}"), context.ObjectID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print message
|
||||||
|
Log::Logger::Write(verbosity, msg.ToStringView());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogContext::Push(const Guid& id)
|
void LogContext::Push(const Guid& id)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Engine/Core/Log.h"
|
||||||
#include "Engine/Core/Config.h"
|
#include "Engine/Core/Config.h"
|
||||||
#include "Engine/Scripting/ScriptingType.h"
|
#include "Engine/Scripting/ScriptingType.h"
|
||||||
|
|
||||||
@@ -9,7 +10,7 @@ class String;
|
|||||||
struct Guid;
|
struct Guid;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Log context data structure. Contains different kinds of context data for different situtations.
|
/// Log context data structure. Contains different kinds of context data for different situations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_STRUCT(NoDefault) struct FLAXENGINE_API LogContextData
|
API_STRUCT(NoDefault) struct FLAXENGINE_API LogContextData
|
||||||
{
|
{
|
||||||
@@ -54,10 +55,10 @@ API_CLASS(Static) class FLAXENGINE_API LogContext
|
|||||||
API_FUNCTION() static LogContextData Get();
|
API_FUNCTION() static LogContextData Get();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a string which represents the current log context on the stack.
|
/// Prints the current log context to the log. Does nothing it
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The formatted string representing the current log context.</returns>
|
/// <param name="verbosity">The verbosity of the log.</param>
|
||||||
API_FUNCTION() static String GetInfo();
|
API_FUNCTION() static void Print(LogType verbosity);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between box and a ray.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -315,7 +315,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between box and a ray.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
||||||
@@ -326,7 +326,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between box and a ray.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
||||||
@@ -338,7 +338,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between box and a ray.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero"/> if there was no intersection.</param>
|
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero"/> if there was no intersection.</param>
|
||||||
@@ -349,7 +349,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Plane.
|
/// Determines if there is an intersection between box and a plane.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plane">The plane to test.</param>
|
/// <param name="plane">The plane to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -359,7 +359,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Bounding Box.
|
/// Determines if there is an intersection between two boxes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="box">The box to test.</param>
|
/// <param name="box">The box to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -369,7 +369,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Bounding Sphere.
|
/// Determines if there is an intersection between box and a sphere.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sphere">The sphere to test.</param>
|
/// <param name="sphere">The sphere to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -379,7 +379,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the current objects contains a point.
|
/// Determines whether box contains a point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="point">The point to test.</param>
|
/// <param name="point">The point to test.</param>
|
||||||
/// <returns>The type of containment the two objects have.</returns>
|
/// <returns>The type of containment the two objects have.</returns>
|
||||||
@@ -389,7 +389,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the current objects contains a Bounding Box.
|
/// Determines whether box contains a Bounding Box.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="box">The box to test.</param>
|
/// <param name="box">The box to test.</param>
|
||||||
/// <returns>The type of containment the two objects have.</returns>
|
/// <returns>The type of containment the two objects have.</returns>
|
||||||
@@ -399,7 +399,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the current objects contains a Bounding Sphere.
|
/// Determines whether box contains a Bounding Sphere.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sphere">The sphere to test.</param>
|
/// <param name="sphere">The sphere to test.</param>
|
||||||
/// <returns>The type of containment the two objects have.</returns>
|
/// <returns>The type of containment the two objects have.</returns>
|
||||||
@@ -409,7 +409,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines the distance between a Bounding Box and a point.
|
/// Determines the distance between box and a point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="point">The point to test.</param>
|
/// <param name="point">The point to test.</param>
|
||||||
/// <returns>The distance between bounding box and a point.</returns>
|
/// <returns>The distance between bounding box and a point.</returns>
|
||||||
@@ -419,7 +419,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines the distance between two Bounding Boxed.
|
/// Determines the distance between two boxes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="box">The bounding box to test.</param>
|
/// <param name="box">The bounding box to test.</param>
|
||||||
/// <returns>The distance between bounding boxes.</returns>
|
/// <returns>The distance between bounding boxes.</returns>
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between sphere and a rat.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
bool Intersects(const Ray& ray) const;
|
bool Intersects(const Ray& ray) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between sphere and a rat.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
||||||
@@ -89,7 +89,7 @@ public:
|
|||||||
bool Intersects(const Ray& ray, Real& distance) const;
|
bool Intersects(const Ray& ray, Real& distance) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between sphere and a rat.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
||||||
@@ -98,7 +98,7 @@ public:
|
|||||||
bool Intersects(const Ray& ray, Real& distance, Vector3& normal) const;
|
bool Intersects(const Ray& ray, Real& distance, Vector3& normal) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between sphere and a rat.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <param name="point">When the method completes, contains the point of intersection, or Vector3::Zero if there was no intersection.</param>
|
/// <param name="point">When the method completes, contains the point of intersection, or Vector3::Zero if there was no intersection.</param>
|
||||||
@@ -106,14 +106,14 @@ public:
|
|||||||
bool Intersects(const Ray& ray, Vector3& point) const;
|
bool Intersects(const Ray& ray, Vector3& point) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Plane.
|
/// Determines if there is an intersection between sphere and a plane.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plane">The plane to test.</param>
|
/// <param name="plane">The plane to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
PlaneIntersectionType Intersects(const Plane& plane) const;
|
PlaneIntersectionType Intersects(const Plane& plane) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a triangle.
|
/// Determines if there is an intersection between sphere and a triangle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||||
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
||||||
@@ -122,28 +122,28 @@ public:
|
|||||||
bool Intersects(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3) const;
|
bool Intersects(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Bounding Box.
|
/// Determines if there is an intersection between sphere and a box.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="box">The box to test.</param>
|
/// <param name="box">The box to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
bool Intersects(const BoundingBox& box) const;
|
bool Intersects(const BoundingBox& box) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Bounding Sphere.
|
/// Determines if there is an intersection between two spheres.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sphere">The sphere to test.</param>
|
/// <param name="sphere">The sphere to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
bool Intersects(const BoundingSphere& sphere) const;
|
bool Intersects(const BoundingSphere& sphere) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the current objects contains a point.
|
/// Determines whether sphere contains a point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="point">The point to test.</param>
|
/// <param name="point">The point to test.</param>
|
||||||
/// <returns> The type of containment the two objects have.</returns>
|
/// <returns> The type of containment the two objects have.</returns>
|
||||||
ContainmentType Contains(const Vector3& point) const;
|
ContainmentType Contains(const Vector3& point) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the current objects contains a triangle.
|
/// Determines whether sphere contains a triangle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||||
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
||||||
@@ -152,14 +152,14 @@ public:
|
|||||||
ContainmentType Contains(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3) const;
|
ContainmentType Contains(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the current objects contains a Bounding Box
|
/// Determines whether sphere contains a box.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="box">The box to test.</param>
|
/// <param name="box">The box to test.</param>
|
||||||
/// <returns>The type of containment the two objects have.</returns>
|
/// <returns>The type of containment the two objects have.</returns>
|
||||||
ContainmentType Contains(const BoundingBox& box) const;
|
ContainmentType Contains(const BoundingBox& box) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the current objects contains a Bounding Sphere.
|
/// Determines whether sphere contains a sphere.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sphere">The sphere to test.</param>
|
/// <param name="sphere">The sphere to test.</param>
|
||||||
/// <returns>The type of containment the two objects have.</returns>
|
/// <returns>The type of containment the two objects have.</returns>
|
||||||
|
|||||||
@@ -290,20 +290,14 @@ namespace Math
|
|||||||
return dividend / divisor;
|
return dividend / divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if value is inside the given range
|
// Checks if value is inside the given range.
|
||||||
// @param value value to check
|
|
||||||
// @param min Minimum value
|
|
||||||
// @param max Maximum value
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static bool IsInRange(const T value, const T min, const T max)
|
static bool IsInRange(const T value, const T min, const T max)
|
||||||
{
|
{
|
||||||
return value >= min && value <= max;
|
return value >= min && value <= max;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if value isn't inside the given range
|
// Checks if value isn't inside the given range.
|
||||||
// @param value value to check
|
|
||||||
// @param min Minimum value
|
|
||||||
// @param max Maximum value
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static bool IsNotInRange(const T value, const T min, const T max)
|
static bool IsNotInRange(const T value, const T min, const T max)
|
||||||
{
|
{
|
||||||
@@ -311,21 +305,19 @@ namespace Math
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Checks whether a number is a power of two.
|
// Checks whether a number is a power of two.
|
||||||
// @param value Number to check
|
|
||||||
// @returns True if value is a power of two
|
|
||||||
static bool IsPowerOfTwo(uint32 value)
|
static bool IsPowerOfTwo(uint32 value)
|
||||||
{
|
{
|
||||||
return (value & value - 1) == 0;
|
return (value & value - 1) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp value to be between minimum and maximum values, inclusive
|
// Clamps value to be between minimum and maximum values, inclusive
|
||||||
template<class T>
|
template<class T>
|
||||||
static T Clamp(const T value, const T min, const T max)
|
static T Clamp(const T value, const T min, const T max)
|
||||||
{
|
{
|
||||||
return value < min ? min : value < max ? value : max;
|
return value < min ? min : value < max ? value : max;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clamp value to be between 0 and 1 range, inclusive
|
// Clamps value to be between 0 and 1 range, inclusive
|
||||||
template<class T>
|
template<class T>
|
||||||
static T Saturate(const T value)
|
static T Saturate(const T value)
|
||||||
{
|
{
|
||||||
@@ -478,54 +470,43 @@ namespace Math
|
|||||||
return Saturate((value - a) / (b - a));
|
return Saturate((value - a) / (b - a));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs smooth (cubic Hermite) interpolation between 0 and 1
|
// Performs smooth (cubic Hermite) interpolation between 0 and 1.
|
||||||
// @param amount Value between 0 and 1 indicating interpolation amount
|
|
||||||
static float SmoothStep(float amount)
|
static float SmoothStep(float amount)
|
||||||
{
|
{
|
||||||
return amount <= 0 ? 0 : amount >= 1 ? 1 : amount * amount * (3 - 2 * amount);
|
return amount <= 0 ? 0 : amount >= 1 ? 1 : amount * amount * (3 - 2 * amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs a smooth(er) interpolation between 0 and 1 with 1st and 2nd order derivatives of zero at endpoints
|
// Performs a smooth(er) interpolation between 0 and 1 with 1st and 2nd order derivatives of zero at endpoints.
|
||||||
// @param amount Value between 0 and 1 indicating interpolation amount
|
|
||||||
static float SmootherStep(float amount)
|
static float SmootherStep(float amount)
|
||||||
{
|
{
|
||||||
return amount <= 0 ? 0 : amount >= 1 ? 1 : amount * amount * amount * (amount * (amount * 6 - 15) + 10);
|
return amount <= 0 ? 0 : amount >= 1 ? 1 : amount * amount * amount * (amount * (amount * 6 - 15) + 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines whether the specified value is close to zero (0.0)
|
// Determines whether the specified value is close to zero (0.0).
|
||||||
// @param a The integer value
|
|
||||||
// @returns True if the specified value is close to zero (0.0). otherwise false
|
|
||||||
inline int32 IsZero(int32 a)
|
inline int32 IsZero(int32 a)
|
||||||
{
|
{
|
||||||
return a == 0;
|
return a == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines whether the specified value is close to zero (0.0f)
|
// Determines whether the specified value is close to zero (0.0f).
|
||||||
// @param a The floating value
|
|
||||||
// @returns True if the specified value is close to zero (0.0f). otherwise false
|
|
||||||
inline bool IsZero(float a)
|
inline bool IsZero(float a)
|
||||||
{
|
{
|
||||||
return Abs(a) < ZeroTolerance;
|
return Abs(a) < ZeroTolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines whether the specified value is close to one (1.0)
|
// Determines whether the specified value is close to one (1.0).
|
||||||
// @param a The integer value
|
|
||||||
// @returns True if the specified value is close to one (1.0). otherwise false
|
|
||||||
inline bool IsOne(int32 a)
|
inline bool IsOne(int32 a)
|
||||||
{
|
{
|
||||||
return a == 1;
|
return a == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines whether the specified value is close to one (1.0f)
|
// Determines whether the specified value is close to one (1.0f).
|
||||||
// @param a The floating value
|
|
||||||
// @returns True if the specified value is close to one (1.0f). otherwise false
|
|
||||||
inline bool IsOne(float a)
|
inline bool IsOne(float a)
|
||||||
{
|
{
|
||||||
return IsZero(a - 1.0f);
|
return IsZero(a - 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a value indicating the sign of a number
|
// Returns a value indicating the sign of a number.
|
||||||
// @returns A number that indicates the sign of value
|
|
||||||
inline float Sign(float v)
|
inline float Sign(float v)
|
||||||
{
|
{
|
||||||
return v > 0.0f ? 1.0f : v < 0.0f ? -1.0f : 0.0f;
|
return v > 0.0f ? 1.0f : v < 0.0f ? -1.0f : 0.0f;
|
||||||
|
|||||||
@@ -165,38 +165,31 @@ namespace Math
|
|||||||
return TruncToInt(ceil(value));
|
return TruncToInt(ceil(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs smooth (cubic Hermite) interpolation between 0 and 1
|
// Performs smooth (cubic Hermite) interpolation between 0 and 1.
|
||||||
// @param amount Value between 0 and 1 indicating interpolation amount
|
|
||||||
static double SmoothStep(double amount)
|
static double SmoothStep(double amount)
|
||||||
{
|
{
|
||||||
return amount <= 0. ? 0. : amount >= 1. ? 1. : amount * amount * (3. - 2. * amount);
|
return amount <= 0. ? 0. : amount >= 1. ? 1. : amount * amount * (3. - 2. * amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs a smooth(er) interpolation between 0 and 1 with 1st and 2nd order derivatives of zero at endpoints
|
// Performs a smooth(er) interpolation between 0 and 1 with 1st and 2nd order derivatives of zero at endpoints.
|
||||||
// @param amount Value between 0 and 1 indicating interpolation amount
|
|
||||||
static double SmootherStep(double amount)
|
static double SmootherStep(double amount)
|
||||||
{
|
{
|
||||||
return amount <= 0. ? 0. : amount >= 1. ? 1. : amount * amount * amount * (amount * (amount * 6. - 15.) + 10.);
|
return amount <= 0. ? 0. : amount >= 1. ? 1. : amount * amount * amount * (amount * (amount * 6. - 15.) + 10.);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines whether the specified value is close to zero (0.0)
|
// Determines whether the specified value is close to zero (0.0).
|
||||||
// @param a The floating value
|
|
||||||
// @returns True if the specified value is close to zero (0.0). otherwise false
|
|
||||||
inline bool IsZero(double a)
|
inline bool IsZero(double a)
|
||||||
{
|
{
|
||||||
return Abs(a) < ZeroTolerance;
|
return Abs(a) < ZeroTolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines whether the specified value is close to one (1.0f)
|
// Determines whether the specified value is close to one (1.0f).
|
||||||
// @param a The floating value
|
|
||||||
// @returns True if the specified value is close to one (1.0f). otherwise false
|
|
||||||
inline bool IsOne(double a)
|
inline bool IsOne(double a)
|
||||||
{
|
{
|
||||||
return IsZero(a - 1.);
|
return IsZero(a - 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a value indicating the sign of a number
|
// Returns a value indicating the sign of a number.
|
||||||
// @returns A number that indicates the sign of value
|
|
||||||
inline double Sign(double v)
|
inline double Sign(double v)
|
||||||
{
|
{
|
||||||
return v > 0. ? 1. : v < 0. ? -1. : 0.;
|
return v > 0. ? 1. : v < 0. ? -1. : 0.;
|
||||||
|
|||||||
@@ -531,27 +531,15 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Calculates the sum of two matrices.
|
// Calculates the sum of two matrices.
|
||||||
// @param left The first matrix to add.
|
|
||||||
// @param right The second matrix to add.
|
|
||||||
// @param result When the method completes, contains the sum of the two matrices.
|
|
||||||
static void Add(const Matrix& left, const Matrix& right, Matrix& result);
|
static void Add(const Matrix& left, const Matrix& right, Matrix& result);
|
||||||
|
|
||||||
// Calculates the difference between two matrices.
|
// Calculates the difference between two matrices.
|
||||||
// @param left The first matrix to subtract.
|
|
||||||
// @param right The second matrix to subtract.
|
|
||||||
// @param result When the method completes, contains the difference between the two matrices.
|
|
||||||
static void Subtract(const Matrix& left, const Matrix& right, Matrix& result);
|
static void Subtract(const Matrix& left, const Matrix& right, Matrix& result);
|
||||||
|
|
||||||
// Scales a matrix by the given value.
|
// Scales a matrix by the given value.
|
||||||
// @param left The matrix to scale.
|
|
||||||
// @param right The amount by which to scale.
|
|
||||||
// @param result When the method completes, contains the scaled matrix.
|
|
||||||
static void Multiply(const Matrix& left, float right, Matrix& result);
|
static void Multiply(const Matrix& left, float right, Matrix& result);
|
||||||
|
|
||||||
// Calculates the product of two matrices.
|
// Calculates the product of two matrices.
|
||||||
// @param left The first matrix to multiply.
|
|
||||||
// @param right The second matrix to multiply.
|
|
||||||
// @returns The product of the two matrices.
|
|
||||||
static Matrix Multiply(const Matrix& left, const Matrix& right)
|
static Matrix Multiply(const Matrix& left, const Matrix& right)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
@@ -560,40 +548,21 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the product of two matrices.
|
// Calculates the product of two matrices.
|
||||||
// @param left The first matrix to multiply.
|
|
||||||
// @param right The second matrix to multiply.
|
|
||||||
// @param result The product of the two matrices.
|
|
||||||
static void Multiply(const Matrix& left, const Matrix& right, Matrix& result);
|
static void Multiply(const Matrix& left, const Matrix& right, Matrix& result);
|
||||||
|
|
||||||
// Scales a matrix by the given value.
|
// Scales a matrix by the given value.
|
||||||
// @param left The matrix to scale.
|
|
||||||
// @param right The amount by which to scale.
|
|
||||||
// @param result When the method completes, contains the scaled matrix.
|
|
||||||
static void Divide(const Matrix& left, float right, Matrix& result);
|
static void Divide(const Matrix& left, float right, Matrix& result);
|
||||||
|
|
||||||
// Calculates the quotient of two matrices.
|
// Calculates the quotient of two matrices.
|
||||||
// @param left The first matrix to divide.
|
|
||||||
// @param right The second matrix to divide.
|
|
||||||
// @param result When the method completes, contains the quotient of the two matrices.
|
|
||||||
static void Divide(const Matrix& left, const Matrix& right, Matrix& result);
|
static void Divide(const Matrix& left, const Matrix& right, Matrix& result);
|
||||||
|
|
||||||
// Negates a matrix.
|
// Negates a matrix.
|
||||||
// @param value The matrix to be negated.
|
|
||||||
// @param result When the method completes, contains the negated matrix.
|
|
||||||
static void Negate(const Matrix& value, Matrix& result);
|
static void Negate(const Matrix& value, Matrix& result);
|
||||||
|
|
||||||
// Performs a linear interpolation between two matrices.
|
// Performs a linear interpolation between two matrices.
|
||||||
// @param start Start matrix.
|
|
||||||
// @param end End matrix.
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end.
|
|
||||||
// @param result When the method completes, contains the linear interpolation of the two matrices.
|
|
||||||
static void Lerp(const Matrix& start, const Matrix& end, float amount, Matrix& result);
|
static void Lerp(const Matrix& start, const Matrix& end, float amount, Matrix& result);
|
||||||
|
|
||||||
// Performs a cubic interpolation between two matrices.
|
// Performs a cubic interpolation between two matrices.
|
||||||
// @param start Start matrix.
|
|
||||||
// @param end End matrix.
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end.
|
|
||||||
// @param result When the method completes, contains the cubic interpolation of the two matrices.
|
|
||||||
static void SmoothStep(const Matrix& start, const Matrix& end, float amount, Matrix& result)
|
static void SmoothStep(const Matrix& start, const Matrix& end, float amount, Matrix& result)
|
||||||
{
|
{
|
||||||
amount = Math::SmoothStep(amount);
|
amount = Math::SmoothStep(amount);
|
||||||
@@ -601,13 +570,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the transpose of the specified matrix.
|
// Calculates the transpose of the specified matrix.
|
||||||
// @param value The matrix whose transpose is to be calculated.
|
|
||||||
// @returns The transpose of the specified matrix.
|
|
||||||
static Matrix Transpose(const Matrix& value);
|
static Matrix Transpose(const Matrix& value);
|
||||||
|
|
||||||
// Calculates the transpose of the specified matrix.
|
// Calculates the transpose of the specified matrix.
|
||||||
// @param value The matrix whose transpose is to be calculated.
|
|
||||||
// @param result When the method completes, contains the transpose of the specified matrix.
|
|
||||||
static void Transpose(const Matrix& value, Matrix& result);
|
static void Transpose(const Matrix& value, Matrix& result);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -630,26 +595,12 @@ public:
|
|||||||
static void Invert(const Matrix& value, Matrix& result);
|
static void Invert(const Matrix& value, Matrix& result);
|
||||||
|
|
||||||
// Creates a left-handed spherical billboard that rotates around a specified object position.
|
// Creates a left-handed spherical billboard that rotates around a specified object position.
|
||||||
// @param objectPosition The position of the object around which the billboard will rotate.
|
|
||||||
// @param cameraPosition The position of the camera.
|
|
||||||
// @param cameraUpFloat The up vector of the camera.
|
|
||||||
// @param cameraForwardFloat The forward vector of the camera.
|
|
||||||
// @param result When the method completes, contains the created billboard matrix.
|
|
||||||
static void Billboard(const Float3& objectPosition, const Float3& cameraPosition, const Float3& cameraUpFloat, const Float3& cameraForwardFloat, Matrix& result);
|
static void Billboard(const Float3& objectPosition, const Float3& cameraPosition, const Float3& cameraUpFloat, const Float3& cameraForwardFloat, Matrix& result);
|
||||||
|
|
||||||
// Creates a left-handed, look-at matrix.
|
// Creates a left-handed, look-at matrix.
|
||||||
// @param eye The position of the viewer's eye.
|
|
||||||
// @param target The camera look-at target.
|
|
||||||
// @param up The camera's up vector.
|
|
||||||
// @param result When the method completes, contains the created look-at matrix.
|
|
||||||
static void LookAt(const Float3& eye, const Float3& target, const Float3& up, Matrix& result);
|
static void LookAt(const Float3& eye, const Float3& target, const Float3& up, Matrix& result);
|
||||||
|
|
||||||
// Creates a left-handed, orthographic projection matrix.
|
// Creates a left-handed, orthographic projection matrix.
|
||||||
// @param width Width of the viewing volume.
|
|
||||||
// @param height Height of the viewing volume.
|
|
||||||
// @param zNear Minimum z-value of the viewing volume.
|
|
||||||
// @param zFar Maximum z-value of the viewing volume.
|
|
||||||
// @param result When the method completes, contains the created projection matrix.
|
|
||||||
static void Ortho(float width, float height, float zNear, float zFar, Matrix& result)
|
static void Ortho(float width, float height, float zNear, float zFar, Matrix& result)
|
||||||
{
|
{
|
||||||
const float halfWidth = width * 0.5f;
|
const float halfWidth = width * 0.5f;
|
||||||
@@ -658,21 +609,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a left-handed, customized orthographic projection matrix.
|
// Creates a left-handed, customized orthographic projection matrix.
|
||||||
// @param left Minimum x-value of the viewing volume.
|
|
||||||
// @param right Maximum x-value of the viewing volume.
|
|
||||||
// @param bottom Minimum y-value of the viewing volume.
|
|
||||||
// @param top Maximum y-value of the viewing volume.
|
|
||||||
// @param zNear Minimum z-value of the viewing volume.
|
|
||||||
// @param zFar Maximum z-value of the viewing volume.
|
|
||||||
// @param result When the method completes, contains the created projection matrix.
|
|
||||||
static void OrthoOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, Matrix& result);
|
static void OrthoOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, Matrix& result);
|
||||||
|
|
||||||
// Creates a left-handed, perspective projection matrix.
|
// Creates a left-handed, perspective projection matrix.
|
||||||
// @param width Width of the viewing volume.
|
|
||||||
// @param height Height of the viewing volume.
|
|
||||||
// @param zNear Minimum z-value of the viewing volume.
|
|
||||||
// @param zFar Maximum z-value of the viewing volume.
|
|
||||||
// @param result When the method completes, contains the created projection matrix.
|
|
||||||
static void Perspective(float width, float height, float zNear, float zFar, Matrix& result)
|
static void Perspective(float width, float height, float zNear, float zFar, Matrix& result)
|
||||||
{
|
{
|
||||||
const float halfWidth = width * 0.5f;
|
const float halfWidth = width * 0.5f;
|
||||||
@@ -681,44 +620,24 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a left-handed, perspective projection matrix based on a field of view.
|
// Creates a left-handed, perspective projection matrix based on a field of view.
|
||||||
// @param fov Field of view in the y direction, in radians.
|
|
||||||
// @param aspect Aspect ratio, defined as view space width divided by height.
|
|
||||||
// @param zNear Minimum z-value of the viewing volume.
|
|
||||||
// @param zFar Maximum z-value of the viewing volume.
|
|
||||||
// @param result When the method completes, contains the created projection matrix.
|
|
||||||
static void PerspectiveFov(float fov, float aspect, float zNear, float zFar, Matrix& result);
|
static void PerspectiveFov(float fov, float aspect, float zNear, float zFar, Matrix& result);
|
||||||
|
|
||||||
// Creates a left-handed, customized perspective projection matrix.
|
// Creates a left-handed, customized perspective projection matrix.
|
||||||
// @param left Minimum x-value of the viewing volume.
|
|
||||||
// @param right Maximum x-value of the viewing volume.
|
|
||||||
// @param bottom Minimum y-value of the viewing volume.
|
|
||||||
// @param top Maximum y-value of the viewing volume.
|
|
||||||
// @param zNear Minimum z-value of the viewing volume.
|
|
||||||
// @param zFar Maximum z-value of the viewing volume.
|
|
||||||
// @param result When the method completes, contains the created projection matrix.
|
|
||||||
static void PerspectiveOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, Matrix& result);
|
static void PerspectiveOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, Matrix& result);
|
||||||
|
|
||||||
// Creates a matrix that scales along the x-axis, y-axis, and y-axis.
|
// Creates a matrix that scales along the x-axis, y-axis, and y-axis.
|
||||||
// @param scale Scaling factor for all three axes.
|
|
||||||
// @param result The created scaling matrix.
|
|
||||||
static Matrix Scaling(const Float3& scale)
|
static Matrix Scaling(const Float3& scale)
|
||||||
{
|
{
|
||||||
return Scaling(scale.X, scale.Y, scale.Z);
|
return Scaling(scale.X, scale.Y, scale.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that scales along the x-axis, y-axis, and y-axis.
|
// Creates a matrix that scales along the x-axis, y-axis, and y-axis.
|
||||||
// @param scale Scaling factor for all three axes.
|
|
||||||
// @param result When the method completes, contains the created scaling matrix.
|
|
||||||
static void Scaling(const Float3& scale, Matrix& result)
|
static void Scaling(const Float3& scale, Matrix& result)
|
||||||
{
|
{
|
||||||
Scaling(scale.X, scale.Y, scale.Z, result);
|
Scaling(scale.X, scale.Y, scale.Z, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that scales along the x-axis, y-axis, and y-axis.
|
// Creates a matrix that scales along the x-axis, y-axis, and y-axis.
|
||||||
// @param x Scaling factor that is applied along the x-axis.
|
|
||||||
// @param y Scaling factor that is applied along the y-axis.
|
|
||||||
// @param z Scaling factor that is applied along the z-axis.
|
|
||||||
// @returns The created scaling matrix.
|
|
||||||
static Matrix Scaling(float x, float y, float z)
|
static Matrix Scaling(float x, float y, float z)
|
||||||
{
|
{
|
||||||
Matrix result = Identity;
|
Matrix result = Identity;
|
||||||
@@ -729,10 +648,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that scales along the x-axis, y-axis, and y-axis.
|
// Creates a matrix that scales along the x-axis, y-axis, and y-axis.
|
||||||
// @param x Scaling factor that is applied along the x-axis.
|
|
||||||
// @param y Scaling factor that is applied along the y-axis.
|
|
||||||
// @param z Scaling factor that is applied along the z-axis.
|
|
||||||
// @param result When the method completes, contains the created scaling matrix.
|
|
||||||
static void Scaling(float x, float y, float z, Matrix& result)
|
static void Scaling(float x, float y, float z, Matrix& result)
|
||||||
{
|
{
|
||||||
result = Identity;
|
result = Identity;
|
||||||
@@ -742,8 +657,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that uniformly scales along all three axis.
|
// Creates a matrix that uniformly scales along all three axis.
|
||||||
// @param scale The uniform scale that is applied along all axis.
|
|
||||||
// @returns The created scaling matrix.
|
|
||||||
static Matrix Scaling(float scale)
|
static Matrix Scaling(float scale)
|
||||||
{
|
{
|
||||||
Matrix result = Identity;
|
Matrix result = Identity;
|
||||||
@@ -752,17 +665,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that uniformly scales along all three axis.
|
// Creates a matrix that uniformly scales along all three axis.
|
||||||
// @param scale The uniform scale that is applied along all axis.
|
|
||||||
// @param result When the method completes, contains the created scaling matrix.
|
|
||||||
static void Scaling(float scale, Matrix& result)
|
static void Scaling(float scale, Matrix& result)
|
||||||
{
|
{
|
||||||
result = Identity;
|
result = Identity;
|
||||||
result.M11 = result.M22 = result.M33 = scale;
|
result.M11 = result.M22 = result.M33 = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that rotates around the x-axis.
|
// Creates a matrix that rotates around the x-axis. Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
||||||
// @param angle Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
|
||||||
// @returns The created rotation matrix.
|
|
||||||
static Matrix RotationX(float angle)
|
static Matrix RotationX(float angle)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
@@ -770,14 +679,10 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that rotates around the x-axis.
|
// Creates a matrix that rotates around the x-axis. Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
||||||
// @param angle Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
|
||||||
// @param result When the method completes, contains the created rotation matrix.
|
|
||||||
static void RotationX(float angle, Matrix& result);
|
static void RotationX(float angle, Matrix& result);
|
||||||
|
|
||||||
// Creates a matrix that rotates around the y-axis.
|
// Creates a matrix that rotates around the y-axis. Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
||||||
// @param angle Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
|
||||||
// @returns The created rotation matrix.
|
|
||||||
static Matrix RotationY(float angle)
|
static Matrix RotationY(float angle)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
@@ -785,14 +690,10 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that rotates around the y-axis.
|
// Creates a matrix that rotates around the y-axis. Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
||||||
// @param angle Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
|
||||||
// @param result When the method completes, contains the created rotation matrix.
|
|
||||||
static void RotationY(float angle, Matrix& result);
|
static void RotationY(float angle, Matrix& result);
|
||||||
|
|
||||||
// Creates a matrix that rotates around the z-axis.
|
// Creates a matrix that rotates around the z-axis. Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
||||||
// @param angle Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
|
||||||
// @returns The created rotation matrix.
|
|
||||||
static Matrix RotationZ(float angle)
|
static Matrix RotationZ(float angle)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
@@ -800,15 +701,10 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that rotates around the z-axis.
|
// Creates a matrix that rotates around the z-axis. Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
||||||
// @param angle Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
|
||||||
// @param result When the method completes, contains the created rotation matrix.
|
|
||||||
static void RotationZ(float angle, Matrix& result);
|
static void RotationZ(float angle, Matrix& result);
|
||||||
|
|
||||||
// Creates a matrix that rotates around an arbitrary axis.
|
// Creates a matrix that rotates around an arbitrary axis (normalized). Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
||||||
// @param axis The axis around which to rotate. This parameter is assumed to be normalized.
|
|
||||||
// @param angle Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
|
||||||
// @returns The created rotation matrix
|
|
||||||
static Matrix RotationAxis(const Float3& axis, float angle)
|
static Matrix RotationAxis(const Float3& axis, float angle)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
@@ -816,10 +712,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a matrix that rotates around an arbitrary axis.
|
// Creates a matrix that rotates around an arbitrary axis (normalized). Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
||||||
// @param axis The axis around which to rotate. This parameter is assumed to be normalized.
|
|
||||||
// @param angle Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.
|
|
||||||
// @param result When the method completes, contains the created rotation matrix.
|
|
||||||
static void RotationAxis(const Float3& axis, float angle, Matrix& result);
|
static void RotationAxis(const Float3& axis, float angle, Matrix& result);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -842,10 +735,6 @@ public:
|
|||||||
static void RotationQuaternion(const Quaternion& rotation, Matrix& result);
|
static void RotationQuaternion(const Quaternion& rotation, Matrix& result);
|
||||||
|
|
||||||
// Creates a rotation matrix with a specified yaw, pitch, and roll.
|
// Creates a rotation matrix with a specified yaw, pitch, and roll.
|
||||||
// @param yaw Yaw around the y-axis, in radians.
|
|
||||||
// @param pitch Pitch around the x-axis, in radians.
|
|
||||||
// @param roll Roll around the z-axis, in radians.
|
|
||||||
// @returns The created rotation matrix.
|
|
||||||
static Matrix RotationYawPitchRoll(float yaw, float pitch, float roll)
|
static Matrix RotationYawPitchRoll(float yaw, float pitch, float roll)
|
||||||
{
|
{
|
||||||
Matrix result;
|
Matrix result;
|
||||||
@@ -854,34 +743,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a rotation matrix with a specified yaw, pitch, and roll.
|
// Creates a rotation matrix with a specified yaw, pitch, and roll.
|
||||||
// @param yaw Yaw around the y-axis, in radians.
|
|
||||||
// @param pitch Pitch around the x-axis, in radians.
|
|
||||||
// @param roll Roll around the z-axis, in radians.
|
|
||||||
// @param result When the method completes, contains the created rotation matrix.
|
|
||||||
static void RotationYawPitchRoll(float yaw, float pitch, float roll, Matrix& result);
|
static void RotationYawPitchRoll(float yaw, float pitch, float roll, Matrix& result);
|
||||||
|
|
||||||
// Creates a translation matrix using the specified offsets.
|
// Creates a translation matrix using the specified offsets.
|
||||||
// @param value The offset for all three coordinate planes.
|
|
||||||
// @returns The created translation matrix.
|
|
||||||
static Matrix Translation(const Float3& value);
|
static Matrix Translation(const Float3& value);
|
||||||
|
|
||||||
// Creates a translation matrix using the specified offsets.
|
// Creates a translation matrix using the specified offsets.
|
||||||
// @param value The offset for all three coordinate planes.
|
|
||||||
// @param result When the method completes, contains the created translation matrix.
|
|
||||||
static void Translation(const Float3& value, Matrix& result);
|
static void Translation(const Float3& value, Matrix& result);
|
||||||
|
|
||||||
// Creates a translation matrix using the specified offsets.
|
// Creates a translation matrix using the specified offsets.
|
||||||
// @param x X-coordinate offset.
|
|
||||||
// @param y Y-coordinate offset.
|
|
||||||
// @param z Z-coordinate offset.
|
|
||||||
// @param result When the method completes, contains the created translation matrix.
|
|
||||||
static void Translation(float x, float y, float z, Matrix& result);
|
static void Translation(float x, float y, float z, Matrix& result);
|
||||||
|
|
||||||
// Creates a skew/shear matrix by means of a translation vector, a rotation vector, and a rotation angle.
|
// Creates a skew/shear matrix by means of a translation vector, a rotation vector, and a rotation angle.
|
||||||
// @param angle The rotation angle.
|
|
||||||
// @param rotationVec The rotation vector.
|
|
||||||
// @param transVec The translation vector.
|
|
||||||
// @param matrix Contains the created skew/shear matrix.
|
|
||||||
static void Skew(float angle, const Float3& rotationVec, const Float3& transVec, Matrix& matrix);
|
static void Skew(float angle, const Float3& rotationVec, const Float3& transVec, Matrix& matrix);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -894,79 +767,55 @@ public:
|
|||||||
static void Transformation(const Float3& scaling, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
static void Transformation(const Float3& scaling, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
||||||
|
|
||||||
// Creates a 3D affine transformation matrix.
|
// Creates a 3D affine transformation matrix.
|
||||||
// @param scaling Scaling factor.
|
|
||||||
// @param rotation The rotation of the transformation.
|
|
||||||
// @param translation The translation factor of the transformation.
|
|
||||||
// @param result When the method completes, contains the created affine transformation matrix.
|
|
||||||
static void AffineTransformation(float scaling, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
static void AffineTransformation(float scaling, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
||||||
|
|
||||||
// Creates a 3D affine transformation matrix.
|
// Creates a 3D affine transformation matrix.
|
||||||
// @param scaling Scaling factor.
|
|
||||||
// @param rotationCenter The center of the rotation.
|
|
||||||
// @param rotation The rotation of the transformation.
|
|
||||||
// @param translation The translation factor of the transformation.
|
|
||||||
// @param result When the method completes, contains the created affine transformation matrix.
|
|
||||||
static void AffineTransformation(float scaling, const Float3& rotationCenter, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
static void AffineTransformation(float scaling, const Float3& rotationCenter, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
||||||
|
|
||||||
// Creates a 2D affine transformation matrix.
|
// Creates a 2D affine transformation matrix.
|
||||||
// @param scaling Scaling factor.
|
|
||||||
// @param rotation The rotation of the transformation.
|
|
||||||
// @param translation The translation factor of the transformation.
|
|
||||||
// @param result When the method completes, contains the created affine transformation matrix.
|
|
||||||
static void AffineTransformation2D(float scaling, float rotation, const Float2& translation, Matrix& result);
|
static void AffineTransformation2D(float scaling, float rotation, const Float2& translation, Matrix& result);
|
||||||
|
|
||||||
// Creates a 2D affine transformation matrix.
|
// Creates a 2D affine transformation matrix.
|
||||||
// @param scaling Scaling factor.
|
|
||||||
// @param rotationCenter The center of the rotation.
|
|
||||||
// @param rotation The rotation of the transformation.
|
|
||||||
// @param translation The translation factor of the transformation.
|
|
||||||
// @param result When the method completes, contains the created affine transformation matrix.
|
|
||||||
static void AffineTransformation2D(float scaling, const Float2& rotationCenter, float rotation, const Float2& translation, Matrix& result);
|
static void AffineTransformation2D(float scaling, const Float2& rotationCenter, float rotation, const Float2& translation, Matrix& result);
|
||||||
|
|
||||||
// Creates a transformation matrix.
|
// Creates a transformation matrix.
|
||||||
// @param scalingCenter Center point of the scaling operation.
|
|
||||||
// @param scalingRotation Scaling rotation amount.
|
|
||||||
// @param scaling Scaling factor.
|
|
||||||
// @param rotationCenter The center of the rotation.
|
|
||||||
// @param rotation The rotation of the transformation.
|
|
||||||
// @param translation The translation factor of the transformation.
|
|
||||||
// @param result When the method completes, contains the created transformation matrix.
|
|
||||||
static void Transformation(const Float3& scalingCenter, const Quaternion& scalingRotation, const Float3& scaling, const Float3& rotationCenter, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
static void Transformation(const Float3& scalingCenter, const Quaternion& scalingRotation, const Float3& scaling, const Float3& rotationCenter, const Quaternion& rotation, const Float3& translation, Matrix& result);
|
||||||
|
|
||||||
// Creates a 2D transformation matrix.
|
// Creates a 2D transformation matrix.
|
||||||
// @param scalingCenter Center point of the scaling operation.
|
|
||||||
// @param scalingRotation Scaling rotation amount.
|
|
||||||
// @param scaling Scaling factor.
|
|
||||||
// @param rotationCenter The center of the rotation.
|
|
||||||
// @param rotation The rotation of the transformation.
|
|
||||||
// @param translation The translation factor of the transformation.
|
|
||||||
// @param result When the method completes, contains the created transformation matrix.
|
|
||||||
static void Transformation2D(const Float2& scalingCenter, float scalingRotation, const Float2& scaling, const Float2& rotationCenter, float rotation, const Float2& translation, Matrix& result);
|
static void Transformation2D(const Float2& scalingCenter, float scalingRotation, const Float2& scaling, const Float2& rotationCenter, float rotation, const Float2& translation, Matrix& result);
|
||||||
|
|
||||||
// Creates a world matrix with the specified parameters.
|
/// <summary>
|
||||||
// @param position Position of the object. This value is used in translation operations.
|
/// Creates a world matrix with the specified parameters.
|
||||||
// @param forward Forward direction of the object.
|
/// </summary>
|
||||||
// @param up Upward direction of the object; usually [0, 1, 0].
|
/// <param name="position">Position of the object. This value is used in translation operations.</param>
|
||||||
// @returns Created world matrix of given transformation world.
|
/// <param name="forward">Forward direction of the object.</param>
|
||||||
|
/// <param name="up">Upward direction of the object; usually [0, 1, 0].</param>
|
||||||
|
/// <returns>Created world matrix of given transformation world.</returns>
|
||||||
static Matrix CreateWorld(const Float3& position, const Float3& forward, const Float3& up);
|
static Matrix CreateWorld(const Float3& position, const Float3& forward, const Float3& up);
|
||||||
|
|
||||||
// Creates a world matrix with the specified parameters.
|
/// <summary>
|
||||||
// @param position Position of the object. This value is used in translation operations.
|
/// Creates a world matrix with the specified parameters.
|
||||||
// @param forward Forward direction of the object.
|
/// </summary>
|
||||||
// @param up Upward direction of the object; usually [0, 1, 0].
|
/// <param name="position">Position of the object. This value is used in translation operations.</param>
|
||||||
// @param result Created world matrix of given transformation world.
|
/// <param name="forward">Forward direction of the object.</param>
|
||||||
|
/// <param name="up">Upward direction of the object; usually [0, 1, 0].</param>
|
||||||
|
/// <param name="result">Created world matrix of given transformation world.</param>
|
||||||
static void CreateWorld(const Float3& position, const Float3& forward, const Float3& up, Matrix& result);
|
static void CreateWorld(const Float3& position, const Float3& forward, const Float3& up, Matrix& result);
|
||||||
|
|
||||||
// Creates a new Matrix that rotates around an arbitrary vector.
|
/// <summary>
|
||||||
// @param axis The axis to rotate around.
|
/// Creates a new Matrix that rotates around an arbitrary vector.
|
||||||
// @param angle The angle to rotate around the vector.
|
/// </summary>
|
||||||
// @returns Result matrix.
|
/// <param name="axis">The axis to rotate around.</param>
|
||||||
|
/// <param name="angle">The angle to rotate around the vector.</param>
|
||||||
|
/// <returns>Result matrix.</returns>
|
||||||
static Matrix CreateFromAxisAngle(const Float3& axis, float angle);
|
static Matrix CreateFromAxisAngle(const Float3& axis, float angle);
|
||||||
|
|
||||||
// Creates a new Matrix that rotates around an arbitrary vector.
|
/// <summary>
|
||||||
// @param axis The axis to rotate around.
|
/// Creates a new Matrix that rotates around an arbitrary vector.
|
||||||
// @param angle The angle to rotate around the vector.
|
/// </summary>
|
||||||
// @param result Result matrix.
|
/// <param name="axis"The axis to rotate around.></param>
|
||||||
|
/// <param name="angle">The angle to rotate around the vector.</param>
|
||||||
|
/// <param name="result">Result matrix.</param>
|
||||||
static void CreateFromAxisAngle(const Float3& axis, float angle, Matrix& result);
|
static void CreateFromAxisAngle(const Float3& axis, float angle, Matrix& result);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ public:
|
|||||||
Vector3 GetSize() const;
|
Vector3 GetSize() const;
|
||||||
|
|
||||||
// Returns the square size of the OBB taking into consideration the scaling applied to the transformation matrix.
|
// Returns the square size of the OBB taking into consideration the scaling applied to the transformation matrix.
|
||||||
// @returns The size of the consideration.
|
|
||||||
Vector3 GetSizeSquared() const;
|
Vector3 GetSizeSquared() const;
|
||||||
|
|
||||||
// Gets the center of the OBB.
|
// Gets the center of the OBB.
|
||||||
@@ -85,13 +84,11 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Transforms this box using a transformation matrix.
|
// Transforms this box using a transformation matrix.
|
||||||
// @param mat The transformation matrix.
|
|
||||||
void Transform(const Matrix& matrix);
|
void Transform(const Matrix& matrix);
|
||||||
void Transform(const ::Transform& transform);
|
void Transform(const ::Transform& transform);
|
||||||
|
|
||||||
// Scales the OBB by scaling its Extents without affecting the Transformation matrix.
|
// Scales the OBB by scaling its Extents without affecting the Transformation matrix.
|
||||||
// By keeping Transformation matrix scaling-free, the collision detection methods will be more accurate.
|
// By keeping Transformation matrix scaling-free, the collision detection methods will be more accurate.
|
||||||
// @param scaling Scale to apply to the box.
|
|
||||||
void Scale(const Vector3& scaling)
|
void Scale(const Vector3& scaling)
|
||||||
{
|
{
|
||||||
Extents *= scaling;
|
Extents *= scaling;
|
||||||
@@ -99,14 +96,12 @@ public:
|
|||||||
|
|
||||||
// Scales the OBB by scaling its Extents without affecting the Transformation matrix.
|
// Scales the OBB by scaling its Extents without affecting the Transformation matrix.
|
||||||
// By keeping Transformation matrix scaling-free, the collision detection methods will be more accurate.
|
// By keeping Transformation matrix scaling-free, the collision detection methods will be more accurate.
|
||||||
// @param scaling Scale to apply to the box.
|
|
||||||
void Scale(Real scaling)
|
void Scale(Real scaling)
|
||||||
{
|
{
|
||||||
Extents *= scaling;
|
Extents *= scaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translates the OBB to a new position using a translation vector.
|
// Translates the OBB to a new position using a translation vector.
|
||||||
// @param translation the translation vector.
|
|
||||||
void Translate(const Vector3& translation)
|
void Translate(const Vector3& translation)
|
||||||
{
|
{
|
||||||
Transformation.Translation += translation;
|
Transformation.Translation += translation;
|
||||||
@@ -165,38 +160,26 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Determines whether a OBB contains a point.
|
// Determines whether a OBB contains a point.
|
||||||
// @param point The point to test.
|
|
||||||
// @returns The type of containment the two objects have.
|
|
||||||
ContainmentType Contains(const Vector3& point, Real* distance = nullptr) const;
|
ContainmentType Contains(const Vector3& point, Real* distance = nullptr) const;
|
||||||
|
|
||||||
// Determines whether a OBB contains a BoundingSphere.
|
/// <summary>
|
||||||
// @param sphere The sphere to test.
|
/// Determines whether a OBB contains a sphere.
|
||||||
// @param ignoreScale Optimize the check operation by assuming that OBB has no scaling applied.
|
/// </summary>
|
||||||
// @returns The type of containment the two objects have.
|
/// <param name="sphere">The sphere to test.</param>
|
||||||
|
/// <param name="ignoreScale">Optimize the check operation by assuming that OBB has no scaling applied.</param>
|
||||||
|
/// <returns>The type of containment the two objects have.</returns>
|
||||||
ContainmentType Contains(const BoundingSphere& sphere, bool ignoreScale = false) const;
|
ContainmentType Contains(const BoundingSphere& sphere, bool ignoreScale = false) const;
|
||||||
|
|
||||||
// Determines whether there is an intersection between a Ray and a OBB.
|
// Determines whether there is an intersection between oriented box and a ray. Returns point of the intersection.
|
||||||
// @param ray The ray to test.
|
|
||||||
// @param point When the method completes, contains the point of intersection, or Vector3.Zero if there was no intersection.
|
|
||||||
// @returns Whether the two objects intersected.
|
|
||||||
bool Intersects(const Ray& ray, Vector3& point) const;
|
bool Intersects(const Ray& ray, Vector3& point) const;
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Ray.
|
// Determines if there is an intersection between oriented box and a ray. Returns distance to the intersection.
|
||||||
// @param ray The ray to test.
|
|
||||||
// @param distance When the method completes, contains the distance of the intersection, or 0 if there was no intersection.
|
|
||||||
// @returns Whether the two objects intersected.
|
|
||||||
bool Intersects(const Ray& ray, Real& distance) const;
|
bool Intersects(const Ray& ray, Real& distance) const;
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Ray.
|
// Determines if there is an intersection between oriented box and a ray. Returns distance to the intersection and surface normal.
|
||||||
// @param ray The ray to test.
|
|
||||||
// @param distance When the method completes, contains the distance of the intersection, or 0 if there was no intersection.
|
|
||||||
// @param normal When the method completes, contains the intersection surface normal vector, or Vector3::Up if there was no intersection.
|
|
||||||
// @returns Whether the two objects intersected.
|
|
||||||
bool Intersects(const Ray& ray, Real& distance, Vector3& normal) const;
|
bool Intersects(const Ray& ray, Real& distance, Vector3& normal) const;
|
||||||
|
|
||||||
// Determines whether there is an intersection between a Ray and a OBB.
|
// Determines whether there is an intersection between a Ray and a OBB.
|
||||||
// @param ray The ray to test.
|
|
||||||
// @returns Whether the two objects intersected.
|
|
||||||
bool Intersects(const Ray& ray) const
|
bool Intersects(const Ray& ray) const
|
||||||
{
|
{
|
||||||
Vector3 point;
|
Vector3 point;
|
||||||
|
|||||||
@@ -7,9 +7,6 @@
|
|||||||
#include "Quaternion.h"
|
#include "Quaternion.h"
|
||||||
#include "../Types/String.h"
|
#include "../Types/String.h"
|
||||||
|
|
||||||
const Real Plane::DistanceEpsilon = 0.0001f;
|
|
||||||
const Real Plane::NormalEpsilon = 1.0f / 65535.0f;
|
|
||||||
|
|
||||||
Plane::Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3)
|
Plane::Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3)
|
||||||
{
|
{
|
||||||
Vector3 cross;
|
Vector3 cross;
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
API_STRUCT() struct FLAXENGINE_API Plane
|
API_STRUCT() struct FLAXENGINE_API Plane
|
||||||
{
|
{
|
||||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Plane);
|
DECLARE_SCRIPTING_TYPE_MINIMAL(Plane);
|
||||||
public:
|
|
||||||
static const Real DistanceEpsilon;
|
static constexpr Real DistanceEpsilon = 0.0001f;
|
||||||
static const Real NormalEpsilon;
|
static constexpr Real NormalEpsilon = 1.0f / 65535.0f;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -132,170 +132,102 @@ public:
|
|||||||
public:
|
public:
|
||||||
static Vector3 Intersection(const Plane& inPlane1, const Plane& inPlane2, const Plane& inPlane3);
|
static Vector3 Intersection(const Plane& inPlane1, const Plane& inPlane2, const Plane& inPlane3);
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a point
|
// Determines if there is an intersection between plane and a point.
|
||||||
// @param point The point to test
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
PlaneIntersectionType Intersects(const Vector3& point) const
|
PlaneIntersectionType Intersects(const Vector3& point) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::PlaneIntersectsPoint(*this, point);
|
return CollisionsHelper::PlaneIntersectsPoint(*this, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
// summary>
|
// Determines if there is an intersection between plane and a ray.
|
||||||
// Determines if there is an intersection between the current object and a Ray
|
|
||||||
// @param ray The ray to test
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Ray& ray) const
|
bool Intersects(const Ray& ray) const
|
||||||
{
|
{
|
||||||
Real distance;
|
Real distance;
|
||||||
return CollisionsHelper::RayIntersectsPlane(ray, *this, distance);
|
return CollisionsHelper::RayIntersectsPlane(ray, *this, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// summary>
|
// Determines if there is an intersection between plane and a ray. Returns distance to the intersection.
|
||||||
// Determines if there is an intersection between the current object and a Ray.
|
|
||||||
// /summary>
|
|
||||||
// @param ray The ray to test
|
|
||||||
// @param distance When the method completes, contains the distance of the intersection, or 0 if there was no intersection
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Ray& ray, Real& distance) const
|
bool Intersects(const Ray& ray, Real& distance) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::RayIntersectsPlane(ray, *this, distance);
|
return CollisionsHelper::RayIntersectsPlane(ray, *this, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// summary>
|
// Determines if there is an intersection between plane and a ray.
|
||||||
// Determines if there is an intersection between the current object and a Ray.
|
|
||||||
// /summary>
|
|
||||||
// @param ray The ray to test
|
|
||||||
// @param point When the method completes, contains the point of intersection, or <see const="Vector3.Zero"/> if there was no intersection
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Ray& ray, Vector3& point) const
|
bool Intersects(const Ray& ray, Vector3& point) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::RayIntersectsPlane(ray, *this, point);
|
return CollisionsHelper::RayIntersectsPlane(ray, *this, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Plane
|
// Determines if there is an intersection between two planes.
|
||||||
// @param plane The plane to test
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Plane& plane) const
|
bool Intersects(const Plane& plane) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::PlaneIntersectsPlane(*this, plane);
|
return CollisionsHelper::PlaneIntersectsPlane(*this, plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Plane
|
// Determines if there is an intersection between two planes. Returns ray that defines a line of intersection.
|
||||||
// @param plane The plane to test
|
|
||||||
// @param line When the method completes, contains the line of intersection as a Ray, or a zero ray if there was no intersection
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Plane& plane, Ray& line) const
|
bool Intersects(const Plane& plane, Ray& line) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::PlaneIntersectsPlane(*this, plane, line);
|
return CollisionsHelper::PlaneIntersectsPlane(*this, plane, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a triangle
|
// Determines if there is an intersection between plane and a triangle.
|
||||||
// @param vertex1 The first vertex of the triangle to test
|
|
||||||
// @param vertex2 The second vertex of the triangle to test
|
|
||||||
// @param vertex3 The third vertex of the triangle to test
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
PlaneIntersectionType Intersects(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3) const
|
PlaneIntersectionType Intersects(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::PlaneIntersectsTriangle(*this, vertex1, vertex2, vertex3);
|
return CollisionsHelper::PlaneIntersectsTriangle(*this, vertex1, vertex2, vertex3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Bounding Box
|
// Determines if there is an intersection between plane and a box.
|
||||||
// @param box The box to test
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
PlaneIntersectionType Intersects(const BoundingBox& box) const
|
PlaneIntersectionType Intersects(const BoundingBox& box) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::PlaneIntersectsBox(*this, box);
|
return CollisionsHelper::PlaneIntersectsBox(*this, box);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Bounding Sphere
|
// Determines if there is an intersection between plane and a sphere.
|
||||||
// @param sphere The sphere to test
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
PlaneIntersectionType Intersects(const BoundingSphere& sphere) const
|
PlaneIntersectionType Intersects(const BoundingSphere& sphere) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::PlaneIntersectsSphere(*this, sphere);
|
return CollisionsHelper::PlaneIntersectsSphere(*this, sphere);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Scales the plane by the given scaling factor
|
// Scales the plane by the given factor.
|
||||||
// @param value The plane to scale
|
|
||||||
// @param scale The amount by which to scale the plane
|
|
||||||
// @param result When the method completes, contains the scaled plane
|
|
||||||
static void Multiply(const Plane& value, Real scale, Plane& result);
|
static void Multiply(const Plane& value, Real scale, Plane& result);
|
||||||
|
|
||||||
// Scales the plane by the given scaling factor
|
// Scales the plane by the given factor.
|
||||||
// @param value The plane to scale
|
|
||||||
// @param scale The amount by which to scale the plane
|
|
||||||
// @returns The scaled plane
|
|
||||||
static Plane Multiply(const Plane& value, Real scale);
|
static Plane Multiply(const Plane& value, Real scale);
|
||||||
|
|
||||||
// Calculates the dot product of the specified vector and plane
|
// Calculates the dot product of the specified vector and plane.
|
||||||
// @param left The source plane
|
|
||||||
// @param right The source vector
|
|
||||||
// @param result When the method completes, contains the dot product of the specified plane and vector
|
|
||||||
static void Dot(const Plane& left, const Vector4& right, Real& result);
|
static void Dot(const Plane& left, const Vector4& right, Real& result);
|
||||||
|
|
||||||
// Calculates the dot product of the specified vector and plane
|
// Calculates the dot product of the specified vector and plane.
|
||||||
// @param left The source plane
|
|
||||||
// @param right The source vector
|
|
||||||
// @returns The dot product of the specified plane and vector
|
|
||||||
static Real Dot(const Plane& left, const Vector4& right);
|
static Real Dot(const Plane& left, const Vector4& right);
|
||||||
|
|
||||||
// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane
|
// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane.
|
||||||
// @param left The source plane
|
|
||||||
// @param right The source vector
|
|
||||||
// @param result When the method completes, contains the dot product of a specified vector and the normal of the Plane plus the distance value of the plane
|
|
||||||
static void DotCoordinate(const Plane& left, const Vector3& right, Real& result);
|
static void DotCoordinate(const Plane& left, const Vector3& right, Real& result);
|
||||||
|
|
||||||
// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane
|
// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane.
|
||||||
// @param left The source plane
|
|
||||||
// @param right The source vector
|
|
||||||
// @returns The dot product of a specified vector and the normal of the Plane plus the distance value of the plane
|
|
||||||
static Real DotCoordinate(const Plane& left, const Vector3& right);
|
static Real DotCoordinate(const Plane& left, const Vector3& right);
|
||||||
|
|
||||||
// Calculates the dot product of the specified vector and the normal of the plane
|
// Calculates the dot product of the specified vector and the normal of the plane.
|
||||||
// @param left The source plane
|
|
||||||
// @param right The source vector
|
|
||||||
// @param result When the method completes, contains the dot product of the specified vector and the normal of the plane
|
|
||||||
static void DotNormal(const Plane& left, const Vector3& right, Real& result);
|
static void DotNormal(const Plane& left, const Vector3& right, Real& result);
|
||||||
|
|
||||||
// Calculates the dot product of the specified vector and the normal of the plane
|
// Calculates the dot product of the specified vector and the normal of the plane.
|
||||||
// @param left The source plane
|
|
||||||
// @param right The source vector
|
|
||||||
// @returns The dot product of the specified vector and the normal of the plane
|
|
||||||
static Real DotNormal(const Plane& left, const Vector3& right);
|
static Real DotNormal(const Plane& left, const Vector3& right);
|
||||||
|
|
||||||
// Changes the coefficients of the normal vector of the plane to make it of unit length
|
// Changes the coefficients of the normal vector of the plane to make it of unit length.
|
||||||
// @param plane The source plane
|
|
||||||
// @param result When the method completes, contains the normalized plane
|
|
||||||
static void Normalize(const Plane& plane, Plane& result);
|
static void Normalize(const Plane& plane, Plane& result);
|
||||||
|
|
||||||
// Changes the coefficients of the normal vector of the plane to make it of unit length
|
// Changes the coefficients of the normal vector of the plane to make it of unit length.
|
||||||
// @param plane The source plane
|
|
||||||
// @returns The normalized plane
|
|
||||||
static Plane Normalize(const Plane& plane);
|
static Plane Normalize(const Plane& plane);
|
||||||
|
|
||||||
// Transforms a normalized plane by a quaternion rotation
|
// Transforms a normalized plane by a quaternion rotation.
|
||||||
// @param plane The normalized source plane
|
|
||||||
// @param rotation The quaternion rotation
|
|
||||||
// @param result When the method completes, contains the transformed plane
|
|
||||||
static void Transform(const Plane& plane, const Quaternion& rotation, Plane& result);
|
static void Transform(const Plane& plane, const Quaternion& rotation, Plane& result);
|
||||||
|
|
||||||
// Transforms a normalized plane by a quaternion rotation
|
// Transforms a normalized plane by a quaternion rotation.
|
||||||
// @param plane The normalized source plane
|
|
||||||
// @param rotation The quaternion rotation
|
|
||||||
// @returns The transformed plane
|
|
||||||
static Plane Transform(const Plane& plane, const Quaternion& rotation);
|
static Plane Transform(const Plane& plane, const Quaternion& rotation);
|
||||||
|
|
||||||
// Transforms a normalized plane by a matrix
|
// Transforms a normalized plane by a matrix.
|
||||||
// @param plane The normalized source plane
|
|
||||||
// @param transformation The transformation matrix
|
|
||||||
// @param result When the method completes, contains the transformed plane
|
|
||||||
static void Transform(const Plane& plane, const Matrix& transformation, Plane& result);
|
static void Transform(const Plane& plane, const Matrix& transformation, Plane& result);
|
||||||
|
|
||||||
// Transforms a normalized plane by a matrix
|
// Transforms a normalized plane by a matrix.
|
||||||
// @param plane The normalized source plane
|
|
||||||
// @param transformation The transformation matrix
|
|
||||||
// @returns When the method completes, contains the transformed plane
|
|
||||||
static Plane Transform(const Plane& plane, const Matrix& transformation);
|
static Plane Transform(const Plane& plane, const Matrix& transformation);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,22 @@ Float3 Quaternion::operator*(const Float3& vector) const
|
|||||||
return Float3::Transform(vector, *this);
|
return Float3::Transform(vector, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Quaternion::Add(const Quaternion& left, const Quaternion& right, Quaternion& result)
|
||||||
|
{
|
||||||
|
result.X = left.X + right.X;
|
||||||
|
result.Y = left.Y + right.Y;
|
||||||
|
result.Z = left.Z + right.Z;
|
||||||
|
result.W = left.W + right.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quaternion::Subtract(const Quaternion& left, const Quaternion& right, Quaternion& result)
|
||||||
|
{
|
||||||
|
result.X = left.X - right.X;
|
||||||
|
result.Y = left.Y - right.Y;
|
||||||
|
result.Z = left.Z - right.Z;
|
||||||
|
result.W = left.W - right.W;
|
||||||
|
}
|
||||||
|
|
||||||
void Quaternion::Multiply(const Quaternion& left, const Quaternion& right, Quaternion& result)
|
void Quaternion::Multiply(const Quaternion& left, const Quaternion& right, Quaternion& result)
|
||||||
{
|
{
|
||||||
const float a = left.Y * right.Z - left.Z * right.Y;
|
const float a = left.Y * right.Z - left.Z * right.Y;
|
||||||
@@ -112,6 +128,14 @@ void Quaternion::Multiply(const Quaternion& left, const Quaternion& right, Quate
|
|||||||
result.W = left.W * right.W - d;
|
result.W = left.W * right.W - d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Quaternion::Negate(const Quaternion& value, Quaternion& result)
|
||||||
|
{
|
||||||
|
result.X = -value.X;
|
||||||
|
result.Y = -value.Y;
|
||||||
|
result.Z = -value.Z;
|
||||||
|
result.W = -value.W;
|
||||||
|
}
|
||||||
|
|
||||||
void Quaternion::Lerp(const Quaternion& start, const Quaternion& end, float amount, Quaternion& result)
|
void Quaternion::Lerp(const Quaternion& start, const Quaternion& end, float amount, Quaternion& result)
|
||||||
{
|
{
|
||||||
const float inverse = 1.0f - amount;
|
const float inverse = 1.0f - amount;
|
||||||
@@ -542,10 +566,8 @@ void Quaternion::RotationYawPitchRoll(float yaw, float pitch, float roll, Quater
|
|||||||
Quaternion Quaternion::GetRotationFromNormal(const Vector3& normal, const Transform& reference)
|
Quaternion Quaternion::GetRotationFromNormal(const Vector3& normal, const Transform& reference)
|
||||||
{
|
{
|
||||||
Float3 up = reference.GetUp();
|
Float3 up = reference.GetUp();
|
||||||
const float dot = Vector3::Dot(normal, up);
|
const Real dot = Vector3::Dot(normal, up);
|
||||||
if (Math::NearEqual(Math::Abs(dot), 1))
|
if (Math::NearEqual(Math::Abs(dot), 1))
|
||||||
{
|
|
||||||
up = reference.GetRight();
|
up = reference.GetRight();
|
||||||
}
|
|
||||||
return Quaternion::LookRotation(normal, up);
|
return Quaternion::LookRotation(normal, up);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ namespace FlaxEngine
|
|||||||
public static float AngleBetween(Quaternion a, Quaternion b)
|
public static float AngleBetween(Quaternion a, Quaternion b)
|
||||||
{
|
{
|
||||||
float num = Dot(a, b);
|
float num = Dot(a, b);
|
||||||
return num > 0.9999999f ? 0 : Mathf.Acos(Mathf.Min(Mathf.Abs(num), 1f)) * 2f * 57.29578f;
|
return num > Tolerance ? 0 : Mathf.Acos(Mathf.Min(Mathf.Abs(num), 1f)) * 2f * 57.29578f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1602,7 +1602,7 @@ namespace FlaxEngine
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool operator ==(Quaternion left, Quaternion right)
|
public static bool operator ==(Quaternion left, Quaternion right)
|
||||||
{
|
{
|
||||||
return Dot(ref left, ref right) > 0.9999999f;
|
return Dot(ref left, ref right) > Tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1614,7 +1614,7 @@ namespace FlaxEngine
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool operator !=(Quaternion left, Quaternion right)
|
public static bool operator !=(Quaternion left, Quaternion right)
|
||||||
{
|
{
|
||||||
return Dot(ref left, ref right) <= 0.9999999f;
|
return Dot(ref left, ref right) <= Tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1714,7 +1714,7 @@ namespace FlaxEngine
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Equals(ref Quaternion other)
|
public bool Equals(ref Quaternion other)
|
||||||
{
|
{
|
||||||
//return Dot(ref this, ref other) > 0.9999999f;
|
//return Dot(ref this, ref other) > Tolerance;
|
||||||
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z) && Mathf.NearEqual(other.W, W);
|
return Mathf.NearEqual(other.X, X) && Mathf.NearEqual(other.Y, Y) && Mathf.NearEqual(other.Z, Z) && Mathf.NearEqual(other.W, W);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ struct Matrix3x3;
|
|||||||
API_STRUCT() struct FLAXENGINE_API Quaternion
|
API_STRUCT() struct FLAXENGINE_API Quaternion
|
||||||
{
|
{
|
||||||
DECLARE_SCRIPTING_TYPE_MINIMAL(Quaternion);
|
DECLARE_SCRIPTING_TYPE_MINIMAL(Quaternion);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Equality tolerance factor used when comparing quaternions via dot operation.
|
||||||
|
/// </summary>
|
||||||
|
API_FIELD() static constexpr Real Tolerance = 0.9999999f;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@@ -342,7 +348,7 @@ public:
|
|||||||
/// <returns><c>true</c> if the specified <see cref="Quaternion" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the specified <see cref="Quaternion" /> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||||
FORCE_INLINE bool operator==(const Quaternion& other) const
|
FORCE_INLINE bool operator==(const Quaternion& other) const
|
||||||
{
|
{
|
||||||
return Dot(*this, other) > 0.9999999f;
|
return Dot(*this, other) > Tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -364,7 +370,7 @@ public:
|
|||||||
/// <returns><c>true</c> if the specified <see cref="Quaternion" /> structures are equal; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the specified <see cref="Quaternion" /> structures are equal; otherwise, <c>false</c>.</returns>
|
||||||
static bool NearEqual(const Quaternion& a, const Quaternion& b)
|
static bool NearEqual(const Quaternion& a, const Quaternion& b)
|
||||||
{
|
{
|
||||||
return Dot(a, b) > 0.9999999f;
|
return Dot(a, b) > Tolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -423,37 +429,16 @@ public:
|
|||||||
static float AngleBetween(const Quaternion& a, const Quaternion& b)
|
static float AngleBetween(const Quaternion& a, const Quaternion& b)
|
||||||
{
|
{
|
||||||
const float dot = Dot(a, b);
|
const float dot = Dot(a, b);
|
||||||
return dot > 0.9999999f ? 0 : Math::Acos(Math::Min(Math::Abs(dot), 1.0f)) * 2.0f * 57.29578f;
|
return dot > Tolerance ? 0 : Math::Acos(Math::Min(Math::Abs(dot), 1.0f)) * 2.0f * 57.29578f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds two quaternions
|
// Adds two quaternions.
|
||||||
// @param left The first quaternion to add
|
static void Add(const Quaternion& left, const Quaternion& right, Quaternion& result);
|
||||||
// @param right The second quaternion to add
|
|
||||||
// @param result When the method completes, contains the sum of the two quaternions
|
|
||||||
static void Add(const Quaternion& left, const Quaternion& right, Quaternion& result)
|
|
||||||
{
|
|
||||||
result.X = left.X + right.X;
|
|
||||||
result.Y = left.Y + right.Y;
|
|
||||||
result.Z = left.Z + right.Z;
|
|
||||||
result.W = left.W + right.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtracts two quaternions
|
// Subtracts two quaternions.
|
||||||
// @param left The first quaternion to subtract
|
static void Subtract(const Quaternion& left, const Quaternion& right, Quaternion& result);
|
||||||
// @param right The second quaternion to subtract
|
|
||||||
// @param result When the method completes, contains the difference of the two quaternions
|
|
||||||
static void Subtract(const Quaternion& left, const Quaternion& right, Quaternion& result)
|
|
||||||
{
|
|
||||||
result.X = left.X - right.X;
|
|
||||||
result.Y = left.Y - right.Y;
|
|
||||||
result.Z = left.Z - right.Z;
|
|
||||||
result.W = left.W - right.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scales a quaternion by the given value
|
// Scales a quaternion by the given value.
|
||||||
// @param value The quaternion to scale
|
|
||||||
// @param scale The amount by which to scale the quaternion
|
|
||||||
// @param result When the method completes, contains the scaled quaternion
|
|
||||||
static void Multiply(const Quaternion& value, float scale, Quaternion& result)
|
static void Multiply(const Quaternion& value, float scale, Quaternion& result)
|
||||||
{
|
{
|
||||||
result.X = value.X * scale;
|
result.X = value.X * scale;
|
||||||
@@ -462,35 +447,16 @@ public:
|
|||||||
result.W = value.W * scale;
|
result.W = value.W * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiplies a quaternion by another
|
// Multiplies a quaternion by another.
|
||||||
// @param left The first quaternion to multiply
|
|
||||||
// @param right The second quaternion to multiply
|
|
||||||
// @param result When the method completes, contains the multiplied quaternion
|
|
||||||
static void Multiply(const Quaternion& left, const Quaternion& right, Quaternion& result);
|
static void Multiply(const Quaternion& left, const Quaternion& right, Quaternion& result);
|
||||||
|
|
||||||
// Reverses the direction of a given quaternion
|
// Reverses the direction of a given quaternion.
|
||||||
// @param value The quaternion to negate
|
static void Negate(const Quaternion& value, Quaternion& result);
|
||||||
// @param result When the method completes, contains a quaternion facing in the opposite direction
|
|
||||||
static void Negate(const Quaternion& value, Quaternion& result)
|
|
||||||
{
|
|
||||||
result.X = -value.X;
|
|
||||||
result.Y = -value.Y;
|
|
||||||
result.Z = -value.Z;
|
|
||||||
result.W = -value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Performs a linear interpolation between two quaternions
|
// Performs a linear interpolation between two quaternions.
|
||||||
// @param start Start quaternion
|
|
||||||
// @param end End quaternion
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end
|
|
||||||
// @param result When the method completes, contains the linear interpolation of the two quaternions
|
|
||||||
static void Lerp(const Quaternion& start, const Quaternion& end, float amount, Quaternion& result);
|
static void Lerp(const Quaternion& start, const Quaternion& end, float amount, Quaternion& result);
|
||||||
|
|
||||||
// Performs a linear interpolation between two quaternion
|
// Performs a linear interpolation between two quaternion.
|
||||||
// @param start Start quaternion
|
|
||||||
// @param end End quaternion
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end
|
|
||||||
// @returns The linear interpolation of the two quaternions
|
|
||||||
static Quaternion Lerp(const Quaternion& start, const Quaternion& end, float amount)
|
static Quaternion Lerp(const Quaternion& start, const Quaternion& end, float amount)
|
||||||
{
|
{
|
||||||
Quaternion result;
|
Quaternion result;
|
||||||
@@ -498,47 +464,25 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a quaternion given a rotation and an axis
|
// Creates a quaternion given an angle cosine (radians in range [-1,1]) and an axis of rotation (normalized).
|
||||||
// @param axis The axis of rotation
|
|
||||||
// @param angle The angle of rotation (in radians).
|
|
||||||
// @param result When the method completes, contains the newly created quaternion
|
|
||||||
static void RotationAxis(const Float3& axis, float angle, Quaternion& result);
|
static void RotationAxis(const Float3& axis, float angle, Quaternion& result);
|
||||||
|
|
||||||
// Creates a quaternion given a angle cosine and an axis
|
// Creates a quaternion given an angle cosine (radians in range [-1,1]) and an axis of rotation (normalized).
|
||||||
// @param axis The axis of rotation
|
|
||||||
// @param cos The angle cosine, it must be within [-1,1] range (in radians).
|
|
||||||
// @param result When the method completes, contains the newly created quaternion
|
|
||||||
static void RotationCosAxis(const Float3& axis, float cos, Quaternion& result);
|
static void RotationCosAxis(const Float3& axis, float cos, Quaternion& result);
|
||||||
|
|
||||||
// Creates a quaternion given a rotation matrix
|
// Creates a quaternion given a rotation matrix.
|
||||||
// @param matrix The rotation matrix
|
|
||||||
// @param result When the method completes, contains the newly created quaternion
|
|
||||||
static void RotationMatrix(const Matrix& matrix, Quaternion& result);
|
static void RotationMatrix(const Matrix& matrix, Quaternion& result);
|
||||||
|
|
||||||
// Creates a quaternion given a rotation matrix
|
// Creates a quaternion given a rotation matrix.
|
||||||
// @param matrix The rotation matrix
|
|
||||||
// @param result When the method completes, contains the newly created quaternion
|
|
||||||
static void RotationMatrix(const Matrix3x3& matrix, Quaternion& result);
|
static void RotationMatrix(const Matrix3x3& matrix, Quaternion& result);
|
||||||
|
|
||||||
// Creates a left-handed, look-at quaternion
|
// Creates a left-handed, look-at quaternion.
|
||||||
// @param eye The position of the viewer's eye
|
|
||||||
// @param target The camera look-at target
|
|
||||||
// @param up The camera's up vector
|
|
||||||
// @param result When the method completes, contains the created look-at quaternion
|
|
||||||
static void LookAt(const Float3& eye, const Float3& target, const Float3& up, Quaternion& result);
|
static void LookAt(const Float3& eye, const Float3& target, const Float3& up, Quaternion& result);
|
||||||
|
|
||||||
// Creates a left-handed, look-at quaternion
|
// Creates a left-handed, look-at quaternion.
|
||||||
// @param forward The camera's forward direction
|
|
||||||
// @param up The camera's up vector
|
|
||||||
// @param result When the method completes, contains the created look-at quaternion
|
|
||||||
static void RotationLookAt(const Float3& forward, const Float3& up, Quaternion& result);
|
static void RotationLookAt(const Float3& forward, const Float3& up, Quaternion& result);
|
||||||
|
|
||||||
// Creates a left-handed spherical billboard that rotates around a specified object position
|
// Creates a left-handed spherical billboard that rotates around a specified object position.
|
||||||
// @param objectPosition The position of the object around which the billboard will rotate
|
|
||||||
// @param cameraPosition The position of the camera
|
|
||||||
// @param cameraUpFloat The up vector of the camera
|
|
||||||
// @param cameraForwardFloat The forward vector of the camera
|
|
||||||
// @param result When the method completes, contains the created billboard quaternion
|
|
||||||
static void Billboard(const Float3& objectPosition, const Float3& cameraPosition, const Float3& cameraUpFloat, const Float3& cameraForwardFloat, Quaternion& result);
|
static void Billboard(const Float3& objectPosition, const Float3& cameraPosition, const Float3& cameraUpFloat, const Float3& cameraForwardFloat, Quaternion& result);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -613,9 +557,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a quaternion given a rotation matrix
|
// Creates a quaternion given a rotation matrix.
|
||||||
// @param matrix The rotation matrix
|
|
||||||
// @returns The newly created quaternion
|
|
||||||
static Quaternion RotationMatrix(const Matrix& matrix)
|
static Quaternion RotationMatrix(const Matrix& matrix)
|
||||||
{
|
{
|
||||||
Quaternion result;
|
Quaternion result;
|
||||||
@@ -623,30 +565,16 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interpolates between two quaternions, using spherical linear interpolation
|
// Interpolates between two quaternions, using spherical linear interpolation.
|
||||||
// @param start Start quaternion
|
|
||||||
// @param end End quaternion
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end
|
|
||||||
// @param result When the method completes, contains the spherical linear interpolation of the two quaternions
|
|
||||||
static void Slerp(const Quaternion& start, const Quaternion& end, float amount, Quaternion& result);
|
static void Slerp(const Quaternion& start, const Quaternion& end, float amount, Quaternion& result);
|
||||||
|
|
||||||
// Creates a quaternion given a yaw, pitch, and roll value (is using degrees)
|
// Creates a quaternion given a yaw, pitch, and roll value (in degrees).
|
||||||
// @param x Roll (in degrees)
|
|
||||||
// @param x Pitch (in degrees)
|
|
||||||
// @param x Yaw (in degrees)
|
|
||||||
// @returns Result rotation
|
|
||||||
static Quaternion Euler(float x, float y, float z);
|
static Quaternion Euler(float x, float y, float z);
|
||||||
|
|
||||||
// Creates a quaternion given a yaw, pitch, and roll value (is using degrees)
|
// Creates a quaternion given a yaw, pitch, and roll value in order: X:roll, Y:pitch, Z:yaw (in degrees).
|
||||||
// @param euler Euler angle rotation with values in order: X:roll, Y:pitch, Z:yaw (in degrees)
|
|
||||||
// @returns Result rotation
|
|
||||||
static Quaternion Euler(const Float3& euler);
|
static Quaternion Euler(const Float3& euler);
|
||||||
|
|
||||||
// Creates a quaternion given a yaw, pitch, and roll value (is using radians)
|
// Creates a quaternion given a yaw, pitch, and roll value (in radians).
|
||||||
// @param yaw The yaw of rotation (in radians)
|
|
||||||
// @param pitch The pitch of rotation (in radians)
|
|
||||||
// @param roll The roll of rotation (in radians)
|
|
||||||
// @param result When the method completes, contains the newly created quaternion
|
|
||||||
static Quaternion RotationYawPitchRoll(float yaw, float pitch, float roll)
|
static Quaternion RotationYawPitchRoll(float yaw, float pitch, float roll)
|
||||||
{
|
{
|
||||||
Quaternion result;
|
Quaternion result;
|
||||||
@@ -654,11 +582,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a quaternion given a yaw, pitch, and roll value (is using radians)
|
// Creates a quaternion given a yaw, pitch, and roll value (in radians).
|
||||||
// @param yaw The yaw of rotation (in radians)
|
|
||||||
// @param pitch The pitch of rotation (in radians)
|
|
||||||
// @param roll The roll of rotation (in radians)
|
|
||||||
// @param result When the method completes, contains the newly created quaternion
|
|
||||||
static void RotationYawPitchRoll(float yaw, float pitch, float roll, Quaternion& result);
|
static void RotationYawPitchRoll(float yaw, float pitch, float roll, Quaternion& result);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public:
|
|||||||
Vector3 GetPoint(Real distance) const;
|
Vector3 GetPoint(Real distance) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a point.
|
/// Determines if there is an intersection between ray and a point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="point">The point to test.</param>
|
/// <param name="point">The point to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="Ray" />.
|
/// Determines if there is an intersection between two rays.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -103,7 +103,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="Ray" />.
|
/// Determines if there is an intersection between ray and a <see cref="Ray" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero" /> if there was no intersection.
|
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero" /> if there was no intersection.
|
||||||
@@ -115,7 +115,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="Plane" />.
|
/// Determines if there is an intersection between ray and a <see cref="Plane" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plane">The plane to test</param>
|
/// <param name="plane">The plane to test</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -126,7 +126,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="Plane" />.
|
/// Determines if there is an intersection between ray and a <see cref="Plane" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plane">The plane to test.</param>
|
/// <param name="plane">The plane to test.</param>
|
||||||
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
||||||
@@ -137,7 +137,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="Plane" />.
|
/// Determines if there is an intersection between ray and a <see cref="Plane" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plane">The plane to test.</param>
|
/// <param name="plane">The plane to test.</param>
|
||||||
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero" /> if there was no intersection.</param>
|
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero" /> if there was no intersection.</param>
|
||||||
@@ -148,7 +148,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a triangle.
|
/// Determines if there is an intersection between ray and a triangle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||||
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
||||||
@@ -161,7 +161,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a triangle.
|
/// Determines if there is an intersection between ray and a triangle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||||
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
||||||
@@ -174,7 +174,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a triangle.
|
/// Determines if there is an intersection between ray and a triangle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||||
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
||||||
@@ -187,7 +187,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="BoundingBox" />.
|
/// Determines if there is an intersection between ray and a <see cref="BoundingBox" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="box">The box to test.</param>
|
/// <param name="box">The box to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -198,7 +198,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="BoundingBox" />.
|
/// Determines if there is an intersection between ray and a <see cref="BoundingBox" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="box">The box to test.</param>
|
/// <param name="box">The box to test.</param>
|
||||||
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
||||||
@@ -209,7 +209,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="BoundingBox" />.
|
/// Determines if there is an intersection between ray and a <see cref="BoundingBox" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="box">The box to test.</param>
|
/// <param name="box">The box to test.</param>
|
||||||
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero" /> if there was no intersection.</param>
|
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero" /> if there was no intersection.</param>
|
||||||
@@ -220,7 +220,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="BoundingSphere" />.
|
/// Determines if there is an intersection between ray and a <see cref="BoundingSphere" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sphere">The sphere to test.</param>
|
/// <param name="sphere">The sphere to test.</param>
|
||||||
/// <returns>Whether the two objects intersected.</returns>
|
/// <returns>Whether the two objects intersected.</returns>
|
||||||
@@ -231,7 +231,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="BoundingSphere" />.
|
/// Determines if there is an intersection between ray and a <see cref="BoundingSphere" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sphere">The sphere to test.</param>
|
/// <param name="sphere">The sphere to test.</param>
|
||||||
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
/// <param name="distance">When the method completes, contains the distance of the intersection, or 0 if there was no intersection.</param>
|
||||||
@@ -242,7 +242,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a <see cref="BoundingSphere" />.
|
/// Determines if there is an intersection between ray and a <see cref="BoundingSphere" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sphere">The sphere to test.</param>
|
/// <param name="sphere">The sphere to test.</param>
|
||||||
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero" /> if there was no intersection.</param>
|
/// <param name="point">When the method completes, contains the point of intersection, or <see cref="Vector3.Zero" /> if there was no intersection.</param>
|
||||||
|
|||||||
@@ -33,20 +33,24 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Rectangle() = default;
|
Rectangle() = default;
|
||||||
|
|
||||||
// Init
|
/// <summary>
|
||||||
// @param x Rectangle location X coordinate
|
/// Initializes a new instance of the <see cref="Rectangle"/> struct.
|
||||||
// @param y Rectangle location Y coordinate
|
/// </summary>
|
||||||
// @param width Rectangle width
|
/// <param name="x">The X coordinate of the upper left corner.</param>
|
||||||
// @param height Rectangle height
|
/// <param name="y">The Y coordinate of the upper left corner.</param>
|
||||||
|
/// <param name="width">The width.</param>
|
||||||
|
/// <param name="height">The height.</param>
|
||||||
Rectangle(float x, float y, float width, float height)
|
Rectangle(float x, float y, float width, float height)
|
||||||
: Location(x, y)
|
: Location(x, y)
|
||||||
, Size(width, height)
|
, Size(width, height)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init
|
/// <summary>
|
||||||
// @param location Rectangle location point
|
/// Initializes a new instance of the <see cref="Rectangle"/> struct.
|
||||||
// @param width Rectangle size
|
/// </summary>
|
||||||
|
/// <param name="location">The location of the upper left corner.</param>
|
||||||
|
/// <param name="size">The size.</param>
|
||||||
Rectangle(const Float2& location, const Float2& size)
|
Rectangle(const Float2& location, const Float2& size)
|
||||||
: Location(location)
|
: Location(location)
|
||||||
, Size(size)
|
, Size(size)
|
||||||
@@ -57,123 +61,114 @@ public:
|
|||||||
String ToString() const;
|
String ToString() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Returns width of the rectangle
|
// Gets width of the rectangle.
|
||||||
float GetWidth() const
|
float GetWidth() const
|
||||||
{
|
{
|
||||||
return Size.X;
|
return Size.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns height of the rectangle
|
// Gets height of the rectangle.
|
||||||
float GetHeight() const
|
float GetHeight() const
|
||||||
{
|
{
|
||||||
return Size.Y;
|
return Size.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets Y coordinate of the top edge of the rectangle
|
// Gets Y coordinate of the top edge of the rectangle.
|
||||||
float GetY() const
|
float GetY() const
|
||||||
{
|
{
|
||||||
return Location.Y;
|
return Location.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets Y coordinate of the top edge of the rectangle
|
// Gets Y coordinate of the top edge of the rectangle.
|
||||||
float GetTop() const
|
float GetTop() const
|
||||||
{
|
{
|
||||||
return Location.Y;
|
return Location.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets Y coordinate of the bottom edge of the rectangle
|
// Gets Y coordinate of the bottom edge of the rectangle.
|
||||||
float GetBottom() const
|
float GetBottom() const
|
||||||
{
|
{
|
||||||
return Location.Y + Size.Y;
|
return Location.Y + Size.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets X coordinate of the left edge of the rectangle
|
// Gets X coordinate of the left edge of the rectangle.
|
||||||
float GetX() const
|
float GetX() const
|
||||||
{
|
{
|
||||||
return Location.X;
|
return Location.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets X coordinate of the left edge of the rectangle
|
// Gets X coordinate of the left edge of the rectangle.
|
||||||
float GetLeft() const
|
float GetLeft() const
|
||||||
{
|
{
|
||||||
return Location.X;
|
return Location.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets X coordinate of the right edge of the rectangle
|
// Gets X coordinate of the right edge of the rectangle.
|
||||||
float GetRight() const
|
float GetRight() const
|
||||||
{
|
{
|
||||||
return Location.X + Size.X;
|
return Location.X + Size.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets position of the upper left corner of the rectangle
|
// Gets position of the upper left corner of the rectangle.
|
||||||
Float2 GetUpperLeft() const
|
Float2 GetUpperLeft() const
|
||||||
{
|
{
|
||||||
return Location;
|
return Location;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets position of the upper right corner of the rectangle
|
// Gets position of the upper right corner of the rectangle.
|
||||||
Float2 GetUpperRight() const
|
Float2 GetUpperRight() const
|
||||||
{
|
{
|
||||||
return Location + Float2(Size.X, 0);
|
return Location + Float2(Size.X, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets position of the bottom right corner of the rectangle
|
// Gets position of the bottom right corner of the rectangle.
|
||||||
Float2 GetLowerRight() const
|
Float2 GetLowerRight() const
|
||||||
{
|
{
|
||||||
return Location + Size;
|
return Location + Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets position of the bottom left corner of the rectangle
|
// Gets position of the bottom left corner of the rectangle.
|
||||||
Float2 GetLowerLeft() const
|
Float2 GetLowerLeft() const
|
||||||
{
|
{
|
||||||
return Location + Float2(0, Size.Y);
|
return Location + Float2(0, Size.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets position of the upper left corner of the rectangle
|
// Gets position of the upper left corner of the rectangle.
|
||||||
Float2 GetTopLeft() const
|
Float2 GetTopLeft() const
|
||||||
{
|
{
|
||||||
return Location;
|
return Location;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets position of the upper right corner of the rectangle
|
// Gets position of the upper right corner of the rectangle.
|
||||||
Float2 GetTopRight() const
|
Float2 GetTopRight() const
|
||||||
{
|
{
|
||||||
return Location + Float2(Size.X, 0);
|
return Location + Float2(Size.X, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets position of the bottom right corner of the rectangle
|
// Gets position of the bottom right corner of the rectangle.
|
||||||
Float2 GetBottomRight() const
|
Float2 GetBottomRight() const
|
||||||
{
|
{
|
||||||
return Location + Size;
|
return Location + Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets position of the bottom left corner of the rectangle
|
// Gets position of the bottom left corner of the rectangle.
|
||||||
Float2 GetBottomLeft() const
|
Float2 GetBottomLeft() const
|
||||||
{
|
{
|
||||||
return Location + Float2(0, Size.Y);
|
return Location + Float2(0, Size.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
// Gets center position of the rectangle.
|
||||||
/// Gets center position of the rectangle
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Center point</returns>
|
|
||||||
Float2 GetCenter() const
|
Float2 GetCenter() const
|
||||||
{
|
{
|
||||||
return Location + Size * 0.5f;
|
return Location + Size * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Offset rectangle Location point
|
|
||||||
// @param v Offset to add
|
|
||||||
// @returns Result rectangle
|
|
||||||
Rectangle operator+(const Float2& v) const
|
Rectangle operator+(const Float2& v) const
|
||||||
{
|
{
|
||||||
return Rectangle(Location + v, Size);
|
return Rectangle(Location + v, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offset rectangle Location point
|
|
||||||
// @param v Offset to subtract
|
|
||||||
// @returns Result rectangle
|
|
||||||
Rectangle operator-(const Float2& v) const
|
Rectangle operator-(const Float2& v) const
|
||||||
{
|
{
|
||||||
return Rectangle(Location - v, Size);
|
return Rectangle(Location - v, Size);
|
||||||
@@ -236,81 +231,51 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Checks if rectangle contains given point
|
// Checks if rectangle contains given point.
|
||||||
// @param location Point location to check
|
|
||||||
// @returns True if point is inside rectangle's area
|
|
||||||
bool Contains(const Float2& location) const;
|
bool Contains(const Float2& location) const;
|
||||||
|
|
||||||
// Determines whether this rectangle entirely contains a specified rectangle
|
// Determines whether this rectangle entirely contains a specified rectangle.
|
||||||
// @param value The rectangle to evaluate
|
|
||||||
// @returns True if this rectangle entirely contains the specified rectangle, or false if not
|
|
||||||
bool Contains(const Rectangle& value) const;
|
bool Contains(const Rectangle& value) const;
|
||||||
|
|
||||||
// Determines whether a specified rectangle intersects with this rectangle
|
// Determines whether a specified rectangle intersects with this rectangle.
|
||||||
// @ value The rectangle to evaluate
|
|
||||||
// @returns True if the specified rectangle intersects with this one, otherwise false
|
|
||||||
bool Intersects(const Rectangle& value) const;
|
bool Intersects(const Rectangle& value) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Offset rectangle position
|
// Offsets rectangle position.
|
||||||
// @param x X coordinate offset
|
|
||||||
// @param y Y coordinate offset
|
|
||||||
void Offset(float x, float y);
|
void Offset(float x, float y);
|
||||||
|
|
||||||
// Offset rectangle position
|
// Offsets rectangle position.
|
||||||
// @param offset X and Y coordinate offset
|
|
||||||
void Offset(const Float2& offset);
|
void Offset(const Float2& offset);
|
||||||
|
|
||||||
// Make offseted rectangle
|
// Make offseted rectangle.
|
||||||
// @param offset X and Y coordinate offset
|
|
||||||
// @returns Offseted rectangle
|
|
||||||
Rectangle MakeOffsetted(const Float2& offset) const;
|
Rectangle MakeOffsetted(const Float2& offset) const;
|
||||||
|
|
||||||
public:
|
// Expands rectangle area in all directions by given amount.
|
||||||
// Expand rectangle area in all directions by given amount
|
|
||||||
// @param toExpand Amount of units to expand a rectangle
|
|
||||||
void Expand(float toExpand);
|
void Expand(float toExpand);
|
||||||
|
|
||||||
// Make expanded rectangle area in all directions by given amount
|
// Makes expanded rectangle area in all directions by given amount.
|
||||||
// @param toExpand Amount of units to expand a rectangle
|
|
||||||
// @returns Expanded rectangle
|
|
||||||
Rectangle MakeExpanded(float toExpand) const;
|
Rectangle MakeExpanded(float toExpand) const;
|
||||||
|
|
||||||
public:
|
// Scale rectangle area in all directions by given amount.
|
||||||
// Scale rectangle area in all directions by given amount
|
|
||||||
// @param scale Scale value to expand a rectangle
|
|
||||||
void Scale(float scale);
|
void Scale(float scale);
|
||||||
|
|
||||||
// Make scaled rectangle area in all directions by given amount
|
// Makes scaled rectangle area in all directions by given amount.
|
||||||
// @param scale Scale value to expand a rectangle
|
|
||||||
// @returns Scaled rectangle
|
|
||||||
Rectangle MakeScaled(float scale) const;
|
Rectangle MakeScaled(float scale) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Calculates a rectangle that contains the union of rectangle and the arbitrary point
|
// Calculates a rectangle that contains the union of rectangle and the arbitrary point.
|
||||||
// @param a The rectangle
|
|
||||||
// @param b The point
|
|
||||||
// @returns Rectangle that contains both rectangle and the point
|
|
||||||
static Rectangle Union(const Rectangle& a, const Float2& b);
|
static Rectangle Union(const Rectangle& a, const Float2& b);
|
||||||
|
|
||||||
// Calculates a rectangle that contains the union of a and b rectangles
|
// Calculates a rectangle that contains the union of a and b rectangles.
|
||||||
// @param a First rectangle
|
|
||||||
// @param b Second rectangle
|
|
||||||
// @returns Rectangle that contains both a and b rectangles
|
|
||||||
static Rectangle Union(const Rectangle& a, const Rectangle& b);
|
static Rectangle Union(const Rectangle& a, const Rectangle& b);
|
||||||
|
|
||||||
// Calculates a rectangle that contains the shared part of a and b rectangles
|
// Calculates a rectangle that contains the shared part of a and b rectangles.
|
||||||
// @param a First rectangle
|
|
||||||
// @param b Second rectangle
|
|
||||||
// @returns Rectangle that contains shared part of a and b rectangles
|
|
||||||
static Rectangle Shared(const Rectangle& a, const Rectangle& b);
|
static Rectangle Shared(const Rectangle& a, const Rectangle& b);
|
||||||
|
|
||||||
// Create rectangle from two points
|
// Creates rectangle from two points.
|
||||||
// @param p1 First point
|
|
||||||
// @param p2 Second point
|
|
||||||
// @returns Rectangle that contains both p1 and p2
|
|
||||||
static Rectangle FromPoints(const Float2& p1, const Float2& p2);
|
static Rectangle FromPoints(const Float2& p1, const Float2& p2);
|
||||||
|
|
||||||
|
// Creates rectangle from list of points.
|
||||||
static Rectangle FromPoints(const Float2* points, int32 pointsCount);
|
static Rectangle FromPoints(const Float2* points, int32 pointsCount);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "CollisionsHelper.h"
|
#include "CollisionsHelper.h"
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a three dimensional triangle.
|
/// Represents a three-dimensional triangle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
struct FLAXENGINE_API Triangle
|
struct FLAXENGINE_API Triangle
|
||||||
{
|
{
|
||||||
@@ -52,38 +52,26 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Determines if there is an intersection between the current object and a Ray
|
// Determines if there is an intersection between triangle and a ray.
|
||||||
// @param ray The ray to test
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Ray& ray) const
|
bool Intersects(const Ray& ray) const
|
||||||
{
|
{
|
||||||
Real distance;
|
Real distance;
|
||||||
return CollisionsHelper::RayIntersectsTriangle(ray, V0, V1, V2, distance);
|
return CollisionsHelper::RayIntersectsTriangle(ray, V0, V1, V2, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Ray
|
/// Determines if there is an intersection between triangle and a ray. Returns distance to the intersection.
|
||||||
// @param ray The ray to test
|
|
||||||
// @param distance When the method completes, contains the distance of the intersection, or 0 if there was no intersection
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Ray& ray, Real& distance) const
|
bool Intersects(const Ray& ray, Real& distance) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::RayIntersectsTriangle(ray, V0, V1, V2, distance);
|
return CollisionsHelper::RayIntersectsTriangle(ray, V0, V1, V2, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Ray
|
// Determines if there is an intersection between triangle and a ray. Returns distance to the intersection and surface normal vector.
|
||||||
// @param ray The ray to test
|
|
||||||
// @param distance When the method completes, contains the distance of the intersection, or 0 if there was no intersection
|
|
||||||
// @param normal When the method completes, contains the intersection surface normal vector, or Vector3::Up if there was no intersection
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Ray& ray, Real& distance, Vector3& normal) const
|
bool Intersects(const Ray& ray, Real& distance, Vector3& normal) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::RayIntersectsTriangle(ray, V0, V1, V2, distance, normal);
|
return CollisionsHelper::RayIntersectsTriangle(ray, V0, V1, V2, distance, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines if there is an intersection between the current object and a Ray
|
// Determines if there is an intersection between triangle and a ray. Returns point of intersection.
|
||||||
// @param ray The ray to test
|
|
||||||
// @param point When the method completes, contains the point of intersection, or <see cref="Vector3.Zero"/> if there was no intersection
|
|
||||||
// @returns Whether the two objects intersected
|
|
||||||
bool Intersects(const Ray& ray, Vector3& point) const
|
bool Intersects(const Ray& ray, Vector3& point) const
|
||||||
{
|
{
|
||||||
return CollisionsHelper::RayIntersectsTriangle(ray, V0, V1, V2, point);
|
return CollisionsHelper::RayIntersectsTriangle(ray, V0, V1, V2, point);
|
||||||
|
|||||||
@@ -499,11 +499,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Clamp vector values within given range
|
// Restricts a value to be within a specified range (inclusive min/max).
|
||||||
// @param v Vector to clamp
|
|
||||||
// @param min Minimum value
|
|
||||||
// @param max Maximum value
|
|
||||||
// @returns Clamped vector
|
|
||||||
static Vector2Base Clamp(const Vector2Base& v, const Vector2Base& min, const Vector2Base& max)
|
static Vector2Base Clamp(const Vector2Base& v, const Vector2Base& min, const Vector2Base& max)
|
||||||
{
|
{
|
||||||
Vector2Base result;
|
Vector2Base result;
|
||||||
@@ -511,20 +507,13 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restricts a value to be within a specified range
|
// Restricts a value to be within a specified range (inclusive min/max).
|
||||||
// @param v The value to clamp
|
|
||||||
// @param min The minimum value,
|
|
||||||
// @param max The maximum value
|
|
||||||
// @param result When the method completes, contains the clamped value
|
|
||||||
static void Clamp(const Vector2Base& v, const Vector2Base& min, const Vector2Base& max, Vector2Base& result)
|
static void Clamp(const Vector2Base& v, const Vector2Base& min, const Vector2Base& max, Vector2Base& result)
|
||||||
{
|
{
|
||||||
result = Vector2Base(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y));
|
result = Vector2Base(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates distance between two points in 2D
|
// Calculates distance between two points in 2D.
|
||||||
// @param a 1st point
|
|
||||||
// @param b 2nd point
|
|
||||||
// @returns Distance
|
|
||||||
static T Distance(const Vector2Base& a, const Vector2Base& b)
|
static T Distance(const Vector2Base& a, const Vector2Base& b)
|
||||||
{
|
{
|
||||||
const T x = a.X - b.X;
|
const T x = a.X - b.X;
|
||||||
@@ -532,10 +521,7 @@ public:
|
|||||||
return Math::Sqrt(x * x + y * y);
|
return Math::Sqrt(x * x + y * y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the squared distance between two points in 2D
|
// Calculates the squared distance between two points in 2D.
|
||||||
// @param a 1st point
|
|
||||||
// @param b 2nd point
|
|
||||||
// @returns Distance
|
|
||||||
static T DistanceSquared(const Vector2Base& a, const Vector2Base& b)
|
static T DistanceSquared(const Vector2Base& a, const Vector2Base& b)
|
||||||
{
|
{
|
||||||
const T x = a.X - b.X;
|
const T x = a.X - b.X;
|
||||||
@@ -557,24 +543,14 @@ public:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs a linear interpolation between two vectors
|
// Performs a linear interpolation between two vectors.
|
||||||
// @param start Start vector
|
|
||||||
// @param end End vector
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end
|
|
||||||
// @param result When the method completes, contains the linear interpolation of the two vectors
|
|
||||||
static void Lerp(const Vector2Base& start, const Vector2Base& end, T amount, Vector2Base& result)
|
static void Lerp(const Vector2Base& start, const Vector2Base& end, T amount, Vector2Base& result)
|
||||||
{
|
{
|
||||||
result.X = Math::Lerp(start.X, end.X, amount);
|
result.X = Math::Lerp(start.X, end.X, amount);
|
||||||
result.Y = Math::Lerp(start.Y, end.Y, amount);
|
result.Y = Math::Lerp(start.Y, end.Y, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <summary>
|
|
||||||
// Performs a linear interpolation between two vectors.
|
// Performs a linear interpolation between two vectors.
|
||||||
// </summary>
|
|
||||||
// @param start Start vector,
|
|
||||||
// @param end End vector,
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of @paramref end"/>,
|
|
||||||
// @returns The linear interpolation of the two vectors
|
|
||||||
static Vector2Base Lerp(const Vector2Base& start, const Vector2Base& end, T amount)
|
static Vector2Base Lerp(const Vector2Base& start, const Vector2Base& end, T amount)
|
||||||
{
|
{
|
||||||
Vector2Base result;
|
Vector2Base result;
|
||||||
|
|||||||
@@ -542,11 +542,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Restricts a value to be within a specified range
|
// Restricts a value to be within a specified range (inclusive min/max).
|
||||||
// @param v The value to clamp
|
|
||||||
// @param min The minimum value,
|
|
||||||
// @param max The maximum value
|
|
||||||
// @returns Clamped value
|
|
||||||
static Vector3Base Clamp(const Vector3Base& v, const Vector3Base& min, const Vector3Base& max)
|
static Vector3Base Clamp(const Vector3Base& v, const Vector3Base& min, const Vector3Base& max)
|
||||||
{
|
{
|
||||||
Vector3Base result;
|
Vector3Base result;
|
||||||
@@ -554,11 +550,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restricts a value to be within a specified range
|
// Restricts a value to be within a specified range (inclusive min/max).
|
||||||
// @param v The value to clamp
|
|
||||||
// @param min The minimum value,
|
|
||||||
// @param max The maximum value
|
|
||||||
// @param result When the method completes, contains the clamped value
|
|
||||||
static void Clamp(const Vector3Base& v, const Vector3Base& min, const Vector3Base& max, Vector3Base& result)
|
static void Clamp(const Vector3Base& v, const Vector3Base& min, const Vector3Base& max, Vector3Base& result)
|
||||||
{
|
{
|
||||||
result = Vector3Base(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y), Math::Clamp(v.Z, min.Z, max.Z));
|
result = Vector3Base(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y), Math::Clamp(v.Z, min.Z, max.Z));
|
||||||
@@ -614,10 +606,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the distance between two vectors
|
// Calculates the distance between two vectors.
|
||||||
// @param a The first vector
|
|
||||||
// @param b The second vector
|
|
||||||
// @returns The distance between the two vectors
|
|
||||||
static T Distance(const Vector3Base& a, const Vector3Base& b)
|
static T Distance(const Vector3Base& a, const Vector3Base& b)
|
||||||
{
|
{
|
||||||
const T x = a.X - b.X;
|
const T x = a.X - b.X;
|
||||||
@@ -626,10 +615,7 @@ public:
|
|||||||
return Math::Sqrt(x * x + y * y + z * z);
|
return Math::Sqrt(x * x + y * y + z * z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the squared distance between two vectors
|
// Calculates the squared distance between two vectors.
|
||||||
// @param a The first vector
|
|
||||||
// @param b The second vector
|
|
||||||
// @returns The squared distance between the two vectors
|
|
||||||
static T DistanceSquared(const Vector3Base& a, const Vector3Base& b)
|
static T DistanceSquared(const Vector3Base& a, const Vector3Base& b)
|
||||||
{
|
{
|
||||||
const T x = a.X - b.X;
|
const T x = a.X - b.X;
|
||||||
@@ -653,52 +639,38 @@ public:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs vector normalization (scales vector up to unit length). This is a faster version that does not performs check for length equal 0 (it assumes that input vector is not empty).
|
// Performs vector normalization (scales vector up to unit length). This is a faster version that does not perform check for length equal 0 (it assumes that input vector is not empty).
|
||||||
// @param inout Input vector to normalize (cannot be zero).
|
|
||||||
// @returns Output vector that is normalized (has unit length)
|
|
||||||
static Vector3Base NormalizeFast(const Vector3Base& v)
|
static Vector3Base NormalizeFast(const Vector3Base& v)
|
||||||
{
|
{
|
||||||
const T inv = 1.0f / v.Length();
|
const T inv = 1.0f / v.Length();
|
||||||
return Vector3Base(v.X * inv, v.Y * inv, v.Z * inv);
|
return Vector3Base(v.X * inv, v.Y * inv, v.Z * inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs vector normalization (scales vector up to unit length)
|
// Performs vector normalization (scales vector up to unit length).
|
||||||
// @param inout Input vector to normalize
|
|
||||||
// @param output Output vector that is normalized (has unit length)
|
|
||||||
static FORCE_INLINE void Normalize(const Vector3Base& input, Vector3Base& result)
|
static FORCE_INLINE void Normalize(const Vector3Base& input, Vector3Base& result)
|
||||||
{
|
{
|
||||||
result = Normalize(input);
|
result = Normalize(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dot product with another vector
|
// Calculates the dot product of two vectors.
|
||||||
FORCE_INLINE static T Dot(const Vector3Base& a, const Vector3Base& b)
|
FORCE_INLINE static T Dot(const Vector3Base& a, const Vector3Base& b)
|
||||||
{
|
{
|
||||||
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the cross product of two vectors
|
// Calculates the cross product of two vectors.
|
||||||
// @param a First source vector
|
|
||||||
// @param b Second source vector
|
|
||||||
// @param result When the method completes, contains the cross product of the two vectors
|
|
||||||
static void Cross(const Vector3Base& a, const Vector3Base& b, Vector3Base& result)
|
static void Cross(const Vector3Base& a, const Vector3Base& b, Vector3Base& result)
|
||||||
{
|
{
|
||||||
result = Vector3Base(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
|
result = Vector3Base(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the cross product of two vectors
|
// Calculates the cross product of two vectors.
|
||||||
// @param a First source vector
|
|
||||||
// @param b Second source vector
|
|
||||||
// @returns Cross product of the two vectors
|
|
||||||
static Vector3Base Cross(const Vector3Base& a, const Vector3Base& b)
|
static Vector3Base Cross(const Vector3Base& a, const Vector3Base& b)
|
||||||
{
|
{
|
||||||
return Vector3Base(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
|
return Vector3Base(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs a linear interpolation between two vectors
|
// Performs a linear interpolation between two vectors.
|
||||||
// @param start Start vector
|
|
||||||
// @param end End vector
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end
|
|
||||||
// @param result When the method completes, contains the linear interpolation of the two vectors
|
|
||||||
static void Lerp(const Vector3Base& start, const Vector3Base& end, T amount, Vector3Base& result)
|
static void Lerp(const Vector3Base& start, const Vector3Base& end, T amount, Vector3Base& result)
|
||||||
{
|
{
|
||||||
result.X = Math::Lerp(start.X, end.X, amount);
|
result.X = Math::Lerp(start.X, end.X, amount);
|
||||||
@@ -706,9 +678,7 @@ public:
|
|||||||
result.Z = Math::Lerp(start.Z, end.Z, amount);
|
result.Z = Math::Lerp(start.Z, end.Z, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <summary>
|
|
||||||
// Performs a linear interpolation between two vectors.
|
// Performs a linear interpolation between two vectors.
|
||||||
// </summary>
|
|
||||||
static Vector3Base Lerp(const Vector3Base& start, const Vector3Base& end, T amount)
|
static Vector3Base Lerp(const Vector3Base& start, const Vector3Base& end, T amount)
|
||||||
{
|
{
|
||||||
Vector3Base result;
|
Vector3Base result;
|
||||||
@@ -716,11 +686,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs a cubic interpolation between two vectors
|
// Performs a cubic interpolation between two vectors.
|
||||||
// @param start Start vector
|
|
||||||
// @param end End vector
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end
|
|
||||||
// @param result When the method completes, contains the cubic interpolation of the two vectors
|
|
||||||
static void SmoothStep(const Vector3Base& start, const Vector3Base& end, T amount, Vector3Base& result)
|
static void SmoothStep(const Vector3Base& start, const Vector3Base& end, T amount, Vector3Base& result)
|
||||||
{
|
{
|
||||||
amount = Math::SmoothStep(amount);
|
amount = Math::SmoothStep(amount);
|
||||||
@@ -745,78 +711,39 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Performs a Hermite spline interpolation.
|
// Performs a Hermite spline interpolation.
|
||||||
// @param value1 First source position vector
|
|
||||||
// @param tangent1 First source tangent vector
|
|
||||||
// @param value2 Second source position vector
|
|
||||||
// @param tangent2 Second source tangent vector
|
|
||||||
// @param amount Weighting factor,
|
|
||||||
// @param result When the method completes, contains the result of the Hermite spline interpolation,
|
|
||||||
static FLAXENGINE_API void Hermite(const Vector3Base& value1, const Vector3Base& tangent1, const Vector3Base& value2, const Vector3Base& tangent2, T amount, Vector3Base& result);
|
static FLAXENGINE_API void Hermite(const Vector3Base& value1, const Vector3Base& tangent1, const Vector3Base& value2, const Vector3Base& tangent2, T amount, Vector3Base& result);
|
||||||
|
|
||||||
// Returns the reflection of a vector off a surface that has the specified normal
|
// Returns the reflection of a vector off a surface that has the specified normal.
|
||||||
// @param vector The source vector
|
|
||||||
// @param normal Normal of the surface
|
|
||||||
// @param result When the method completes, contains the reflected vector
|
|
||||||
static FLAXENGINE_API void Reflect(const Vector3Base& vector, const Vector3Base& normal, Vector3Base& result);
|
static FLAXENGINE_API void Reflect(const Vector3Base& vector, const Vector3Base& normal, Vector3Base& result);
|
||||||
|
|
||||||
// Transforms a 3D vector by the given Quaternion rotation
|
// Transforms a 3D vector by the given Quaternion rotation.
|
||||||
// @param vector The vector to rotate
|
|
||||||
// @param rotation The Quaternion rotation to apply
|
|
||||||
// @param result When the method completes, contains the transformed Vector3
|
|
||||||
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Quaternion& rotation, Vector3Base& result);
|
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Quaternion& rotation, Vector3Base& result);
|
||||||
|
|
||||||
// Transforms a 3D vector by the given Quaternion rotation
|
// Transforms a 3D vector by the given Quaternion rotation.
|
||||||
// @param vector The vector to rotate
|
|
||||||
// @param rotation The Quaternion rotation to apply
|
|
||||||
// @returns The transformed Vector3
|
|
||||||
static FLAXENGINE_API Vector3Base Transform(const Vector3Base& vector, const Quaternion& rotation);
|
static FLAXENGINE_API Vector3Base Transform(const Vector3Base& vector, const Quaternion& rotation);
|
||||||
|
|
||||||
// Transforms a 3D vector by the given matrix
|
// Transforms a 3D vector by the given matrix.
|
||||||
// @param vector The source vector
|
|
||||||
// @param transform The transformation matrix
|
|
||||||
// @param result When the method completes, contains the transformed Vector3
|
|
||||||
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Matrix& transform, Vector3Base& result);
|
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Matrix& transform, Vector3Base& result);
|
||||||
|
|
||||||
// Transforms a 3D vector by the given matrix
|
// Transforms a 3D vector by the given matrix.
|
||||||
// @param vector The source vector
|
|
||||||
// @param transform The transformation matrix
|
|
||||||
// @param result When the method completes, contains the transformed Vector3
|
|
||||||
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Matrix3x3& transform, Vector3Base& result);
|
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Matrix3x3& transform, Vector3Base& result);
|
||||||
|
|
||||||
// Transforms a 3D vector by the given transformation
|
// Transforms a 3D vector by the given transformation.
|
||||||
// @param vector The source vector
|
|
||||||
// @param transform The transformation
|
|
||||||
// @param result When the method completes, contains the transformed Vector3
|
|
||||||
static FLAXENGINE_API void Transform(const Vector3Base& vector, const ::Transform& transform, Vector3Base& result);
|
static FLAXENGINE_API void Transform(const Vector3Base& vector, const ::Transform& transform, Vector3Base& result);
|
||||||
|
|
||||||
// Transforms a 3D vector by the given matrix
|
// Transforms a 3D vector by the given matrix.
|
||||||
// @param vector The source vector
|
|
||||||
// @param transform The transformation matrix
|
|
||||||
// @returns Transformed Vector3
|
|
||||||
static FLAXENGINE_API Vector3Base Transform(const Vector3Base& vector, const Matrix& transform);
|
static FLAXENGINE_API Vector3Base Transform(const Vector3Base& vector, const Matrix& transform);
|
||||||
|
|
||||||
// Transforms a 3D vector by the given transformation
|
// Transforms a 3D vector by the given transformation.
|
||||||
// @param vector The source vector
|
|
||||||
// @param transform The transformation
|
|
||||||
// @returns Transformed Vector3
|
|
||||||
static FLAXENGINE_API Vector3Base Transform(const Vector3Base& vector, const ::Transform& transform);
|
static FLAXENGINE_API Vector3Base Transform(const Vector3Base& vector, const ::Transform& transform);
|
||||||
|
|
||||||
// Transforms a 3D vector by the given matrix
|
// Transforms a 3D vector by the given matrix.
|
||||||
// @param vector The source vector
|
|
||||||
// @param transform The transformation matrix
|
|
||||||
// @param result When the method completes, contains the transformed Vector4
|
|
||||||
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Matrix& transform, Vector4Base<T>& result);
|
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Matrix& transform, Vector4Base<T>& result);
|
||||||
|
|
||||||
// Performs a coordinate transformation using the given matrix
|
// Performs a coordinate transformation using the given matrix.
|
||||||
// @param coordinate The coordinate vector to transform
|
|
||||||
// @param transform The transformation matrix
|
|
||||||
// @param result When the method completes, contains the transformed coordinates
|
|
||||||
static FLAXENGINE_API void TransformCoordinate(const Vector3Base& coordinate, const Matrix& transform, Vector3Base& result);
|
static FLAXENGINE_API void TransformCoordinate(const Vector3Base& coordinate, const Matrix& transform, Vector3Base& result);
|
||||||
|
|
||||||
// Performs a normal transformation using the given matrix
|
// Performs a normal transformation using the given matrix.
|
||||||
// @param normal The normal vector to transform
|
|
||||||
// @param transform The transformation matrix
|
|
||||||
// @param result When the method completes, contains the transformed normal
|
|
||||||
static FLAXENGINE_API void TransformNormal(const Vector3Base& normal, const Matrix& transform, Vector3Base& result);
|
static FLAXENGINE_API void TransformNormal(const Vector3Base& normal, const Matrix& transform, Vector3Base& result);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -838,28 +765,10 @@ public:
|
|||||||
return vector - Project(vector, planeNormal);
|
return vector - Project(vector, planeNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Projects a 3D vector from object space into screen space
|
// Projects a 3D vector from object space into screen space using the provided viewport and transformation matrix.
|
||||||
// @param vector The vector to project
|
|
||||||
// @param x The X position of the viewport
|
|
||||||
// @param y The Y position of the viewport
|
|
||||||
// @param width The width of the viewport
|
|
||||||
// @param height The height of the viewport
|
|
||||||
// @param minZ The minimum depth of the viewport
|
|
||||||
// @param maxZ The maximum depth of the viewport
|
|
||||||
// @param worldViewProjection The combined world-view-projection matrix
|
|
||||||
// @param result When the method completes, contains the vector in screen space
|
|
||||||
static FLAXENGINE_API void Project(const Vector3Base& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Vector3Base& result);
|
static FLAXENGINE_API void Project(const Vector3Base& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Vector3Base& result);
|
||||||
|
|
||||||
// Projects a 3D vector from object space into screen space
|
// Projects a 3D vector from object space into screen space using the provided viewport and transformation matrix.
|
||||||
// @param vector The vector to project
|
|
||||||
// @param x The X position of the viewport
|
|
||||||
// @param y The Y position of the viewport
|
|
||||||
// @param width The width of the viewport
|
|
||||||
// @param height The height of the viewport
|
|
||||||
// @param minZ The minimum depth of the viewport
|
|
||||||
// @param maxZ The maximum depth of the viewport
|
|
||||||
// @param worldViewProjection The combined world-view-projection matrix
|
|
||||||
// @returns The vector in screen space
|
|
||||||
static Vector3Base Project(const Vector3Base& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection)
|
static Vector3Base Project(const Vector3Base& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection)
|
||||||
{
|
{
|
||||||
Vector3Base result;
|
Vector3Base result;
|
||||||
@@ -867,28 +776,10 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Projects a 3D vector from screen space into object space
|
// Projects a 3D vector from screen space into object space using the provided viewport and transformation matrix.
|
||||||
// @param vector The vector to project
|
|
||||||
// @param x The X position of the viewport
|
|
||||||
// @param y The Y position of the viewport
|
|
||||||
// @param width The width of the viewport
|
|
||||||
// @param height The height of the viewport
|
|
||||||
// @param minZ The minimum depth of the viewport
|
|
||||||
// @param maxZ The maximum depth of the viewport
|
|
||||||
// @param worldViewProjection The combined world-view-projection matrix
|
|
||||||
// @param result When the method completes, contains the vector in object space
|
|
||||||
static FLAXENGINE_API void Unproject(const Vector3Base& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Vector3Base& result);
|
static FLAXENGINE_API void Unproject(const Vector3Base& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection, Vector3Base& result);
|
||||||
|
|
||||||
// Projects a 3D vector from screen space into object space
|
// Projects a 3D vector from screen space into object space using the provided viewport and transformation matrix.
|
||||||
// @param vector The vector to project
|
|
||||||
// @param x The X position of the viewport
|
|
||||||
// @param y The Y position of the viewport
|
|
||||||
// @param width The width of the viewport
|
|
||||||
// @param height The height of the viewport
|
|
||||||
// @param minZ The minimum depth of the viewport
|
|
||||||
// @param maxZ The maximum depth of the viewport
|
|
||||||
// @param worldViewProjection The combined world-view-projection matrix
|
|
||||||
// @returns The vector in object space
|
|
||||||
static Vector3Base Unproject(const Vector3Base& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection)
|
static Vector3Base Unproject(const Vector3Base& vector, float x, float y, float width, float height, float minZ, float maxZ, const Matrix& worldViewProjection)
|
||||||
{
|
{
|
||||||
Vector3Base result;
|
Vector3Base result;
|
||||||
|
|||||||
@@ -455,11 +455,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Restricts a value to be within a specified range
|
// Restricts a value to be within a specified range (inclusive min/max).
|
||||||
// @param v The value to clamp
|
|
||||||
// @param min The minimum value,
|
|
||||||
// @param max The maximum value
|
|
||||||
// @returns Clamped value
|
|
||||||
static Vector4Base Clamp(const Vector4Base& v, const Vector4Base& min, const Vector4Base& max)
|
static Vector4Base Clamp(const Vector4Base& v, const Vector4Base& min, const Vector4Base& max)
|
||||||
{
|
{
|
||||||
Vector4Base result;
|
Vector4Base result;
|
||||||
@@ -467,21 +463,13 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restricts a value to be within a specified range
|
// Restricts a value to be within a specified range (inclusive min/max).
|
||||||
// @param v The value to clamp
|
|
||||||
// @param min The minimum value,
|
|
||||||
// @param max The maximum value
|
|
||||||
// @param result When the method completes, contains the clamped value
|
|
||||||
static void Clamp(const Vector4Base& v, const Vector4Base& min, const Vector4Base& max, Vector4Base& result)
|
static void Clamp(const Vector4Base& v, const Vector4Base& min, const Vector4Base& max, Vector4Base& result)
|
||||||
{
|
{
|
||||||
result = Vector4Base(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y), Math::Clamp(v.Z, min.Z, max.Z), Math::Clamp(v.W, min.W, max.W));
|
result = Vector4Base(Math::Clamp(v.X, min.X, max.X), Math::Clamp(v.Y, min.Y, max.Y), Math::Clamp(v.Z, min.Z, max.Z), Math::Clamp(v.W, min.W, max.W));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Performs a linear interpolation between two vectors
|
// Performs a linear interpolation between two vectors.
|
||||||
// @param start Start vector
|
|
||||||
// @param end End vector
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of end
|
|
||||||
// @param result When the method completes, contains the linear interpolation of the two vectors
|
|
||||||
static void Lerp(const Vector4Base& start, const Vector4Base& end, T amount, Vector4Base& result)
|
static void Lerp(const Vector4Base& start, const Vector4Base& end, T amount, Vector4Base& result)
|
||||||
{
|
{
|
||||||
result.X = Math::Lerp(start.X, end.X, amount);
|
result.X = Math::Lerp(start.X, end.X, amount);
|
||||||
@@ -490,13 +478,7 @@ public:
|
|||||||
result.W = Math::Lerp(start.W, end.W, amount);
|
result.W = Math::Lerp(start.W, end.W, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <summary>
|
|
||||||
// Performs a linear interpolation between two vectors.
|
// Performs a linear interpolation between two vectors.
|
||||||
// </summary>
|
|
||||||
// @param start Start vector,
|
|
||||||
// @param end End vector,
|
|
||||||
// @param amount Value between 0 and 1 indicating the weight of @paramref end"/>,
|
|
||||||
// @returns The linear interpolation of the two vectors
|
|
||||||
static Vector4Base Lerp(const Vector4Base& start, const Vector4Base& end, T amount)
|
static Vector4Base Lerp(const Vector4Base& start, const Vector4Base& end, T amount)
|
||||||
{
|
{
|
||||||
Vector4Base result;
|
Vector4Base result;
|
||||||
@@ -558,7 +540,7 @@ inline Vector4Base<T> operator/(typename TOtherFloat<T>::Type a, const Vector4Ba
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
inline uint32 GetHash(const Vector4Base<T>& key)
|
inline uint32 GetHash(const Vector4Base<T>& key)
|
||||||
{
|
{
|
||||||
return (((((*(uint32*)&key.X * 397) ^ *(uint32*)&key.Y) * 397) ^ *(uint32*)&key.Z) * 397) ^*(uint32*)&key.W;
|
return (((((*(uint32*)&key.X * 397) ^ *(uint32*)&key.Y) * 397) ^ *(uint32*)&key.Z) * 397) ^ *(uint32*)&key.W;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Math
|
namespace Math
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
struct Matrix;
|
struct Matrix;
|
||||||
struct Rectangle;
|
struct Rectangle;
|
||||||
|
|
||||||
// Describes the viewport dimensions.
|
/// <summary>
|
||||||
|
/// Describes the viewport dimensions.
|
||||||
|
/// </summary>
|
||||||
API_STRUCT(InBuild) struct FLAXENGINE_API Viewport
|
API_STRUCT(InBuild) struct FLAXENGINE_API Viewport
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -54,29 +56,16 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Viewport() = default;
|
Viewport() = default;
|
||||||
|
|
||||||
// Init
|
/// <summary>
|
||||||
// @param x The x coordinate of the upper-left corner of the viewport in pixels
|
/// Initializes a new instance of the <see cref="Viewport"/> struct.
|
||||||
// @param y The y coordinate of the upper-left corner of the viewport in pixels
|
/// </summary>
|
||||||
// @param width The width of the viewport in pixels
|
/// <param name="x">The x coordinate of the upper-left corner of the viewport in pixels.</param>
|
||||||
// @param height The height of the viewport in pixels
|
/// <param name="y">The y coordinate of the upper-left corner of the viewport in pixels.</param>
|
||||||
Viewport(float x, float y, float width, float height)
|
/// <param name="width">The width of the viewport in pixels.</param>
|
||||||
: X(x)
|
/// <param name="height">The height of the viewport in pixels.</param>
|
||||||
, Y(y)
|
/// <param name="minDepth">The minimum depth of the clip volume.</param>
|
||||||
, Width(width)
|
/// <param name="maxDepth">The maximum depth of the clip volumes.</param>
|
||||||
, Height(height)
|
Viewport(float x, float y, float width, float height, float minDepth = 0.0f, float maxDepth = 1.0f)
|
||||||
, MinDepth(0.0f)
|
|
||||||
, MaxDepth(1.0f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init
|
|
||||||
// @param x The x coordinate of the upper-left corner of the viewport in pixels
|
|
||||||
// @param y The y coordinate of the upper-left corner of the viewport in pixels
|
|
||||||
// @param width The width of the viewport in pixels
|
|
||||||
// @param height The height of the viewport in pixels
|
|
||||||
// @param minDepth The minimum depth of the clip volume
|
|
||||||
// @param maxDepth The maximum depth of the clip volume
|
|
||||||
Viewport(float x, float y, float width, float height, float minDepth, float maxDepth)
|
|
||||||
: X(x)
|
: X(x)
|
||||||
, Y(y)
|
, Y(y)
|
||||||
, Width(width)
|
, Width(width)
|
||||||
@@ -100,31 +89,26 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init
|
/// <summary>
|
||||||
// @param bounds A bounding box that defines the location and size of the viewport in a render target
|
/// Initializes a new instance of the <see cref="Viewport"/> struct.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bounds">A bounding rectangle that defines the location and size of the viewport in a render target.</param>
|
||||||
Viewport(const Rectangle& bounds);
|
Viewport(const Rectangle& bounds);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
String ToString() const;
|
String ToString() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Gets the aspect ratio used by the viewport
|
// Gets the aspect ratio used by the viewport.
|
||||||
// @returns The aspect ratio
|
|
||||||
float GetAspectRatio() const
|
float GetAspectRatio() const
|
||||||
{
|
{
|
||||||
if (Height != 0.0f)
|
return Height != 0.0f ? Width / Height : 0.0f;
|
||||||
{
|
|
||||||
return Width / Height;
|
|
||||||
}
|
|
||||||
return 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the size of the viewport
|
// Gets the size of the viewport.
|
||||||
// @eturns The bounds
|
|
||||||
Rectangle GetBounds() const;
|
Rectangle GetBounds() const;
|
||||||
|
|
||||||
// Sets the size of the viewport
|
// Sets the size of the viewport.
|
||||||
// @param bounds The bounds
|
|
||||||
void SetBounds(const Rectangle& bounds);
|
void SetBounds(const Rectangle& bounds);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -139,16 +123,20 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Projects a 3D vector from object space into screen space
|
/// <summary>
|
||||||
// @param source The vector to project
|
/// Projects a 3D vector from object space into screen space.
|
||||||
// @param vp A combined WorldViewProjection matrix
|
/// </summary>
|
||||||
// @param vector The projected vector
|
/// <param name="source">The vector to project.</param>
|
||||||
|
/// <param name="vp">A combined World*View*Projection matrix.</param>
|
||||||
|
/// <param name="result">The projected vector.</param>
|
||||||
void Project(const Vector3& source, const Matrix& vp, Vector3& result) const;
|
void Project(const Vector3& source, const Matrix& vp, Vector3& result) const;
|
||||||
|
|
||||||
// Converts a screen space point into a corresponding point in world space
|
/// <summary>
|
||||||
// @param source The vector to project
|
/// Converts a screen space point into a corresponding point in world space.
|
||||||
// @param vp An inverted combined WorldViewProjection matrix
|
/// </summary>
|
||||||
// @param vector The unprojected vector
|
/// <param name="source">The vector to un-project.</param>
|
||||||
|
/// <param name="ivp">An inverted combined World*View*Projection matrix.</param>
|
||||||
|
/// <param name="result">The un-projected vector</param>
|
||||||
void Unproject(const Vector3& source, const Matrix& ivp, Vector3& result) const;
|
void Unproject(const Vector3& source, const Matrix& ivp, Vector3& result) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,14 @@
|
|||||||
#include "Engine/Core/Formatting.h"
|
#include "Engine/Core/Formatting.h"
|
||||||
#include "Engine/Core/Templates.h"
|
#include "Engine/Core/Templates.h"
|
||||||
|
|
||||||
class String;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Globally Unique Identifier
|
/// Globally Unique Identifier (GUID) represented by 128-bit integer (16 bytes) that can be used across all computers and networks wherever a unique identifier is required. Such an identifier has a very low probability of being duplicated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
API_STRUCT(InBuild, Namespace="System") struct FLAXENGINE_API Guid
|
API_STRUCT(InBuild, Namespace="System") struct FLAXENGINE_API Guid
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Accepted format specifiers for the format parameter
|
/// Accepted format specifiers for the format parameter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
enum class FormatType
|
enum class FormatType
|
||||||
{
|
{
|
||||||
@@ -42,28 +40,28 @@ public:
|
|||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
// The first component
|
// The first component.
|
||||||
uint32 A;
|
uint32 A;
|
||||||
|
|
||||||
// The second component
|
// The second component.
|
||||||
uint32 B;
|
uint32 B;
|
||||||
|
|
||||||
// The third component
|
// The third component.
|
||||||
uint32 C;
|
uint32 C;
|
||||||
|
|
||||||
// The fourth component
|
// The fourth component.
|
||||||
uint32 D;
|
uint32 D;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Raw bytes with the GUID
|
// Raw bytes with the Guid.
|
||||||
byte Raw[16];
|
byte Raw[16];
|
||||||
|
|
||||||
// Raw values with the GUID
|
// Raw values with the Guid.
|
||||||
uint32 Values[4];
|
uint32 Values[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Empty Guid (considered as invalid ID)
|
// Empty Guid (considered as invalid ID).
|
||||||
static Guid Empty;
|
static Guid Empty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -74,11 +72,13 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates and initializes a new Guid from the specified components
|
/// <summary>
|
||||||
// @param a The first component
|
/// Initializes a new instance of the <see cref="Guid"/> struct.
|
||||||
// @param b The second component
|
/// </summary>
|
||||||
// @param c The third component
|
/// <param name="a">The first component.</param>
|
||||||
// @param d The fourth component
|
/// <param name="b">The second component.</param>
|
||||||
|
/// <param name="c">The third component.</param>
|
||||||
|
/// <param name="d">The fourth component.</param>
|
||||||
Guid(uint32 a, uint32 b, uint32 c, uint32 d)
|
Guid(uint32 a, uint32 b, uint32 c, uint32 d)
|
||||||
: A(a)
|
: A(a)
|
||||||
, B(b)
|
, B(b)
|
||||||
@@ -98,41 +98,27 @@ public:
|
|||||||
return ((A ^ other.A) | (B ^ other.B) | (C ^ other.C) | (D ^ other.D)) != 0;
|
return ((A ^ other.A) | (B ^ other.B) | (C ^ other.C) | (D ^ other.D)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provides access to the GUIDs components
|
// Provides access to the Guid components (0...3).
|
||||||
// @param index The index of the component to return (0...3)
|
|
||||||
// @returns The component value
|
|
||||||
uint32& operator[](int32 index)
|
uint32& operator[](int32 index)
|
||||||
{
|
{
|
||||||
ASSERT(index >= 0 && index < 4);
|
ASSERT(index >= 0 && index < 4);
|
||||||
return Values[index];
|
return Values[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provides read-only access to the GUIDs components.
|
// Provides read-only access to the Guid components (0...3).
|
||||||
// @param index The index of the component to return (0...3).
|
|
||||||
// @return The component
|
|
||||||
const uint32& operator[](int index) const
|
const uint32& operator[](int index) const
|
||||||
{
|
{
|
||||||
ASSERT(index >= 0 && index < 4);
|
ASSERT(index >= 0 && index < 4);
|
||||||
return Values[index];
|
return Values[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invalidates the Guid
|
|
||||||
FORCE_INLINE void Invalidate()
|
|
||||||
{
|
|
||||||
A = B = C = D = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks whether this Guid is valid or not. A Guid that has all its components set to zero is considered invalid.
|
// Checks whether this Guid is valid or not. A Guid that has all its components set to zero is considered invalid.
|
||||||
// @return true if valid, otherwise false
|
|
||||||
FORCE_INLINE bool IsValid() const
|
FORCE_INLINE bool IsValid() const
|
||||||
{
|
{
|
||||||
return (A | B | C | D) != 0;
|
return (A | B | C | D) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// Checks if Guid is valid.
|
||||||
/// Checks if Guid is valid
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if Guid isn't empty</returns>
|
|
||||||
explicit operator bool() const
|
explicit operator bool() const
|
||||||
{
|
{
|
||||||
return (A | B | C | D) != 0;
|
return (A | B | C | D) != 0;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create string builder with initial capacity
|
/// Create string builder with initial capacity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="capacity">Initial capacity for chars count</param>
|
/// <param name="capacity">Initial capacity for chars count</param>
|
||||||
StringBuilder(int32 capacity)
|
StringBuilder(int32 capacity)
|
||||||
@@ -36,16 +36,15 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets capacity
|
/// Gets the buffer capacity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Capacity of the string builder</returns>
|
|
||||||
FORCE_INLINE int32 Capacity() const
|
FORCE_INLINE int32 Capacity() const
|
||||||
{
|
{
|
||||||
return _data.Capacity();
|
return _data.Capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets capacity.
|
/// Sets the buffer capacity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="capacity">Capacity to set</param>
|
/// <param name="capacity">Capacity to set</param>
|
||||||
FORCE_INLINE void SetCapacity(const int32 capacity)
|
FORCE_INLINE void SetCapacity(const int32 capacity)
|
||||||
@@ -71,7 +70,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets string
|
/// Gets the string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="result">String</param>
|
/// <param name="result">String</param>
|
||||||
void ToString(String& result) const
|
void ToString(String& result) const
|
||||||
@@ -80,27 +79,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Append single character to the string
|
|
||||||
// @param c Character to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& Append(const Char c)
|
StringBuilder& Append(const Char c)
|
||||||
{
|
{
|
||||||
_data.Add(c);
|
_data.Add(c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append single character to the string
|
|
||||||
// @param c Character to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& Append(const char c)
|
StringBuilder& Append(const char c)
|
||||||
{
|
{
|
||||||
_data.Add(c);
|
_data.Add(c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append characters sequence to the string
|
|
||||||
// @param str String to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& Append(const Char* str)
|
StringBuilder& Append(const Char* str)
|
||||||
{
|
{
|
||||||
const int32 length = StringUtils::Length(str);
|
const int32 length = StringUtils::Length(str);
|
||||||
@@ -108,19 +98,12 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append characters sequence to the string
|
|
||||||
// @param str String to append
|
|
||||||
// @param length String length
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& Append(const Char* str, int32 length)
|
StringBuilder& Append(const Char* str, int32 length)
|
||||||
{
|
{
|
||||||
_data.Add(str, length);
|
_data.Add(str, length);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append characters sequence to the string
|
|
||||||
// @param str String to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& Append(const char* str)
|
StringBuilder& Append(const char* str)
|
||||||
{
|
{
|
||||||
const int32 length = str && *str ? StringUtils::Length(str) : 0;
|
const int32 length = str && *str ? StringUtils::Length(str) : 0;
|
||||||
@@ -131,23 +114,18 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append String to the string
|
|
||||||
// @param str String to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& Append(const String& str)
|
StringBuilder& Append(const String& str)
|
||||||
{
|
{
|
||||||
_data.Add(*str, str.Length());
|
_data.Add(*str, str.Length());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder& Append(const StringView& str)
|
StringBuilder& Append(const StringView& str)
|
||||||
{
|
{
|
||||||
_data.Add(*str, str.Length());
|
_data.Add(*str, str.Length());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append int to the string
|
|
||||||
// @param val Value to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& Append(int32 val)
|
StringBuilder& Append(int32 val)
|
||||||
{
|
{
|
||||||
auto str = StringUtils::ToString(val);
|
auto str = StringUtils::ToString(val);
|
||||||
@@ -155,9 +133,6 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append int to the string
|
|
||||||
// @param val Value to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& Append(uint32 val)
|
StringBuilder& Append(uint32 val)
|
||||||
{
|
{
|
||||||
auto str = StringUtils::ToString(val);
|
auto str = StringUtils::ToString(val);
|
||||||
@@ -165,11 +140,8 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append formatted message to the string
|
|
||||||
// @param format Format string
|
|
||||||
// @param args Array with custom arguments for the message
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
StringBuilder& AppendFormat(const Char* format, const Args& ... args)
|
StringBuilder& AppendFormat(const Char* format, const Args&... args)
|
||||||
{
|
{
|
||||||
fmt_flax::allocator allocator;
|
fmt_flax::allocator allocator;
|
||||||
fmt_flax::memory_buffer buffer(allocator);
|
fmt_flax::memory_buffer buffer(allocator);
|
||||||
@@ -177,16 +149,12 @@ public:
|
|||||||
return Append(buffer.data(), (int32)buffer.size());
|
return Append(buffer.data(), (int32)buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
StringBuilder& AppendLine()
|
StringBuilder& AppendLine()
|
||||||
{
|
{
|
||||||
Append(TEXT(PLATFORM_LINE_TERMINATOR));
|
Append(TEXT(PLATFORM_LINE_TERMINATOR));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append int to the string
|
|
||||||
// @param val Value to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& AppendLine(int32 val)
|
StringBuilder& AppendLine(int32 val)
|
||||||
{
|
{
|
||||||
Append(val);
|
Append(val);
|
||||||
@@ -194,9 +162,6 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append int to the string
|
|
||||||
// @param val Value to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& AppendLine(uint32 val)
|
StringBuilder& AppendLine(uint32 val)
|
||||||
{
|
{
|
||||||
Append(val);
|
Append(val);
|
||||||
@@ -204,9 +169,6 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append String to the string
|
|
||||||
// @param str String to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& AppendLine(const Char* str)
|
StringBuilder& AppendLine(const Char* str)
|
||||||
{
|
{
|
||||||
const int32 length = StringUtils::Length(str);
|
const int32 length = StringUtils::Length(str);
|
||||||
@@ -215,9 +177,6 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append String to the string
|
|
||||||
// @param str String to append
|
|
||||||
// @return Current String Builder instance
|
|
||||||
StringBuilder& AppendLine(const String& str)
|
StringBuilder& AppendLine(const String& str)
|
||||||
{
|
{
|
||||||
_data.Add(*str, str.Length());
|
_data.Add(*str, str.Length());
|
||||||
@@ -226,38 +185,25 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Retrieves substring created from characters starting from startIndex
|
// Gets pointer to the string.
|
||||||
// @param startIndex Index of the first character to subtract
|
|
||||||
// @param count Amount of characters to retrieve
|
|
||||||
// @return Substring created from StringBuilder data
|
|
||||||
String Substring(int32 startIndex, int32 count) const
|
|
||||||
{
|
|
||||||
ASSERT(startIndex >= 0 && startIndex + count <= _data.Count() && count > 0);
|
|
||||||
return String(_data.Get() + startIndex, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Get pointer to the string
|
|
||||||
// @returns Pointer to Array of Chars if Num, otherwise the empty string
|
|
||||||
FORCE_INLINE const Char* operator*() const
|
FORCE_INLINE const Char* operator*() const
|
||||||
{
|
{
|
||||||
return _data.Count() > 0 ? _data.Get() : TEXT("");
|
return _data.Count() > 0 ? _data.Get() : TEXT("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get pointer to the string
|
// Gets pointer to the string.
|
||||||
// @returns Pointer to Array of Chars if Num, otherwise the empty string
|
|
||||||
FORCE_INLINE Char* operator*()
|
FORCE_INLINE Char* operator*()
|
||||||
{
|
{
|
||||||
return _data.Count() > 0 ? _data.Get() : (Char*)TEXT("");
|
return _data.Count() > 0 ? _data.Get() : (Char*)TEXT("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get string as array of Chars
|
// Gets string buffer as array of Chars.
|
||||||
FORCE_INLINE Array<Char>& GetCharArray()
|
FORCE_INLINE Array<Char>& GetCharArray()
|
||||||
{
|
{
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get string as const array of Chars
|
// Gets string buffer as const array of Chars.
|
||||||
FORCE_INLINE const Array<Char>& GetCharArray() const
|
FORCE_INLINE const Array<Char>& GetCharArray() const
|
||||||
{
|
{
|
||||||
return _data;
|
return _data;
|
||||||
|
|||||||
@@ -38,11 +38,14 @@ namespace Utilities
|
|||||||
return (T)round((double)value * 1000.0) / (T)1000;
|
return (T)round((double)value * 1000.0) / (T)1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts units to the best fitting human-readable denominator
|
/// <summary>
|
||||||
// @param units Units count
|
/// Converts units to the best fitting human-readable denominator.
|
||||||
// @param divider Amount of units required for the next size
|
/// </summary>
|
||||||
// @param sizes Array with human-readable sizes to convert from
|
/// <typeparam name="T">Value type.</typeparam>
|
||||||
// @return The best fitting string of the units
|
/// <param name="units">Units count</param>
|
||||||
|
/// <param name="divider">Amount of units required for the next size.</param>
|
||||||
|
/// <param name="sizes">Array with human-readable sizes to convert from.</param>
|
||||||
|
/// <returns>The best fitting string of the units.</returns>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
String UnitsToText(T units, int32 divider, const Span<const Char*> sizes)
|
String UnitsToText(T units, int32 divider, const Span<const Char*> sizes)
|
||||||
{
|
{
|
||||||
@@ -61,18 +64,24 @@ namespace Utilities
|
|||||||
return String::Format(TEXT("{0} {1}"), text, sizes[i]);
|
return String::Format(TEXT("{0} {1}"), text, sizes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts size of the file (in bytes) to the best fitting string
|
/// <summary>
|
||||||
// @param bytes Size of the file in bytes
|
/// Converts size of the data (in bytes) to the best fitting string.
|
||||||
// @return The best fitting string of the file size
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Value type.</typeparam>
|
||||||
|
/// <param name="bytes">Size of the data in bytes.</param>
|
||||||
|
/// <returns>The best fitting string of the data size.</returns>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
String BytesToText(T bytes)
|
String BytesToText(T bytes)
|
||||||
{
|
{
|
||||||
return UnitsToText(bytes, 1024, Private::BytesSizes);
|
return UnitsToText(bytes, 1024, Private::BytesSizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts hertz to the best fitting string
|
/// <summary>
|
||||||
// @param hertz Hertz for convertion
|
/// Converts hertz to the best fitting string.
|
||||||
// @return The best fitting string
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Value type.</typeparam>
|
||||||
|
/// <param name="hertz">Value in hertz for conversion.</param>
|
||||||
|
/// <returns>The best fitting string.</returns>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
String HertzToText(T hertz)
|
String HertzToText(T hertz)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ namespace FlaxEngine.Interop
|
|||||||
#if FLAX_EDITOR
|
#if FLAX_EDITOR
|
||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
#endif
|
#endif
|
||||||
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedHandleMarshaller.ManagedToNative))]
|
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedHandleMarshaller.ManagedToNativeState))]
|
||||||
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedOut, typeof(ManagedHandleMarshaller.ManagedToNative))]
|
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedOut, typeof(ManagedHandleMarshaller.ManagedToNativeState))]
|
||||||
[CustomMarshaller(typeof(object), MarshalMode.ElementIn, typeof(ManagedHandleMarshaller.ManagedToNative))]
|
[CustomMarshaller(typeof(object), MarshalMode.ElementIn, typeof(ManagedHandleMarshaller.ManagedToNative))]
|
||||||
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedOut, typeof(ManagedHandleMarshaller.NativeToManaged))]
|
[CustomMarshaller(typeof(object), MarshalMode.ManagedToUnmanagedOut, typeof(ManagedHandleMarshaller.NativeToManaged))]
|
||||||
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedIn, typeof(ManagedHandleMarshaller.NativeToManaged))]
|
[CustomMarshaller(typeof(object), MarshalMode.UnmanagedToManagedIn, typeof(ManagedHandleMarshaller.NativeToManaged))]
|
||||||
@@ -31,7 +31,20 @@ namespace FlaxEngine.Interop
|
|||||||
#endif
|
#endif
|
||||||
public static class NativeToManaged
|
public static class NativeToManaged
|
||||||
{
|
{
|
||||||
public static object ConvertToManaged(IntPtr unmanaged) => unmanaged == IntPtr.Zero ? null : ManagedHandle.FromIntPtr(unmanaged).Target;
|
public static object ConvertToManaged(IntPtr unmanaged)
|
||||||
|
{
|
||||||
|
if (unmanaged == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
object managed = ManagedHandle.FromIntPtr(unmanaged).Target;
|
||||||
|
if (managed is ManagedArray managedArray)
|
||||||
|
{
|
||||||
|
var managedArrayHandle = ManagedHandle.Alloc(managedArray, GCHandleType.Normal);
|
||||||
|
managed = NativeInterop.MarshalToManaged((IntPtr)managedArrayHandle, managedArray.ArrayType);
|
||||||
|
managedArrayHandle.Free();
|
||||||
|
}
|
||||||
|
return managed;
|
||||||
|
}
|
||||||
|
|
||||||
public static IntPtr ConvertToUnmanaged(object managed) => managed != null ? ManagedHandle.ToIntPtr(managed, GCHandleType.Weak) : IntPtr.Zero;
|
public static IntPtr ConvertToUnmanaged(object managed) => managed != null ? ManagedHandle.ToIntPtr(managed, GCHandleType.Weak) : IntPtr.Zero;
|
||||||
|
|
||||||
public static void Free(IntPtr unmanaged)
|
public static void Free(IntPtr unmanaged)
|
||||||
@@ -40,6 +53,52 @@ namespace FlaxEngine.Interop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if FLAX_EDITOR
|
||||||
|
[HideInEditor]
|
||||||
|
#endif
|
||||||
|
public struct ManagedToNativeState
|
||||||
|
{
|
||||||
|
ManagedArray managedArray;
|
||||||
|
IntPtr handle;
|
||||||
|
|
||||||
|
public void FromManaged(object managed)
|
||||||
|
{
|
||||||
|
if (managed == null)
|
||||||
|
return;
|
||||||
|
if (managed is Array arr)
|
||||||
|
{
|
||||||
|
var type = managed.GetType();
|
||||||
|
var elementType = type.GetElementType();
|
||||||
|
if (NativeInterop.ArrayFactory.GetMarshalledType(elementType) == elementType)
|
||||||
|
{
|
||||||
|
// Use pooled managed array wrapper to be passed around as handle to it
|
||||||
|
(ManagedHandle tmp, managedArray) = ManagedArray.WrapPooledArray(arr);
|
||||||
|
handle = ManagedHandle.ToIntPtr(tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Convert array contents to be properly accessed by the native code (as GCHandles array)
|
||||||
|
managedArray = NativeInterop.ManagedArrayToGCHandleWrappedArray(arr);
|
||||||
|
handle = ManagedHandle.ToIntPtr(ManagedHandle.Alloc(managedArray));
|
||||||
|
managedArray = null; // It's not pooled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handle = ManagedHandle.ToIntPtr(managed, GCHandleType.Weak);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr ToUnmanaged()
|
||||||
|
{
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Free()
|
||||||
|
{
|
||||||
|
managedArray?.FreePooled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if FLAX_EDITOR
|
#if FLAX_EDITOR
|
||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
#endif
|
#endif
|
||||||
@@ -50,12 +109,6 @@ namespace FlaxEngine.Interop
|
|||||||
|
|
||||||
public static void Free(IntPtr unmanaged)
|
public static void Free(IntPtr unmanaged)
|
||||||
{
|
{
|
||||||
// This is a weak handle, no need to free it
|
|
||||||
/*
|
|
||||||
if (unmanaged == IntPtr.Zero)
|
|
||||||
return;
|
|
||||||
ManagedHandle.FromIntPtr(unmanaged).Free();
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,6 +395,7 @@ namespace FlaxEngine.Interop
|
|||||||
{
|
{
|
||||||
public static Dictionary<T, U> ConvertToManaged(IntPtr unmanaged) => DictionaryMarshaller<T, U>.ToManaged(unmanaged);
|
public static Dictionary<T, U> ConvertToManaged(IntPtr unmanaged) => DictionaryMarshaller<T, U>.ToManaged(unmanaged);
|
||||||
public static IntPtr ConvertToUnmanaged(Dictionary<T, U> managed) => DictionaryMarshaller<T, U>.ToNative(managed, GCHandleType.Weak);
|
public static IntPtr ConvertToUnmanaged(Dictionary<T, U> managed) => DictionaryMarshaller<T, U>.ToNative(managed, GCHandleType.Weak);
|
||||||
|
|
||||||
public static void Free(IntPtr unmanaged)
|
public static void Free(IntPtr unmanaged)
|
||||||
{
|
{
|
||||||
//DictionaryMarshaller<T, U>.Free(unmanaged); // No need to free weak handles
|
//DictionaryMarshaller<T, U>.Free(unmanaged); // No need to free weak handles
|
||||||
@@ -614,6 +668,7 @@ namespace FlaxEngine.Interop
|
|||||||
{
|
{
|
||||||
public static string ConvertToManaged(IntPtr unmanaged) => ManagedString.ToManaged(unmanaged);
|
public static string ConvertToManaged(IntPtr unmanaged) => ManagedString.ToManaged(unmanaged);
|
||||||
public static unsafe IntPtr ConvertToUnmanaged(string managed) => managed == null ? IntPtr.Zero : ManagedHandle.ToIntPtr(managed, GCHandleType.Weak);
|
public static unsafe IntPtr ConvertToUnmanaged(string managed) => managed == null ? IntPtr.Zero : ManagedHandle.ToIntPtr(managed, GCHandleType.Weak);
|
||||||
|
|
||||||
public static void Free(IntPtr unmanaged)
|
public static void Free(IntPtr unmanaged)
|
||||||
{
|
{
|
||||||
//ManagedString.Free(unmanaged); // No need to free weak handles
|
//ManagedString.Free(unmanaged); // No need to free weak handles
|
||||||
|
|||||||
@@ -600,31 +600,19 @@ void RenderTools::ComputeSphereModelDrawMatrix(const RenderView& view, const Flo
|
|||||||
resultIsViewInside = Float3::DistanceSquared(view.Position, position) < Math::Square(radius * 1.1f); // Manually tweaked bias
|
resultIsViewInside = Float3::DistanceSquared(view.Position, position) < Math::Square(radius * 1.1f); // Manually tweaked bias
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 MipLevelsCount(int32 width, bool useMipLevels)
|
int32 MipLevelsCount(int32 width)
|
||||||
{
|
{
|
||||||
if (!useMipLevels)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
int32 result = 1;
|
int32 result = 1;
|
||||||
while (width > 1)
|
while (width > 1)
|
||||||
{
|
{
|
||||||
width >>= 1;
|
width >>= 1;
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 MipLevelsCount(int32 width, int32 height, bool useMipLevels)
|
int32 MipLevelsCount(int32 width, int32 height)
|
||||||
{
|
{
|
||||||
// Check if use mip maps
|
|
||||||
if (!useMipLevels)
|
|
||||||
{
|
|
||||||
// No mipmaps chain, only single mip map
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count mip maps
|
|
||||||
int32 result = 1;
|
int32 result = 1;
|
||||||
while (width > 1 || height > 1)
|
while (width > 1 || height > 1)
|
||||||
{
|
{
|
||||||
@@ -637,11 +625,8 @@ int32 MipLevelsCount(int32 width, int32 height, bool useMipLevels)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels)
|
int32 MipLevelsCount(int32 width, int32 height, int32 depth)
|
||||||
{
|
{
|
||||||
if (!useMipLevels)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
int32 result = 1;
|
int32 result = 1;
|
||||||
while (width > 1 || height > 1 || depth > 1)
|
while (width > 1 || height > 1 || depth > 1)
|
||||||
{
|
{
|
||||||
@@ -653,7 +638,6 @@ int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels)
|
|||||||
depth >>= 1;
|
depth >>= 1;
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,23 +136,11 @@ public:
|
|||||||
static void ComputeSphereModelDrawMatrix(const RenderView& view, const Float3& position, float radius, Matrix& resultWorld, bool& resultIsViewInside);
|
static void ComputeSphereModelDrawMatrix(const RenderView& view, const Float3& position, float radius, Matrix& resultWorld, bool& resultIsViewInside);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate mip levels count for a texture 1D
|
// Calculates mip levels count for a texture 1D.
|
||||||
// @param width Most detailed mip width
|
extern int32 MipLevelsCount(int32 width);
|
||||||
// @param useMipLevels True if use mip levels, otherwise false (use only 1 mip)
|
|
||||||
// @returns Mip levels count
|
|
||||||
extern int32 MipLevelsCount(int32 width, bool useMipLevels = true);
|
|
||||||
|
|
||||||
// Calculate mip levels count for a texture 2D
|
// Calculates mip levels count for a texture 2D.
|
||||||
// @param width Most detailed mip width
|
extern int32 MipLevelsCount(int32 width, int32 height);
|
||||||
// @param height Most detailed mip height
|
|
||||||
// @param useMipLevels True if use mip levels, otherwise false (use only 1 mip)
|
|
||||||
// @returns Mip levels count
|
|
||||||
extern int32 MipLevelsCount(int32 width, int32 height, bool useMipLevels = true);
|
|
||||||
|
|
||||||
// Calculate mip levels count for a texture 3D
|
// Calculates mip levels count for a texture 3D.
|
||||||
// @param width Most detailed mip width
|
extern int32 MipLevelsCount(int32 width, int32 height, int32 depth);
|
||||||
// @param height Most detailed mip height
|
|
||||||
// @param depth Most detailed mip depths
|
|
||||||
// @param useMipLevels True if use mip levels, otherwise false (use only 1 mip)
|
|
||||||
// @returns Mip levels count
|
|
||||||
extern int32 MipLevelsCount(int32 width, int32 height, int32 depth, bool useMipLevels = true);
|
|
||||||
|
|||||||
@@ -852,7 +852,7 @@ public:
|
|||||||
API_FUNCTION() bool HasActorInChildren(Actor* a) const;
|
API_FUNCTION() bool HasActorInChildren(Actor* a) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines if there is an intersection between the current object and a Ray.
|
/// Determines if there is an intersection between the current object and a ray.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ray">The ray to test.</param>
|
/// <param name="ray">The ray to test.</param>
|
||||||
/// <param name="distance">When the method completes, contains the distance of the intersection (if any valid).</param>
|
/// <param name="distance">When the method completes, contains the distance of the intersection (if any valid).</param>
|
||||||
@@ -879,7 +879,7 @@ public:
|
|||||||
/// Rotates actor to orient it towards the specified world position with upwards direction.
|
/// Rotates actor to orient it towards the specified world position with upwards direction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="worldPos">The world position to orient towards.</param>
|
/// <param name="worldPos">The world position to orient towards.</param>
|
||||||
/// <param name="worldUp">The up direction that Constrains y axis orientation to a plane this vector lies on. This rule might be broken if forward and up direction are nearly parallel.</param>
|
/// <param name="worldUp">The up direction that constrains up axis orientation to a plane this vector lies on. This rule might be broken if forward and up direction are nearly parallel.</param>
|
||||||
API_FUNCTION() void LookAt(const Vector3& worldPos, const Vector3& worldUp);
|
API_FUNCTION() void LookAt(const Vector3& worldPos, const Vector3& worldUp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ namespace FlaxEngine
|
|||||||
public static T[] GetScripts<T>() where T : Script
|
public static T[] GetScripts<T>() where T : Script
|
||||||
{
|
{
|
||||||
var scripts = GetScripts(typeof(T));
|
var scripts = GetScripts(typeof(T));
|
||||||
|
if (typeof(T) == typeof(Script))
|
||||||
|
return (T[])scripts;
|
||||||
if (scripts.Length == 0)
|
if (scripts.Length == 0)
|
||||||
return Array.Empty<T>();
|
return Array.Empty<T>();
|
||||||
var result = new T[scripts.Length];
|
var result = new T[scripts.Length];
|
||||||
@@ -126,6 +128,8 @@ namespace FlaxEngine
|
|||||||
public static T[] GetActors<T>(bool activeOnly = false) where T : Actor
|
public static T[] GetActors<T>(bool activeOnly = false) where T : Actor
|
||||||
{
|
{
|
||||||
var actors = GetActors(typeof(T), activeOnly);
|
var actors = GetActors(typeof(T), activeOnly);
|
||||||
|
if (typeof(T) == typeof(Actor))
|
||||||
|
return (T[])actors;
|
||||||
if (actors.Length == 0)
|
if (actors.Length == 0)
|
||||||
return Array.Empty<T>();
|
return Array.Empty<T>();
|
||||||
var result = new T[actors.Length];
|
var result = new T[actors.Length];
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "Engine/Core/Collections/CollectionPoolCache.h"
|
#include "Engine/Core/Collections/CollectionPoolCache.h"
|
||||||
#include "Engine/Profiler/ProfilerCPU.h"
|
#include "Engine/Profiler/ProfilerCPU.h"
|
||||||
#include "Engine/Core/Cache.h"
|
#include "Engine/Core/Cache.h"
|
||||||
|
#include "Engine/Core/LogContext.h"
|
||||||
#include "Engine/Debug/Exceptions/ArgumentException.h"
|
#include "Engine/Debug/Exceptions/ArgumentException.h"
|
||||||
#include "Engine/Engine/EngineService.h"
|
#include "Engine/Engine/EngineService.h"
|
||||||
#include "Engine/Scripting/Script.h"
|
#include "Engine/Scripting/Script.h"
|
||||||
@@ -122,6 +123,7 @@ Actor* PrefabManager::SpawnPrefab(Prefab* prefab, const Transform& transform, Ac
|
|||||||
}
|
}
|
||||||
auto& data = *prefab->Data;
|
auto& data = *prefab->Data;
|
||||||
SceneObjectsFactory::Context context(modifier.Value);
|
SceneObjectsFactory::Context context(modifier.Value);
|
||||||
|
LogContextScope logContext(prefabId);
|
||||||
|
|
||||||
// Deserialize prefab objects
|
// Deserialize prefab objects
|
||||||
auto prevIdMapping = Scripting::ObjectsLookupIdMapping.Get();
|
auto prevIdMapping = Scripting::ObjectsLookupIdMapping.Get();
|
||||||
|
|||||||
@@ -1302,6 +1302,15 @@ bool NetworkReplicator::HasObject(const ScriptingObject* obj)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkReplicator::MapObjectId(Guid& objectId)
|
||||||
|
{
|
||||||
|
if (!IdsRemappingTable.TryGet(objectId, objectId))
|
||||||
|
{
|
||||||
|
// Try inverse mapping
|
||||||
|
IdsRemappingTable.KeyOf(objectId, &objectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ScriptingObject* NetworkReplicator::ResolveForeignObject(Guid objectId)
|
ScriptingObject* NetworkReplicator::ResolveForeignObject(Guid objectId)
|
||||||
{
|
{
|
||||||
if (const auto& object = ResolveObject(objectId))
|
if (const auto& object = ResolveObject(objectId))
|
||||||
|
|||||||
@@ -116,6 +116,12 @@ public:
|
|||||||
/// <param name="obj">The network object.</param>
|
/// <param name="obj">The network object.</param>
|
||||||
/// <returns>True if object exists in networking, otherwise false.</returns>
|
/// <returns>True if object exists in networking, otherwise false.</returns>
|
||||||
API_FUNCTION() static bool HasObject(const ScriptingObject* obj);
|
API_FUNCTION() static bool HasObject(const ScriptingObject* obj);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maps object ID into server or client ID (depending on the source ID). Leaves source value unchanged if that specific ID is unused.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectId">The network object identifier to map. Contains result ID once the method completes.</param>
|
||||||
|
API_FUNCTION() static void MapObjectId(API_PARAM(Ref) Guid& objectId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves foreign Guid into a local ScriptingObject
|
/// Resolves foreign Guid into a local ScriptingObject
|
||||||
|
|||||||
@@ -494,28 +494,28 @@ void PhysicsScene::CollectResults()
|
|||||||
bool PhysicsScene::LineCast(const Vector3& start, const Vector3& end, uint32 layerMask, bool hitTriggers)
|
bool PhysicsScene::LineCast(const Vector3& start, const Vector3& end, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
Vector3 directionToEnd = end - start;
|
Vector3 directionToEnd = end - start;
|
||||||
const float distanceToEnd = directionToEnd.Length();
|
const Real distanceToEnd = directionToEnd.Length();
|
||||||
if (distanceToEnd >= ZeroTolerance)
|
if (distanceToEnd >= ZeroTolerance)
|
||||||
directionToEnd /= distanceToEnd;
|
directionToEnd /= distanceToEnd;
|
||||||
return PhysicsBackend::RayCast(_scene, start, directionToEnd, distanceToEnd, layerMask, hitTriggers);
|
return PhysicsBackend::RayCast(_scene, start, directionToEnd, (float)distanceToEnd, layerMask, hitTriggers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsScene::LineCast(const Vector3& start, const Vector3& end, RayCastHit& hitInfo, uint32 layerMask, bool hitTriggers)
|
bool PhysicsScene::LineCast(const Vector3& start, const Vector3& end, RayCastHit& hitInfo, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
Vector3 directionToEnd = end - start;
|
Vector3 directionToEnd = end - start;
|
||||||
const float distanceToEnd = directionToEnd.Length();
|
const Real distanceToEnd = directionToEnd.Length();
|
||||||
if (distanceToEnd >= ZeroTolerance)
|
if (distanceToEnd >= ZeroTolerance)
|
||||||
directionToEnd /= distanceToEnd;
|
directionToEnd /= distanceToEnd;
|
||||||
return PhysicsBackend::RayCast(_scene, start, directionToEnd, hitInfo, distanceToEnd, layerMask, hitTriggers);
|
return PhysicsBackend::RayCast(_scene, start, directionToEnd, hitInfo, (float)distanceToEnd, layerMask, hitTriggers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsScene::LineCastAll(const Vector3& start, const Vector3& end, Array<RayCastHit>& results, uint32 layerMask, bool hitTriggers)
|
bool PhysicsScene::LineCastAll(const Vector3& start, const Vector3& end, Array<RayCastHit>& results, uint32 layerMask, bool hitTriggers)
|
||||||
{
|
{
|
||||||
Vector3 directionToEnd = end - start;
|
Vector3 directionToEnd = end - start;
|
||||||
const float distanceToEnd = directionToEnd.Length();
|
const Real distanceToEnd = directionToEnd.Length();
|
||||||
if (distanceToEnd >= ZeroTolerance)
|
if (distanceToEnd >= ZeroTolerance)
|
||||||
directionToEnd /= distanceToEnd;
|
directionToEnd /= distanceToEnd;
|
||||||
return PhysicsBackend::RayCastAll(_scene, start, directionToEnd, results, distanceToEnd, layerMask, hitTriggers);
|
return PhysicsBackend::RayCastAll(_scene, start, directionToEnd, results, (float)distanceToEnd, layerMask, hitTriggers);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||||
|
|||||||
@@ -167,18 +167,18 @@ bool AndroidFileSystem::DirectoryGetFiles(Array<String>& results, const String&
|
|||||||
return getFilesFromDirectoryAll(results, pathANSI.Get(), searchPatternANSI.Get());
|
return getFilesFromDirectoryAll(results, pathANSI.Get(), searchPatternANSI.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidFileSystem::GetChildDirectories(Array<String>& results, const String& directory)
|
bool AndroidFileSystem::GetChildDirectories(Array<String>& results, const String& path)
|
||||||
{
|
{
|
||||||
size_t pathLength;
|
size_t pathLength;
|
||||||
struct stat statPath, statEntry;
|
struct stat statPath, statEntry;
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
const StringAsANSI<> pathANSI(*directory, directory.Length());
|
const StringAsANSI<> pathANSI(*path, path.Length());
|
||||||
const char* path = pathANSI.Get();
|
const char* pathStr = pathANSI.Get();
|
||||||
|
|
||||||
// Stat for the path
|
// Stat for the path
|
||||||
stat(path, &statPath);
|
stat(pathStr, &statPath);
|
||||||
|
|
||||||
// If path does not exists or is not dir - exit with status -1
|
// If path does not exist or is not dir - exit with status -1
|
||||||
if (S_ISDIR(statPath.st_mode) == 0)
|
if (S_ISDIR(statPath.st_mode) == 0)
|
||||||
{
|
{
|
||||||
// Is not directory
|
// Is not directory
|
||||||
@@ -186,7 +186,7 @@ bool AndroidFileSystem::GetChildDirectories(Array<String>& results, const String
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If not possible to read the directory for this user
|
// If not possible to read the directory for this user
|
||||||
DIR* dir = opendir(path);
|
DIR* dir = opendir(pathStr);
|
||||||
if (dir == nullptr)
|
if (dir == nullptr)
|
||||||
{
|
{
|
||||||
// Cannot open directory
|
// Cannot open directory
|
||||||
@@ -194,7 +194,7 @@ bool AndroidFileSystem::GetChildDirectories(Array<String>& results, const String
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The length of the path
|
// The length of the path
|
||||||
pathLength = strlen(path);
|
pathLength = strlen(pathStr);
|
||||||
|
|
||||||
// Iteration through entries in the directory
|
// Iteration through entries in the directory
|
||||||
while ((entry = readdir(dir)) != nullptr)
|
while ((entry = readdir(dir)) != nullptr)
|
||||||
@@ -204,20 +204,20 @@ bool AndroidFileSystem::GetChildDirectories(Array<String>& results, const String
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Determinate a full path of an entry
|
// Determinate a full path of an entry
|
||||||
char full_path[256];
|
char fullPath[256];
|
||||||
ASSERT(pathLength + strlen(entry->d_name) < ARRAY_COUNT(full_path));
|
ASSERT(pathLength + strlen(entry->d_name) < ARRAY_COUNT(fullPath));
|
||||||
strcpy(full_path, path);
|
strcpy(fullPath, pathStr);
|
||||||
strcat(full_path, "/");
|
strcat(fullPath, "/");
|
||||||
strcat(full_path, entry->d_name);
|
strcat(fullPath, entry->d_name);
|
||||||
|
|
||||||
// Stat for the entry
|
// Stat for the entry
|
||||||
stat(full_path, &statEntry);
|
stat(fullPath, &statEntry);
|
||||||
|
|
||||||
// Check for directory
|
// Check for directory
|
||||||
if (S_ISDIR(statEntry.st_mode) != 0)
|
if (S_ISDIR(statEntry.st_mode) != 0)
|
||||||
{
|
{
|
||||||
// Add directory
|
// Add directory
|
||||||
results.Add(String(full_path));
|
results.Add(String(fullPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,11 @@
|
|||||||
class FLAXENGINE_API AndroidFileSystem : public FileSystemBase
|
class FLAXENGINE_API AndroidFileSystem : public FileSystemBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static bool CreateDirectory(const StringView& path);
|
static bool CreateDirectory(const StringView& path);
|
||||||
static bool DeleteDirectory(const String& path, bool deleteContents = true);
|
static bool DeleteDirectory(const String& path, bool deleteContents = true);
|
||||||
static bool DirectoryExists(const StringView& path);
|
static bool DirectoryExists(const StringView& path);
|
||||||
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern, DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern = TEXT("*"), DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
||||||
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& directory);
|
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& path);
|
||||||
static bool FileExists(const StringView& path);
|
static bool FileExists(const StringView& path);
|
||||||
static bool DeleteFile(const StringView& path);
|
static bool DeleteFile(const StringView& path);
|
||||||
static uint64 GetFileSize(const StringView& path);
|
static uint64 GetFileSize(const StringView& path);
|
||||||
@@ -25,25 +24,10 @@ public:
|
|||||||
static bool SetReadOnly(const StringView& path, bool isReadOnly);
|
static bool SetReadOnly(const StringView& path, bool isReadOnly);
|
||||||
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false);
|
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false);
|
||||||
static bool CopyFile(const StringView& dst, const StringView& src);
|
static bool CopyFile(const StringView& dst, const StringView& src);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets last time when file has been modified (in UTC).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The file path to check.</param>
|
|
||||||
/// <returns>The last write time or DateTime::MinValue() if cannot get data.</returns>
|
|
||||||
static DateTime GetFileLastEditTime(const StringView& path);
|
static DateTime GetFileLastEditTime(const StringView& path);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the special folder path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The folder type.</param>
|
|
||||||
/// <param name="result">The result full path.</param>
|
|
||||||
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static bool getFilesFromDirectoryTop(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
static bool getFilesFromDirectoryTop(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
||||||
static bool getFilesFromDirectoryAll(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
static bool getFilesFromDirectoryAll(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -145,19 +145,19 @@ bool AppleFileSystem::DirectoryGetFiles(Array<String>& results, const String& pa
|
|||||||
return getFilesFromDirectoryAll(results, pathANSI.Get(), searchPatternANSI.Get());
|
return getFilesFromDirectoryAll(results, pathANSI.Get(), searchPatternANSI.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppleFileSystem::GetChildDirectories(Array<String>& results, const String& directory)
|
bool AppleFileSystem::GetChildDirectories(Array<String>& results, const String& path)
|
||||||
{
|
{
|
||||||
size_t pathLength;
|
size_t pathLength;
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
struct stat statPath, statEntry;
|
struct stat statPath, statEntry;
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
const StringAsANSI<> pathANSI(*directory, directory.Length());
|
const StringAsANSI<> pathANSI(*path, path.Length());
|
||||||
const char* path = pathANSI.Get();
|
const char* pathStr = pathANSI.Get();
|
||||||
|
|
||||||
// Stat for the path
|
// Stat for the path
|
||||||
stat(path, &statPath);
|
stat(pathStr, &statPath);
|
||||||
|
|
||||||
// If path does not exists or is not dir - exit with status -1
|
// If path does not exist or is not dir - exit with status -1
|
||||||
if (S_ISDIR(statPath.st_mode) == 0)
|
if (S_ISDIR(statPath.st_mode) == 0)
|
||||||
{
|
{
|
||||||
// Is not directory
|
// Is not directory
|
||||||
@@ -165,14 +165,14 @@ bool AppleFileSystem::GetChildDirectories(Array<String>& results, const String&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If not possible to read the directory for this user
|
// If not possible to read the directory for this user
|
||||||
if ((dir = opendir(path)) == NULL)
|
if ((dir = opendir(pathStr)) == NULL)
|
||||||
{
|
{
|
||||||
// Cannot open directory
|
// Cannot open directory
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The length of the path
|
// The length of the path
|
||||||
pathLength = strlen(path);
|
pathLength = strlen(pathStr);
|
||||||
|
|
||||||
// Iteration through entries in the directory
|
// Iteration through entries in the directory
|
||||||
while ((entry = readdir(dir)) != NULL)
|
while ((entry = readdir(dir)) != NULL)
|
||||||
@@ -182,20 +182,20 @@ bool AppleFileSystem::GetChildDirectories(Array<String>& results, const String&
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Determinate a full path of an entry
|
// Determinate a full path of an entry
|
||||||
char full_path[256];
|
char fullPath[256];
|
||||||
ASSERT(pathLength + strlen(entry->d_name) < ARRAY_COUNT(full_path));
|
ASSERT(pathLength + strlen(entry->d_name) < ARRAY_COUNT(fullPath));
|
||||||
strcpy(full_path, path);
|
strcpy(fullPath, path);
|
||||||
strcat(full_path, "/");
|
strcat(fullPath, "/");
|
||||||
strcat(full_path, entry->d_name);
|
strcat(fullPath, entry->d_name);
|
||||||
|
|
||||||
// Stat for the entry
|
// Stat for the entry
|
||||||
stat(full_path, &statEntry);
|
stat(fullPath, &statEntry);
|
||||||
|
|
||||||
// Check for directory
|
// Check for directory
|
||||||
if (S_ISDIR(statEntry.st_mode) != 0)
|
if (S_ISDIR(statEntry.st_mode) != 0)
|
||||||
{
|
{
|
||||||
// Add directory
|
// Add directory
|
||||||
results.Add(String(full_path));
|
results.Add(String(fullPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,12 @@
|
|||||||
class FLAXENGINE_API AppleFileSystem : public FileSystemBase
|
class FLAXENGINE_API AppleFileSystem : public FileSystemBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// [FileSystemBase]
|
// [FileSystemBase]
|
||||||
static bool CreateDirectory(const StringView& path);
|
static bool CreateDirectory(const StringView& path);
|
||||||
static bool DeleteDirectory(const String& path, bool deleteContents = true);
|
static bool DeleteDirectory(const String& path, bool deleteContents = true);
|
||||||
static bool DirectoryExists(const StringView& path);
|
static bool DirectoryExists(const StringView& path);
|
||||||
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern, DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern = TEXT("*"), DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
||||||
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& directory);
|
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& path);
|
||||||
static bool FileExists(const StringView& path);
|
static bool FileExists(const StringView& path);
|
||||||
static bool DeleteFile(const StringView& path);
|
static bool DeleteFile(const StringView& path);
|
||||||
static uint64 GetFileSize(const StringView& path);
|
static uint64 GetFileSize(const StringView& path);
|
||||||
@@ -26,25 +25,10 @@ public:
|
|||||||
static bool SetReadOnly(const StringView& path, bool isReadOnly);
|
static bool SetReadOnly(const StringView& path, bool isReadOnly);
|
||||||
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false);
|
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false);
|
||||||
static bool CopyFile(const StringView& dst, const StringView& src);
|
static bool CopyFile(const StringView& dst, const StringView& src);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets last time when file has been modified (in UTC).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The file path to check.</param>
|
|
||||||
/// <returns>The last write time or DateTime::MinValue() if cannot get data.</returns>
|
|
||||||
static DateTime GetFileLastEditTime(const StringView& path);
|
static DateTime GetFileLastEditTime(const StringView& path);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the special folder path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The folder type.</param>
|
|
||||||
/// <param name="result">The result full path.</param>
|
|
||||||
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static bool getFilesFromDirectoryTop(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
static bool getFilesFromDirectoryTop(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
||||||
static bool getFilesFromDirectoryAll(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
static bool getFilesFromDirectoryAll(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ String FileSystemBase::ConvertAbsolutePathToRelative(const String& basePath, con
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystemBase::CopyFile(const String& dst, const String& src)
|
bool FileSystemBase::CopyFile(const StringView& dst, const StringView& src)
|
||||||
{
|
{
|
||||||
// Open and create files
|
// Open and create files
|
||||||
const auto srcFile = File::Open(src, FileMode::OpenExisting, FileAccess::Read);
|
const auto srcFile = File::Open(src, FileMode::OpenExisting, FileAccess::Read);
|
||||||
@@ -247,7 +247,7 @@ uint64 FileSystemBase::GetDirectorySize(const StringView& path)
|
|||||||
{
|
{
|
||||||
uint64 result = 0;
|
uint64 result = 0;
|
||||||
Array<String> files;
|
Array<String> files;
|
||||||
FileSystem::DirectoryGetFiles(files, path, TEXT("*"), DirectorySearchOption::AllDirectories);
|
FileSystem::DirectoryGetFiles(files, path);
|
||||||
for (const String& file : files)
|
for (const String& file : files)
|
||||||
result += FileSystem::GetFileSize(file);
|
result += FileSystem::GetFileSize(file);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -43,8 +43,133 @@ API_INJECT_CODE(cpp, "#include \"Engine/Platform/FileSystem.h\"");
|
|||||||
API_CLASS(Static, Name="FileSystem", Tag="NativeInvokeUseName")
|
API_CLASS(Static, Name="FileSystem", Tag="NativeInvokeUseName")
|
||||||
class FLAXENGINE_API FileSystemBase
|
class FLAXENGINE_API FileSystemBase
|
||||||
{
|
{
|
||||||
DECLARE_SCRIPTING_TYPE_MINIMAL(FileSystemBase);
|
DECLARE_SCRIPTING_TYPE_MINIMAL(FileSystemBase);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Directory path</param>
|
||||||
|
/// <returns>True if failed to create directory, otherwise false.</returns>
|
||||||
|
static bool CreateDirectory(const StringView& path) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes an existing directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Directory path</param>
|
||||||
|
/// <param name="deleteContents">True if delete all subdirectories and files, otherwise false.</param>
|
||||||
|
/// <returns>True if failed to delete directory, otherwise false.</returns>
|
||||||
|
static bool DeleteDirectory(const String& path, bool deleteContents = true) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if directory exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Directory path.</param>
|
||||||
|
/// <returns>True if directory exists, otherwise false.</returns>
|
||||||
|
static bool DirectoryExists(const StringView& path) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the paths of files that match the specified search pattern in the specified directory, using a value to determine whether to search subdirectories.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="results">Output list with all found file paths. Items are appended without clearing the list first.</param>
|
||||||
|
/// <param name="path">Path of the directory to search in it.</param>
|
||||||
|
/// <param name="searchPattern">Custom search pattern to use during that operation Use asterisk character (*) for name-based filtering (eg. `*.txt` to find all files with `.txt` extension)..</param>
|
||||||
|
/// <param name="option">Additional search options that define rules.</param>
|
||||||
|
/// <returns>True if an error occurred, otherwise false.</returns>
|
||||||
|
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern = TEXT("*"), DirectorySearchOption option = DirectorySearchOption::AllDirectories) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds the paths of directories that are inside the specified directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="results">Output list with all found directory paths. Items are appended without clearing the list first.</param>
|
||||||
|
/// <param name="path">Path of the directory to search in it.</param>
|
||||||
|
/// <returns>True if an error occurred, otherwise false.</returns>
|
||||||
|
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& path) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dst">Destination path.</param>
|
||||||
|
/// <param name="src">Source directory path.</param>
|
||||||
|
/// <param name="withSubDirectories">True if copy subdirectories of the source folder, otherwise only top-level files will be cloned.</param>
|
||||||
|
/// <returns>True if failed, otherwise false.</returns>
|
||||||
|
static bool CopyDirectory(const String& dst, const String& src, bool withSubDirectories = true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the size of the directory (in bytes) defined by size of all files contained by it.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Directory path.</param>
|
||||||
|
/// <returns>Amount of bytes in directory, or 0 if failed.</returns>
|
||||||
|
static uint64 GetDirectorySize(const StringView& path);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a given file exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">File path to check.</param>
|
||||||
|
/// <returns>True if file exists, otherwise false.</returns>
|
||||||
|
static bool FileExists(const StringView& path) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes an existing file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">File path</param>
|
||||||
|
/// <returns>True if operation failed, otherwise false.</returns>
|
||||||
|
static bool DeleteFile(const StringView& path) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the size of the file (in bytes).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">File path</param>
|
||||||
|
/// <returns>Amount of bytes in file, or 0 if failed.</returns>
|
||||||
|
static uint64 GetFileSize(const StringView& path) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if file is read-only.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">File path.</param>
|
||||||
|
/// <returns>True if file is read-only, otherwise false. Returns false if failed or path is invalid.</returns>
|
||||||
|
static bool IsReadOnly(const StringView& path) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets file read-only flag.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">File path.</param>
|
||||||
|
/// <param name="isReadOnly">Read-only flag value to set.</param>
|
||||||
|
/// <returns>True if operation failed, otherwise false.</returns>
|
||||||
|
static bool SetReadOnly(const StringView& path, bool isReadOnly) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves the file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dst">Destination path.</param>
|
||||||
|
/// <param name="src">Source file path.</param>
|
||||||
|
/// <param name="overwrite">True if allow overriding destination file if it already exists, otherwise action will fail.</param>
|
||||||
|
/// <returns>True if failed, otherwise false.</returns>
|
||||||
|
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dst">Destination path.</param>
|
||||||
|
/// <param name="src">Source file path.</param>
|
||||||
|
/// <returns>True if failed, otherwise false.</returns>
|
||||||
|
static bool CopyFile(const StringView& dst, const StringView& src);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets last time when file has been modified (in UTC).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The file path to check.</param>
|
||||||
|
/// <returns>The last write time or DateTime::MinValue() if cannot get data.</returns>
|
||||||
|
static DateTime GetFileLastEditTime(const StringView& path) = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the special folder path.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The folder type.</param>
|
||||||
|
/// <param name="result">The result full path.</param>
|
||||||
|
static void GetSpecialFolderPath(const SpecialFolder type, String& result) = delete;
|
||||||
|
|
||||||
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Displays a standard dialog box that prompts the user to open a file(s).
|
/// Displays a standard dialog box that prompts the user to open a file(s).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -97,28 +222,26 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FileSystemBase);
|
|||||||
API_FUNCTION() static bool ShowFileExplorer(const StringView& path);
|
API_FUNCTION() static bool ShowFileExplorer(const StringView& path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void SaveBitmapToFile(byte* data, uint32 width, uint32 height, uint32 bitsPerPixel, const uint32 padding, const String& path);
|
static void SaveBitmapToFile(byte* data, uint32 width, uint32 height, uint32 bitsPerPixel, const uint32 padding, const String& path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static bool AreFilePathsEqual(const StringView& path1, const StringView& path2);
|
static bool AreFilePathsEqual(const StringView& path1, const StringView& path2);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Normalize input path for valid path name for current platform file system
|
/// Normalizes input path for valid path name for current platform file system.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Path to normalize</param>
|
/// <param name="path">Path to normalize</param>
|
||||||
static void NormalizePath(String& path);
|
static void NormalizePath(String& path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if path type is relative
|
/// Checks if path type is relative.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Input path to check</param>
|
/// <param name="path">Input path to check</param>
|
||||||
/// <returns>True if input path is relative one, otherwise false</returns>
|
/// <returns>True if input path is relative one, otherwise false</returns>
|
||||||
static bool IsRelative(const StringView& path);
|
static bool IsRelative(const StringView& path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves file extension (without a dot)
|
/// Retrieves file extension (without a dot).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Input path to process</param>
|
/// <param name="path">Input path to process</param>
|
||||||
/// <returns>File extension</returns>
|
/// <returns>File extension</returns>
|
||||||
@@ -131,22 +254,15 @@ public:
|
|||||||
static void GetTempFilePath(String& tmpPath);
|
static void GetTempFilePath(String& tmpPath);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static bool CopyFile(const String& dst, const String& src);
|
|
||||||
static bool CopyDirectory(const String& dst, const String& src, bool withSubDirectories);
|
|
||||||
static uint64 GetDirectorySize(const StringView& path);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts path relative to the engine startup folder into absolute path
|
/// Converts path relative to the engine startup folder into absolute path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Path relative to the engine directory</param>
|
/// <param name="path">Path relative to the engine directory</param>
|
||||||
/// <returns>Absolute path</returns>
|
/// <returns>Absolute path</returns>
|
||||||
static String ConvertRelativePathToAbsolute(const String& path);
|
static String ConvertRelativePathToAbsolute(const String& path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts path relative to basePath into absolute path
|
/// Converts path relative to basePath into absolute path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="basePath">Base path</param>
|
/// <param name="basePath">Base path</param>
|
||||||
/// <param name="path">Path relative to basePath</param>
|
/// <param name="path">Path relative to basePath</param>
|
||||||
@@ -154,14 +270,14 @@ public:
|
|||||||
static String ConvertRelativePathToAbsolute(const String& basePath, const String& path);
|
static String ConvertRelativePathToAbsolute(const String& basePath, const String& path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts absolute path into relative path to engine startup folder
|
/// Converts absolute path into relative path to engine startup folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Absolute path</param>
|
/// <param name="path">Absolute path</param>
|
||||||
/// <returns>Relative path</returns>
|
/// <returns>Relative path</returns>
|
||||||
static String ConvertAbsolutePathToRelative(const String& path);
|
static String ConvertAbsolutePathToRelative(const String& path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts absolute path into relative path to basePath
|
/// Converts absolute path into relative path to basePath.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="basePath">Base path</param>
|
/// <param name="basePath">Base path</param>
|
||||||
/// <param name="path">Absolute path</param>
|
/// <param name="path">Absolute path</param>
|
||||||
@@ -169,6 +285,5 @@ public:
|
|||||||
static String ConvertAbsolutePathToRelative(const String& basePath, const String& path);
|
static String ConvertAbsolutePathToRelative(const String& basePath, const String& path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static bool DirectoryCopyHelper(const String& dst, const String& src, bool withSubDirectories);
|
static bool DirectoryCopyHelper(const String& dst, const String& src, bool withSubDirectories);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -291,17 +291,17 @@ bool LinuxFileSystem::DirectoryGetFiles(Array<String>& results, const String& pa
|
|||||||
return getFilesFromDirectoryAll(results, pathANSI.Get(), searchPatternANSI.Get());
|
return getFilesFromDirectoryAll(results, pathANSI.Get(), searchPatternANSI.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinuxFileSystem::GetChildDirectories(Array<String>& results, const String& directory)
|
bool LinuxFileSystem::GetChildDirectories(Array<String>& results, const String& path)
|
||||||
{
|
{
|
||||||
size_t pathLength;
|
size_t pathLength;
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
struct stat statPath, statEntry;
|
struct stat statPath, statEntry;
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
const StringAsUTF8<> pathANSI(*directory, directory.Length());
|
const StringAsUTF8<> pathANSI(*path, path.Length());
|
||||||
const char* path = pathANSI.Get();
|
const char* pathStr = pathANSI.Get();
|
||||||
|
|
||||||
// Stat for the path
|
// Stat for the path
|
||||||
stat(path, &statPath);
|
stat(pathStr, &statPath);
|
||||||
|
|
||||||
// If path does not exists or is not dir - exit with status -1
|
// If path does not exists or is not dir - exit with status -1
|
||||||
if (S_ISDIR(statPath.st_mode) == 0)
|
if (S_ISDIR(statPath.st_mode) == 0)
|
||||||
@@ -311,14 +311,14 @@ bool LinuxFileSystem::GetChildDirectories(Array<String>& results, const String&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If not possible to read the directory for this user
|
// If not possible to read the directory for this user
|
||||||
if ((dir = opendir(path)) == NULL)
|
if ((dir = opendir(pathStr)) == NULL)
|
||||||
{
|
{
|
||||||
// Cannot open directory
|
// Cannot open directory
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The length of the path
|
// The length of the path
|
||||||
pathLength = strlen(path);
|
pathLength = strlen(pathStr);
|
||||||
|
|
||||||
// Iteration through entries in the directory
|
// Iteration through entries in the directory
|
||||||
while ((entry = readdir(dir)) != NULL)
|
while ((entry = readdir(dir)) != NULL)
|
||||||
@@ -328,20 +328,20 @@ bool LinuxFileSystem::GetChildDirectories(Array<String>& results, const String&
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Determinate a full path of an entry
|
// Determinate a full path of an entry
|
||||||
char full_path[256];
|
char fullPath[256];
|
||||||
ASSERT(pathLength + strlen(entry->d_name) < ARRAY_COUNT(full_path));
|
ASSERT(pathLength + strlen(entry->d_name) < ARRAY_COUNT(fullPath));
|
||||||
strcpy(full_path, path);
|
strcpy(fullPath, path);
|
||||||
strcat(full_path, "/");
|
strcat(fullPath, "/");
|
||||||
strcat(full_path, entry->d_name);
|
strcat(fullPath, entry->d_name);
|
||||||
|
|
||||||
// Stat for the entry
|
// Stat for the entry
|
||||||
stat(full_path, &statEntry);
|
stat(fullPath, &statEntry);
|
||||||
|
|
||||||
// Check for directory
|
// Check for directory
|
||||||
if (S_ISDIR(statEntry.st_mode) != 0)
|
if (S_ISDIR(statEntry.st_mode) != 0)
|
||||||
{
|
{
|
||||||
// Add directory
|
// Add directory
|
||||||
results.Add(String(full_path));
|
results.Add(String(fullPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
class FLAXENGINE_API LinuxFileSystem : public FileSystemBase
|
class FLAXENGINE_API LinuxFileSystem : public FileSystemBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// [FileSystemBase]
|
// [FileSystemBase]
|
||||||
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
||||||
static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path);
|
static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path);
|
||||||
@@ -20,8 +19,8 @@ public:
|
|||||||
static bool CreateDirectory(const StringView& path);
|
static bool CreateDirectory(const StringView& path);
|
||||||
static bool DeleteDirectory(const String& path, bool deleteContents = true);
|
static bool DeleteDirectory(const String& path, bool deleteContents = true);
|
||||||
static bool DirectoryExists(const StringView& path);
|
static bool DirectoryExists(const StringView& path);
|
||||||
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern, DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern = TEXT("*"), DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
||||||
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& directory);
|
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& path);
|
||||||
static bool FileExists(const StringView& path);
|
static bool FileExists(const StringView& path);
|
||||||
static bool DeleteFile(const StringView& path);
|
static bool DeleteFile(const StringView& path);
|
||||||
static bool MoveFileToRecycleBin(const StringView& path);
|
static bool MoveFileToRecycleBin(const StringView& path);
|
||||||
@@ -30,25 +29,10 @@ public:
|
|||||||
static bool SetReadOnly(const StringView& path, bool isReadOnly);
|
static bool SetReadOnly(const StringView& path, bool isReadOnly);
|
||||||
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false);
|
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false);
|
||||||
static bool CopyFile(const StringView& dst, const StringView& src);
|
static bool CopyFile(const StringView& dst, const StringView& src);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets last time when file has been modified (in UTC).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The file path to check.</param>
|
|
||||||
/// <returns>The last write time or DateTime::MinValue() if cannot get data.</returns>
|
|
||||||
static DateTime GetFileLastEditTime(const StringView& path);
|
static DateTime GetFileLastEditTime(const StringView& path);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the special folder path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The folder type.</param>
|
|
||||||
/// <param name="result">The result full path.</param>
|
|
||||||
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
private:
|
||||||
static bool UrnEncodePath(const char *path, char *result, int maxLength);
|
static bool UrnEncodePath(const char *path, char *result, int maxLength);
|
||||||
static bool getFilesFromDirectoryTop(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
static bool getFilesFromDirectoryTop(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
||||||
static bool getFilesFromDirectoryAll(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
static bool getFilesFromDirectoryAll(Array<String, HeapAllocation>& results, const char* path, const char* searchPattern);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
class FLAXENGINE_API MacFileSystem : public AppleFileSystem
|
class FLAXENGINE_API MacFileSystem : public AppleFileSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// [AppleFileSystem]
|
// [AppleFileSystem]
|
||||||
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
||||||
static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
||||||
|
|||||||
@@ -64,55 +64,27 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Returns true if character is uppercase
|
|
||||||
static bool IsUpper(char c);
|
static bool IsUpper(char c);
|
||||||
|
|
||||||
// Returns true if character is lowercase
|
|
||||||
static bool IsLower(char c);
|
static bool IsLower(char c);
|
||||||
|
|
||||||
static bool IsAlpha(char c);
|
static bool IsAlpha(char c);
|
||||||
|
|
||||||
static bool IsPunct(char c);
|
static bool IsPunct(char c);
|
||||||
|
|
||||||
static bool IsAlnum(char c);
|
static bool IsAlnum(char c);
|
||||||
|
|
||||||
static bool IsDigit(char c);
|
static bool IsDigit(char c);
|
||||||
|
|
||||||
static bool IsHexDigit(char c);
|
static bool IsHexDigit(char c);
|
||||||
|
|
||||||
// Returns true if character is a whitespace
|
|
||||||
static bool IsWhitespace(char c);
|
static bool IsWhitespace(char c);
|
||||||
|
|
||||||
// Convert wide character to upper case
|
|
||||||
static char ToUpper(char c);
|
static char ToUpper(char c);
|
||||||
|
|
||||||
// Convert wide character to lower case
|
|
||||||
static char ToLower(char c);
|
static char ToLower(char c);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Returns true if character is uppercase
|
|
||||||
static bool IsUpper(Char c);
|
static bool IsUpper(Char c);
|
||||||
|
|
||||||
// Returns true if character is lowercase
|
|
||||||
static bool IsLower(Char c);
|
static bool IsLower(Char c);
|
||||||
|
|
||||||
static bool IsAlpha(Char c);
|
static bool IsAlpha(Char c);
|
||||||
|
|
||||||
static bool IsPunct(Char c);
|
static bool IsPunct(Char c);
|
||||||
|
|
||||||
static bool IsAlnum(Char c);
|
static bool IsAlnum(Char c);
|
||||||
|
|
||||||
static bool IsDigit(Char c);
|
static bool IsDigit(Char c);
|
||||||
|
|
||||||
static bool IsHexDigit(Char c);
|
static bool IsHexDigit(Char c);
|
||||||
|
|
||||||
// Returns true if character is a whitespace
|
|
||||||
static bool IsWhitespace(Char c);
|
static bool IsWhitespace(Char c);
|
||||||
|
|
||||||
// Convert wide character to upper case
|
|
||||||
static Char ToUpper(Char c);
|
static Char ToUpper(Char c);
|
||||||
|
|
||||||
// Convert wide character to lower case
|
|
||||||
static Char ToLower(Char c);
|
static Char ToLower(Char c);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -141,40 +113,28 @@ public:
|
|||||||
static int32 CompareIgnoreCase(const char* str1, const char* str2, int32 maxCount);
|
static int32 CompareIgnoreCase(const char* str1, const char* str2, int32 maxCount);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Get string length. Returns 0 if str is null.
|
// Gets the string length. Returns 0 if str is null.
|
||||||
static int32 Length(const Char* str);
|
static int32 Length(const Char* str);
|
||||||
|
|
||||||
// Get string length. Returns 0 if str is null.
|
// Gets the string length. Returns 0 if str is null.
|
||||||
static int32 Length(const char* str);
|
static int32 Length(const char* str);
|
||||||
|
|
||||||
// Copy string
|
// Copies the string.
|
||||||
static Char* Copy(Char* dst, const Char* src);
|
static Char* Copy(Char* dst, const Char* src);
|
||||||
|
|
||||||
// Copy string (count is maximum amount of characters to copy)
|
// Copies the string (count is maximum amount of characters to copy).
|
||||||
static Char* Copy(Char* dst, const Char* src, int32 count);
|
static Char* Copy(Char* dst, const Char* src, int32 count);
|
||||||
|
|
||||||
// Finds string in string, case sensitive
|
// Finds specific sub-string in the input string. Returns the first found position in the input string or nulll if failed.
|
||||||
// @param str The string to look through
|
|
||||||
// @param toFind The string to find inside str
|
|
||||||
// @return Position in str if Find was found, otherwise null
|
|
||||||
static const Char* Find(const Char* str, const Char* toFind);
|
static const Char* Find(const Char* str, const Char* toFind);
|
||||||
|
|
||||||
// Finds string in string, case sensitive
|
// Finds specific sub-string in the input string, case sensitive. Returns the first found position in the input string or nulll if failed.
|
||||||
// @param str The string to look through
|
|
||||||
// @param toFind The string to find inside str
|
|
||||||
// @return Position in str if Find was found, otherwise null
|
|
||||||
static const char* Find(const char* str, const char* toFind);
|
static const char* Find(const char* str, const char* toFind);
|
||||||
|
|
||||||
// Finds string in string, case insensitive
|
// Finds specific sub-string in the input string, case insensitive. Returns the first found position in the input string or nulll if failed.
|
||||||
// @param str The string to look through
|
|
||||||
// @param toFind The string to find inside str
|
|
||||||
// @return Position in str if toFind was found, otherwise null
|
|
||||||
static const Char* FindIgnoreCase(const Char* str, const Char* toFind);
|
static const Char* FindIgnoreCase(const Char* str, const Char* toFind);
|
||||||
|
|
||||||
// Finds string in string, case insensitive
|
// Finds specific sub-string in the input string, case insensitive. Returns the first found position in the input string or nulll if failed.
|
||||||
// @param str The string to look through
|
|
||||||
// @param toFind The string to find inside str
|
|
||||||
// @return Position in str if toFind was found, otherwise null
|
|
||||||
static const char* FindIgnoreCase(const char* str, const char* toFind);
|
static const char* FindIgnoreCase(const char* str, const char* toFind);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -197,101 +157,94 @@ public:
|
|||||||
static char* ConvertUTF162UTF8(const Char* from, int32 fromLength, int32& toLength);
|
static char* ConvertUTF162UTF8(const Char* from, int32 fromLength, int32& toLength);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Returns the directory name of the specified path string
|
/// <summary>
|
||||||
// @param path The path string from which to obtain the directory name
|
/// Gets the directory name of the specified path string.
|
||||||
// @returns Directory name
|
/// </summary>
|
||||||
|
/// <param name="path">The path string from which to obtain the directory name.</param>
|
||||||
|
/// <returns>Directory name.</returns>
|
||||||
static StringView GetDirectoryName(const StringView& path);
|
static StringView GetDirectoryName(const StringView& path);
|
||||||
|
|
||||||
// Returns the file name and extension of the specified path string
|
/// <summary>
|
||||||
// @param path The path string from which to obtain the file name and extension
|
/// Gets the file name and extension of the specified path string
|
||||||
// @returns File name with extension
|
/// </summary>
|
||||||
|
/// <param name="path">The path string from which to obtain the file name and extension.</param>
|
||||||
|
/// <returns>File name with extension.</returns>
|
||||||
static StringView GetFileName(const StringView& path);
|
static StringView GetFileName(const StringView& path);
|
||||||
|
|
||||||
// Returns the file name without extension of the specified path string
|
/// <summary>
|
||||||
// @param path The path string from which to obtain the file name
|
/// Gets the file name without extension of the specified path string.
|
||||||
// @returns File name without extension
|
/// </summary>
|
||||||
|
/// <param name="path">The path string from which to obtain the file name.</param>
|
||||||
|
/// <returns>File name without extension.</returns>
|
||||||
static StringView GetFileNameWithoutExtension(const StringView& path);
|
static StringView GetFileNameWithoutExtension(const StringView& path);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the path without extension.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path string.</param>
|
||||||
|
/// <returns>The path string without extension.</returns>
|
||||||
static StringView GetPathWithoutExtension(const StringView& path);
|
static StringView GetPathWithoutExtension(const StringView& path);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Normalizes path string and removes any relative parts such as `/../` and `/./`.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The input and output string with path to process.</param>
|
||||||
static void PathRemoveRelativeParts(String& path);
|
static void PathRemoveRelativeParts(String& path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Converts hexadecimal character into the value.
|
// Converts hexadecimal character into the value.
|
||||||
static int32 HexDigit(Char c);
|
static int32 HexDigit(Char c);
|
||||||
|
|
||||||
// Parse text to unsigned integer value
|
// Parses text to unsigned integer value. Returns true if failed to convert the value.
|
||||||
// @param str String to parse
|
|
||||||
// @return Result value
|
|
||||||
// @returns True if cannot convert data, otherwise false
|
|
||||||
template<typename CharType>
|
template<typename CharType>
|
||||||
static bool ParseHex(const CharType* str, uint32* result)
|
static bool ParseHex(const CharType* str, uint32* result)
|
||||||
{
|
{
|
||||||
uint32 sum = 0;
|
uint32 sum = 0;
|
||||||
const CharType* p = str;
|
const CharType* p = str;
|
||||||
|
|
||||||
if (*p == '0' && *(p + 1) == 'x')
|
if (*p == '0' && *(p + 1) == 'x')
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
while (*p)
|
while (*p)
|
||||||
{
|
{
|
||||||
int32 c = *p - '0';
|
int32 c = *p - '0';
|
||||||
|
|
||||||
if (c < 0 || c > 9)
|
if (c < 0 || c > 9)
|
||||||
{
|
{
|
||||||
c = ToLower(*p) - 'a' + 10;
|
c = ToLower(*p) - 'a' + 10;
|
||||||
if (c < 10 || c > 15)
|
if (c < 10 || c > 15)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sum = 16 * sum + c;
|
sum = 16 * sum + c;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = sum;
|
*result = sum;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse text to unsigned integer value
|
// Parses text to unsigned integer value. Returns true if failed to convert the value.
|
||||||
// @param str String to parse
|
|
||||||
// @param length Text length
|
|
||||||
// @return Result value
|
|
||||||
// @returns True if cannot convert data, otherwise false
|
|
||||||
template<typename CharType>
|
template<typename CharType>
|
||||||
static bool ParseHex(const CharType* str, int32 length, uint32* result)
|
static bool ParseHex(const CharType* str, int32 length, uint32* result)
|
||||||
{
|
{
|
||||||
uint32 sum = 0;
|
uint32 sum = 0;
|
||||||
const CharType* p = str;
|
const CharType* p = str;
|
||||||
const CharType* end = str + length;
|
const CharType* end = str + length;
|
||||||
|
|
||||||
if (*p == '0' && *(p + 1) == 'x')
|
if (*p == '0' && *(p + 1) == 'x')
|
||||||
p += 2;
|
p += 2;
|
||||||
|
|
||||||
while (*p && p < end)
|
while (*p && p < end)
|
||||||
{
|
{
|
||||||
int32 c = *p - '0';
|
int32 c = *p - '0';
|
||||||
|
|
||||||
if (c < 0 || c > 9)
|
if (c < 0 || c > 9)
|
||||||
{
|
{
|
||||||
c = ToLower(*p) - 'a' + 10;
|
c = ToLower(*p) - 'a' + 10;
|
||||||
if (c < 10 || c > 15)
|
if (c < 10 || c > 15)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sum = 16 * sum + c;
|
sum = 16 * sum + c;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = sum;
|
*result = sum;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse text to scalar value
|
// Parses text to scalar integer value. Returns true if failed to convert the value.
|
||||||
// @param str String to parse
|
|
||||||
// @return Result value
|
|
||||||
// @returns True if cannot convert data, otherwise false
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static bool Parse(const T* str, U* result)
|
static bool Parse(const T* str, U* result)
|
||||||
{
|
{
|
||||||
@@ -308,11 +261,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse text to scalar value
|
// Parses text to scalar integer value. Returns true if failed to convert the value.
|
||||||
// @param str String to parse
|
|
||||||
// @param length Text length to read
|
|
||||||
// @return Result value
|
|
||||||
// @returns True if cannot convert data, otherwise false
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
static bool Parse(const T* str, uint32 length, U* result)
|
static bool Parse(const T* str, uint32 length, U* result)
|
||||||
{
|
{
|
||||||
@@ -329,11 +278,10 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse Unicode text to float value
|
// Parses text to the scalar value. Returns true if failed to convert the value.
|
||||||
// @param str String to parse
|
|
||||||
// @return Result value
|
|
||||||
// @returns True if cannot convert data, otherwise false
|
|
||||||
static bool Parse(const Char* str, float* result);
|
static bool Parse(const Char* str, float* result);
|
||||||
|
|
||||||
|
// Parses text to the scalar value. Returns true if failed to convert the value.
|
||||||
static bool Parse(const char* str, float* result);
|
static bool Parse(const char* str, float* result);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -345,9 +293,7 @@ public:
|
|||||||
static String ToString(double value);
|
static String ToString(double value);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Returns the String to double null-terminated string
|
// Converts the string to double null-terminated string.
|
||||||
// @param str Double null-terminated string
|
|
||||||
// @return Double null-terminated String
|
|
||||||
static String GetZZString(const Char* str);
|
static String GetZZString(const Char* str);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,7 @@
|
|||||||
class FLAXENGINE_API UWPFileSystem : public Win32FileSystem
|
class FLAXENGINE_API UWPFileSystem : public Win32FileSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// [FileSystemBase]
|
||||||
/// <summary>
|
|
||||||
/// Gets the special folder path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The folder type.</param>
|
|
||||||
/// <param name="result">The result full path.</param>
|
|
||||||
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -129,11 +129,11 @@ bool Win32FileSystem::DirectoryGetFiles(Array<String>& results, const String& pa
|
|||||||
return getFilesFromDirectoryAll(results, path, searchPattern);
|
return getFilesFromDirectoryAll(results, path, searchPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Win32FileSystem::GetChildDirectories(Array<String>& results, const String& directory)
|
bool Win32FileSystem::GetChildDirectories(Array<String>& results, const String& path)
|
||||||
{
|
{
|
||||||
// Try to find first file
|
// Try to find first file
|
||||||
WIN32_FIND_DATA info;
|
WIN32_FIND_DATA info;
|
||||||
String pattern = directory / TEXT('*');
|
String pattern = path / TEXT('*');
|
||||||
const HANDLE handle = FindFirstFileW(*pattern, &info);
|
const HANDLE handle = FindFirstFileW(*pattern, &info);
|
||||||
if (INVALID_HANDLE_VALUE == handle)
|
if (INVALID_HANDLE_VALUE == handle)
|
||||||
{
|
{
|
||||||
@@ -151,7 +151,7 @@ bool Win32FileSystem::GetChildDirectories(Array<String>& results, const String&
|
|||||||
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
{
|
{
|
||||||
// Add directory
|
// Add directory
|
||||||
results.Add(directory / info.cFileName);
|
results.Add(path / info.cFileName);
|
||||||
}
|
}
|
||||||
} while (FindNextFileW(handle, &info) != 0);
|
} while (FindNextFileW(handle, &info) != 0);
|
||||||
FindClose(handle);
|
FindClose(handle);
|
||||||
|
|||||||
@@ -11,81 +11,23 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class FLAXENGINE_API Win32FileSystem : public FileSystemBase
|
class FLAXENGINE_API Win32FileSystem : public FileSystemBase
|
||||||
{
|
{
|
||||||
// TODO: fix docs
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// [FileSystemBase]
|
||||||
// Creates a new directory
|
|
||||||
// @param path Directory path
|
|
||||||
// @returns True if cannot create directory, otherwise false
|
|
||||||
static bool CreateDirectory(const StringView& path);
|
static bool CreateDirectory(const StringView& path);
|
||||||
|
|
||||||
// Deletes an existing directory
|
|
||||||
// @param path Directory path
|
|
||||||
// @param deleteSubdirectories True if delete all subdirectories and files, otherwise false
|
|
||||||
// @returns True if cannot delete directory, otherwise false
|
|
||||||
static bool DeleteDirectory(const String& path, bool deleteContents = true);
|
static bool DeleteDirectory(const String& path, bool deleteContents = true);
|
||||||
|
|
||||||
// Check if directory exists
|
|
||||||
// @param path Directory path to check
|
|
||||||
// @returns True if directory exists, otherwise false
|
|
||||||
static bool DirectoryExists(const StringView& path);
|
static bool DirectoryExists(const StringView& path);
|
||||||
|
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern = TEXT("*"), DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
||||||
// Finds the names of files (including their paths) that match the specified search pattern in the specified directory, using a value to determine whether to search subdirectories
|
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& path);
|
||||||
// @param results When this method completes, this list contains list of all filenames that match the specified search pattern
|
|
||||||
// @param path Path of the directory to search in it
|
|
||||||
// @param searchPattern Custom search pattern to use during that operation
|
|
||||||
// @param option Additional search options
|
|
||||||
// @returns True if an error occurred, otherwise false
|
|
||||||
static bool DirectoryGetFiles(Array<String, HeapAllocation>& results, const String& path, const Char* searchPattern, DirectorySearchOption option = DirectorySearchOption::AllDirectories);
|
|
||||||
|
|
||||||
// Finds the names of directories (including their paths) that are inside the specified directory
|
|
||||||
// @param results When this method completes, this list contains list of all filenames that match the specified search pattern
|
|
||||||
// @param directory Path of the directory to search in it
|
|
||||||
// @returns True if an error occurred, otherwise false
|
|
||||||
static bool GetChildDirectories(Array<String, HeapAllocation>& results, const String& directory);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Check if file exists
|
|
||||||
// @param path File path to check
|
|
||||||
// @returns True if file exists, otherwise false
|
|
||||||
static bool FileExists(const StringView& path);
|
static bool FileExists(const StringView& path);
|
||||||
|
|
||||||
// Deletes an existing file
|
|
||||||
// @param path File path
|
|
||||||
// @returns True if cannot delete file, otherwise false
|
|
||||||
static bool DeleteFile(const StringView& path);
|
static bool DeleteFile(const StringView& path);
|
||||||
|
|
||||||
// Tries to get size of the file
|
|
||||||
// @param path File path to check
|
|
||||||
// @returns Amount of bytes in file
|
|
||||||
static uint64 GetFileSize(const StringView& path);
|
static uint64 GetFileSize(const StringView& path);
|
||||||
|
|
||||||
// Check if file is read-only
|
|
||||||
// @param path File path to check
|
|
||||||
// @returns True if file is read-only
|
|
||||||
static bool IsReadOnly(const StringView& path);
|
static bool IsReadOnly(const StringView& path);
|
||||||
|
|
||||||
// Sets file read-only flag
|
|
||||||
// @param path File path
|
|
||||||
// @returns True if cannot update file
|
|
||||||
static bool SetReadOnly(const StringView& path, bool isReadOnly);
|
static bool SetReadOnly(const StringView& path, bool isReadOnly);
|
||||||
|
|
||||||
// Move file
|
|
||||||
// @param dst Destination path
|
|
||||||
// @param src Source path
|
|
||||||
// @returns True if cannot move file
|
|
||||||
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false);
|
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false);
|
||||||
|
|
||||||
// Clone file
|
|
||||||
// @param dst Destination path
|
|
||||||
// @param src Source path
|
|
||||||
// @returns True if cannot copy file
|
|
||||||
static bool CopyFile(const StringView& dst, const StringView& src);
|
static bool CopyFile(const StringView& dst, const StringView& src);
|
||||||
|
static DateTime GetFileLastEditTime(const StringView& path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the UNIX style line endings into DOS style (from \n into \r\n).
|
/// Converts the UNIX style line endings into DOS style (from \n into \r\n).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -93,17 +35,7 @@ public:
|
|||||||
/// <param name="output">The output result.</param>
|
/// <param name="output">The output result.</param>
|
||||||
static void ConvertLineEndingsToDos(const StringView& text, Array<Char, HeapAllocation>& output);
|
static void ConvertLineEndingsToDos(const StringView& text, Array<Char, HeapAllocation>& output);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets last time when file has been modified (in UTC).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The file path to check.</param>
|
|
||||||
/// <returns>The last write time or DateTime::MinValue() if cannot get data.</returns>
|
|
||||||
static DateTime GetFileLastEditTime(const StringView& path);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static bool getFilesFromDirectoryTop(Array<String, HeapAllocation>& results, const String& directory, const Char* searchPattern);
|
static bool getFilesFromDirectoryTop(Array<String, HeapAllocation>& results, const String& directory, const Char* searchPattern);
|
||||||
static bool getFilesFromDirectoryAll(Array<String, HeapAllocation>& results, const String& directory, const Char* searchPattern);
|
static bool getFilesFromDirectoryAll(Array<String, HeapAllocation>& results, const String& directory, const Char* searchPattern);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
class FLAXENGINE_API WindowsFileSystem : public Win32FileSystem
|
class FLAXENGINE_API WindowsFileSystem : public Win32FileSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Moves a file to the recycle bin with possible undo instead of removing it permanently.
|
/// Moves a file to the recycle bin with possible undo instead of removing it permanently.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -20,26 +19,15 @@ public:
|
|||||||
/// <returns>True if cannot perform that operation, otherwise false.</returns>
|
/// <returns>True if cannot perform that operation, otherwise false.</returns>
|
||||||
static bool MoveFileToRecycleBin(const StringView& path);
|
static bool MoveFileToRecycleBin(const StringView& path);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
static bool AreFilePathsEqual(const StringView& path1, const StringView& path2);
|
static bool AreFilePathsEqual(const StringView& path1, const StringView& path2);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the special folder path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The folder type.</param>
|
|
||||||
/// <param name="result">The result full path.</param>
|
|
||||||
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// [Win32FileSystem]
|
// [Win32FileSystem]
|
||||||
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
||||||
static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, Array<String, HeapAllocation>& filenames);
|
||||||
static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path);
|
static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, String& path);
|
||||||
static bool ShowFileExplorer(const StringView& path);
|
static bool ShowFileExplorer(const StringView& path);
|
||||||
|
static void GetSpecialFolderPath(const SpecialFolder type, String& result);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -339,11 +339,10 @@ int32 Font::HitTestText(const StringView& text, const Float2& location, const Te
|
|||||||
float baseLinesDistance = static_cast<float>(_height) * layout.BaseLinesGapScale * scale;
|
float baseLinesDistance = static_cast<float>(_height) * layout.BaseLinesGapScale * scale;
|
||||||
|
|
||||||
// Offset position to match lines origin space
|
// Offset position to match lines origin space
|
||||||
Float2 rootOffset = layout.Bounds.Location + lines.First().Location;
|
Float2 testPoint = location - layout.Bounds.Location;
|
||||||
Float2 testPoint = location - rootOffset;
|
|
||||||
|
|
||||||
// Get line which may intersect with the position (it's possible because lines have fixed height)
|
// Get line which may intersect with the position (it's possible because lines have fixed height)
|
||||||
int32 lineIndex = Math::Clamp(Math::FloorToInt(testPoint.Y / baseLinesDistance), 0, lines.Count() - 1);
|
int32 lineIndex = Math::Clamp(Math::FloorToInt((testPoint.Y - lines.First().Location.Y) / baseLinesDistance), 0, lines.Count() - 1);
|
||||||
const FontLineCache& line = lines[lineIndex];
|
const FontLineCache& line = lines[lineIndex];
|
||||||
float x = line.Location.X;
|
float x = line.Location.X;
|
||||||
|
|
||||||
@@ -403,7 +402,19 @@ Float2 Font::GetCharPosition(const StringView& text, int32 index, const TextLayo
|
|||||||
{
|
{
|
||||||
// Check if there is no need to do anything
|
// Check if there is no need to do anything
|
||||||
if (text.IsEmpty())
|
if (text.IsEmpty())
|
||||||
return layout.Bounds.Location;
|
{
|
||||||
|
Float2 location = layout.Bounds.Location;
|
||||||
|
if (layout.VerticalAlignment == TextAlignment::Center)
|
||||||
|
location.Y += layout.Bounds.Size.Y * 0.5f - static_cast<float>(_height) * 0.5f;
|
||||||
|
else if (layout.VerticalAlignment == TextAlignment::Far)
|
||||||
|
location.Y += layout.Bounds.Size.Y - static_cast<float>(_height) * 0.5f;
|
||||||
|
|
||||||
|
if (layout.HorizontalAlignment == TextAlignment::Center)
|
||||||
|
location.X += layout.Bounds.Size.X * 0.5f;
|
||||||
|
else if (layout.HorizontalAlignment == TextAlignment::Far)
|
||||||
|
location.X += layout.Bounds.Size.X;
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
// Process text
|
// Process text
|
||||||
Array<FontLineCache> lines;
|
Array<FontLineCache> lines;
|
||||||
@@ -411,7 +422,6 @@ Float2 Font::GetCharPosition(const StringView& text, int32 index, const TextLayo
|
|||||||
ASSERT(lines.HasItems());
|
ASSERT(lines.HasItems());
|
||||||
float scale = layout.Scale / FontManager::FontScale;
|
float scale = layout.Scale / FontManager::FontScale;
|
||||||
float baseLinesDistance = static_cast<float>(_height) * layout.BaseLinesGapScale * scale;
|
float baseLinesDistance = static_cast<float>(_height) * layout.BaseLinesGapScale * scale;
|
||||||
Float2 rootOffset = layout.Bounds.Location + lines.First().Location;
|
|
||||||
|
|
||||||
// Find line with that position
|
// Find line with that position
|
||||||
FontCharacterEntry previous;
|
FontCharacterEntry previous;
|
||||||
@@ -423,7 +433,7 @@ Float2 Font::GetCharPosition(const StringView& text, int32 index, const TextLayo
|
|||||||
// Check if desire position is somewhere inside characters in line range
|
// Check if desire position is somewhere inside characters in line range
|
||||||
if (Math::IsInRange(index, line.FirstCharIndex, line.LastCharIndex))
|
if (Math::IsInRange(index, line.FirstCharIndex, line.LastCharIndex))
|
||||||
{
|
{
|
||||||
float x = line.Location.X;
|
Float2 charPos = line.Location;
|
||||||
|
|
||||||
// Check all characters in the line
|
// Check all characters in the line
|
||||||
for (int32 currentIndex = line.FirstCharIndex; currentIndex < index; currentIndex++)
|
for (int32 currentIndex = line.FirstCharIndex; currentIndex < index; currentIndex++)
|
||||||
@@ -436,21 +446,21 @@ Float2 Font::GetCharPosition(const StringView& text, int32 index, const TextLayo
|
|||||||
// Apply kerning
|
// Apply kerning
|
||||||
if (!isWhitespace && previous.IsValid)
|
if (!isWhitespace && previous.IsValid)
|
||||||
{
|
{
|
||||||
x += entry.Font->GetKerning(previous.Character, entry.Character);
|
charPos.X += entry.Font->GetKerning(previous.Character, entry.Character);
|
||||||
}
|
}
|
||||||
previous = entry;
|
previous = entry;
|
||||||
|
|
||||||
// Move
|
// Move
|
||||||
x += entry.AdvanceX * scale;
|
charPos.X += entry.AdvanceX * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upper left corner of the character
|
// Upper left corner of the character
|
||||||
return rootOffset + Float2(x, static_cast<float>(lineIndex * baseLinesDistance));
|
return layout.Bounds.Location + charPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position after last character in the last line
|
// Position after last character in the last line
|
||||||
return rootOffset + Float2(lines.Last().Size.X, static_cast<float>((lines.Count() - 1) * baseLinesDistance));
|
return layout.Bounds.Location + lines.Last().Location + Float2(lines.Last().Size.X, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::FlushFaceSize() const
|
void Font::FlushFaceSize() const
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace FlaxEngine
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The size of the font characters.
|
/// The size of the font characters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[EditorOrder(10), Limit(1, 500, 0.1f), Tooltip("The size of the font characters.")]
|
[EditorOrder(10), Limit(1, 500, 0.5f), Tooltip("The size of the font characters.")]
|
||||||
public float Size
|
public float Size
|
||||||
{
|
{
|
||||||
get => _size;
|
get => _size;
|
||||||
|
|||||||
@@ -841,10 +841,11 @@ void Render2D::PushClip(const Rectangle& clipRect)
|
|||||||
{
|
{
|
||||||
RENDER2D_CHECK_RENDERING_STATE;
|
RENDER2D_CHECK_RENDERING_STATE;
|
||||||
|
|
||||||
|
const auto& mask = ClipLayersStack.Peek();
|
||||||
RotatedRectangle clipRectTransformed;
|
RotatedRectangle clipRectTransformed;
|
||||||
ApplyTransform(clipRect, clipRectTransformed);
|
ApplyTransform(clipRect, clipRectTransformed);
|
||||||
const Rectangle bounds = Rectangle::Shared(clipRectTransformed.ToBoundingRect(), ClipLayersStack.Peek().Bounds);
|
const Rectangle bounds = Rectangle::Shared(clipRectTransformed.ToBoundingRect(), mask.Bounds);
|
||||||
ClipLayersStack.Push({ clipRectTransformed, bounds });
|
ClipLayersStack.Push({ RotatedRectangle::Shared(clipRectTransformed, mask.Bounds), bounds });
|
||||||
|
|
||||||
OnClipScissors();
|
OnClipScissors();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
struct RotatedRectangle
|
struct RotatedRectangle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The transformed top left corner.
|
/// The transformed top left corner.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -27,7 +26,6 @@ public:
|
|||||||
Float2 ExtentY;
|
Float2 ExtentY;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RotatedRectangle"/> struct.
|
/// Initializes a new instance of the <see cref="RotatedRectangle"/> struct.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -60,7 +58,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert rotated rectangle to the axis-aligned rectangle that builds rotated rectangle bounding box.
|
/// Convert rotated rectangle to the axis-aligned rectangle that builds rotated rectangle bounding box.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -95,8 +92,24 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
/// <summary>
|
||||||
|
/// Calculates a rectangle that contains the shared part of both rectangles.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">The first rectangle.</param>
|
||||||
|
/// <param name="b">The second rectangle.</param>
|
||||||
|
/// <returns>Rectangle that contains shared part of a and b rectangles.</returns>
|
||||||
|
static RotatedRectangle Shared(const RotatedRectangle& a, const Rectangle& b)
|
||||||
|
{
|
||||||
|
// Clip the rotated rectangle bounds within the given AABB
|
||||||
|
RotatedRectangle result = a;
|
||||||
|
result.TopLeft = Float2::Max(a.TopLeft, b.GetTopLeft());
|
||||||
|
// TODO: do a little better math below (in case of actually rotated rectangle)
|
||||||
|
result.ExtentX.X = Math::Min(result.TopLeft.X + result.ExtentX.X, b.GetRight()) - result.TopLeft.X;
|
||||||
|
result.ExtentY.Y = Math::Min(result.TopLeft.Y + result.ExtentY.Y, b.GetBottom()) - result.TopLeft.Y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
bool operator ==(const RotatedRectangle& other) const
|
bool operator ==(const RotatedRectangle& other) const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace FlaxEngine
|
namespace FlaxEngine
|
||||||
{
|
{
|
||||||
partial struct SpriteHandle
|
partial struct SpriteHandle : IEquatable<SpriteHandle>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invalid sprite handle.
|
/// Invalid sprite handle.
|
||||||
@@ -107,5 +108,53 @@ namespace FlaxEngine
|
|||||||
Atlas.SetSprite(Index, ref sprite);
|
Atlas.SetSprite(Index, ref sprite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests for equality between two objects.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first value to compare.</param>
|
||||||
|
/// <param name="right">The second value to compare.</param>
|
||||||
|
/// <returns><c>true</c> if <paramref name="left" /> has the same value as <paramref name="right" />; otherwise, <c>false</c>.</returns>
|
||||||
|
public static bool operator ==(SpriteHandle left, SpriteHandle right)
|
||||||
|
{
|
||||||
|
return left.Index == right.Index && left.Atlas == right.Atlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests for inequality between two objects.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The first value to compare.</param>
|
||||||
|
/// <param name="right">The second value to compare.</param>
|
||||||
|
/// <returns><c>true</c> if <paramref name="left" /> has a different value than <paramref name="right" />; otherwise, <c>false</c>.</returns>
|
||||||
|
public static bool operator !=(SpriteHandle left, SpriteHandle right)
|
||||||
|
{
|
||||||
|
return left.Index != right.Index || left.Atlas != right.Atlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool Equals(SpriteHandle other)
|
||||||
|
{
|
||||||
|
return Index == other.Index && Atlas == other.Atlas;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is SpriteHandle other && Equals(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(Atlas, Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (Atlas)
|
||||||
|
return $"{System.IO.Path.GetFileNameWithoutExtension(Atlas.Path)}[{Index}]";
|
||||||
|
return "Invalid";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -757,43 +757,51 @@ bool DynamicDiffuseGlobalIlluminationPass::Render(RenderContext& renderContext,
|
|||||||
if (_debugModel && _debugModel->IsLoaded() && _debugModel->CanBeRendered() && _debugMaterial && _debugMaterial->IsLoaded())
|
if (_debugModel && _debugModel->IsLoaded() && _debugModel->CanBeRendered() && _debugMaterial && _debugMaterial->IsLoaded())
|
||||||
{
|
{
|
||||||
RenderContext debugRenderContext(renderContext);
|
RenderContext debugRenderContext(renderContext);
|
||||||
debugRenderContext.List = RenderList::GetFromPool();
|
|
||||||
debugRenderContext.View.Pass = DrawPass::GBuffer;
|
|
||||||
debugRenderContext.View.Prepare(debugRenderContext);
|
|
||||||
Matrix world;
|
Matrix world;
|
||||||
Matrix::Scaling(Float3(0.2f), world);
|
Matrix::Scaling(Float3(0.2f), world);
|
||||||
const Mesh& debugMesh = _debugModel->LODs[0].Meshes[0];
|
const Mesh& debugMesh = _debugModel->LODs[0].Meshes[0];
|
||||||
for (int32 probeIndex = 0; probeIndex < ddgiData.ProbesCountTotal; probeIndex++)
|
constexpr int32 maxProbesPerDrawing = 32 * 1024;
|
||||||
debugMesh.Draw(debugRenderContext, _debugMaterial, world, StaticFlags::None, true, DrawPass::GBuffer, (float)probeIndex);
|
int32 probesDrawingStart = 0;
|
||||||
debugRenderContext.List->SortDrawCalls(debugRenderContext, false, DrawCallsListType::GBuffer);
|
while (probesDrawingStart < ddgiData.ProbesCountTotal)
|
||||||
context->SetViewportAndScissors(debugRenderContext.View.ScreenSize.X, debugRenderContext.View.ScreenSize.Y);
|
|
||||||
GPUTextureView* targetBuffers[5] =
|
|
||||||
{
|
{
|
||||||
lightBuffer,
|
debugRenderContext.List = RenderList::GetFromPool();
|
||||||
renderContext.Buffers->GBuffer0->View(),
|
debugRenderContext.View.Pass = DrawPass::GBuffer;
|
||||||
renderContext.Buffers->GBuffer1->View(),
|
debugRenderContext.View.Prepare(debugRenderContext);
|
||||||
renderContext.Buffers->GBuffer2->View(),
|
// TODO: refactor this into BatchedDrawCalls for faster draw calls processing
|
||||||
renderContext.Buffers->GBuffer3->View(),
|
const int32 probesDrawingEnd = Math::Min(probesDrawingStart + maxProbesPerDrawing, ddgiData.ProbesCountTotal);
|
||||||
};
|
for (int32 probeIndex = probesDrawingStart; probeIndex < probesDrawingEnd; probeIndex++)
|
||||||
context->SetRenderTarget(*renderContext.Buffers->DepthBuffer, ToSpan(targetBuffers, ARRAY_COUNT(targetBuffers)));
|
debugMesh.Draw(debugRenderContext, _debugMaterial, world, StaticFlags::None, true, DrawPass::GBuffer, (float)probeIndex);
|
||||||
{
|
debugRenderContext.List->SortDrawCalls(debugRenderContext, false, DrawCallsListType::GBuffer);
|
||||||
// Pass DDGI data to the material
|
context->SetViewportAndScissors(debugRenderContext.View.ScreenSize.X, debugRenderContext.View.ScreenSize.Y);
|
||||||
_debugMaterial->SetParameterValue(TEXT("ProbesData"), Variant(ddgiData.ProbesData));
|
GPUTextureView* targetBuffers[5] =
|
||||||
#if DDGI_DEBUG_INSTABILITY
|
|
||||||
_debugMaterial->SetParameterValue(TEXT("ProbesIrradiance"), Variant(ddgiData.ProbesInstability));
|
|
||||||
#else
|
|
||||||
_debugMaterial->SetParameterValue(TEXT("ProbesIrradiance"), Variant(ddgiData.ProbesIrradiance));
|
|
||||||
#endif
|
|
||||||
_debugMaterial->SetParameterValue(TEXT("ProbesDistance"), Variant(ddgiData.ProbesDistance));
|
|
||||||
auto cb = _debugMaterial->GetShader()->GetCB(3);
|
|
||||||
if (cb)
|
|
||||||
{
|
{
|
||||||
context->UpdateCB(cb, &ddgiData.Result.Constants);
|
lightBuffer,
|
||||||
context->BindCB(3, cb);
|
renderContext.Buffers->GBuffer0->View(),
|
||||||
|
renderContext.Buffers->GBuffer1->View(),
|
||||||
|
renderContext.Buffers->GBuffer2->View(),
|
||||||
|
renderContext.Buffers->GBuffer3->View(),
|
||||||
|
};
|
||||||
|
context->SetRenderTarget(*renderContext.Buffers->DepthBuffer, ToSpan(targetBuffers, ARRAY_COUNT(targetBuffers)));
|
||||||
|
{
|
||||||
|
// Pass DDGI data to the material
|
||||||
|
_debugMaterial->SetParameterValue(TEXT("ProbesData"), Variant(ddgiData.ProbesData));
|
||||||
|
#if DDGI_DEBUG_INSTABILITY
|
||||||
|
_debugMaterial->SetParameterValue(TEXT("ProbesIrradiance"), Variant(ddgiData.ProbesInstability));
|
||||||
|
#else
|
||||||
|
_debugMaterial->SetParameterValue(TEXT("ProbesIrradiance"), Variant(ddgiData.ProbesIrradiance));
|
||||||
|
#endif
|
||||||
|
_debugMaterial->SetParameterValue(TEXT("ProbesDistance"), Variant(ddgiData.ProbesDistance));
|
||||||
|
auto cb = _debugMaterial->GetShader()->GetCB(3);
|
||||||
|
if (cb)
|
||||||
|
{
|
||||||
|
context->UpdateCB(cb, &ddgiData.Result.Constants);
|
||||||
|
context->BindCB(3, cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
debugRenderContext.List->ExecuteDrawCalls(debugRenderContext, DrawCallsListType::GBuffer);
|
||||||
|
RenderList::ReturnToPool(debugRenderContext.List);
|
||||||
|
probesDrawingStart = probesDrawingEnd;
|
||||||
}
|
}
|
||||||
debugRenderContext.List->ExecuteDrawCalls(debugRenderContext, DrawCallsListType::GBuffer);
|
|
||||||
RenderList::ReturnToPool(debugRenderContext.List);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -318,6 +318,11 @@ void ProbesRendererService::Update()
|
|||||||
// Calculate time delta since last update
|
// Calculate time delta since last update
|
||||||
auto timeNow = Time::Update.UnscaledTime;
|
auto timeNow = Time::Update.UnscaledTime;
|
||||||
auto timeSinceUpdate = timeNow - _lastProbeUpdate;
|
auto timeSinceUpdate = timeNow - _lastProbeUpdate;
|
||||||
|
if (timeSinceUpdate < 0)
|
||||||
|
{
|
||||||
|
_lastProbeUpdate = timeNow;
|
||||||
|
timeSinceUpdate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if render job is done
|
// Check if render job is done
|
||||||
if (isUpdateSynced())
|
if (isUpdateSynced())
|
||||||
@@ -351,8 +356,9 @@ void ProbesRendererService::Update()
|
|||||||
auto dt = (float)Time::Update.UnscaledDeltaTime.GetTotalSeconds();
|
auto dt = (float)Time::Update.UnscaledDeltaTime.GetTotalSeconds();
|
||||||
for (int32 i = 0; i < _probesToBake.Count(); i++)
|
for (int32 i = 0; i < _probesToBake.Count(); i++)
|
||||||
{
|
{
|
||||||
_probesToBake[i].Timeout -= dt;
|
auto& e = _probesToBake[i];
|
||||||
if (_probesToBake[i].Timeout <= 0)
|
e.Timeout -= dt;
|
||||||
|
if (e.Timeout <= 0)
|
||||||
{
|
{
|
||||||
firstValidEntryIndex = i;
|
firstValidEntryIndex = i;
|
||||||
break;
|
break;
|
||||||
@@ -417,6 +423,9 @@ void ProbesRenderer::OnRender(RenderTask* task, GPUContext* context)
|
|||||||
if (_current.Actor == nullptr)
|
if (_current.Actor == nullptr)
|
||||||
{
|
{
|
||||||
// Probe has been unlinked (or deleted)
|
// Probe has been unlinked (or deleted)
|
||||||
|
_task->Enabled = false;
|
||||||
|
_updateFrameNumber = 0;
|
||||||
|
_current.Type = EntryType::Invalid;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -28,21 +28,9 @@ public:
|
|||||||
|
|
||||||
struct Entry
|
struct Entry
|
||||||
{
|
{
|
||||||
EntryType Type;
|
EntryType Type = EntryType::Invalid;
|
||||||
ScriptingObjectReference<Actor> Actor;
|
ScriptingObjectReference<Actor> Actor;
|
||||||
float Timeout;
|
float Timeout = 0.0f;
|
||||||
|
|
||||||
Entry()
|
|
||||||
{
|
|
||||||
Type = EntryType::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entry(const Entry& other)
|
|
||||||
{
|
|
||||||
Type = other.Type;
|
|
||||||
Actor = other.Actor;
|
|
||||||
Timeout = other.Timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UseTextureData() const;
|
bool UseTextureData() const;
|
||||||
int32 GetResolution() const;
|
int32 GetResolution() const;
|
||||||
|
|||||||
@@ -887,7 +887,8 @@ ScriptingObject* Scripting::FindObject(Guid id, const MClass* type)
|
|||||||
// Check type
|
// Check type
|
||||||
if (!type || result->Is(type))
|
if (!type || result->Is(type))
|
||||||
return result;
|
return result;
|
||||||
LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}. {3}", id, String(result->GetType().Fullname), String(type->GetFullName()), LogContext::GetInfo());
|
LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}", id, String(result->GetType().Fullname), String(type->GetFullName()));
|
||||||
|
LogContext::Print(LogType::Warning);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,7 +907,8 @@ ScriptingObject* Scripting::FindObject(Guid id, const MClass* type)
|
|||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}. {2}", id, String(type->GetFullName()), LogContext::GetInfo());
|
LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}", id, String(type->GetFullName()));
|
||||||
|
LogContext::Print(LogType::Warning);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -737,7 +737,10 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject*
|
|||||||
if (klass && !obj->Is(klass))
|
if (klass && !obj->Is(klass))
|
||||||
{
|
{
|
||||||
if (!skipLog)
|
if (!skipLog)
|
||||||
LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}. {3}", *id, String(obj->GetType().Fullname), String(klass->GetFullName()), LogContext::GetInfo());
|
{
|
||||||
|
LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}", *id, String(obj->GetType().Fullname), String(klass->GetFullName()));
|
||||||
|
LogContext::Print(LogType::Warning);
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return obj->GetOrCreateManagedInstance();
|
return obj->GetOrCreateManagedInstance();
|
||||||
@@ -746,9 +749,10 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject*
|
|||||||
if (!skipLog)
|
if (!skipLog)
|
||||||
{
|
{
|
||||||
if (klass)
|
if (klass)
|
||||||
LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}. {2}", *id, String(klass->GetFullName()), LogContext::GetInfo());
|
LOG(Warning, "Unable to find scripting object with ID={0} of type {1}", *id, String(klass->GetFullName()));
|
||||||
else
|
else
|
||||||
LOG(Warning, "Unable to find scripting object with ID={0}", *id);
|
LOG(Warning, "Unable to find scripting object with ID={0}", *id);
|
||||||
|
LogContext::Print(LogType::Warning);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ public:
|
|||||||
virtual void ReadBytes(void* data, uint32 bytes) = 0;
|
virtual void ReadBytes(void* data, uint32 bytes) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Reads byte from the stream
|
|
||||||
// @returns Single byte
|
|
||||||
byte ReadByte()
|
byte ReadByte()
|
||||||
{
|
{
|
||||||
byte data;
|
byte data;
|
||||||
@@ -31,7 +29,6 @@ public:
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads bool from the stream
|
|
||||||
bool ReadBool()
|
bool ReadBool()
|
||||||
{
|
{
|
||||||
byte data;
|
byte data;
|
||||||
@@ -39,8 +36,6 @@ public:
|
|||||||
return data != 0;
|
return data != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads char from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
char ReadChar()
|
char ReadChar()
|
||||||
{
|
{
|
||||||
char data;
|
char data;
|
||||||
@@ -53,78 +48,56 @@ public:
|
|||||||
ReadBytes(data, sizeof(byte));
|
ReadBytes(data, sizeof(byte));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads Char from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadChar(Char* data)
|
FORCE_INLINE void ReadChar(Char* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(Char));
|
ReadBytes(data, sizeof(Char));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads uint8 from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadUint8(uint8* data)
|
FORCE_INLINE void ReadUint8(uint8* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(uint8));
|
ReadBytes(data, sizeof(uint8));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads int8 from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadInt8(int8* data)
|
FORCE_INLINE void ReadInt8(int8* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(int8));
|
ReadBytes(data, sizeof(int8));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads uint16 from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadUint16(uint16* data)
|
FORCE_INLINE void ReadUint16(uint16* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(uint16));
|
ReadBytes(data, sizeof(uint16));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads int16 from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadInt16(int16* data)
|
FORCE_INLINE void ReadInt16(int16* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(int16));
|
ReadBytes(data, sizeof(int16));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads uint32 from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadUint32(uint32* data)
|
FORCE_INLINE void ReadUint32(uint32* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(uint32));
|
ReadBytes(data, sizeof(uint32));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads int32 from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadInt32(int32* data)
|
FORCE_INLINE void ReadInt32(int32* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(int32));
|
ReadBytes(data, sizeof(int32));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads uint64 from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadUint64(uint64* data)
|
FORCE_INLINE void ReadUint64(uint64* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(uint64));
|
ReadBytes(data, sizeof(uint64));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads int64 from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadInt64(int64* data)
|
FORCE_INLINE void ReadInt64(int64* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(int64));
|
ReadBytes(data, sizeof(int64));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads float from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadFloat(float* data)
|
FORCE_INLINE void ReadFloat(float* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(float));
|
ReadBytes(data, sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads double from the stream
|
|
||||||
// @param data Data to read
|
|
||||||
FORCE_INLINE void ReadDouble(double* data)
|
FORCE_INLINE void ReadDouble(double* data)
|
||||||
{
|
{
|
||||||
ReadBytes(data, sizeof(double));
|
ReadBytes(data, sizeof(double));
|
||||||
@@ -160,6 +133,7 @@ public:
|
|||||||
Read(ptr);
|
Read(ptr);
|
||||||
v = ptr;
|
v = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
FORCE_INLINE void Read(SoftObjectReference<T>& v)
|
FORCE_INLINE void Read(SoftObjectReference<T>& v)
|
||||||
{
|
{
|
||||||
@@ -167,6 +141,7 @@ public:
|
|||||||
ReadBytes(id, sizeof(id));
|
ReadBytes(id, sizeof(id));
|
||||||
v.Set(*(Guid*)id);
|
v.Set(*(Guid*)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
FORCE_INLINE void Read(AssetReference<T>& v)
|
FORCE_INLINE void Read(AssetReference<T>& v)
|
||||||
{
|
{
|
||||||
@@ -174,6 +149,7 @@ public:
|
|||||||
ReadBytes(id, sizeof(id));
|
ReadBytes(id, sizeof(id));
|
||||||
v = (T*)::LoadAsset(*(Guid*)id, T::TypeInitializer);
|
v = (T*)::LoadAsset(*(Guid*)id, T::TypeInitializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
FORCE_INLINE void Read(WeakAssetReference<T>& v)
|
FORCE_INLINE void Read(WeakAssetReference<T>& v)
|
||||||
{
|
{
|
||||||
@@ -181,6 +157,7 @@ public:
|
|||||||
ReadBytes(id, sizeof(id));
|
ReadBytes(id, sizeof(id));
|
||||||
v = (T*)::LoadAsset(*(Guid*)id, T::TypeInitializer);
|
v = (T*)::LoadAsset(*(Guid*)id, T::TypeInitializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
FORCE_INLINE void Read(SoftAssetReference<T>& v)
|
FORCE_INLINE void Read(SoftAssetReference<T>& v)
|
||||||
{
|
{
|
||||||
@@ -240,38 +217,30 @@ public:
|
|||||||
public:
|
public:
|
||||||
// Reads StringAnsi from the stream
|
// Reads StringAnsi from the stream
|
||||||
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
||||||
// @param data Data to read
|
|
||||||
void ReadStringAnsi(StringAnsi* data);
|
void ReadStringAnsi(StringAnsi* data);
|
||||||
|
|
||||||
// Reads StringAnsi from the stream with a key
|
// Reads StringAnsi from the stream with a key
|
||||||
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
||||||
// @param data Data to read
|
|
||||||
void ReadStringAnsi(StringAnsi* data, int8 lock);
|
void ReadStringAnsi(StringAnsi* data, int8 lock);
|
||||||
|
|
||||||
// Reads String from the stream
|
// Reads String from the stream
|
||||||
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
||||||
// @param data Data to read
|
|
||||||
void ReadString(String* data);
|
void ReadString(String* data);
|
||||||
|
|
||||||
// Reads String from the stream
|
// Reads String from the stream
|
||||||
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
||||||
// @param data Data to read
|
|
||||||
// @param lock Characters pass in the stream
|
|
||||||
void ReadString(String* data, int16 lock);
|
void ReadString(String* data, int16 lock);
|
||||||
|
|
||||||
// Reads CommonValue from the stream
|
// Reads CommonValue from the stream
|
||||||
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
||||||
// @param data Data to read
|
|
||||||
void ReadCommonValue(CommonValue* data);
|
void ReadCommonValue(CommonValue* data);
|
||||||
|
|
||||||
// Reads VariantType from the stream
|
// Reads VariantType from the stream
|
||||||
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
||||||
// @param data Data to read
|
|
||||||
void ReadVariantType(VariantType* data);
|
void ReadVariantType(VariantType* data);
|
||||||
|
|
||||||
// Reads Variant from the stream
|
// Reads Variant from the stream
|
||||||
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
/// [Deprecated on 11.10.2022, expires on 11.10.2024]
|
||||||
// @param data Data to read
|
|
||||||
void ReadVariant(Variant* data);
|
void ReadVariant(Variant* data);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -13,35 +13,44 @@
|
|||||||
class IRunnable : public Object
|
class IRunnable : public Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Virtual destructor
|
// Virtual destructor
|
||||||
virtual ~IRunnable()
|
virtual ~IRunnable()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initializes the runnable object
|
/// <summary>
|
||||||
// @return True if initialization was successful, otherwise false
|
/// Initializes the runnable object.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if initialization was successful, otherwise false.</returns>
|
||||||
virtual bool Init()
|
virtual bool Init()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs the runnable object.
|
/// <summary>
|
||||||
// @return The exit code
|
/// Executes the runnable object.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The exit code. Non-zero on error.</returns>
|
||||||
virtual int32 Run() = 0;
|
virtual int32 Run() = 0;
|
||||||
|
|
||||||
// Stops the runnable object. Called when thread is being terminated
|
/// <summary>
|
||||||
|
/// Stops the runnable object. Called when thread is being terminated
|
||||||
|
/// </summary>
|
||||||
virtual void Stop()
|
virtual void Stop()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exits the runnable object
|
/// <summary>
|
||||||
|
/// Exits the runnable object
|
||||||
|
/// </summary>
|
||||||
virtual void Exit()
|
virtual void Exit()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when thread ends work (via Kill or normally)
|
/// <summary>
|
||||||
// @param wasKilled True if thread has been killed
|
/// Called when thread ends work (via Kill or normally).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wasKilled">True if thread has been killed.</param>
|
||||||
virtual void AfterWork(bool wasKilled)
|
virtual void AfterWork(bool wasKilled)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -53,18 +62,15 @@ public:
|
|||||||
class SimpleRunnable : public IRunnable
|
class SimpleRunnable : public IRunnable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool _autoDelete;
|
bool _autoDelete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Working function
|
/// Working function
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Function<int32()> OnWork;
|
Function<int32()> OnWork;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Init
|
/// Init
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -75,7 +81,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// [IRunnable]
|
// [IRunnable]
|
||||||
String ToString() const override
|
String ToString() const override
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -183,11 +183,15 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value)
|
|||||||
break;
|
break;
|
||||||
// Pre-skinned Local Position
|
// Pre-skinned Local Position
|
||||||
case 13:
|
case 13:
|
||||||
value = _treeType == MaterialTreeType::VertexShader ? Value(VariantType::Float3, TEXT("input.PreSkinnedPosition")) : Value::Zero;
|
value = Value(VariantType::Float3, TEXT("input.PreSkinnedPosition"));
|
||||||
|
if (_treeType != MaterialTreeType::VertexShader)
|
||||||
|
value = VsToPs(node, box).AsFloat3();
|
||||||
break;
|
break;
|
||||||
// Pre-skinned Local Normal
|
// Pre-skinned Local Normal
|
||||||
case 14:
|
case 14:
|
||||||
value = _treeType == MaterialTreeType::VertexShader ? Value(VariantType::Float3, TEXT("input.PreSkinnedNormal")) : Value::Zero;
|
value = Value(VariantType::Float3, TEXT("input.PreSkinnedNormal"));
|
||||||
|
if (_treeType != MaterialTreeType::VertexShader)
|
||||||
|
value = VsToPs(node, box).AsFloat3();
|
||||||
break;
|
break;
|
||||||
// Depth
|
// Depth
|
||||||
case 15:
|
case 15:
|
||||||
@@ -211,38 +215,8 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value)
|
|||||||
break;
|
break;
|
||||||
// Interpolate VS To PS
|
// Interpolate VS To PS
|
||||||
case 20:
|
case 20:
|
||||||
{
|
value = VsToPs(node, node->GetBox(0));
|
||||||
const auto input = node->GetBox(0);
|
|
||||||
|
|
||||||
// If used in VS then pass the value from the input box
|
|
||||||
if (_treeType == MaterialTreeType::VertexShader)
|
|
||||||
{
|
|
||||||
value = tryGetValue(input, Value::Zero).AsFloat4();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if can use more interpolants
|
|
||||||
if (_vsToPsInterpolants.Count() == 16)
|
|
||||||
{
|
|
||||||
OnError(node, box, TEXT("Too many VS to PS interpolants used."));
|
|
||||||
value = Value::Zero;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if can use interpolants
|
|
||||||
const auto layer = GetRootLayer();
|
|
||||||
if (!layer || layer->Domain == MaterialDomain::Decal || layer->Domain == MaterialDomain::PostProcess)
|
|
||||||
{
|
|
||||||
OnError(node, box, TEXT("VS to PS interpolants are not supported in Decal or Post Process materials."));
|
|
||||||
value = Value::Zero;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Indicate the interpolator slot usage
|
|
||||||
value = Value(VariantType::Float4, String::Format(TEXT("input.CustomVSToPS[{0}]"), _vsToPsInterpolants.Count()));
|
|
||||||
_vsToPsInterpolants.Add(input);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
// Terrain Holes Mask
|
// Terrain Holes Mask
|
||||||
case 21:
|
case 21:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -832,4 +832,32 @@ void MaterialGenerator::WriteCustomGlobalCode(const Array<const MaterialGraph::N
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShaderGenerator::Value MaterialGenerator::VsToPs(Node* node, Box* input)
|
||||||
|
{
|
||||||
|
// If used in VS then pass the value from the input box
|
||||||
|
if (_treeType == MaterialTreeType::VertexShader)
|
||||||
|
{
|
||||||
|
return tryGetValue(input, Value::Zero).AsFloat4();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if can use more interpolants
|
||||||
|
if (_vsToPsInterpolants.Count() == 16)
|
||||||
|
{
|
||||||
|
OnError(node, input, TEXT("Too many VS to PS interpolants used."));
|
||||||
|
return Value::Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if can use interpolants
|
||||||
|
const auto layer = GetRootLayer();
|
||||||
|
if (!layer || layer->Domain == MaterialDomain::Decal || layer->Domain == MaterialDomain::PostProcess)
|
||||||
|
{
|
||||||
|
OnError(node, input, TEXT("VS to PS interpolants are not supported in Decal or Post Process materials."));
|
||||||
|
return Value::Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indicate the interpolator slot usage
|
||||||
|
_vsToPsInterpolants.Add(input);
|
||||||
|
return Value(VariantType::Float4, String::Format(TEXT("input.CustomVSToPS[{0}]"), _vsToPsInterpolants.Count() - 1));
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ private:
|
|||||||
MaterialValue AccessParticleAttribute(Node* caller, const StringView& name, ParticleAttributeValueTypes valueType, const Char* index = nullptr, ParticleAttributeSpace space = ParticleAttributeSpace::AsIs);
|
MaterialValue AccessParticleAttribute(Node* caller, const StringView& name, ParticleAttributeValueTypes valueType, const Char* index = nullptr, ParticleAttributeSpace space = ParticleAttributeSpace::AsIs);
|
||||||
void prepareLayer(MaterialLayer* layer, bool allowVisibleParams);
|
void prepareLayer(MaterialLayer* layer, bool allowVisibleParams);
|
||||||
void WriteCustomGlobalCode(const Array<const MaterialGraph::Node*, InlinedAllocation<8>>& nodes, int32 templateInputsMapping);
|
void WriteCustomGlobalCode(const Array<const MaterialGraph::Node*, InlinedAllocation<8>>& nodes, int32 templateInputsMapping);
|
||||||
|
Value VsToPs(Node* node, Box* input);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ bool ModelTool::GenerateModelSDF(Model* inputModel, ModelData* modelData, float
|
|||||||
sdf.ResolutionScale = resolutionScale;
|
sdf.ResolutionScale = resolutionScale;
|
||||||
sdf.LOD = lodIndex;
|
sdf.LOD = lodIndex;
|
||||||
const int32 maxMips = 3;
|
const int32 maxMips = 3;
|
||||||
const int32 mipCount = Math::Min(MipLevelsCount(resolution.X, resolution.Y, resolution.Z, true), maxMips);
|
const int32 mipCount = Math::Min(MipLevelsCount(resolution.X, resolution.Y, resolution.Z), maxMips);
|
||||||
PixelFormat format = PixelFormat::R16_UNorm;
|
PixelFormat format = PixelFormat::R16_UNorm;
|
||||||
int32 formatStride = 2;
|
int32 formatStride = 2;
|
||||||
float formatMaxValue = MAX_uint16;
|
float formatMaxValue = MAX_uint16;
|
||||||
|
|||||||
@@ -710,7 +710,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path
|
|||||||
bool hasSourceMipLevels = isPowerOfTwo && sourceMipLevels > 1;
|
bool hasSourceMipLevels = isPowerOfTwo && sourceMipLevels > 1;
|
||||||
bool useMipLevels = isPowerOfTwo && (options.GenerateMipMaps || hasSourceMipLevels) && (width > 1 || height > 1);
|
bool useMipLevels = isPowerOfTwo && (options.GenerateMipMaps || hasSourceMipLevels) && (width > 1 || height > 1);
|
||||||
int32 arraySize = (int32)currentImage->GetMetadata().arraySize;
|
int32 arraySize = (int32)currentImage->GetMetadata().arraySize;
|
||||||
int32 mipLevels = MipLevelsCount(width, height, useMipLevels);
|
int32 mipLevels = useMipLevels ? MipLevelsCount(width, height) : 1;
|
||||||
if (useMipLevels && !options.GenerateMipMaps && mipLevels != sourceMipLevels)
|
if (useMipLevels && !options.GenerateMipMaps && mipLevels != sourceMipLevels)
|
||||||
{
|
{
|
||||||
errorMsg = String::Format(TEXT("Imported texture has not full mip chain, loaded mips count: {0}, expected: {1}"), sourceMipLevels, mipLevels);
|
errorMsg = String::Format(TEXT("Imported texture has not full mip chain, loaded mips count: {0}, expected: {1}"), sourceMipLevels, mipLevels);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user