#region --- License --- /* Copyright (c) 2006, 2007 Stefanos Apostolopoulos * See license.txt for license info */ #endregion using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace OpenTK.Math { /// /// Represents a four-dimensional vector. /// [StructLayout(LayoutKind.Sequential)] public struct Vector4 { #region Fields /// /// The X component of the Vector4. /// public float X; /// /// The Y component of the Vector4. /// public float Y; /// /// The Z component of the Vector4. /// public float Z; /// /// The Z component of the Vector4. /// public float W; #endregion #region Constructors /// /// Constructs a new Vector4. /// /// The x component of the Vector4. /// The y component of the Vector4. /// The z component of the Vector4. /// The z component of the Vector4. public Vector4(float x, float y, float z, float w) { X = x; Y = y; Z = z; W = w; } /// /// Constructs a new Vector4 from the given Vector2. /// /// The Vector2 to copy components from. public Vector4(Vector2 v) { X = v.X; Y = v.Y; Z = 0.0f; W = 0.0f; } /// /// Constructs a new Vector4 from the given Vector3. /// /// The Vector3 to copy components from. public Vector4(Vector3 v) { X = v.X; Y = v.Y; Z = v.Z; W = 0.0f; } /// /// Constructs a new Vector4 from the given Vector4. /// /// The Vector4 to copy components from. public Vector4(Vector4 v) { X = v.X; Y = v.Y; Z = v.Z; W = v.W; } #endregion #region Functions #region public Vector4 Add(Vector4 right) /// /// Adds the given Vector4 to the current Vector4. W-coordinate remains unaffected. /// /// The right operand of the addition. /// A new Vector4 containing the result of the addition. public Vector4 Add(Vector4 right) { X += right.X; Y += right.Y; Z += right.Z; W += right.W; return this; } #endregion #region public Vector4 Sub(Vector4 right) /// /// Subtracts the given Vector4 from the current Vector4. /// /// The right operand of the subtraction. /// A new Vector4 containing the result of the subtraction. public Vector4 Sub(Vector4 right) { X -= right.X; Y -= right.Y; Z -= right.Z; W -= right.W; return this; } #endregion #region public float Dot(Vector4 right) /// /// Computes the dot product between the current Vector4 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 + W * right.W; } #endregion #region public float Length /// /// Gets the length (magnitude) of the vector. /// /// /// public float Length { get { 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); } } #endregion #region public float LengthSquared /// /// 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 { return X * X + Y * Y + Z * Z + W * W; } } #endregion #region public Vector4 Normalize() /// /// Scales the Vector4 to unit length. /// /// The normalized version of the current vector. public Vector4 Normalize() { float scale = 1.0f / this.Length; X *= scale; Y *= scale; Z *= scale; W *= scale; return this; } #endregion #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. /// /// The scale of the X component. /// The scale of the Y component. /// The scale of the Z component. /// The scale of the Z component. /// 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); } #endregion #endregion #region Operator overloads public static Vector4 operator +(Vector4 left, Vector4 right) { return left.Add(right); } public static Vector4 operator -(Vector4 left, Vector4 right) { return left.Sub(right); } [CLSCompliant(false)] 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() { return String.Format("({0}, {1}, {2}, {3})", X, Y, Z, W); } } }