From 2be39a740ef6bd613d9eba5bbd872c5fb89cfe43 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Thu, 28 Oct 2021 23:26:42 +0200 Subject: [PATCH] improve handling of arbitrary Epsilon values --- CHANGELOG.md | 2 ++ MLEM.Ui/Elements/Element.cs | 14 ++++++++++---- MLEM.Ui/Elements/ScrollBar.cs | 2 +- MLEM/Cameras/Camera.cs | 8 +++++++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fccb82..8c73a60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Additions Improvements - Exposed Camera's RoundPosition +- Exposed the epsilon value used by Camera ### MLEM.Ui Additions @@ -23,6 +24,7 @@ Additions Improvements - Cache TokenizedString inner offsets for non-Left text alignments to improve performance +- Exposed the epsilon value used by Element calculations Fixes - Fixed VerticalSpace height parameter being an integer diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index 0dd40ab..e3b79e0 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -18,6 +18,12 @@ namespace MLEM.Ui.Elements { /// public abstract class Element : GenericDataHolder, IDisposable { + /// + /// This field holds an epsilon value used in element , position and resulting calculations to mitigate floating point rounding inaccuracies. + /// If ui elements used are extremely small or extremely large, this value can be reduced or increased. + /// + public static float Epsilon = 0.01F; + /// /// A list of all of this element's direct children. /// Use or to manipulate this list while calling all of the necessary callbacks. @@ -607,9 +613,9 @@ namespace MLEM.Ui.Elements { break; case Anchor.AutoInline: var newX = prevArea.Right + this.ScaledOffset.X; - // with awkward ui scale values, floating point rounding can cause an element that would usually be - // positioned correctly to be pushed into the next line due to a very small deviation, so we add 0.01 here - if (newX + newSize.X <= parentArea.Right + 0.01F) { + // with awkward ui scale values, floating point rounding can cause an element that would usually + // be positioned correctly to be pushed into the next line due to a very small deviation + if (newX + newSize.X <= parentArea.Right + Epsilon) { pos.X = newX; pos.Y = prevArea.Y + this.ScaledOffset.Y; } else { @@ -676,7 +682,7 @@ namespace MLEM.Ui.Elements { } // we want to leave some leeway to prevent float rounding causing an infinite loop - if (!autoSize.Equals(this.UnscrolledArea.Size, 0.01F)) { + if (!autoSize.Equals(this.UnscrolledArea.Size, Epsilon)) { recursion++; if (recursion >= 16) { throw new ArithmeticException($"The area of {this} with root {this.Root.Name} has recursively updated too often. Does its child {foundChild} contain any conflicting auto-sizing settings?"); diff --git a/MLEM.Ui/Elements/ScrollBar.cs b/MLEM.Ui/Elements/ScrollBar.cs index a3b2b06..fd7a048 100644 --- a/MLEM.Ui/Elements/ScrollBar.cs +++ b/MLEM.Ui/Elements/ScrollBar.cs @@ -45,7 +45,7 @@ namespace MLEM.Ui.Elements { // force current value to be clamped this.CurrentValue = this.CurrentValue; // auto-hide if necessary - var shouldHide = this.maxValue <= 0.01F; + var shouldHide = this.maxValue <= Epsilon; if (this.AutoHideWhenEmpty && this.IsHidden != shouldHide) { this.IsHidden = shouldHide; this.OnAutoHide?.Invoke(this); diff --git a/MLEM/Cameras/Camera.cs b/MLEM/Cameras/Camera.cs index 7f119ba..a4341b7 100644 --- a/MLEM/Cameras/Camera.cs +++ b/MLEM/Cameras/Camera.cs @@ -11,6 +11,12 @@ namespace MLEM.Cameras { /// public class Camera { + /// + /// This field holds an epsilon value used in some camera calculations to mitigate floating point rounding inaccuracies. + /// If camera or size are extremely small or extremely big, this value can be reduced or increased. + /// + public static float Epsilon = 0.01F; + /// /// The top-left corner of the camera's viewport. /// @@ -158,7 +164,7 @@ namespace MLEM.Cameras { if (this.Max.Y > max.Y) this.Max = new Vector2(this.Max.X, max.Y); } - return !this.Position.Equals(lastPos, 0.001F); + return !this.Position.Equals(lastPos, Epsilon); } ///