Skip to content

Commit 14f7e6f

Browse files
committed
Add Min(float) and octahedron encode/decode to Vector3.cs
1 parent 0b6a717 commit 14f7e6f

File tree

1 file changed

+61
-0
lines changed
  • modules/mono/glue/GodotSharp/GodotSharp/Core

1 file changed

+61
-0
lines changed

modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs

+61
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,23 @@ public readonly Vector3 Min(Vector3 with)
487487
);
488488
}
489489

490+
/// <summary>
491+
/// Returns the result of the component-wise minimum between
492+
/// this vector and <paramref name="with"/>.
493+
/// Equivalent to <c>new Vector3(Mathf.Min(X, with), Mathf.Min(Y, with), Mathf.Min(Z, with))</c>.
494+
/// </summary>
495+
/// <param name="with">The other value to use.</param>
496+
/// <returns>The resulting minimum vector.</returns>
497+
public readonly Vector3 Min(real_t with)
498+
{
499+
return new Vector3
500+
(
501+
Mathf.Min(X, with),
502+
Mathf.Min(Y, with),
503+
Mathf.Min(Z, with)
504+
);
505+
}
506+
490507
/// <summary>
491508
/// Returns the axis of the vector's highest value. See <see cref="Axis"/>.
492509
/// If all components are equal, this method returns <see cref="Axis.X"/>.
@@ -751,6 +768,50 @@ public readonly Vector3 Snapped(real_t step)
751768
);
752769
}
753770

771+
/// <summary>
772+
/// Returns the octahedral-encoded (oct32) form of this Vector3 as a Vector2. Since a Vector2 occupies 1/3 less memory compared to Vector3,
773+
/// this form of compression can be used to pass greater amounts of normalized Vector3s without increasing storage or memory requirements.
774+
/// See also <see cref="Normalized()"/>, <see cref="OctahedronDecode(Vector2)"/>.
775+
/// Note: OctahedronEncode can only be used for normalized vectors. OctahedronEncode does not check whether this Vector3 is normalized,
776+
/// and will return a value that does not decompress to the original value if the Vector3 is not normalized.
777+
/// Note: Octahedral compression is lossy, although visual differences are rarely perceptible in real world scenarios.
778+
/// </summary>
779+
/// <returns>The encoded Vector2.</returns>
780+
public readonly Vector2 OctahedronEncode()
781+
{
782+
Vector3 n = this;
783+
n /= Mathf.Abs(n.X) + Mathf.Abs(n.Y) + Mathf.Abs(n.Z);
784+
Vector2 o;
785+
if (n.Z >= 0.0f)
786+
{
787+
o.X = n.X;
788+
o.Y = n.Y;
789+
}
790+
else
791+
{
792+
o.X = (1.0f - Mathf.Abs(n.Y)) * (n.X >= 0.0f ? 1.0f : -1.0f);
793+
o.Y = (1.0f - Mathf.Abs(n.X)) * (n.Y >= 0.0f ? 1.0f : -1.0f);
794+
}
795+
o.X = o.X * 0.5f + 0.5f;
796+
o.Y = o.Y * 0.5f + 0.5f;
797+
return o;
798+
}
799+
800+
/// <summary>
801+
/// Returns the Vector3 from an octahedral-compressed form created using <see cref="OctahedronEncode()"/> (stored as a Vector2).
802+
/// </summary>
803+
/// <param name="oct">Encoded Vector2</param>
804+
/// <returns>The decoded normalized Vector3.</returns>
805+
public static Vector3 OctahedronDecode(Vector2 oct)
806+
{
807+
var f = new Vector2(oct.X * 2.0f - 1.0f, oct.Y * 2.0f - 1.0f);
808+
var n = new Vector3(f.X, f.Y, 1.0f - Mathf.Abs(f.X) - Mathf.Abs(f.Y));
809+
real_t t = Mathf.Clamp(-n.Z, 0.0f, 1.0f);
810+
n.X += n.X >= 0 ? -t : t;
811+
n.Y += n.Y >= 0 ? -t : t;
812+
return n.Normalized();
813+
}
814+
754815
// Constants
755816
private static readonly Vector3 _zero = new Vector3(0, 0, 0);
756817
private static readonly Vector3 _one = new Vector3(1, 1, 1);

0 commit comments

Comments
 (0)