| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819 |
- #region --- License ---
- /*
- Copyright (c) 2006 - 2008 The Open Toolkit library.
- Permission is hereby granted, free of charge, to any person obtaining a copy of
- this software and associated documentation files (the "Software"), to deal in
- the Software without restriction, including without limitation the rights to
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- of the Software, and to permit persons to whom the Software is furnished to do
- so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
- #endregion
- using System;
- using System.Runtime.InteropServices;
- using System.ComponentModel;
- using System.Xml.Serialization;
- namespace AtomicEngine
- {
- /// <summary>
- /// Represents a Quaternion.
- /// </summary>
- [StructLayout(LayoutKind.Sequential)]
- public struct Quaternion : IEquatable<Quaternion>
- {
- #region Fields
- float w;
- Vector3 xyz;
- #endregion
- #region Constructors
- /// <summary>
- /// Construct a new Quaternion from vector and w components
- /// </summary>
- /// <param name="v">The vector part</param>
- /// <param name="w">The w part</param>
- public Quaternion(Vector3 v, float w)
- {
- this.xyz = v;
- this.w = w;
- }
- /// <summary>
- /// Construct a new Quaternion
- /// </summary>
- /// <param name="x">The x component</param>
- /// <param name="y">The y component</param>
- /// <param name="z">The z component</param>
- /// <param name="w">The w component</param>
- public Quaternion(float x, float y, float z, float w)
- : this(new Vector3(x, y, z), w)
- { }
- // From Euler angles
- public Quaternion (float x, float y, float z)
- {
- const float M_DEGTORAD_2 = (float)Math.PI / 360.0f;
- x *= M_DEGTORAD_2;
- y *= M_DEGTORAD_2;
- z *= M_DEGTORAD_2;
- float sinX = (float)Math.Sin(x);
- float cosX = (float)Math.Cos(x);
- float sinY = (float)Math.Sin(y);
- float cosY = (float)Math.Cos(y);
- float sinZ = (float)Math.Sin(z);
- float cosZ = (float)Math.Cos(z);
- xyz = new Vector3(cosY * sinX * cosZ + sinY * cosX * sinZ,
- sinY * cosX * cosZ - cosY * sinX * sinZ,
- cosY * cosX * sinZ - sinY * sinX * cosZ);
- w = cosY * cosX * cosZ + sinY * sinX * sinZ;
- }
-
- public Quaternion (ref Matrix3 matrix)
- {
- double scale = System.Math.Pow(matrix.Determinant, 1.0d / 3.0d);
- float x, y, z;
-
- w = (float) (System.Math.Sqrt(System.Math.Max(0, scale + matrix[0, 0] + matrix[1, 1] + matrix[2, 2])) / 2);
- x = (float) (System.Math.Sqrt(System.Math.Max(0, scale + matrix[0, 0] - matrix[1, 1] - matrix[2, 2])) / 2);
- y = (float) (System.Math.Sqrt(System.Math.Max(0, scale - matrix[0, 0] + matrix[1, 1] - matrix[2, 2])) / 2);
- z = (float) (System.Math.Sqrt(System.Math.Max(0, scale - matrix[0, 0] - matrix[1, 1] + matrix[2, 2])) / 2);
- xyz = new Vector3 (x, y, z);
-
- if (matrix[2, 1] - matrix[1, 2] < 0) X = -X;
- if (matrix[0, 2] - matrix[2, 0] < 0) Y = -Y;
- if (matrix[1, 0] - matrix[0, 1] < 0) Z = -Z;
- }
- #endregion
- #region Public Members
- #region Properties
- /// <summary>
- /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance.
- /// </summary>
- [Obsolete("Use Xyz property instead.")]
- [CLSCompliant(false)]
- [EditorBrowsable(EditorBrowsableState.Never)]
-
- public Vector3 XYZ { get { return Xyz; } set { Xyz = value; } }
- /// <summary>
- /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance.
- /// </summary>
- public Vector3 Xyz { get { return xyz; } set { xyz = value; } }
- /// <summary>
- /// Gets or sets the X component of this instance.
- /// </summary>
-
- public float X { get { return xyz.X; } set { xyz.X = value; } }
- /// <summary>
- /// Gets or sets the Y component of this instance.
- /// </summary>
-
- public float Y { get { return xyz.Y; } set { xyz.Y = value; } }
- /// <summary>
- /// Gets or sets the Z component of this instance.
- /// </summary>
-
- public float Z { get { return xyz.Z; } set { xyz.Z = value; } }
- /// <summary>
- /// Gets or sets the W component of this instance.
- /// </summary>
- public float W { get { return w; } set { w = value; } }
- #endregion
- #region Instance
- #region ToAxisAngle
- /// <summary>
- /// Convert the current quaternion to axis angle representation
- /// </summary>
- /// <param name="axis">The resultant axis</param>
- /// <param name="angle">The resultant angle</param>
- public void ToAxisAngle(out Vector3 axis, out float angle)
- {
- Vector4 result = ToAxisAngle();
- axis = result.Xyz;
- angle = result.W;
- }
- /// <summary>
- /// Convert this instance to an axis-angle representation.
- /// </summary>
- /// <returns>A Vector4 that is the axis-angle representation of this quaternion.</returns>
- public Vector4 ToAxisAngle()
- {
- Quaternion q = this;
- if (q.W > 1.0f)
- q.Normalize();
- Vector4 result = new Vector4();
- result.W = 2.0f * (float)System.Math.Acos(q.W); // angle
- float den = (float)System.Math.Sqrt(1.0 - q.W * q.W);
- if (den > 0.0001f)
- {
- result.Xyz = q.Xyz / den;
- }
- else
- {
- // This occurs when the angle is zero.
- // Not a problem: just set an arbitrary normalized axis.
- result.Xyz = Vector3.UnitX;
- }
- return result;
- }
- #endregion
- #region public float Length
- /// <summary>
- /// Gets the length (magnitude) of the quaternion.
- /// </summary>
- /// <seealso cref="LengthSquared"/>
- public float Length
- {
- get
- {
- return (float)System.Math.Sqrt(W * W + Xyz.LengthSquared);
- }
- }
- #endregion
- #region public float LengthSquared
- /// <summary>
- /// Gets the square of the quaternion length (magnitude).
- /// </summary>
- public float LengthSquared
- {
- get
- {
- return W * W + Xyz.LengthSquared;
- }
- }
- #endregion
- #region public void Normalize()
- /// <summary>
- /// Scales the Quaternion to unit length.
- /// </summary>
- public void Normalize()
- {
- float scale = 1.0f / this.Length;
- Xyz *= scale;
- W *= scale;
- }
- #endregion
- #region EulerAngles
- public Vector3 ToEulerAngles()
- {
- // Derivation from http://www.geometrictools.com/Documentation/EulerAngles.pdf
- // Order of rotations: Z first, then X, then Y
- float check = 2.0f*(-Y*Z + W*X);
- const float radToDeg = 180f/(float) Math.PI;
- if (check < -0.995f)
- {
- return new Vector3(-90f, 0f, -(float)Math.Atan2(2.0f * (X * Z - W * Y), 1.0f - 2.0f * (Y * Y + Z * Z)) * radToDeg);
- }
- else if (check > 0.995f)
- {
- return new Vector3(90f, 0f, (float)Math.Atan2(2.0f * (X * Z - W * Y), 1.0f - 2.0f * (Y * Y + Z * Z)) * radToDeg);
- }
- else
- {
- return new Vector3(
- (float)Math.Asin(check) * radToDeg,
- (float)Math.Atan2(2.0f * (X * Z - W * Y), 1.0f - 2.0f * (X * X + Y * Y)) * radToDeg,
- (float)Math.Atan2(2.0f * (X * Y - W * Z), 1.0f - 2.0f * (X * X + Z * Z)) * radToDeg);
- }
- }
- public float YawAngle => ToEulerAngles().Y;
- public float PitchAngle => ToEulerAngles().X;
- public float RollAngle => ToEulerAngles().Z;
- #endregion
- #region public void Conjugate()
- /// <summary>
- /// Convert this quaternion to its conjugate
- /// </summary>
- public void Conjugate()
- {
- Xyz = -Xyz;
- }
- #endregion
- #endregion
- #region Static
- #region Fields
- /// <summary>
- /// Defines the identity quaternion.
- /// </summary>
- public static Quaternion Identity = new Quaternion(0, 0, 0, 1);
- #endregion
- #region Add
- /// <summary>
- /// Add two quaternions
- /// </summary>
- /// <param name="left">The first operand</param>
- /// <param name="right">The second operand</param>
- /// <returns>The result of the addition</returns>
- public static Quaternion Add(Quaternion left, Quaternion right)
- {
- return new Quaternion(
- left.Xyz + right.Xyz,
- left.W + right.W);
- }
- /// <summary>
- /// Add two quaternions
- /// </summary>
- /// <param name="left">The first operand</param>
- /// <param name="right">The second operand</param>
- /// <param name="result">The result of the addition</param>
- public static void Add(ref Quaternion left, ref Quaternion right, out Quaternion result)
- {
- result = new Quaternion(
- left.Xyz + right.Xyz,
- left.W + right.W);
- }
- #endregion
- #region Sub
- /// <summary>
- /// Subtracts two instances.
- /// </summary>
- /// <param name="left">The left instance.</param>
- /// <param name="right">The right instance.</param>
- /// <returns>The result of the operation.</returns>
- public static Quaternion Sub(Quaternion left, Quaternion right)
- {
- return new Quaternion(
- left.Xyz - right.Xyz,
- left.W - right.W);
- }
- /// <summary>
- /// Subtracts two instances.
- /// </summary>
- /// <param name="left">The left instance.</param>
- /// <param name="right">The right instance.</param>
- /// <param name="result">The result of the operation.</param>
- public static void Sub(ref Quaternion left, ref Quaternion right, out Quaternion result)
- {
- result = new Quaternion(
- left.Xyz - right.Xyz,
- left.W - right.W);
- }
- #endregion
- #region Mult
- /// <summary>
- /// Multiplies two instances.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <returns>A new instance containing the result of the calculation.</returns>
- [Obsolete("Use Multiply instead.")]
- public static Quaternion Mult(Quaternion left, Quaternion right)
- {
- return new Quaternion(
- right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz),
- left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz));
- }
- /// <summary>
- /// Multiplies two instances.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <param name="result">A new instance containing the result of the calculation.</param>
- [Obsolete("Use Multiply instead.")]
- public static void Mult(ref Quaternion left, ref Quaternion right, out Quaternion result)
- {
- result = new Quaternion(
- right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz),
- left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz));
- }
- /// <summary>
- /// Multiplies two instances.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <returns>A new instance containing the result of the calculation.</returns>
- public static Quaternion Multiply(Quaternion left, Quaternion right)
- {
- Quaternion result;
- Multiply(ref left, ref right, out result);
- return result;
- }
- /// <summary>
- /// Multiplies two instances.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <param name="result">A new instance containing the result of the calculation.</param>
- public static void Multiply(ref Quaternion left, ref Quaternion right, out Quaternion result)
- {
- result = new Quaternion(
- right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz),
- left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz));
- }
- /// <summary>
- /// Multiplies an instance by a scalar.
- /// </summary>
- /// <param name="quaternion">The instance.</param>
- /// <param name="scale">The scalar.</param>
- /// <param name="result">A new instance containing the result of the calculation.</param>
- public static void Multiply(ref Quaternion quaternion, float scale, out Quaternion result)
- {
- result = new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale);
- }
- [Obsolete ("Use the overload without the ref float scale")]
- public static void Multiply(ref Quaternion quaternion, ref float scale, out Quaternion result)
- {
- result = new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale);
- }
-
- /// <summary>
- /// Multiplies an instance by a scalar.
- /// </summary>
- /// <param name="quaternion">The instance.</param>
- /// <param name="scale">The scalar.</param>
- /// <returns>A new instance containing the result of the calculation.</returns>
- public static Quaternion Multiply(Quaternion quaternion, float scale)
- {
- return new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale);
- }
- #endregion
- #region Conjugate
- /// <summary>
- /// Get the conjugate of the given quaternion
- /// </summary>
- /// <param name="q">The quaternion</param>
- /// <returns>The conjugate of the given quaternion</returns>
- public static Quaternion Conjugate(Quaternion q)
- {
- return new Quaternion(-q.Xyz, q.W);
- }
- /// <summary>
- /// Get the conjugate of the given quaternion
- /// </summary>
- /// <param name="q">The quaternion</param>
- /// <param name="result">The conjugate of the given quaternion</param>
- public static void Conjugate(ref Quaternion q, out Quaternion result)
- {
- result = new Quaternion(-q.Xyz, q.W);
- }
- #endregion
- #region Invert
- /// <summary>
- /// Get the inverse of the given quaternion
- /// </summary>
- /// <param name="q">The quaternion to invert</param>
- /// <returns>The inverse of the given quaternion</returns>
- public static Quaternion Invert(Quaternion q)
- {
- Quaternion result;
- Invert(ref q, out result);
- return result;
- }
- /// <summary>
- /// Get the inverse of the given quaternion
- /// </summary>
- /// <param name="q">The quaternion to invert</param>
- /// <param name="result">The inverse of the given quaternion</param>
- public static void Invert(ref Quaternion q, out Quaternion result)
- {
- float lengthSq = q.LengthSquared;
- if (lengthSq != 0.0)
- {
- float i = 1.0f / lengthSq;
- result = new Quaternion(q.Xyz * -i, q.W * i);
- }
- else
- {
- result = q;
- }
- }
- #endregion
- #region Normalize
- /// <summary>
- /// Scale the given quaternion to unit length
- /// </summary>
- /// <param name="q">The quaternion to normalize</param>
- /// <returns>The normalized quaternion</returns>
- public static Quaternion Normalize(Quaternion q)
- {
- Quaternion result;
- Normalize(ref q, out result);
- return result;
- }
- /// <summary>
- /// Scale the given quaternion to unit length
- /// </summary>
- /// <param name="q">The quaternion to normalize</param>
- /// <param name="result">The normalized quaternion</param>
- public static void Normalize(ref Quaternion q, out Quaternion result)
- {
- float scale = 1.0f / q.Length;
- result = new Quaternion(q.Xyz * scale, q.W * scale);
- }
- #endregion
- #region FromAxisAngle
- /// <summary>
- /// Build a quaternion from the given axis and angle
- /// </summary>
- /// <param name="axis">The axis to rotate about</param>
- /// <param name="angle">The rotation angle in radians</param>
- /// <returns></returns>
- public static Quaternion FromAxisAngle(Vector3 axis, float angle)
- {
- axis.Normalize();
- angle *= (float)Math.PI /360f;
- var sinAngle = (float)Math.Sin(angle);
- var cosAngle = (float)Math.Cos(angle);
- return new Quaternion(axis.X * sinAngle, axis.Y * sinAngle, axis.Z * sinAngle, cosAngle);
- }
- #endregion
- #region FromRotationTo
- public static Quaternion FromRotationTo(Vector3 start, Vector3 end)
- {
- Quaternion result = new Quaternion();
- start.Normalize();
- end.Normalize();
- const float epsilon = 0.000001f;
- float d = Vector3.Dot(start, end);
- if (d > -1.0f + epsilon)
- {
- Vector3 c = Vector3.Cross(start, end);
- float s = (float)Math.Sqrt((1.0f + d) * 2.0f);
- float invS = 1.0f / s;
- result.X = c.X * invS;
- result.Y = c.Y * invS;
- result.Z = c.Z * invS;
- result.W = 0.5f * s;
- }
- else
- {
- Vector3 axis = Vector3.Cross(Vector3.UnitX, start);
- if (axis.Length < epsilon)
- axis = Vector3.Cross(Vector3.UnitY, start);
- return FromAxisAngle(axis, 180.0f);
- }
- return result;
- }
- #endregion
- #region Slerp
- /// <summary>
- /// Do Spherical linear interpolation between two quaternions
- /// </summary>
- /// <param name="q1">The first quaternion</param>
- /// <param name="q2">The second quaternion</param>
- /// <param name="blend">The blend factor</param>
- /// <returns>A smooth blend between the given quaternions</returns>
- public static Quaternion Slerp(Quaternion q1, Quaternion q2, float blend)
- {
- // if either input is zero, return the other.
- if (q1.LengthSquared == 0.0f)
- {
- if (q2.LengthSquared == 0.0f)
- {
- return Identity;
- }
- return q2;
- }
- else if (q2.LengthSquared == 0.0f)
- {
- return q1;
- }
- float cosHalfAngle = q1.W * q2.W + Vector3.Dot(q1.Xyz, q2.Xyz);
- if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f)
- {
- // angle = 0.0f, so just return one input.
- return q1;
- }
- else if (cosHalfAngle < 0.0f)
- {
- q2.Xyz = -q2.Xyz;
- q2.W = -q2.W;
- cosHalfAngle = -cosHalfAngle;
- }
- float blendA;
- float blendB;
- if (cosHalfAngle < 0.99f)
- {
- // do proper slerp for big angles
- float halfAngle = (float)System.Math.Acos(cosHalfAngle);
- float sinHalfAngle = (float)System.Math.Sin(halfAngle);
- float oneOverSinHalfAngle = 1.0f / sinHalfAngle;
- blendA = (float)System.Math.Sin(halfAngle * (1.0f - blend)) * oneOverSinHalfAngle;
- blendB = (float)System.Math.Sin(halfAngle * blend) * oneOverSinHalfAngle;
- }
- else
- {
- // do lerp if angle is really small.
- blendA = 1.0f - blend;
- blendB = blend;
- }
- Quaternion result = new Quaternion(blendA * q1.Xyz + blendB * q2.Xyz, blendA * q1.W + blendB * q2.W);
- if (result.LengthSquared > 0.0f)
- return Normalize(result);
- else
- return Identity;
- }
- #endregion
- #endregion
- #region Operators
- /// <summary>
- /// Adds two instances.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <returns>The result of the calculation.</returns>
- public static Quaternion operator +(Quaternion left, Quaternion right)
- {
- left.Xyz += right.Xyz;
- left.W += right.W;
- return left;
- }
- /// <summary>
- /// Subtracts two instances.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <returns>The result of the calculation.</returns>
- public static Quaternion operator -(Quaternion left, Quaternion right)
- {
- left.Xyz -= right.Xyz;
- left.W -= right.W;
- return left;
- }
- /// <summary>
- /// Multiplies two instances.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <returns>The result of the calculation.</returns>
- public static Quaternion operator *(Quaternion left, Quaternion right)
- {
- Multiply(ref left, ref right, out left);
- return left;
- }
- /// <summary>
- /// Multiplies an instance by a scalar.
- /// </summary>
- /// <param name="quaternion">The instance.</param>
- /// <param name="scale">The scalar.</param>
- /// <returns>A new instance containing the result of the calculation.</returns>
- public static Quaternion operator *(Quaternion quaternion, float scale)
- {
- Multiply(ref quaternion, scale, out quaternion);
- return quaternion;
- }
- /// <summary>
- /// Multiplies an instance by a scalar.
- /// </summary>
- /// <param name="quaternion">The instance.</param>
- /// <param name="scale">The scalar.</param>
- /// <returns>A new instance containing the result of the calculation.</returns>
- public static Quaternion operator *(float scale, Quaternion quaternion)
- {
- return new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale);
- }
-
- /// <summary>
- /// Multiplies an instance by a vector3.
- /// </summary>
- /// <param name="quaternion">The instance.</param>
- /// <param name="vector">The vector.</param>
- /// <returns>A new instance containing the result of the calculation.</returns>
- public static Vector3 operator *(Quaternion quaternion, Vector3 vector)
- {
- var qVec = new Vector3(quaternion.X, quaternion.Y, quaternion.Z);
- var cross1 = Vector3.Cross(qVec, vector);
- var cross2 = Vector3.Cross(qVec, cross1);
- return vector + 2.0f * (cross1 * quaternion.W + cross2);
- }
- /// <summary>
- /// Compares two instances for equality.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <returns>True, if left equals right; false otherwise.</returns>
- public static bool operator ==(Quaternion left, Quaternion right)
- {
- return left.Equals(right);
- }
- /// <summary>
- /// Compares two instances for inequality.
- /// </summary>
- /// <param name="left">The first instance.</param>
- /// <param name="right">The second instance.</param>
- /// <returns>True, if left does not equal right; false otherwise.</returns>
- public static bool operator !=(Quaternion left, Quaternion right)
- {
- return !left.Equals(right);
- }
- #endregion
- #region Overrides
- #region public override string ToString()
- /// <summary>
- /// Returns a System.String that represents the current Quaternion.
- /// </summary>
- /// <returns></returns>
- public override string ToString()
- {
- return String.Format("V: {0}, W: {1}", Xyz, W);
- }
- #endregion
- #region public override bool Equals (object o)
- /// <summary>
- /// Compares this object instance to another object for equality.
- /// </summary>
- /// <param name="other">The other object to be used in the comparison.</param>
- /// <returns>True if both objects are Quaternions of equal value. Otherwise it returns false.</returns>
- public override bool Equals(object other)
- {
- if (other is Quaternion == false) return false;
- return this == (Quaternion)other;
- }
- #endregion
- #region public override int GetHashCode ()
- /// <summary>
- /// Provides the hash code for this object.
- /// </summary>
- /// <returns>A hash code formed from the bitwise XOR of this objects members.</returns>
- public override int GetHashCode()
- {
- return Xyz.GetHashCode() ^ W.GetHashCode();
- }
- #endregion
- #endregion
- #endregion
- #region IEquatable<Quaternion> Members
- /// <summary>
- /// Compares this Quaternion instance to another Quaternion for equality.
- /// </summary>
- /// <param name="other">The other Quaternion to be used in the comparison.</param>
- /// <returns>True if both instances are equal; false otherwise.</returns>
- public bool Equals(Quaternion other)
- {
- return Xyz == other.Xyz && W == other.W;
- }
- #endregion
- }
- }
|