Skip to content

Commit

Permalink
Vector Refactorings (#55)
Browse files Browse the repository at this point in the history
* Add Get extension method to Vector2

* Add CopyTo for all vector types to support optimized matrix code even when system.numerics.vector is unavailable

Always enable extension methods so that we have a single codebase for those methods, and throw an Exception when an index is out of range for the Get methods.

* Implement feedback from TheAIBot
  • Loading branch information
giawa committed Sep 3, 2020
1 parent ba4d59a commit f20d0e2
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 85 deletions.
35 changes: 32 additions & 3 deletions OpenGL/Math/Vector2.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if USE_NUMERICS
using System;
#if USE_NUMERICS
using System.Numerics;
#else
using System;
using System.Runtime.InteropServices;
#endif

Expand Down Expand Up @@ -318,8 +318,37 @@ public static void Swap(ref Vector2 v1, ref Vector2 v2)
v1 = v2;
v2 = t;
}

/// <summary>
/// Copies the elements of the vector to a specified array.
/// </summary>
/// <param name="array">The destination array.</param>
/// <param name="offset">The index at which to copy the first element of the vector.</param>
public void CopyTo(float[] array, int offset)
{
array[offset + 0] = X;
array[offset + 1] = Y;
}
#endregion
}
#else
#endif

/// <summary>
/// Extension methods for the Vector4 structure.
/// </summary>
public static class Vector2Extensions
{
/// <summary>
/// Provide an accessor for each of the elements of the Vector structure.
/// </summary>
/// <param name="v">The Vector2 to access.</param>
/// <param name="index">The element to access (0 = X, 1 = Y).</param>
/// <returns>The element of the Vector2 as indexed by index.</returns>
public static float Get(this Vector2 tv, int index)
{
if (index != 0 && index != 1)
throw new ArgumentOutOfRangeException(nameof(index));
return (index == 0 ? tv.X : tv.Y);
}
}
}
67 changes: 14 additions & 53 deletions OpenGL/Math/Vector3.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if USE_NUMERICS
using System;
#if USE_NUMERICS
using System.Numerics;
#else
using System;
using System.Runtime.InteropServices;
#endif

Expand Down Expand Up @@ -234,16 +234,6 @@ public static float Dot(Vector3 v1, Vector3 v2)
return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
}

/// <summary>
/// Performs the Vector3 scalar dot product.
/// </summary>
/// <param name="v">Second dot product term</param>
/// <returns>Vector3.Dot(this, v)</returns>
public float Dot(Vector3 v)
{
return Vector3.Dot(this, v);
}

/// <summary>
/// A System.Numerics compatible version of SquaredLength.
/// </summary>
Expand Down Expand Up @@ -274,16 +264,6 @@ public Vector3 Cross(Vector3 v)
return Vector3.Cross(this, v);
}

/// <summary>
/// Normalizes the Vector3 structure to have a peak value of one.
/// </summary>
/// <returns>if (Length = 0) return Zero; else return Vector3(x,y,z)/Length</returns>
public Vector3 Normalize()
{
if (Length() == 0) return Zero;
else return new Vector3(X, Y, Z) / Length();
}

/// <summary>
/// Checks to see if any value (x, y, z) are within 0.0001 of 0.
/// If so this method truncates that value to zero.
Expand All @@ -297,28 +277,6 @@ public Vector3 Truncate()
return new Vector3(_x, _y, _z);
}

/// <summary>
/// Store the minimum values of x, y, and z between the two vectors.
/// </summary>
/// <param name="v">Vector to check against</param>
public void TakeMin(Vector3 v)
{
if (v.X < X) X = v.X;
if (v.Y < Y) Y = v.Y;
if (v.Z < Z) Z = v.Z;
}

/// <summary>
/// Store the maximum values of x, y, and z between the two vectors.
/// </summary>
/// <param name="v">Vector to check against</param>
public void TakeMax(Vector3 v)
{
if (v.X > X) X = v.X;
if (v.Y > Y) Y = v.Y;
if (v.Z > Z) Z = v.Z;
}

/// <summary>
/// Returns the maximum component of the Vector3.
/// </summary>
Expand Down Expand Up @@ -624,20 +582,22 @@ public static Vector3 Transform(Vector3 v, Quaternion q)
{
return q * v;
}

