From 3dc34e2d9c6d585bd20a4a7a0a822cdcad482d63 Mon Sep 17 00:00:00 2001 From: nothingTVatYT <34131388+nothingTVatYT@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:51:02 +0100 Subject: [PATCH] add more units and categories --- Source/Editor/Utilities/ShuntingYardParser.cs | 46 ++++++++++++++++++- Source/Editor/Utilities/Utils.cs | 21 ++++++--- Source/Engine/Utilities/Utils.cs | 9 +++- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/Source/Editor/Utilities/ShuntingYardParser.cs b/Source/Editor/Utilities/ShuntingYardParser.cs index f8fa05e5b..0034896e1 100644 --- a/Source/Editor/Utilities/ShuntingYardParser.cs +++ b/Source/Editor/Utilities/ShuntingYardParser.cs @@ -123,7 +123,34 @@ namespace FlaxEditor.Utilities ["-infinity"] = -double.MaxValue, ["m"] = Units.Meters2Units, ["cm"] = Units.Meters2Units / 100, - ["km"] = Units.Meters2Units * 1000 + ["km"] = Units.Meters2Units * 1000, + ["s"] = 1, + ["ms"] = 0.001, + ["min"] = 60, + ["h"] = 3600, + ["cm²"] = (Units.Meters2Units / 100) * (Units.Meters2Units / 100), + ["cm³"] = (Units.Meters2Units / 100) * (Units.Meters2Units / 100) * (Units.Meters2Units / 100), + ["dm²"] = (Units.Meters2Units / 10) * (Units.Meters2Units / 10), + ["dm³"] = (Units.Meters2Units / 10) * (Units.Meters2Units / 10) * (Units.Meters2Units / 10), + ["l"] = (Units.Meters2Units / 10) * (Units.Meters2Units / 10) * (Units.Meters2Units / 10), + ["m²"] = Units.Meters2Units * Units.Meters2Units, + ["m³"] = Units.Meters2Units * Units.Meters2Units * Units.Meters2Units, + ["kg"] = 1, + ["g"] = 0.001, + ["N"] = Units.Meters2Units + }; + + /// + /// List known units which cannot be handled as a variable easily because they contain operator + /// symbols (mostly a forward slash). The value is the factor to calculate game units. + /// + private static readonly IDictionary UnitSymbols = new Dictionary + { + ["cm/s"] = Units.Meters2Units / 100, + ["cm/s²"] = Units.Meters2Units / 100, + ["m/s"] = Units.Meters2Units, + ["m/s²"] = Units.Meters2Units, + ["km/h"] = 1/3.6 * Units.Meters2Units }; /// @@ -174,6 +201,23 @@ namespace FlaxEditor.Utilities { // Prepare text text = text.Replace(',', '.').Replace("°", ""); + foreach (var kv in UnitSymbols) + { + int idx; + do + { + idx = text.IndexOf(kv.Key, StringComparison.InvariantCulture); + if (idx > 0) + { + if (DetermineType(text[idx - 1]) != TokenType.Number) + throw new ParsingException($"unit found without a number: {kv.Key} at {idx} in {text}"); + if (Mathf.Abs(kv.Value - 1) < Mathf.Epsilon) + text = text.Remove(idx, kv.Key.Length); + else + text = text.Replace(kv.Key, "*" + kv.Value); + } + } while (idx > 0); + } // Necessary to correctly parse negative numbers var previous = TokenType.WhiteSpace; diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index ac5a3c3c6..be5399111 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -1179,21 +1179,30 @@ namespace FlaxEditor.Utilities /// the formatted string public static string FormatFloat(float value, FlaxEngine.Utils.ValueCategory category) { + const string format = "g7"; if (!Units.UseUnitsFormatting) return FormatFloat(value); switch (category) { case FlaxEngine.Utils.ValueCategory.Distance: if (!Units.AutomaticUnitsFormatting) - return (value / Units.Meters2Units).ToString("g7", CultureInfo.InvariantCulture) + "m"; + return (value / Units.Meters2Units).ToString(format, CultureInfo.InvariantCulture) + "m"; var absValue = Mathf.Abs(value); - // in case a unit != cm this would be (value / Maters2Units * 100) + // in case a unit != cm this would be (value / Meters2Units * 100) if (absValue < Units.Meters2Units) - return value.ToString("g7", CultureInfo.InvariantCulture) + "cm"; + return value.ToString(format, CultureInfo.InvariantCulture) + "cm"; if (absValue < Units.Meters2Units * 1000) - return (value / Units.Meters2Units).ToString("g7", CultureInfo.InvariantCulture) + "m"; - return (value / 1000 / Units.Meters2Units).ToString("g7", CultureInfo.InvariantCulture) + "km"; - case FlaxEngine.Utils.ValueCategory.Angle: return value.ToString("g7", CultureInfo.InvariantCulture) + "°"; + return (value / Units.Meters2Units).ToString(format, CultureInfo.InvariantCulture) + "m"; + return (value / 1000 / Units.Meters2Units).ToString(format, CultureInfo.InvariantCulture) + "km"; + case FlaxEngine.Utils.ValueCategory.Angle: return value.ToString(format, CultureInfo.InvariantCulture) + "°"; + case FlaxEngine.Utils.ValueCategory.Time: return value.ToString(format, CultureInfo.InvariantCulture) + "s"; + // some fonts have a symbol for that: "\u33A7" + case FlaxEngine.Utils.ValueCategory.Speed: return (value / Units.Meters2Units).ToString(format, CultureInfo.InvariantCulture) + "m/s"; + case FlaxEngine.Utils.ValueCategory.Acceleration: return (value / Units.Meters2Units).ToString(format, CultureInfo.InvariantCulture) + "m/s²"; + case FlaxEngine.Utils.ValueCategory.Area: return (value / Units.Meters2Units / Units.Meters2Units).ToString(format, CultureInfo.InvariantCulture) + "m²"; + case FlaxEngine.Utils.ValueCategory.Volume: return (value / Units.Meters2Units / Units.Meters2Units / Units.Meters2Units).ToString(format, CultureInfo.InvariantCulture) + "m³"; + case FlaxEngine.Utils.ValueCategory.Mass: return value.ToString(format, CultureInfo.InvariantCulture) + "kg"; + case FlaxEngine.Utils.ValueCategory.Force: return (value / Units.Meters2Units).ToString(format, CultureInfo.InvariantCulture) + "N"; case FlaxEngine.Utils.ValueCategory.None: default: return FormatFloat(value); diff --git a/Source/Engine/Utilities/Utils.cs b/Source/Engine/Utilities/Utils.cs index 195bacf96..9ae42fa43 100644 --- a/Source/Engine/Utilities/Utils.cs +++ b/Source/Engine/Utilities/Utils.cs @@ -1046,7 +1046,14 @@ namespace FlaxEngine { None, Distance, - Angle + Area, + Volume, + Mass, + Angle, + Speed, + Acceleration, + Time, + Force } } }