Merge remote-tracking branch 'origin/master' into 1.11

# Conflicts:
#	Content/Editor/DebugMaterials/DDGIDebugProbes.flax
#	Source/Editor/Windows/OutputLogWindow.cs
#	Source/Engine/Level/Actor.cpp
This commit is contained in:
Wojtek Figat
2025-09-24 18:18:27 +02:00
136 changed files with 1821 additions and 662 deletions

View File

@@ -1,12 +1,14 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Implementation of <see cref="IBrush"/> for <see cref="FlaxEngine.GPUTexture"/>.
/// </summary>
/// <seealso cref="IBrush" />
public sealed class GPUTextureBrush : IBrush
public sealed class GPUTextureBrush : IBrush, IEquatable<GPUTextureBrush>
{
/// <summary>
/// The GPU texture.
@@ -47,5 +49,29 @@ namespace FlaxEngine.GUI
else
Render2D.DrawTexture(Texture, rect, color);
}
/// <inheritdoc />
public bool Equals(GPUTextureBrush other)
{
return other != null && Texture == other.Texture && Filter == other.Filter;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is GPUTextureBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Texture, (int)Filter);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
}

View File

@@ -1,5 +1,7 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
@@ -23,7 +25,7 @@ namespace FlaxEngine.GUI
/// <summary>
/// Interface that unifies input source textures, sprites, render targets, and any other brushes to be used in a more generic way.
/// </summary>
public interface IBrush
public interface IBrush : IComparable
{
/// <summary>
/// Gets the size of the image brush in pixels (if relevant).

View File

@@ -1,12 +1,14 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Implementation of <see cref="IBrush"/> for linear color gradient (made of 2 color).
/// </summary>
/// <seealso cref="IBrush" />
public sealed class LinearGradientBrush : IBrush
public sealed class LinearGradientBrush : IBrush, IEquatable<LinearGradientBrush>
{
/// <summary>
/// The brush start color.
@@ -50,5 +52,29 @@ namespace FlaxEngine.GUI
var endColor = EndColor * color;
Render2D.FillRectangle(rect, startColor, startColor, endColor, endColor);
}
/// <inheritdoc />
public bool Equals(LinearGradientBrush other)
{
return other != null && StartColor == other.StartColor && EndColor == other.EndColor;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is LinearGradientBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(StartColor, EndColor);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
}

View File

@@ -1,12 +1,14 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Implementation of <see cref="IBrush"/> for <see cref="FlaxEngine.MaterialBase"/> rendering.
/// </summary>
/// <seealso cref="IBrush" />
public sealed class MaterialBrush : IBrush
public sealed class MaterialBrush : IBrush, IEquatable<MaterialBrush>
{
/// <summary>
/// The material.
@@ -38,5 +40,29 @@ namespace FlaxEngine.GUI
{
Render2D.DrawMaterial(Material, rect, color);
}
/// <inheritdoc />
public bool Equals(MaterialBrush other)
{
return other != null && Material == other.Material;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is MaterialBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Material);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
}

View File

@@ -1,12 +1,14 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Implementation of <see cref="IBrush"/> for single color fill.
/// </summary>
/// <seealso cref="IBrush" />
public sealed class SolidColorBrush : IBrush
public sealed class SolidColorBrush : IBrush, IEquatable<SolidColorBrush>
{
/// <summary>
/// The brush color.
@@ -39,5 +41,29 @@ namespace FlaxEngine.GUI
{
Render2D.FillRectangle(rect, Color * color);
}
/// <inheritdoc />
public bool Equals(SolidColorBrush other)
{
return other != null && Color == other.Color;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is SolidColorBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Color);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
}

View File

@@ -1,12 +1,14 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Implementation of <see cref="IBrush"/> for <see cref="FlaxEngine.Sprite"/>.
/// </summary>
/// <seealso cref="IBrush" />
public sealed class SpriteBrush : IBrush
public sealed class SpriteBrush : IBrush, IEquatable<SpriteBrush>
{
/// <summary>
/// The sprite.
@@ -47,6 +49,30 @@ namespace FlaxEngine.GUI
else
Render2D.DrawSprite(Sprite, rect, color);
}
/// <inheritdoc />
public bool Equals(SpriteBrush other)
{
return other != null && Sprite == other.Sprite && Filter == other.Filter;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is SpriteBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Sprite, (int)Filter);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
/// <summary>
@@ -121,5 +147,29 @@ namespace FlaxEngine.GUI
}
#endif
}
/// <inheritdoc />
public bool Equals(Sprite9SlicingBrush other)
{
return other != null && Sprite == other.Sprite && Filter == other.Filter;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is Sprite9SlicingBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Sprite, (int)Filter);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
}

View File