/// <summary>
/// Provide an accessor for each of the elements of the Vector structure.
/// Copies the elements of the vector to a specified array.
/// </summary>
/// <param name="v">The Vector3 to access.</param>
/// <param name="index">The element to access (0 = X, 1 = Y, 2 = Z).</param>
/// <returns>The element of the Vector3 as indexed by i.</returns>
public float Get(int index)
/// <param name="array">The destination array.</param>
/// <param name="offset">The index at which to copy the first element of the vector.</param>
public void CopyTo(float[] array, int offset)
{
return (index == 0 ? X : (index == 1 ? Y : Z));
array[offset + 0] = X;
array[offset + 1] = Y;
array[offset + 2] = Z;
}
#endregion
}
#else
#endif

/// <summary>
/// Extension methods for the Vector3 structure.
/// </summary>
Expand Down Expand Up @@ -697,8 +657,9 @@ public static float Dot(this Vector3 tv, Vector3 v)
/// <returns>The element of the Vector3 as indexed by i.</returns>
public static float Get(this Vector3 v, int index)
{
if (index < 0 || index > 2)
throw new ArgumentOutOfRangeException(nameof(index));
return (index == 0 ? v.X : (index == 1 ? v.Y : v.Z));
}
}
#endif
}
59 changes: 30 additions & 29 deletions OpenGL/Math/Vector4.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#if USE_NUMERICS
using System;
#if USE_NUMERICS
using System.Numerics;
#else
using System;
using System.Runtime.InteropServices;
#endif

Expand All @@ -13,7 +13,7 @@ public struct Vector4 : IEquatable<Vector4>
{
public float X, Y, Z, W;

#region Static Constructors
#region Static Constructors
public static Vector4 Zero
{
get { return new Vector4(0.0f, 0.0f, 0.0f, 0.0f); }
Expand Down Expand Up @@ -45,7 +45,7 @@ public static Vector4 One
}
#endregion

#region Operators
#region Operators
public static Vector4 operator +(Vector4 v1, Vector4 v2)
{
return new Vector4(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z, v1.W + v2.W);
Expand Down Expand Up @@ -122,17 +122,17 @@ public static Vector4 One
}
#endregion

#region Constructors
#region Constructors
/// <summary>Creates a Vector4 structure whose elements have the specified values.</summary>
/// <param name="x">The value to assign to the X field.</param>
/// <param name="y">The value to assign to the Y field.</param>
/// <param name="z">The value to assign to the Z field.</param>
/// <param name="w">The value to assign to the W field.</param>
public Vector4(float x, float y, float z, float w)
{
X = x;
Y = y;
Z = z;
X = x;
Y = y;
Z = z;
W = w;
}

Expand All @@ -141,9 +141,9 @@ public Vector4(float x, float y, float z, float w)
/// <param name="w">The value to assign to the W field.</param>
public Vector4(Vector3 v, float w)
{
X = v.X;
Y = v.Y;
Z = v.Z;
X = v.X;
Y = v.Y;
Z = v.Z;
W = w;
}

Expand All @@ -167,7 +167,7 @@ public Vector4(Vector2 v, float z, float w)
}
#endregion

#region Overrides
#region Overrides
public override bool Equals(object obj)
{
if (!(obj is Vector4)) return false;
Expand Down Expand Up @@ -208,21 +208,9 @@ public static Vector4 Parse(string text)

return new Vector4(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3]));
}

public float Get(int index)
{
switch (index)
{
case 0: return X;
case 1: return Y;
case 2: return Z;
case 3: return W;
default: return 0; // error case
}
}
#endregion

#region Properties
#region Properties
/// <summary>
/// Get the length of the Vector4 structure.
/// </summary>
Expand All @@ -240,7 +228,7 @@ public float SquaredLength
}
#endregion

#region Methods
#region Methods
/// <summary>
/// Vector4 scalar dot product.
/// </summary>
Expand Down Expand Up @@ -342,9 +330,23 @@ public static void Swap(ref Vector4 v1, ref Vector4 v2)
v1 = v2;
v2 = t;
}

/// <summary>
/// Copies the elements of the vector to a specified array.
/// </summary>
/// <param name="array">The destination array.</param>
/// <param name="offset">The index at which to copy the first element of the vector.</param>
public void CopyTo(float[] array, int offset)
{
array[offset + 0] = X;
array[offset + 1] = Y;
array[offset + 2] = Z;
array[offset + 3] = W;
}
#endregion
}
#else
#endif

/// <summary>
/// Extension methods for the Vector4 structure.
/// </summary>
Expand All @@ -364,9 +366,8 @@ public static float Get(this Vector4 v, int index)
case 1: return v.Y;
case 2: return v.Z;
case 3: return v.W;
default: return 0; // error case
default: throw new ArgumentOutOfRangeException(nameof(index));
}
}
}
#endif
}

0 comments on commit f20d0e2

Please sign in to comment.