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
}
}
}