@@ -1,12 +1,14 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Implementation of <see cref="IBrush"/> for <see cref="FlaxEngine.Texture"/>.
/// </summary>
/// <seealso cref="IBrush" />
public sealed class TextureBrush : IBrush
public sealed class TextureBrush : IBrush, IEquatable<TextureBrush>
{
/// <summary>
/// The texture.
@@ -47,13 +49,37 @@ namespace FlaxEngine.GUI
else
Render2D.DrawTexture(Texture, rect, color);
}
/// <inheritdoc />
public bool Equals(TextureBrush other)
{
return other != null && Texture == other.Texture && Filter == other.Filter;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is TextureBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Texture, (int)Filter);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
/// <summary>
/// Implementation of <see cref="IBrush"/> for <see cref="FlaxEngine.Texture"/> using 9-slicing.
/// </summary>
/// <seealso cref="IBrush" />
public sealed class Texture9SlicingBrush : IBrush
public sealed class Texture9SlicingBrush : IBrush, IEquatable<Texture9SlicingBrush>
{
/// <summary>
/// The texture.
@@ -130,5 +156,29 @@ namespace FlaxEngine.GUI
}
#endif
}
/// <inheritdoc />
public bool Equals(Texture9SlicingBrush other)
{
return other != null && Texture == other.Texture && Filter == other.Filter && BorderSize == other.BorderSize && Border == other.Border;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is Texture9SlicingBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Texture, (int)Filter, BorderSize, Border.GetHashCode());
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
}

View File

@@ -1,5 +1,7 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
@@ -20,7 +22,7 @@ namespace FlaxEngine.GUI
/// </summary>
/// <seealso cref="IBrush" />
/// <seealso cref="UIBrushAsset" />
public sealed class UIBrush : IBrush
public sealed class UIBrush : IBrush, IEquatable<UIBrush>
{
/// <summary>
/// The UI Brush asset to use.
@@ -71,5 +73,29 @@ namespace FlaxEngine.GUI
if (asset != null && asset.Brush != null)
asset.Brush.Draw(rect, color);
}
/// <inheritdoc />
public bool Equals(UIBrush other)
{
return other != null && Asset == other.Asset;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is UIBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Asset);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
}

View File

@@ -1,12 +1,14 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
/// Implementation of <see cref="IBrush"/> for <see cref="FlaxEngine.VideoPlayer"/> frame displaying.
/// </summary>
/// <seealso cref="IBrush" />
public sealed class VideoBrush : IBrush
public sealed class VideoBrush : IBrush, IEquatable<VideoBrush>
{
/// <summary>
/// The video player to display frame from it.
@@ -57,5 +59,29 @@ namespace FlaxEngine.GUI
else
Render2D.DrawTexture(texture, rect, color);
}
/// <inheritdoc />
public bool Equals(VideoBrush other)
{
return other != null && Player == other.Player && Filter == other.Filter;
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is VideoBrush other && Equals(other);
}
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Player, (int)Filter);
}
/// <inheritdoc />
public int CompareTo(object obj)
{
return Equals(obj) ? 1 : 0;
}
}
}

View File

@@ -240,11 +240,13 @@ namespace FlaxEngine.GUI
// Organize text blocks within line
var horizontalAlignments = TextBlockStyle.Alignments.Baseline;
var verticalAlignments = TextBlockStyle.Alignments.Baseline;
for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{
ref TextBlock textBlock = ref textBlocks[i];
var vOffset = lineSize.Y - textBlock.Bounds.Height;
horizontalAlignments |= textBlock.Style.Alignment & TextBlockStyle.Alignments.HorizontalMask;
verticalAlignments |= textBlock.Style.Alignment & TextBlockStyle.Alignments.VerticalMask;
switch (textBlock.Style.Alignment & TextBlockStyle.Alignments.VerticalMask)
{
case TextBlockStyle.Alignments.Baseline:
@@ -272,14 +274,16 @@ namespace FlaxEngine.GUI
}
}
}
var hOffset = Width - lineSize.X;
// Organize blocks within whole container
var sizeOffset = Size - lineSize;
if ((horizontalAlignments & TextBlockStyle.Alignments.Center) == TextBlockStyle.Alignments.Center)
{
hOffset *= 0.5f;
sizeOffset.X *= 0.5f;
for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{
ref TextBlock textBlock = ref textBlocks[i];
textBlock.Bounds.Location.X += hOffset;
textBlock.Bounds.Location.X += sizeOffset.X;
}
}
else if ((horizontalAlignments & TextBlockStyle.Alignments.Right) == TextBlockStyle.Alignments.Right)
@@ -287,7 +291,24 @@ namespace FlaxEngine.GUI
for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{
ref TextBlock textBlock = ref textBlocks[i];
textBlock.Bounds.Location.X += hOffset;
textBlock.Bounds.Location.X += sizeOffset.X;
}
}
if ((verticalAlignments & TextBlockStyle.Alignments.Middle) == TextBlockStyle.Alignments.Middle)
{
sizeOffset.Y *= 0.5f;
for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{
ref TextBlock textBlock = ref textBlocks[i];
textBlock.Bounds.Location.Y += sizeOffset.Y;
}
}
else if ((verticalAlignments & TextBlockStyle.Alignments.Bottom) == TextBlockStyle.Alignments.Bottom)
{
for (int i = context.LineStartTextBlockIndex; i < _textBlocks.Count; i++)
{
ref TextBlock textBlock = ref textBlocks[i];
textBlock.Bounds.Location.Y += sizeOffset.Y;
}
}

View File

@@ -1,5 +1,7 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
namespace FlaxEngine.GUI
{
/// <summary>
@@ -10,6 +12,7 @@ namespace FlaxEngine.GUI
/// <summary>
/// Text block alignments modes.
/// </summary>
[Flags]
public enum Alignments
{
/// <summary>