using System;
using System.IO;
using System.Diagnostics;
#if !(UNITY_STANDALONE || UNITY_EDITOR)
using System.Numerics;
#endif
class Testing
{
string logFile;
int sampleCount;
public Testing(string logFile, int sampleCount)
{
this.logFile = logFile;
this.sampleCount = sampleCount;
}
/// <summary>
/// Complete copy of Unity3D Vector3 struct
/// </summary>
public void TestVector3UnityCustom()
{
GC.Collect();
GC.WaitForPendingFinalizers();
Stopwatch watch = new Stopwatch();
float x = 2;
//Results
long msPlusEqualProp = -1;
long msManualAdd = -1;
long msPlusEqualVar = -1;
long msManualAddNonProp = -1;
long msMulVar = -1;
long msMulConst = -1;
Vector3Unity res = Vector3Unity.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res += Vector3Unity.one;
}
watch.Stop();
msPlusEqualProp = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res.x += Vector3Unity.one.x;
res.y += Vector3Unity.one.y;
res.z += Vector3Unity.one.z;
}
watch.Stop();
msManualAdd = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
Vector3Unity toAdd = Vector3Unity.one;
for (int i = 0; i < sampleCount; i++)
{
res += toAdd;
}
watch.Stop();
msPlusEqualVar = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
toAdd = Vector3Unity.one;
for (int i = 0; i < sampleCount; i++)
{
res.x += toAdd.x;
res.y += toAdd.y;
res.z += toAdd.z;
}
watch.Stop();
msManualAddNonProp = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= x;
}
watch.Stop();
msMulVar = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= 2;
}
watch.Stop();
msMulConst = watch.ElapsedMilliseconds;
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= UnityEngine.Vector3 COPY =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "Test: res += Vector3.one: " + msPlusEqualProp + " ms\r\n");
File.AppendAllText(logFile, "Test: Manual Add: " + msManualAdd + " ms\r\n");
File.AppendAllText(logFile, "Test: res += res: " + msPlusEqualVar + " ms\r\n");
File.AppendAllText(logFile, "Test: Manual Add (non-property): " + msManualAddNonProp + " ms\r\n");
File.AppendAllText(logFile, "Test: Vector3 => res *= x: " + msMulVar + " ms\r\n");
File.AppendAllText(logFile, "Test: Vector3 => res *= const: " + msMulVar + " ms\r\n");
File.AppendAllText(logFile, "\r\n");
}
public void TestVector3Numerics()
{
#if !(UNITY_STANDALONE || UNITY_EDITOR)
GC.Collect();
GC.WaitForPendingFinalizers();
//Results
long msPlusEqualProp = -1;
long msManualAdd = -1;
long msPlusEqualVar = -1;
long msManualAddNonProp = -1;
long msMulVar = -1;
long msMulConst = -1;
Stopwatch watch = new Stopwatch();
float x = 2;
Vector3 res = Vector3.One;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res += Vector3.One;
}
watch.Stop();
msPlusEqualProp = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res.X += Vector3.One.X;
res.Y += Vector3.One.Y;
res.Z += Vector3.One.Z;
}
watch.Stop();
msManualAdd = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
Vector3 toAdd = Vector3.One;
for (int i = 0; i < sampleCount; i++)
{
res += toAdd;
}
watch.Stop();
msPlusEqualVar = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
toAdd = Vector3.One;
for (int i = 0; i < sampleCount; i++)
{
res.X += toAdd.X;
res.Y += toAdd.Y;
res.Z += toAdd.Z;
}
watch.Stop();
msManualAddNonProp = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= x;
}
watch.Stop();
msMulVar = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= 2;
}
watch.Stop();
msMulConst = watch.ElapsedMilliseconds;
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= System.Numerics.Vector3 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "res => res += Vector3.One: " + msPlusEqualProp + " ms\r\n");
File.AppendAllText(logFile, "Test: res => Manual Add: " + msManualAdd + " ms\r\n");
File.AppendAllText(logFile, "Test: vec += vec " + msPlusEqualVar + " ms\r\n");
File.AppendAllText(logFile, "Test: Vector3 => Manual Add (non-property) " + msManualAddNonProp + " ms\r\n");
File.AppendAllText(logFile, "Test: res *= x: " + msMulVar + " ms\r\n");
File.AppendAllText(logFile, "Test: res *= const: " + msMulConst + " ms\r\n");
File.AppendAllText(logFile, "\r\n");
#else
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= System.Numerics.Vector3 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "System.Numerics not available in Unity3D\r\n");
File.AppendAllText(logFile, "\r\n");
#endif
}
public void TestVector3Unity()
{
#if UNITY_STANDALONE || UNTY_EDITOR
GC.Collect();
GC.WaitForPendingFinalizers();
//Results
long msPlusEqualProp = -1;
long msManualAdd = -1;
long msPlusEqualVar = -1;
long msManualAddNonProp = -1;
long msMulVar = -1;
long msMulConst = -1;
Stopwatch watch = new Stopwatch();
float x = 2;
UnityEngine.Vector3 res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res += UnityEngine.Vector3.one;
}
watch.Stop();
msPlusEqualProp = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res.x += UnityEngine.Vector3.one.x;
res.y += UnityEngine.Vector3.one.y;
res.z += UnityEngine.Vector3.one.z;
}
watch.Stop();
msManualAdd = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
UnityEngine.Vector3 toAdd = UnityEngine.Vector3.one;
for (int i = 0; i < sampleCount; i++)
{
res += toAdd;
}
watch.Stop();
msPlusEqualVar = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
toAdd = UnityEngine.Vector3.one;
for (int i = 0; i < sampleCount; i++)
{
res.x += toAdd.x;
res.y += toAdd.y;
res.z += toAdd.z;
}
watch.Stop();
msManualAddNonProp = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= x;
}
watch.Stop();
msMulVar = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= 2;
}
watch.Stop();
msMulConst = watch.ElapsedMilliseconds;
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= System.Numerics.UnityEngine.Vector3 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "res => res += UnityEngine.Vector3.one: " + msPlusEqualProp + " ms\r\n");
File.AppendAllText(logFile, "Test: res => Manual Add: " + msManualAdd + " ms\r\n");
File.AppendAllText(logFile, "Test: vec += vec " + msPlusEqualVar + " ms\r\n");
File.AppendAllText(logFile, "Test: UnityEngine.Vector3 => Manual Add (non-property) " + msManualAddNonProp + " ms\r\n");
File.AppendAllText(logFile, "Test: res *= x: " + msMulVar + " ms\r\n");
File.AppendAllText(logFile, "Test: res *= const: " + msMulConst + " ms\r\n");
File.AppendAllText(logFile, "\r\n");
#else
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= UnityEngine.Vector3 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "Unity3D Not found...\r\n");
File.AppendAllText(logFile, "\r\n");
#endif
}
public void TestAll()
{
File.WriteAllText(logFile, "Samples: " + sampleCount + "\r\n");
File.AppendAllText(logFile, "CLR Version: " + Environment.Version + "\r\n");
File.AppendAllText(logFile, "Runtime Version: " + (typeof(string).Assembly.ImageRuntimeVersion) + "\r\n");
File.AppendAllText(logFile, "Is Mono: " + (Type.GetType("Mono.Runtime") != null) + "\r\n");
File.AppendAllText(logFile, "Is Unity3D: " + this.IsUnity() + "\r\n");
File.AppendAllText(logFile, "Is Unity3D Editor: " + this.IsUnityEditor() + "\r\n");
TestVector3UnityCustom();
TestVector3Numerics();
TestVector3Unity();
}
private bool IsUnity()
{
#if UNITY_STANDALONE || UNITY_EDITOR
return true;
#else
return false;
#endif
}
private bool IsUnityEditor()
{
#if UNITY_EDITOR
return true;
#else
return false;
#endif
}
}
public struct Vector3Unity
{
private static readonly Vector3Unity zeroVector = new Vector3Unity(0.0f, 0.0f, 0.0f);
private static readonly Vector3Unity oneVector = new Vector3Unity(1f, 1f, 1f);
private static readonly Vector3Unity upVector = new Vector3Unity(0.0f, 1f, 0.0f);
private static readonly Vector3Unity downVector = new Vector3Unity(0.0f, -1f, 0.0f);
private static readonly Vector3Unity leftVector = new Vector3Unity(-1f, 0.0f, 0.0f);
private static readonly Vector3Unity rightVector = new Vector3Unity(1f, 0.0f, 0.0f);
private static readonly Vector3Unity forwardVector = new Vector3Unity(0.0f, 0.0f, 1f);
private static readonly Vector3Unity backVector = new Vector3Unity(0.0f, 0.0f, -1f);
private static readonly Vector3Unity positiveInfinityVector = new Vector3Unity(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
private static readonly Vector3Unity negativeInfinityVector = new Vector3Unity(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
public const float kEpsilon = 1E-05f;
/// <summary>
/// <para>X component of the vector.</para>
/// </summary>
public float x;
/// <summary>
/// <para>Y component of the vector.</para>
/// </summary>
public float y;
/// <summary>
/// <para>Z component of the vector.</para>
/// </summary>
public float z;
public float this[int index]
{
get
{
switch (index)
{
case 0:
return this.x;
case 1:
return this.y;
case 2:
return this.z;
default:
throw new IndexOutOfRangeException("Invalid Vector3 index!");
}
}
set
{
switch (index)
{
case 0:
this.x = value;
break;
case 1:
this.y = value;
break;
case 2:
this.z = value;
break;
default:
throw new IndexOutOfRangeException("Invalid Vector3 index!");
}
}
}
/// <summary>
/// <para>Returns this vector with a magnitude of 1 (Read Only).</para>
/// </summary>
public Vector3Unity normalized
{
get
{
return Vector3Unity.Normalize(this);
}
}
/// <summary>
/// <para>Returns the length of this vector (Read Only).</para>
/// </summary>
public float magnitude
{
get
{
return (float)Math.Sqrt(x * x + y * y + z * z);
}
}
/// <summary>
/// <para>Returns the squared length of this vector (Read Only).</para>
/// </summary>
public float sqrMagnitude
{
get
{
return x * x + y * y + z * z;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, 0, 0).</para>
/// </summary>
public static Vector3Unity zero
{
get
{
return Vector3Unity.zeroVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(1, 1, 1).</para>
/// </summary>
public static Vector3Unity one
{
get
{
return Vector3Unity.oneVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, 0, 1).</para>
/// </summary>
public static Vector3Unity forward
{
get
{
return Vector3Unity.forwardVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, 0, -1).</para>
/// </summary>
public static Vector3Unity back
{
get
{
return Vector3Unity.backVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, 1, 0).</para>
/// </summary>
public static Vector3Unity up
{
get
{
return Vector3Unity.upVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, -1, 0).</para>
/// </summary>
public static Vector3Unity down
{
get
{
return Vector3Unity.downVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(-1, 0, 0).</para>
/// </summary>
public static Vector3Unity left
{
get
{
return Vector3Unity.leftVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(1, 0, 0).</para>
/// </summary>
public static Vector3Unity right
{
get
{
return Vector3Unity.rightVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity).</para>
/// </summary>
public static Vector3Unity positiveInfinity
{
get
{
return Vector3Unity.positiveInfinityVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity).</para>
/// </summary>
public static Vector3Unity negativeInfinity
{
get
{
return Vector3Unity.negativeInfinityVector;
}
}
[Obsolete("Use Vector3.forward instead.")]
public static Vector3Unity fwd
{
get
{
return new Vector3Unity(0.0f, 0.0f, 1f);
}
}
/// <summary>
/// <para>Creates a new vector with given x, y, z components.</para>
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
public Vector3Unity(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
/// <summary>
/// <para>Creates a new vector with given x, y components and sets z to zero.</para>
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public Vector3Unity(float x, float y)
{
this.x = x;
this.y = y;
this.z = 0.0f;
}
public static Vector3Unity operator +(Vector3Unity a, Vector3Unity b)
{
return new Vector3Unity(a.x + b.x, a.y + b.y, a.z + b.z);
}
public static Vector3Unity operator -(Vector3Unity a, Vector3Unity b)
{
return new Vector3Unity(a.x - b.x, a.y - b.y, a.z - b.z);
}
public static Vector3Unity operator -(Vector3Unity a)
{
return new Vector3Unity(-a.x, -a.y, -a.z);
}
public static Vector3Unity operator *(Vector3Unity a, float d)
{
return new Vector3Unity(a.x * d, a.y * d, a.z * d);
}
public static Vector3Unity operator *(float d, Vector3Unity a)
{
return new Vector3Unity(a.x * d, a.y * d, a.z * d);
}
public static Vector3Unity operator /(Vector3Unity a, float d)
{
return new Vector3Unity(a.x / d, a.y / d, a.z / d);
}
public static bool operator ==(Vector3Unity lhs, Vector3Unity rhs)
{
return (double)Vector3Unity.SqrMagnitude(lhs - rhs) < 9.99999943962493E-11;
}
public static bool operator !=(Vector3Unity lhs, Vector3Unity rhs)
{
return !(lhs == rhs);
}
/// <summary>
/// <para>Spherically interpolates between two vectors.</para>
/// </summary>
/// <param name="a">Dear Unity... EXPLANATON??????</param>
/// <param name="b">Dear Unity... EXPLANATON??????</param>
/// <param name="t">Dear Unity... EXPLANATON??????</param>
public static Vector3Unity Lerp(Vector3Unity a, Vector3Unity b, float t)
{
t = (t > 1 ? 1 : t < 0 ? 0 : t); //Clamp T. Use ternary operator, faster than IF-ELSE
return new Vector3Unity(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t);
}
/// <summary>
/// <para>Spherically interpolates between two vectors.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="t"></param>
public static Vector3Unity LerpUnclamped(Vector3Unity a, Vector3Unity b, float t)
{
return new Vector3Unity(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t);
}
/// <summary>
/// <para>Moves a point current in a straight line towards a target point.</para>
/// </summary>
/// <param name="current"></param>
/// <param name="target"></param>
/// <param name="maxDistanceDelta"></param>
public static Vector3Unity MoveTowards(Vector3Unity current, Vector3Unity target, float maxDistanceDelta)
{
Vector3Unity vector3 = target - current;
float magnitude = vector3.magnitude;
if (magnitude <= maxDistanceDelta || magnitude < 1.40129846432482E-45) return target;
return current + vector3 / magnitude * maxDistanceDelta;
}
/// <summary>
/// <para>Set x, y and z components of an existing Vector3.</para>
/// </summary>
/// <param name="newX"></param>
/// <param name="newY"></param>
/// <param name="newZ"></param>
public void Set(float newX, float newY, float newZ)
{
this.x = newX;
this.y = newY;
this.z = newZ;
}
/// <summary>
/// <para>Multiplies two vectors component-wise.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
public static Vector3Unity Scale(Vector3Unity a, Vector3Unity b)
{
return new Vector3Unity(a.x * b.x, a.y * b.y, a.z * b.z);
}
/// <summary>
/// <para>Multiplies every component of this vector by the same component of scale.</para>
/// </summary>
/// <param name="scale"></param>
public void Scale(Vector3Unity scale)
{
this.x *= scale.x;
this.y *= scale.y;
this.z *= scale.z;
}
/// <summary>
/// <para>Cross Product of two vectors.</para>
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
public static Vector3Unity Cross(Vector3Unity lhs, Vector3Unity rhs)
{
return new Vector3Unity((float)((double)lhs.y * (double)rhs.z - (double)lhs.z * (double)rhs.y), (float)((double)lhs.z * (double)rhs.x - (double)lhs.x * (double)rhs.z), (float)((double)lhs.x * (double)rhs.y - (double)lhs.y * (double)rhs.x));
}
public override int GetHashCode()
{
return this.x.GetHashCode() ^ this.y.GetHashCode() << 2 ^ this.z.GetHashCode() >> 2;
}
/// <summary>
/// <para>Returns true if the given vector is exactly equal to this vector.</para>
/// </summary>
/// <param name="other"></param>
public override bool Equals(object other)
{
if (!(other is Vector3Unity))
return false;
Vector3Unity vector3 = (Vector3Unity)other;
return this.x.Equals(vector3.x) && this.y.Equals(vector3.y) && this.z.Equals(vector3.z);
}
/// <summary>
/// <para>Reflects a vector off the plane defined by a normal.</para>
/// </summary>
/// <param name="inDirection"></param>
/// <param name="inNormal"></param>
public static Vector3Unity Reflect(Vector3Unity inDirection, Vector3Unity inNormal)
{
return -2f * Vector3Unity.Dot(inNormal, inDirection) * inNormal + inDirection;
}
/// <summary>
/// <para>Makes this vector have a magnitude of 1.</para>
/// </summary>
/// <param name="value"></param>
public static Vector3Unity Normalize(Vector3Unity value)
{
float num = Vector3Unity.Magnitude(value);
if ((double)num > 9.99999974737875E-06)
return value / num;
return Vector3Unity.zero;
}
public void Normalize()
{
float num = Vector3Unity.Magnitude(this);
if ((double)num > 9.99999974737875E-06)
this = this / num;
else
this = Vector3Unity.zero;
}
/// <summary>
/// <para>Dot Product of two vectors.</para>
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
public static float Dot(Vector3Unity lhs, Vector3Unity rhs)
{
return (float)((double)lhs.x * (double)rhs.x + (double)lhs.y * (double)rhs.y + (double)lhs.z * (double)rhs.z);
}
public static float Magnitude(Vector3Unity vector)
{
return vector.magnitude;
}
public static float SqrMagnitude(Vector3Unity vector)
{
return vector.sqrMagnitude;
}
}
using System.IO;
using System.Diagnostics;
#if !(UNITY_STANDALONE || UNITY_EDITOR)
using System.Numerics;
#endif
class Testing
{
string logFile;
int sampleCount;
public Testing(string logFile, int sampleCount)
{
this.logFile = logFile;
this.sampleCount = sampleCount;
}
/// <summary>
/// Complete copy of Unity3D Vector3 struct
/// </summary>
public void TestVector3UnityCustom()
{
GC.Collect();
GC.WaitForPendingFinalizers();
Stopwatch watch = new Stopwatch();
float x = 2;
//Results
long msPlusEqualProp = -1;
long msManualAdd = -1;
long msPlusEqualVar = -1;
long msManualAddNonProp = -1;
long msMulVar = -1;
long msMulConst = -1;
Vector3Unity res = Vector3Unity.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res += Vector3Unity.one;
}
watch.Stop();
msPlusEqualProp = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res.x += Vector3Unity.one.x;
res.y += Vector3Unity.one.y;
res.z += Vector3Unity.one.z;
}
watch.Stop();
msManualAdd = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
Vector3Unity toAdd = Vector3Unity.one;
for (int i = 0; i < sampleCount; i++)
{
res += toAdd;
}
watch.Stop();
msPlusEqualVar = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
toAdd = Vector3Unity.one;
for (int i = 0; i < sampleCount; i++)
{
res.x += toAdd.x;
res.y += toAdd.y;
res.z += toAdd.z;
}
watch.Stop();
msManualAddNonProp = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= x;
}
watch.Stop();
msMulVar = watch.ElapsedMilliseconds;
res = Vector3Unity.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= 2;
}
watch.Stop();
msMulConst = watch.ElapsedMilliseconds;
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= UnityEngine.Vector3 COPY =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "Test: res += Vector3.one: " + msPlusEqualProp + " ms\r\n");
File.AppendAllText(logFile, "Test: Manual Add: " + msManualAdd + " ms\r\n");
File.AppendAllText(logFile, "Test: res += res: " + msPlusEqualVar + " ms\r\n");
File.AppendAllText(logFile, "Test: Manual Add (non-property): " + msManualAddNonProp + " ms\r\n");
File.AppendAllText(logFile, "Test: Vector3 => res *= x: " + msMulVar + " ms\r\n");
File.AppendAllText(logFile, "Test: Vector3 => res *= const: " + msMulVar + " ms\r\n");
File.AppendAllText(logFile, "\r\n");
}
public void TestVector3Numerics()
{
#if !(UNITY_STANDALONE || UNITY_EDITOR)
GC.Collect();
GC.WaitForPendingFinalizers();
//Results
long msPlusEqualProp = -1;
long msManualAdd = -1;
long msPlusEqualVar = -1;
long msManualAddNonProp = -1;
long msMulVar = -1;
long msMulConst = -1;
Stopwatch watch = new Stopwatch();
float x = 2;
Vector3 res = Vector3.One;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res += Vector3.One;
}
watch.Stop();
msPlusEqualProp = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res.X += Vector3.One.X;
res.Y += Vector3.One.Y;
res.Z += Vector3.One.Z;
}
watch.Stop();
msManualAdd = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
Vector3 toAdd = Vector3.One;
for (int i = 0; i < sampleCount; i++)
{
res += toAdd;
}
watch.Stop();
msPlusEqualVar = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
toAdd = Vector3.One;
for (int i = 0; i < sampleCount; i++)
{
res.X += toAdd.X;
res.Y += toAdd.Y;
res.Z += toAdd.Z;
}
watch.Stop();
msManualAddNonProp = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= x;
}
watch.Stop();
msMulVar = watch.ElapsedMilliseconds;
res = Vector3.One;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= 2;
}
watch.Stop();
msMulConst = watch.ElapsedMilliseconds;
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= System.Numerics.Vector3 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "res => res += Vector3.One: " + msPlusEqualProp + " ms\r\n");
File.AppendAllText(logFile, "Test: res => Manual Add: " + msManualAdd + " ms\r\n");
File.AppendAllText(logFile, "Test: vec += vec " + msPlusEqualVar + " ms\r\n");
File.AppendAllText(logFile, "Test: Vector3 => Manual Add (non-property) " + msManualAddNonProp + " ms\r\n");
File.AppendAllText(logFile, "Test: res *= x: " + msMulVar + " ms\r\n");
File.AppendAllText(logFile, "Test: res *= const: " + msMulConst + " ms\r\n");
File.AppendAllText(logFile, "\r\n");
#else
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= System.Numerics.Vector3 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "System.Numerics not available in Unity3D\r\n");
File.AppendAllText(logFile, "\r\n");
#endif
}
public void TestVector3Unity()
{
#if UNITY_STANDALONE || UNTY_EDITOR
GC.Collect();
GC.WaitForPendingFinalizers();
//Results
long msPlusEqualProp = -1;
long msManualAdd = -1;
long msPlusEqualVar = -1;
long msManualAddNonProp = -1;
long msMulVar = -1;
long msMulConst = -1;
Stopwatch watch = new Stopwatch();
float x = 2;
UnityEngine.Vector3 res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res += UnityEngine.Vector3.one;
}
watch.Stop();
msPlusEqualProp = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res.x += UnityEngine.Vector3.one.x;
res.y += UnityEngine.Vector3.one.y;
res.z += UnityEngine.Vector3.one.z;
}
watch.Stop();
msManualAdd = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
UnityEngine.Vector3 toAdd = UnityEngine.Vector3.one;
for (int i = 0; i < sampleCount; i++)
{
res += toAdd;
}
watch.Stop();
msPlusEqualVar = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
toAdd = UnityEngine.Vector3.one;
for (int i = 0; i < sampleCount; i++)
{
res.x += toAdd.x;
res.y += toAdd.y;
res.z += toAdd.z;
}
watch.Stop();
msManualAddNonProp = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= x;
}
watch.Stop();
msMulVar = watch.ElapsedMilliseconds;
res = UnityEngine.Vector3.one;
watch.Reset();
watch.Start();
for (int i = 0; i < sampleCount; i++)
{
res *= 2;
}
watch.Stop();
msMulConst = watch.ElapsedMilliseconds;
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= System.Numerics.UnityEngine.Vector3 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "res => res += UnityEngine.Vector3.one: " + msPlusEqualProp + " ms\r\n");
File.AppendAllText(logFile, "Test: res => Manual Add: " + msManualAdd + " ms\r\n");
File.AppendAllText(logFile, "Test: vec += vec " + msPlusEqualVar + " ms\r\n");
File.AppendAllText(logFile, "Test: UnityEngine.Vector3 => Manual Add (non-property) " + msManualAddNonProp + " ms\r\n");
File.AppendAllText(logFile, "Test: res *= x: " + msMulVar + " ms\r\n");
File.AppendAllText(logFile, "Test: res *= const: " + msMulConst + " ms\r\n");
File.AppendAllText(logFile, "\r\n");
#else
File.AppendAllText(logFile, "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= UnityEngine.Vector3 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\r\n");
File.AppendAllText(logFile, "Unity3D Not found...\r\n");
File.AppendAllText(logFile, "\r\n");
#endif
}
public void TestAll()
{
File.WriteAllText(logFile, "Samples: " + sampleCount + "\r\n");
File.AppendAllText(logFile, "CLR Version: " + Environment.Version + "\r\n");
File.AppendAllText(logFile, "Runtime Version: " + (typeof(string).Assembly.ImageRuntimeVersion) + "\r\n");
File.AppendAllText(logFile, "Is Mono: " + (Type.GetType("Mono.Runtime") != null) + "\r\n");
File.AppendAllText(logFile, "Is Unity3D: " + this.IsUnity() + "\r\n");
File.AppendAllText(logFile, "Is Unity3D Editor: " + this.IsUnityEditor() + "\r\n");
TestVector3UnityCustom();
TestVector3Numerics();
TestVector3Unity();
}
private bool IsUnity()
{
#if UNITY_STANDALONE || UNITY_EDITOR
return true;
#else
return false;
#endif
}
private bool IsUnityEditor()
{
#if UNITY_EDITOR
return true;
#else
return false;
#endif
}
}
public struct Vector3Unity
{
private static readonly Vector3Unity zeroVector = new Vector3Unity(0.0f, 0.0f, 0.0f);
private static readonly Vector3Unity oneVector = new Vector3Unity(1f, 1f, 1f);
private static readonly Vector3Unity upVector = new Vector3Unity(0.0f, 1f, 0.0f);
private static readonly Vector3Unity downVector = new Vector3Unity(0.0f, -1f, 0.0f);
private static readonly Vector3Unity leftVector = new Vector3Unity(-1f, 0.0f, 0.0f);
private static readonly Vector3Unity rightVector = new Vector3Unity(1f, 0.0f, 0.0f);
private static readonly Vector3Unity forwardVector = new Vector3Unity(0.0f, 0.0f, 1f);
private static readonly Vector3Unity backVector = new Vector3Unity(0.0f, 0.0f, -1f);
private static readonly Vector3Unity positiveInfinityVector = new Vector3Unity(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
private static readonly Vector3Unity negativeInfinityVector = new Vector3Unity(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
public const float kEpsilon = 1E-05f;
/// <summary>
/// <para>X component of the vector.</para>
/// </summary>
public float x;
/// <summary>
/// <para>Y component of the vector.</para>
/// </summary>
public float y;
/// <summary>
/// <para>Z component of the vector.</para>
/// </summary>
public float z;
public float this[int index]
{
get
{
switch (index)
{
case 0:
return this.x;
case 1:
return this.y;
case 2:
return this.z;
default:
throw new IndexOutOfRangeException("Invalid Vector3 index!");
}
}
set
{
switch (index)
{
case 0:
this.x = value;
break;
case 1:
this.y = value;
break;
case 2:
this.z = value;
break;
default:
throw new IndexOutOfRangeException("Invalid Vector3 index!");
}
}
}
/// <summary>
/// <para>Returns this vector with a magnitude of 1 (Read Only).</para>
/// </summary>
public Vector3Unity normalized
{
get
{
return Vector3Unity.Normalize(this);
}
}
/// <summary>
/// <para>Returns the length of this vector (Read Only).</para>
/// </summary>
public float magnitude
{
get
{
return (float)Math.Sqrt(x * x + y * y + z * z);
}
}
/// <summary>
/// <para>Returns the squared length of this vector (Read Only).</para>
/// </summary>
public float sqrMagnitude
{
get
{
return x * x + y * y + z * z;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, 0, 0).</para>
/// </summary>
public static Vector3Unity zero
{
get
{
return Vector3Unity.zeroVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(1, 1, 1).</para>
/// </summary>
public static Vector3Unity one
{
get
{
return Vector3Unity.oneVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, 0, 1).</para>
/// </summary>
public static Vector3Unity forward
{
get
{
return Vector3Unity.forwardVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, 0, -1).</para>
/// </summary>
public static Vector3Unity back
{
get
{
return Vector3Unity.backVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, 1, 0).</para>
/// </summary>
public static Vector3Unity up
{
get
{
return Vector3Unity.upVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(0, -1, 0).</para>
/// </summary>
public static Vector3Unity down
{
get
{
return Vector3Unity.downVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(-1, 0, 0).</para>
/// </summary>
public static Vector3Unity left
{
get
{
return Vector3Unity.leftVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(1, 0, 0).</para>
/// </summary>
public static Vector3Unity right
{
get
{
return Vector3Unity.rightVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity).</para>
/// </summary>
public static Vector3Unity positiveInfinity
{
get
{
return Vector3Unity.positiveInfinityVector;
}
}
/// <summary>
/// <para>Shorthand for writing Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity).</para>
/// </summary>
public static Vector3Unity negativeInfinity
{
get
{
return Vector3Unity.negativeInfinityVector;
}
}
[Obsolete("Use Vector3.forward instead.")]
public static Vector3Unity fwd
{
get
{
return new Vector3Unity(0.0f, 0.0f, 1f);
}
}
/// <summary>
/// <para>Creates a new vector with given x, y, z components.</para>
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
public Vector3Unity(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
/// <summary>
/// <para>Creates a new vector with given x, y components and sets z to zero.</para>
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public Vector3Unity(float x, float y)
{
this.x = x;
this.y = y;
this.z = 0.0f;
}
public static Vector3Unity operator +(Vector3Unity a, Vector3Unity b)
{
return new Vector3Unity(a.x + b.x, a.y + b.y, a.z + b.z);
}
public static Vector3Unity operator -(Vector3Unity a, Vector3Unity b)
{
return new Vector3Unity(a.x - b.x, a.y - b.y, a.z - b.z);
}
public static Vector3Unity operator -(Vector3Unity a)
{
return new Vector3Unity(-a.x, -a.y, -a.z);
}
public static Vector3Unity operator *(Vector3Unity a, float d)
{
return new Vector3Unity(a.x * d, a.y * d, a.z * d);
}
public static Vector3Unity operator *(float d, Vector3Unity a)
{
return new Vector3Unity(a.x * d, a.y * d, a.z * d);
}
public static Vector3Unity operator /(Vector3Unity a, float d)
{
return new Vector3Unity(a.x / d, a.y / d, a.z / d);
}
public static bool operator ==(Vector3Unity lhs, Vector3Unity rhs)
{
return (double)Vector3Unity.SqrMagnitude(lhs - rhs) < 9.99999943962493E-11;
}
public static bool operator !=(Vector3Unity lhs, Vector3Unity rhs)
{
return !(lhs == rhs);
}
/// <summary>
/// <para>Spherically interpolates between two vectors.</para>
/// </summary>
/// <param name="a">Dear Unity... EXPLANATON??????</param>
/// <param name="b">Dear Unity... EXPLANATON??????</param>
/// <param name="t">Dear Unity... EXPLANATON??????</param>
public static Vector3Unity Lerp(Vector3Unity a, Vector3Unity b, float t)
{
t = (t > 1 ? 1 : t < 0 ? 0 : t); //Clamp T. Use ternary operator, faster than IF-ELSE
return new Vector3Unity(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t);
}
/// <summary>
/// <para>Spherically interpolates between two vectors.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="t"></param>
public static Vector3Unity LerpUnclamped(Vector3Unity a, Vector3Unity b, float t)
{
return new Vector3Unity(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t);
}
/// <summary>
/// <para>Moves a point current in a straight line towards a target point.</para>
/// </summary>
/// <param name="current"></param>
/// <param name="target"></param>
/// <param name="maxDistanceDelta"></param>
public static Vector3Unity MoveTowards(Vector3Unity current, Vector3Unity target, float maxDistanceDelta)
{
Vector3Unity vector3 = target - current;
float magnitude = vector3.magnitude;
if (magnitude <= maxDistanceDelta || magnitude < 1.40129846432482E-45) return target;
return current + vector3 / magnitude * maxDistanceDelta;
}
/// <summary>
/// <para>Set x, y and z components of an existing Vector3.</para>
/// </summary>
/// <param name="newX"></param>
/// <param name="newY"></param>
/// <param name="newZ"></param>
public void Set(float newX, float newY, float newZ)
{
this.x = newX;
this.y = newY;
this.z = newZ;
}
/// <summary>
/// <para>Multiplies two vectors component-wise.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
public static Vector3Unity Scale(Vector3Unity a, Vector3Unity b)
{
return new Vector3Unity(a.x * b.x, a.y * b.y, a.z * b.z);
}
/// <summary>
/// <para>Multiplies every component of this vector by the same component of scale.</para>
/// </summary>
/// <param name="scale"></param>
public void Scale(Vector3Unity scale)
{
this.x *= scale.x;
this.y *= scale.y;
this.z *= scale.z;
}
/// <summary>
/// <para>Cross Product of two vectors.</para>
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
public static Vector3Unity Cross(Vector3Unity lhs, Vector3Unity rhs)
{
return new Vector3Unity((float)((double)lhs.y * (double)rhs.z - (double)lhs.z * (double)rhs.y), (float)((double)lhs.z * (double)rhs.x - (double)lhs.x * (double)rhs.z), (float)((double)lhs.x * (double)rhs.y - (double)lhs.y * (double)rhs.x));
}
public override int GetHashCode()
{
return this.x.GetHashCode() ^ this.y.GetHashCode() << 2 ^ this.z.GetHashCode() >> 2;
}
/// <summary>
/// <para>Returns true if the given vector is exactly equal to this vector.</para>
/// </summary>
/// <param name="other"></param>
public override bool Equals(object other)
{
if (!(other is Vector3Unity))
return false;
Vector3Unity vector3 = (Vector3Unity)other;
return this.x.Equals(vector3.x) && this.y.Equals(vector3.y) && this.z.Equals(vector3.z);
}
/// <summary>
/// <para>Reflects a vector off the plane defined by a normal.</para>
/// </summary>
/// <param name="inDirection"></param>
/// <param name="inNormal"></param>
public static Vector3Unity Reflect(Vector3Unity inDirection, Vector3Unity inNormal)
{
return -2f * Vector3Unity.Dot(inNormal, inDirection) * inNormal + inDirection;
}
/// <summary>
/// <para>Makes this vector have a magnitude of 1.</para>
/// </summary>
/// <param name="value"></param>
public static Vector3Unity Normalize(Vector3Unity value)
{
float num = Vector3Unity.Magnitude(value);
if ((double)num > 9.99999974737875E-06)
return value / num;
return Vector3Unity.zero;
}
public void Normalize()
{
float num = Vector3Unity.Magnitude(this);
if ((double)num > 9.99999974737875E-06)
this = this / num;
else
this = Vector3Unity.zero;
}
/// <summary>
/// <para>Dot Product of two vectors.</para>
/// </summary>
/// <param name="lhs"></param>
/// <param name="rhs"></param>
public static float Dot(Vector3Unity lhs, Vector3Unity rhs)
{
return (float)((double)lhs.x * (double)rhs.x + (double)lhs.y * (double)rhs.y + (double)lhs.z * (double)rhs.z);
}
public static float Magnitude(Vector3Unity vector)
{
return vector.magnitude;
}
public static float SqrMagnitude(Vector3Unity vector)
{
return vector.sqrMagnitude;
}
}