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