From 95da49b8e8d6403349a391c5bf63039c95c5e02d Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Wed, 24 Oct 2007 23:40:06 +0000 Subject: [PATCH] Completed the OpenTK.Math Vector[234] overhaul. Added LengthFast and NormalizeFast functions. Removed overloads. Made the pointer conversions explicit. --- Source/OpenTK/Math/Vector2.cs | 26 +++-- Source/OpenTK/Math/Vector3.cs | 207 +++++++++++++++++----------------- Source/OpenTK/Math/Vector4.cs | 192 ++++++++++++++----------------- 3 files changed, 201 insertions(+), 224 deletions(-) diff --git a/Source/OpenTK/Math/Vector2.cs b/Source/OpenTK/Math/Vector2.cs index f30c5732..d7944c5d 100644 --- a/Source/OpenTK/Math/Vector2.cs +++ b/Source/OpenTK/Math/Vector2.cs @@ -160,7 +160,7 @@ namespace OpenTK.Math { get { - return OpenTK.Math.Functions.InverseSqrtFast(X * X + Y * Y); + return 1.0f / OpenTK.Math.Functions.InverseSqrtFast(X * X + Y * Y); } } @@ -195,8 +195,10 @@ namespace OpenTK.Math /// The normalized version of the current vector. public Vector2 Normalize() { - float length = this.Length; - return new Vector2(X / length, Y / Length); + float scale = 1.0f / this.Length; + X *= scale; + Y *= scale; + return this; } #endregion @@ -204,14 +206,14 @@ namespace OpenTK.Math #region public Vector2 NormalizeFast() /// - /// Scales the Vector2 to unit length. + /// Scales the Vector2 to approximately unit length. /// /// The normalized version of the current vector. public Vector2 NormalizeFast() { - float length = this.LengthFast; - this.X = X / length; - this.Y = Y / length; + float scale = Functions.InverseSqrtFast(X * X + Y * Y); + X *= scale; + Y *= scale; return this; } @@ -249,11 +251,19 @@ namespace OpenTK.Math } [CLSCompliant(false)] - unsafe public static implicit operator float*(Vector2 v) + unsafe public static explicit operator float*(Vector2 v) { return &v.X; } + public static explicit operator IntPtr(Vector2 v) + { + unsafe + { + return (IntPtr)(&v.X); + } + } + #endregion #region public override string ToString() diff --git a/Source/OpenTK/Math/Vector3.cs b/Source/OpenTK/Math/Vector3.cs index c9984047..ccc891f9 100644 --- a/Source/OpenTK/Math/Vector3.cs +++ b/Source/OpenTK/Math/Vector3.cs @@ -11,9 +11,9 @@ using System.Runtime.InteropServices; namespace OpenTK.Math { - /// - /// Represents a three-dimensional vector. - /// + /// + /// Represents a three-dimensional vector. + /// [StructLayout(LayoutKind.Sequential)] public struct Vector3 { @@ -88,51 +88,24 @@ namespace OpenTK.Math #region Functions - #region Add - - /// - /// Adds the given Vector2 to the current Vector3. - /// - /// The right operand of the addition. - /// A new Vector3 containing the result of the addition. - public Vector3 Add(Vector2 right) - { - return new Vector3(X + right.X, Y + right.Y, Z); - } + #region public Vector3 Add(Vector3 right) /// /// Adds the given Vector3 to the current Vector3. /// /// The right operand of the addition. - /// A new Vector3 containing the result of the addition. + /// The current Vector3, containing the result of the addition. public Vector3 Add(Vector3 right) { - return new Vector3(X + right.X, Y + right.Y, Z + right.Z); - } - - /// - /// Adds the given Vector4 to the current Vector3. W-coordinate remains unaffected. - /// - /// The right operand of the addition. - /// A new Vector4 containing the result of the addition. - public Vector4 Add(Vector4 right) - { - return new Vector4(X + right.X, Y + right.Y, Z + right.Z, right.W); + X += right.X; + Y += right.Y; + Z += right.Z; + return this; } #endregion - #region Sub - - /// - /// Subtracts the given Vector2 from the current Vector3. - /// - /// The right operand of the subtraction. - /// A new Vector3 containing the result of the subtraction. - public Vector3 Sub(Vector2 right) - { - return new Vector3(X - right.X, Y - right.Y, Z); - } + #region public Vector3 Sub(Vector3 right) /// /// Subtracts the given Vector3 from the current Vector3. @@ -141,32 +114,15 @@ namespace OpenTK.Math /// A new Vector3 containing the result of the subtraction. public Vector3 Sub(Vector3 right) { - return new Vector3(X - right.X, Y - right.Y, Z - right.Z); - } - - /// - /// Subtracts the given Vector4 from the current Vector3. - /// - /// The right operand of the subtraction. - /// A new Vector4 containing the result of the subtraction. - public Vector4 Sub(Vector4 right) - { - return new Vector4(X - right.X, Y - right.Y, Z - right.Z, -right.W); + X -= right.X; + Y -= right.Y; + Z -= right.Z; + return this; } #endregion - #region Dot - - /// - /// Computes the dot product between the current Vector3 and the given Vector2. - /// - /// The right operand of the dot product. - /// A float containing the result of the dot product. - public float Dot(Vector2 right) - { - return X * right.X + Y * right.Y; - } + #region public float Dot(Vector3 right) /// /// Computes the dot product between the current Vector3 and the given Vector3. @@ -178,31 +134,25 @@ namespace OpenTK.Math return X * right.X + Y * right.Y + Z * right.Z; } - /// - /// Computes the dot product between the current Vector3 and the given Vector4. - /// - /// The right operand of the dot product. - /// A float containing the result of the dot product. - public float Dot(Vector4 right) - { - return X * right.X + Y * right.Y + Z * right.Z; - } - #endregion - #region Cross + #region public Vector3 Cross(Vector3 right) /// - /// Computes the cross product between the current and the given Vector3. + /// Computes the cross product between the current and the given Vector3. The current Vector3 is set to the result of the computation. /// /// The right operand of the cross product - /// A new Vector3 containing the result of the computation. + /// The current public Vector3 Cross(Vector3 right) { - return new Vector3( - Y * right.Z - Z * right.Y, - Z * right.X - X * right.Z, - X * right.Y - Y * right.X); + float + x = Y * right.Z - Z * right.Y, + y = Z * right.X - X * right.Z, + z = X * right.Y - Y * right.X; + X = x; + Y = y; + Z = z; + return this; } #endregion @@ -210,13 +160,37 @@ namespace OpenTK.Math #region public float Length /// - /// Gets the length of the vector. + /// Gets the length (magnitude) of the vector. /// + /// + /// public float Length { get { - return (float)System.Math.Sqrt(this.LengthSquared); + return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z); + } + } + + #endregion + + #region public float LengthFast + + /// + /// Gets an approximation of the vector length (magnitude). + /// + /// + /// This property uses an approximation of the square root function to calculate vector magnitude, with + /// an upper error bound of 0.001. + /// + /// + /// + /// + public float LengthFast + { + get + { + return 1.0f / OpenTK.Math.Functions.InverseSqrtFast(X * X + Y * Y + Z * Z); } } @@ -225,8 +199,14 @@ namespace OpenTK.Math #region public float LengthSquared /// - /// Gets the square of the vector length. + /// Gets the square of the vector length (magnitude). /// + /// + /// This property avoids the costly square root operation required by the Length property. This makes it more suitable + /// for comparisons. + /// + /// + /// public float LengthSquared { get @@ -245,8 +225,28 @@ namespace OpenTK.Math /// The normalized version of the current vector. public Vector3 Normalize() { - float length = this.Length; - return new Vector3(X / length, Y / Length, Z / length); + float scale = 1.0f / this.Length; + X *= scale; + Y *= scale; + Z *= scale; + return this; + } + + #endregion + + #region public Vector3 NormalizeFast() + + /// + /// Scales the Vector3 to approximately unit length. + /// + /// The normalized version of the current vector. + public Vector3 NormalizeFast() + { + float scale = Functions.InverseSqrtFast(X * X + Y * Y + Z * Z); + X *= scale; + Y *= scale; + Z *= scale; + return this; } #endregion @@ -259,10 +259,13 @@ namespace OpenTK.Math /// The scale of the X component. /// The scale of the Y component. /// The scale of the Z component. - /// A new, scaled Vector3. + /// The current Vector3, scaled. public Vector3 Scale(float sx, float sy, float sz) { - return new Vector3(X * sx, Y * sy, Z * sz); + this.X = X * sx; + this.Y = Y * sy; + this.Z = Z * sz; + return this; } #endregion @@ -271,42 +274,34 @@ namespace OpenTK.Math #region Operator overloads - public static Vector3 operator +(Vector3 left, Vector2 right) - { - return left.Add(right); - } - public static Vector3 operator +(Vector3 left, Vector3 right) { - return left.Add(right); - } - - public static Vector4 operator +(Vector3 left, Vector4 right) - { - return left.Add(right); - } - - public static Vector3 operator -(Vector3 left, Vector2 right) - { - return left.Sub(right); + return new Vector3(left.Add(right)); } public static Vector3 operator -(Vector3 left, Vector3 right) { - return left.Sub(right); - } - - public static Vector4 operator -(Vector3 left, Vector4 right) - { - return left.Sub(right); + return new Vector3(left.Sub(right)); } [CLSCompliant(false)] - unsafe public static implicit operator float*(Vector3 v) + unsafe public static explicit operator float*(Vector3 v) { return &v.X; } + public static explicit operator IntPtr(Vector3 v) + { + unsafe + { + return (IntPtr)(&v.X); + } + } + + #endregion + + #region Static functions + #endregion public override string ToString() diff --git a/Source/OpenTK/Math/Vector4.cs b/Source/OpenTK/Math/Vector4.cs index 0ac88408..56f51205 100644 --- a/Source/OpenTK/Math/Vector4.cs +++ b/Source/OpenTK/Math/Vector4.cs @@ -98,27 +98,7 @@ namespace OpenTK.Math #region Functions - #region Add - - /// - /// Adds the given Vector2 to the current Vector4. - /// - /// The right operand of the addition. - /// A new Vector4 containing the result of the addition. - public Vector4 Add(Vector2 right) - { - return new Vector4(X + right.X, Y + right.Y, Z, W); - } - - /// - /// Adds the given Vector3 to the current Vector4. - /// - /// The right operand of the addition. - /// A new Vector4 containing the result of the addition. - public Vector4 Add(Vector3 right) - { - return new Vector4(X + right.X, Y + right.Y, Z + right.Z, W); - } + #region public Vector4 Add(Vector4 right) /// /// Adds the given Vector4 to the current Vector4. W-coordinate remains unaffected. @@ -127,32 +107,16 @@ namespace OpenTK.Math /// A new Vector4 containing the result of the addition. public Vector4 Add(Vector4 right) { - return new Vector4(X + right.X, Y + right.Y, Z + right.Z, W + right.W); + X += right.X; + Y += right.Y; + Z += right.Z; + W += right.W; + return this; } #endregion - #region Sub - - /// - /// Subtracts the given Vector2 from the current Vector4. - /// - /// The right operand of the subtraction. - /// A new Vector4 containing the result of the subtraction. - public Vector4 Sub(Vector2 right) - { - return new Vector4(X - right.X, Y - right.Y, Z, W); - } - - /// - /// Subtracts the given Vector3 from the current Vector4. - /// - /// The right operand of the subtraction. - /// A new Vector4 containing the result of the subtraction. - public Vector4 Sub(Vector3 right) - { - return new Vector4(X - right.X, Y - right.Y, Z - right.Z, W); - } + #region public Vector4 Sub(Vector4 right) /// /// Subtracts the given Vector4 from the current Vector4. @@ -161,32 +125,16 @@ namespace OpenTK.Math /// A new Vector4 containing the result of the subtraction. public Vector4 Sub(Vector4 right) { - return new Vector4(X - right.X, Y - right.Y, Z - right.Z, W - right.W); + X -= right.X; + Y -= right.Y; + Z -= right.Z; + W -= right.W; + return this; } #endregion - #region Dot - - /// - /// Computes the dot product between the current Vector4 and the given Vector2. - /// - /// The right operand of the dot product. - /// A float containing the result of the dot product. - public float Dot(Vector2 right) - { - return X * right.X + Y * right.Y; - } - - /// - /// Computes the dot product between the current Vector4 and the given Vector3. - /// - /// The right operand of the dot product. - /// A float containing the result of the dot product. - public float Dot(Vector3 right) - { - return X * right.X + Y * right.Y + Z * right.Z; - } + #region public float Dot(Vector4 right) /// /// Computes the dot product between the current Vector4 and the given Vector4. @@ -199,34 +147,41 @@ namespace OpenTK.Math } #endregion - /* - #region Cross - /// - /// Computes the cross product between the current and the given Vector3. - /// - /// The right operand of the cross product - /// A new Vector3 containing the result of the computation. - public Vector3 Cross(Vector3 right) - { - return new Vector3( - Y * right.Z - Z * right.Y, - Z * right.X - X * right.Z, - X * right.Y - Y * right.X); - } - - #endregion - */ #region public float Length /// - /// Gets the length of the vector. + /// Gets the length (magnitude) of the vector. /// + /// + /// public float Length { get { - return (float)System.Math.Sqrt(this.LengthSquared); + return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W); + } + } + + #endregion + + #region public float LengthFast + + /// + /// Gets an approximation of the vector length (magnitude). + /// + /// + /// This property uses an approximation of the square root function to calculate vector magnitude, with + /// an upper error bound of 0.001. + /// + /// + /// + /// + public float LengthFast + { + get + { + return 1.0f / OpenTK.Math.Functions.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W); } } @@ -235,8 +190,14 @@ namespace OpenTK.Math #region public float LengthSquared /// - /// Gets the square of the vector length. + /// Gets the square of the vector length (magnitude). /// + /// + /// This property avoids the costly square root operation required by the Length property. This makes it more suitable + /// for comparisons. + /// + /// + /// public float LengthSquared { get @@ -255,13 +216,35 @@ namespace OpenTK.Math /// The normalized version of the current vector. public Vector4 Normalize() { - float length = this.Length; - return new Vector4(X / length, Y / Length, Z / length, W / length); + float scale = 1.0f / this.Length; + X *= scale; + Y *= scale; + Z *= scale; + W *= scale; + return this; } #endregion - #region public Vector2 Scale(float sx, float sy, float sz, float sw) + #region public Vector4 NormalizeFast() + + /// + /// Scales the Vector4 to approximately unit length. + /// + /// The normalized version of the current vector. + public Vector4 NormalizeFast() + { + float scale = Functions.InverseSqrtFast(X * X + Y * Y + Z * Z); + X *= scale; + Y *= scale; + Z *= scale; + W *= scale; + return this; + } + + #endregion + + #region public Vector4 Scale(float sx, float sy, float sz, float sw) /// /// Scales the current Vector4 by the given amounts. @@ -270,7 +253,7 @@ namespace OpenTK.Math /// The scale of the Y component. /// The scale of the Z component. /// The scale of the Z component. - /// A new, scaled Vector4. + /// The current Vector4, scaled. public Vector4 Scale(float sx, float sy, float sz, float sw) { return new Vector4(X * sx, Y * sy, Z * sz, W * sw); @@ -282,42 +265,31 @@ namespace OpenTK.Math #region Operator overloads - public static Vector4 operator +(Vector4 left, Vector2 right) - { - return left.Add(right); - } - - public static Vector4 operator +(Vector4 left, Vector3 right) - { - return left.Add(right); - } - public static Vector4 operator +(Vector4 left, Vector4 right) { return left.Add(right); } - public static Vector4 operator -(Vector4 left, Vector2 right) - { - return left.Sub(right); - } - - public static Vector4 operator -(Vector4 left, Vector3 right) - { - return left.Sub(right); - } - public static Vector4 operator -(Vector4 left, Vector4 right) { return left.Sub(right); } [CLSCompliant(false)] - unsafe public static implicit operator float*(Vector4 v) + unsafe public static explicit operator float*(Vector4 v) { return &v.X; } + public static explicit operator IntPtr(Vector4 v) + { + unsafe + { + return (IntPtr)(&v.X); + } + } + + #endregion public override string ToString()