From 14f7e6ff60e4b6de959123f4b52060355ab60f22 Mon Sep 17 00:00:00 2001 From: Adam Johnston Date: Mon, 3 Feb 2025 01:28:12 -0800 Subject: [PATCH] Add Min(float) and octahedron encode/decode to Vector3.cs --- .../GodotSharp/GodotSharp/Core/Vector3.cs | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index ef66d5bbe0d..9c403d2e201 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -487,6 +487,23 @@ namespace Godot ); } + /// + /// Returns the result of the component-wise minimum between + /// this vector and . + /// Equivalent to new Vector3(Mathf.Min(X, with), Mathf.Min(Y, with), Mathf.Min(Z, with)). + /// + /// The other value to use. + /// The resulting minimum vector. + public readonly Vector3 Min(real_t with) + { + return new Vector3 + ( + Mathf.Min(X, with), + Mathf.Min(Y, with), + Mathf.Min(Z, with) + ); + } + /// /// Returns the axis of the vector's highest value. See . /// If all components are equal, this method returns . @@ -751,6 +768,50 @@ namespace Godot ); } + /// + /// Returns the octahedral-encoded (oct32) form of this Vector3 as a Vector2. Since a Vector2 occupies 1/3 less memory compared to Vector3, + /// this form of compression can be used to pass greater amounts of normalized Vector3s without increasing storage or memory requirements. + /// See also , . + /// Note: OctahedronEncode can only be used for normalized vectors. OctahedronEncode does not check whether this Vector3 is normalized, + /// and will return a value that does not decompress to the original value if the Vector3 is not normalized. + /// Note: Octahedral compression is lossy, although visual differences are rarely perceptible in real world scenarios. + /// + /// The encoded Vector2. + public readonly Vector2 OctahedronEncode() + { + Vector3 n = this; + n /= Mathf.Abs(n.X) + Mathf.Abs(n.Y) + Mathf.Abs(n.Z); + Vector2 o; + if (n.Z >= 0.0f) + { + o.X = n.X; + o.Y = n.Y; + } + else + { + o.X = (1.0f - Mathf.Abs(n.Y)) * (n.X >= 0.0f ? 1.0f : -1.0f); + o.Y = (1.0f - Mathf.Abs(n.X)) * (n.Y >= 0.0f ? 1.0f : -1.0f); + } + o.X = o.X * 0.5f + 0.5f; + o.Y = o.Y * 0.5f + 0.5f; + return o; + } + + /// + /// Returns the Vector3 from an octahedral-compressed form created using (stored as a Vector2). + /// + /// Encoded Vector2 + /// The decoded normalized Vector3. + public static Vector3 OctahedronDecode(Vector2 oct) + { + var f = new Vector2(oct.X * 2.0f - 1.0f, oct.Y * 2.0f - 1.0f); + var n = new Vector3(f.X, f.Y, 1.0f - Mathf.Abs(f.X) - Mathf.Abs(f.Y)); + real_t t = Mathf.Clamp(-n.Z, 0.0f, 1.0f); + n.X += n.X >= 0 ? -t : t; + n.Y += n.Y >= 0 ? -t : t; + return n.Normalized(); + } + // Constants private static readonly Vector3 _zero = new Vector3(0, 0, 0); private static readonly Vector3 _one = new Vector3(1, 1, 1);