/BulletNoXna/BulletNoXna/LinearMath/Quaternion.cs
https://bitbucket.org/cjrgaming/bullet-noxna · C# · 678 lines · 550 code · 104 blank · 24 comment · 33 complexity · 3ce21abe54ed774fec7e945f9c977d1d MD5 · raw file
- #region License
- /*
- MIT License
- Copyright © 2006 The Mono.Xna Team
- All rights reserved.
- 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 License
- using System;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Text;
- namespace BulletXNA.LinearMath
- {
- [Serializable]
- public struct Quaternion : IEquatable<Quaternion>
- {
- public float X;
- public float Y;
- public float Z;
- public float W;
- static Quaternion identity = new Quaternion(0, 0, 0, 1);
-
- public Quaternion(float x, float y, float z, float w)
- {
- this.X = x;
- this.Y = y;
- this.Z = z;
- this.W = w;
- }
-
-
- public Quaternion(Vector3 vectorPart, float scalarPart)
- {
- this.X = vectorPart.X;
- this.Y = vectorPart.Y;
- this.Z = vectorPart.Z;
- this.W = scalarPart;
- }
- public static Quaternion Identity
- {
- get{ return identity; }
- }
- public static Quaternion Add(Quaternion quaternion1, Quaternion quaternion2)
- {
- return new Quaternion(quaternion1.X + quaternion2.X, quaternion1.Y + quaternion2.Y, quaternion1.Z + quaternion2.Z, quaternion1.W + quaternion2.W);
- }
- public static void Add(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
- {
- result.W = quaternion1.W + quaternion2.W;
- result.X = quaternion1.X + quaternion2.X;
- result.Y = quaternion1.Y + quaternion2.Y;
- result.Z = quaternion1.Z + quaternion2.Z;
- }
- public static Quaternion Concatenate(Quaternion value1, Quaternion value2)
- {
- Quaternion quaternion;
- quaternion.X = ((value2.X * value1.W) + (value1.X * value2.W)) + (value2.Y * value1.Z) - (value2.Z * value1.Y);
- quaternion.Y = ((value2.Y * value1.W) + (value1.Y * value2.W)) + (value2.Z * value1.X) - (value2.X * value1.Z);
- quaternion.Z = ((value2.Z * value1.W) + (value1.Z * value2.W)) + (value2.X * value1.Y) - (value2.Y * value1.X);
- quaternion.W = (value2.W * value1.W) - ((value2.X * value1.X) + (value2.Y * value1.Y)) + (value2.Z * value1.Z);
- return quaternion;
- }
- public void Conjugate()
- {
- this.X = -this.X;
- this.Y = -this.Y;
- this.Z = -this.Z;
- }
- public static Quaternion Conjugate(Quaternion value)
- {
- Quaternion quaternion;
- quaternion.X = -value.X;
- quaternion.Y = -value.Y;
- quaternion.Z = -value.Z;
- quaternion.W = value.W;
- return quaternion;
- }
- public static void Conjugate(ref Quaternion value, out Quaternion result)
- {
- result.X = -value.X;
- result.Y = -value.Y;
- result.Z = -value.Z;
- result.W = value.W;
- }
- public static void Concatenate(ref Quaternion value1, ref Quaternion value2, out Quaternion result)
- {
- result.X = ((value2.X * value1.W) + (value1.X * value2.W)) + (value2.Y * value1.Z) - (value2.Z * value1.Y);
- result.Y = ((value2.Y * value1.W) + (value1.Y * value2.W)) + (value2.Z * value1.X) - (value2.X * value1.Z);
- result.Z = ((value2.Z * value1.W) + (value1.Z * value2.W)) + (value2.X * value1.Y) - (value2.Y * value1.X);
- result.W = (value2.W * value1.W) - ((value2.X * value1.X) + (value2.Y * value1.Y)) + (value2.Z * value1.Z);
- }
- public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
- {
- Quaternion quaternion;
- quaternion.X = (float)(((Math.Cos((yaw * 0.5)) * Math.Sin((pitch * 0.5))) * Math.Cos((roll * 0.5))) + ((Math.Sin((yaw * 0.5)) * Math.Cos((pitch * 0.5))) * Math.Sin((roll * 0.5))));
- quaternion.Y = (float)(((Math.Sin((yaw * 0.5)) * Math.Cos((pitch * 0.5))) * Math.Cos((roll * 0.5))) - ((Math.Cos((yaw * 0.5)) * Math.Sin((pitch * 0.5))) * Math.Sin((roll * 0.5))));
- quaternion.Z = (float)(((Math.Cos((yaw * 0.5)) * Math.Cos((pitch * 0.5))) * Math.Sin((roll * 0.5))) - ((Math.Sin((yaw * 0.5)) * Math.Sin((pitch * 0.5))) * Math.Cos((roll * 0.5))));
- quaternion.W = (float)(((Math.Cos((yaw * 0.5)) * Math.Cos((pitch * 0.5))) * Math.Cos((roll * 0.5))) + ((Math.Sin((yaw * 0.5)) * Math.Sin((pitch * 0.5))) * Math.Sin((roll * 0.5))));
- return quaternion;
- }
- public static void CreateFromYawPitchRoll(float yaw, float pitch, float roll, out Quaternion result)
- {
- result.X = (float)(((Math.Cos((yaw * 0.5)) * Math.Sin((pitch * 0.5))) * Math.Cos((roll * 0.5))) + ((Math.Sin((yaw * 0.5)) * Math.Cos((pitch * 0.5))) * Math.Sin((roll * 0.5))));
- result.Y = (float)(((Math.Sin((yaw * 0.5)) * Math.Cos((pitch * 0.5))) * Math.Cos((roll * 0.5))) - ((Math.Cos((yaw * 0.5)) * Math.Sin((pitch * 0.5))) * Math.Sin((roll * 0.5))));
- result.Z = (float)(((Math.Cos((yaw * 0.5)) * Math.Cos((pitch * 0.5))) * Math.Sin((roll * 0.5))) - ((Math.Sin((yaw * 0.5)) * Math.Sin((pitch * 0.5))) * Math.Cos((roll * 0.5))));
- result.W = (float)(((Math.Cos((yaw * 0.5)) * Math.Cos((pitch * 0.5))) * Math.Cos((roll * 0.5))) + ((Math.Sin((yaw * 0.5)) * Math.Sin((pitch * 0.5))) * Math.Sin((roll * 0.5))));
- }
- public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)
- {
- double sin_a = Math.Sin(angle / 2.0);
- return new Quaternion((float)(axis.X * sin_a),(float)(axis.Y * sin_a),(float)(axis.Z * sin_a),(float)Math.Cos(angle / 2.0));
- }
- public static void CreateFromAxisAngle(ref Vector3 axis, float angle, out Quaternion result)
- {
- double sin_a = Math.Sin(angle / 2.0);
- result.X = (float)(axis.X * sin_a);
- result.Y = (float)(axis.Y * sin_a);
- result.Z = (float)(axis.Z * sin_a);
- result.W = (float)Math.Cos(angle / 2.0);
- }
- public static Quaternion CreateFromRotationMatrix(Matrix matrix)
- {
- Quaternion result;
- if ((matrix._basis[0, 0] + matrix._basis[1, 1] + matrix._basis[2, 2]) > 0.0F)
- {
- double M1 = System.Math.Sqrt((matrix._basis[0, 0] + matrix._basis[1, 1] + matrix._basis[2, 2] + 1.0));
- result.W = (float)(M1 * 0.5);
- M1 = 0.5 / M1;
- result.X = (float)((matrix._basis[1, 2] - matrix._basis[2, 1]) * M1);
- result.Y = (float)((matrix._basis[2, 0] - matrix._basis[0, 2]) * M1);
- result.Z = (float)((matrix._basis[0, 1] - matrix._basis[1, 0]) * M1);
- return result;
- }
- if ((matrix._basis[0, 0] >= matrix._basis[1, 1]) && (matrix._basis[0, 0] >= matrix._basis[2, 2]))
- {
- double M2 = System.Math.Sqrt((1.0 + matrix._basis[0, 0] - matrix._basis[1, 1] - matrix._basis[2, 2]));
- double M3 = 0.5 / M2;
- result.X = (float)(0.5 * M2);
- result.Y = (float)((matrix._basis[0, 1] + matrix._basis[1, 0]) * M3);
- result.Z = (float)((matrix._basis[0, 2] + matrix._basis[2, 0]) * M3);
- result.W = (float)((matrix._basis[1, 2] - matrix._basis[2, 1]) * M3);
- return result;
- }
- if (matrix._basis[1, 1] > matrix._basis[2, 2])
- {
- double M4 = System.Math.Sqrt((double)(1.0 + matrix._basis[1, 1] - matrix._basis[0, 0] - matrix._basis[2, 2]));
- double M5 = 0.5 / M4;
- result.X = (float)((matrix._basis[1, 0] + matrix._basis[0, 1]) * M5);
- result.Y = (float)(0.5 * M4);
- result.Z = (float)((matrix._basis[2, 1] + matrix._basis[1, 2]) * M5);
- result.W = (float)((matrix._basis[2, 0] - matrix._basis[0, 2]) * M5);
- return result;
- }
- double M6 = System.Math.Sqrt((1.0 + matrix._basis[2, 2] - matrix._basis[0, 0] - matrix._basis[1, 1]));
- double M7 = 0.5 / M6;
- result.X = (float)((matrix._basis[2, 0] + matrix._basis[0, 2]) * M7);
- result.Y = (float)((matrix._basis[2, 1] + matrix._basis[1, 2]) * M7);
- result.Z = (float)(0.5 * M6);
- result.W = (float)((matrix._basis[0, 1] - matrix._basis[1, 0]) * M7);
- return result;
- }
- public static void CreateFromRotationMatrix(ref Matrix matrix, out Quaternion result)
- {
- if ((matrix._basis[0, 0] + matrix._basis[1, 1] + matrix._basis[2, 2]) > 0.0F)
- {
- double M1 = System.Math.Sqrt((matrix._basis[0, 0] + matrix._basis[1, 1] + matrix._basis[2, 2] + 1.0));
- result.W = (float)(M1 * 0.5);
- M1 = 0.5 / M1;
- result.X = (float)((matrix._basis[1, 2] - matrix._basis[2, 1]) * M1);
- result.Y = (float)((matrix._basis[2, 0] - matrix._basis[0, 2]) * M1);
- result.Z = (float)((matrix._basis[0, 1] - matrix._basis[1, 0]) * M1);
- return;
- }
- if ((matrix._basis[0, 0] >= matrix._basis[1, 1]) && (matrix._basis[0, 0] >= matrix._basis[2, 2]))
- {
- double M2 = System.Math.Sqrt((1.0 + matrix._basis[0, 0] - matrix._basis[1, 1] - matrix._basis[2, 2]));
- double M3 = 0.5 / M2;
- result.X = (float)(0.5 * M2);
- result.Y = (float)((matrix._basis[0, 1] + matrix._basis[1, 0]) * M3);
- result.Z = (float)((matrix._basis[0, 2] + matrix._basis[2, 0]) * M3);
- result.W = (float)((matrix._basis[1, 2] - matrix._basis[2, 1]) * M3);
- return;
- }
- if (matrix._basis[1, 1] > matrix._basis[2, 2])
- {
- double M4 = System.Math.Sqrt((1.0 + matrix._basis[1, 1] - matrix._basis[0, 0] - matrix._basis[2, 2]));
- double M5 = 0.5 / M4;
- result.X = (float)((matrix._basis[1, 0] + matrix._basis[0, 1]) * M5);
- result.Y = (float)(0.5 * M4);
- result.Z = (float)((matrix._basis[2, 1] + matrix._basis[1, 2]) * M5);
- result.W = (float)((matrix._basis[2, 0] - matrix._basis[0, 2]) * M5);
- return;
- }
- double M6 = System.Math.Sqrt((1.0 + matrix._basis[2, 2] - matrix._basis[0, 0] - matrix._basis[1, 1]));
- double M7 = 0.5 / M6;
- result.X = (float)((matrix._basis[2, 0] + matrix._basis[0, 2]) * M7);
- result.Y = (float)((matrix._basis[2, 1] + matrix._basis[1, 2]) * M7);
- result.Z = (float)(0.5 * M6);
- result.W = (float)((matrix._basis[0, 1] - matrix._basis[1, 0]) * M7);
- }
- public static Quaternion Divide(Quaternion quaternion1, Quaternion quaternion2)
- {
- Quaternion result;
- double w5 = 1.0 / ((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y) + (quaternion2.Z * quaternion2.Z) + (quaternion2.W * quaternion2.W));
- double w4 = -quaternion2.X * w5;
- double w3 = -quaternion2.Y * w5;
- double w2 = -quaternion2.Z * w5;
- double w1 = quaternion2.W * w5;
- result.X = (float)((quaternion1.X * w1) + (w4 * quaternion1.W) + ((quaternion1.Y * w2) - (quaternion1.Z * w3)));
- result.Y = (float)((quaternion1.Y * w1) + (w3 * quaternion1.W) + ((quaternion1.Z * w4) - (quaternion1.X * w2)));
- result.Z = (float)((quaternion1.Z * w1) + (w2 * quaternion1.W) + ((quaternion1.X * w3) - (quaternion1.Y * w4)));
- result.W = (float)((quaternion1.W * quaternion2.W * w5) - ((quaternion1.X * w4) + (quaternion1.Y * w3) + (quaternion1.Z * w2)));
- return result;
- }
- public static void Divide(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
- {
- double w5 = 1.0 / ((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y) + (quaternion2.Z * quaternion2.Z) + (quaternion2.W * quaternion2.W));
- double w4 = -quaternion2.X * w5;
- double w3 = -quaternion2.Y * w5;
- double w2 = -quaternion2.Z * w5;
- double w1 = quaternion2.W * w5;
- result.X = (float)((quaternion1.X * w1) + (w4 * quaternion1.W) + ((quaternion1.Y * w2) - (quaternion1.Z * w3)));
- result.Y = (float)((quaternion1.Y * w1) + (w3 * quaternion1.W) + ((quaternion1.Z * w4) - (quaternion1.X * w2)));
- result.Z = (float)((quaternion1.Z * w1) + (w2 * quaternion1.W) + ((quaternion1.X * w3) - (quaternion1.Y * w4)));
- result.W = (float)((quaternion1.W * quaternion2.W * w5) - ((quaternion1.X * w4) + (quaternion1.Y * w3) + (quaternion1.Z * w2)));
- }
- public static float Dot(Quaternion quaternion1, Quaternion quaternion2)
- {
- return (quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y) + (quaternion1.Z * quaternion2.Z) + (quaternion1.W * quaternion2.W);
- }
- public static void Dot(ref Quaternion quaternion1, ref Quaternion quaternion2, out float result)
- {
- result = (quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y) + (quaternion1.Z * quaternion2.Z) + (quaternion1.W * quaternion2.W);
- }
- public override bool Equals(object obj)
- {
- return (obj is Quaternion) ? this == (Quaternion)obj : false;
- }
- public bool Equals(Quaternion other)
- {
- if ((X == other.X) && (Y == other.Y) && (Z == other.Z))
- return W == other.W;
- return false;
- }
- public override int GetHashCode()
- {
- return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
- }
- public static Quaternion Inverse(Quaternion quaternion)
- {
- Quaternion result;
- double m1 = 1.0 / ((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y) + (quaternion.Z * quaternion.Z) + (quaternion.W * quaternion.W));
- result.X = (float)(-quaternion.X * m1);
- result.Y = (float)(-quaternion.Y * m1);
- result.Z = (float)(-quaternion.Z * m1);
- result.W = (float)(quaternion.W * m1);
- return result;
- }
- public static void Inverse(ref Quaternion quaternion, out Quaternion result)
- {
- double m1 = 1.0 / ((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y) + (quaternion.Z * quaternion.Z) + (quaternion.W * quaternion.W));
- result.X = (float)(-quaternion.X * m1);
- result.Y = (float)(-quaternion.Y * m1);
- result.Z = (float)(-quaternion.Z * m1);
- result.W = (float)(quaternion.W * m1);
- }
- public float Length()
- {
- return (float)System.Math.Sqrt(((X * X) + (Y * Y) + (Z * Z) + (W * W)));
- }
- public float LengthSquared()
- {
- return (X * X) + (Y * Y) + (Z * Z) + (W * W);
- }
- public static Quaternion Lerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
- {
- Quaternion result;
- double f2 = 1.0 - amount;
- double tempX, tempY, tempZ, tempW;
- if (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y) + (quaternion1.Z * quaternion2.Z) + (quaternion1.W * quaternion2.W)) >= 0.0F)
- {
- tempX = (f2 * quaternion1.X) + (amount * quaternion2.X);
- tempY = (f2 * quaternion1.Y) + (amount * quaternion2.Y);
- tempZ = (f2 * quaternion1.Z) + (amount * quaternion2.Z);
- tempW = (f2 * quaternion1.W) + (amount * quaternion2.W);
- }
- else
- {
- tempX = (f2 * quaternion1.X) - (amount * quaternion2.X);
- tempY = (f2 * quaternion1.Y) - (amount * quaternion2.Y);
- tempZ = (f2 * quaternion1.Z) - (amount * quaternion2.Z);
- tempW = (f2 * quaternion1.W) - (amount * quaternion2.W);
- }
- double f4 = (tempX * tempX) + (tempY * tempY) + (tempZ * tempZ) + (tempW * tempW);
- double f3 = 1.0 / System.Math.Sqrt(f4);
- result.X = (float)(tempX * f3);
- result.Y = (float)(tempY * f3);
- result.Z = (float)(tempZ * f3);
- result.W = (float)(tempW * f3);
- return result;
- }
- public static void Lerp(ref Quaternion quaternion1, ref Quaternion quaternion2, float amount, out Quaternion result)
- {
- double m2 = 1.0 - amount;
- double tempX, tempY, tempZ, tempW;
- if (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y) + (quaternion1.Z * quaternion2.Z) + (quaternion1.W * quaternion2.W)) >= 0.0F)
- {
- tempX = ((m2 * quaternion1.X) + (amount * quaternion2.X));
- tempY = ((m2 * quaternion1.Y) + (amount * quaternion2.Y));
- tempZ = ((m2 * quaternion1.Z) + (amount * quaternion2.Z));
- tempW = ((m2 * quaternion1.W) + (amount * quaternion2.W));
- }
- else
- {
- tempX = ((m2 * quaternion1.X) - (amount * quaternion2.X));
- tempY = ((m2 * quaternion1.Y) - (amount * quaternion2.Y));
- tempZ = ((m2 * quaternion1.Z) - (amount * quaternion2.Z));
- tempW = ((m2 * quaternion1.W) - (amount * quaternion2.W));
- }
- double m4 = (tempX * tempX) + (tempY * tempY) + (tempZ * tempZ) + (tempW * tempW);
- double m3 = 1.0 / System.Math.Sqrt(m4);
- result.X = (float)(tempX * m3);
- result.Y = (float)(tempY * m3);
- result.Z = (float)(tempZ * m3);
- result.W = (float)(tempW * m3);
- }
- public static Quaternion Slerp(Quaternion quaternion1, Quaternion quaternion2, float t)
- {
- float theta = Angle(quaternion1, quaternion2);
- if(theta != 0)
- {
- double d = 1.0/Math.Sin(theta);
- double s0 = Math.Sin((1.0 - t)*theta);
- double s1 = Math.Sin(t*theta);
- if(Quaternion.Dot(quaternion1, quaternion2) < 0)
- {
- return new Quaternion((float)((quaternion1.X * s0 + -quaternion2.X * s1) *d),
- (float)((quaternion1.Y * s0 + -quaternion2.Y * s1) *d),
- (float)((quaternion1.Z * s0 + -quaternion2.Z * s1) *d),
- (float)((quaternion1.W * s0 + -quaternion2.W * s1) *d));
- }
- else
- {
- return new Quaternion((float)((quaternion1.X * s0 + quaternion2.X * s1) * d),
- (float)((quaternion1.Y * s0 + quaternion2.Y * s1) * d),
- (float)((quaternion1.Z * s0 + quaternion2.Z * s1) * d),
- (float)((quaternion1.W * s0 + quaternion2.W * s1) * d));
- }
- }
- return quaternion1;
- }
- public static float Angle(Quaternion p, Quaternion q)
- {
- double s = Math.Sqrt(p.LengthSquared() * q.LengthSquared());
- Debug.Assert(s != 0.0);
- return (float)Math.Acos(Quaternion.Dot(p, q) / s);
- }
- public static void Slerp(ref Quaternion quaternion1, ref Quaternion quaternion2, float t, out Quaternion result)
- {
- float theta = Angle(quaternion1, quaternion2);
- if (theta != 0)
- {
- double d = 1.0 / Math.Sin(theta);
- double s0 = Math.Sin((1.0 - t) * theta);
- double s1 = Math.Sin(t * theta);
- if (Quaternion.Dot(quaternion1, quaternion2) < 0)
- {
- result = new Quaternion((float)((quaternion1.X * s0 + -quaternion2.X * s1) * d),
- (float)((quaternion1.Y * s0 + -quaternion2.Y * s1) * d),
- (float)((quaternion1.Z * s0 + -quaternion2.Z * s1) * d),
- (float)((quaternion1.W * s0 + -quaternion2.W * s1) * d));
- }
- else
- {
- result = new Quaternion((float)((quaternion1.X * s0 + quaternion2.X * s1) * d),
- (float)((quaternion1.Y * s0 + quaternion2.Y * s1) * d),
- (float)((quaternion1.Z * s0 + quaternion2.Z * s1) * d),
- (float)((quaternion1.W * s0 + quaternion2.W * s1) * d));
- }
- }
- else
- {
- result = quaternion1;
- }
- }
- public static Quaternion Subtract(Quaternion quaternion1, Quaternion quaternion2)
- {
- return new Quaternion(quaternion1.X - quaternion2.X, quaternion1.Y - quaternion2.Y, quaternion1.Z - quaternion2.Z, quaternion1.W - quaternion2.W);
- }
- public static void Subtract(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
- {
- result.X = quaternion1.X - quaternion2.X;
- result.Y = quaternion1.Y - quaternion2.Y;
- result.Z = quaternion1.Z - quaternion2.Z;
- result.W = quaternion1.W - quaternion2.W;
- }
- public static Quaternion Multiply(Quaternion quaternion1, Quaternion quaternion2)
- {
- Quaternion result;
- double f12 = (quaternion1.Y * quaternion2.Z) - (quaternion1.Z * quaternion2.Y);
- double f11 = (quaternion1.Z * quaternion2.X) - (quaternion1.X * quaternion2.Z);
- double f10 = (quaternion1.X * quaternion2.Y) - (quaternion1.Y * quaternion2.X);
- double f9 = (quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y) + (quaternion1.Z * quaternion2.Z);
- result.X = (float)((quaternion1.X * quaternion2.W) + (quaternion2.X * quaternion1.W) + f12);
- result.Y = (float)((quaternion1.Y * quaternion2.W) + (quaternion2.Y * quaternion1.W) + f11);
- result.Z = (float)((quaternion1.Z * quaternion2.W) + (quaternion2.Z * quaternion1.W) + f10);
- result.W = (float)((quaternion1.W * quaternion2.W) - f9);
- return result;
- }
- public static Quaternion Multiply(Quaternion quaternion1, float scaleFactor)
- {
- Quaternion result;
- result.X = quaternion1.X * scaleFactor;
- result.Y = quaternion1.Y * scaleFactor;
- result.Z = quaternion1.Z * scaleFactor;
- result.W = quaternion1.W * scaleFactor;
- return result;
- }
- public static void Multiply(ref Quaternion quaternion1, float scaleFactor, out Quaternion result)
- {
- result.X = quaternion1.X * scaleFactor;
- result.Y = quaternion1.Y * scaleFactor;
- result.Z = quaternion1.Z * scaleFactor;
- result.W = quaternion1.W * scaleFactor;
- }
- public static void Multiply(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
- {
- double f12 = (quaternion1.Y * quaternion2.Z) - (quaternion1.Z * quaternion2.Y);
- double f11 = (quaternion1.Z * quaternion2.X) - (quaternion1.X * quaternion2.Z);
- double f10 = (quaternion1.X * quaternion2.Y) - (quaternion1.Y * quaternion2.X);
- double f9 = (quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y) + (quaternion1.Z * quaternion2.Z);
- result.X = (float)((quaternion1.X * quaternion2.W) + (quaternion2.X * quaternion1.W) + f12);
- result.Y = (float)((quaternion1.Y * quaternion2.W) + (quaternion2.Y * quaternion1.W) + f11);
- result.Z = (float)((quaternion1.Z * quaternion2.W) + (quaternion2.Z * quaternion1.W) + f10);
- result.W = (float)((quaternion1.W * quaternion2.W) - f9);
- }
- public static Quaternion Negate(Quaternion quaternion)
- {
- Quaternion result;
- result.X = -quaternion.X;
- result.Y = -quaternion.Y;
- result.Z = -quaternion.Z;
- result.W = -quaternion.W;
- return result;
- }
- public static void Negate(ref Quaternion quaternion, out Quaternion result)
- {
- result.X = -quaternion.X;
- result.Y = -quaternion.Y;
- result.Z = -quaternion.Z;
- result.W = -quaternion.W;
- }
- public void Normalize()
- {
- double f1 = (1.0 / System.Math.Sqrt((double)((this.X * this.X) + (this.Y * this.Y) + (this.Z * this.Z) + (this.W * this.W))));
- X = (float)(X*f1);
- Y = (float)(Y * f1);
- Z = (float)(Z * f1);
- W = (float)(W * f1);
- }
- public static Quaternion Normalize(Quaternion quaternion)
- {
- Quaternion result;
- double f1 = (1.0 / System.Math.Sqrt((double)((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y) + (quaternion.Z * quaternion.Z) + (quaternion.W * quaternion.W))));
- result.X = (float)(quaternion.X * f1);
- result.Y = (float)(quaternion.Y * f1);
- result.Z = (float)(quaternion.Z * f1);
- result.W = (float)(quaternion.W * f1);
- return result;
- }
- public static void Normalize(ref Quaternion quaternion, out Quaternion result)
- {
- double f1 = (1.0 / System.Math.Sqrt((double)((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y) + (quaternion.Z * quaternion.Z) + (quaternion.W * quaternion.W))));
- result.X = (float)(quaternion.X * f1);
- result.Y = (float)(quaternion.Y * f1);
- result.Z = (float)(quaternion.Z * f1);
- result.W = (float)(quaternion.W * f1);
- }
- public static Quaternion operator +(Quaternion quaternion1, Quaternion quaternion2)
- {
- return new Quaternion(quaternion1.X + quaternion2.X, quaternion1.Y + quaternion2.Y, quaternion1.Z + quaternion2.Z, quaternion1.W + quaternion2.W);
- }
- public static Quaternion operator /(Quaternion quaternion1, Quaternion quaternion2)
- {
- Quaternion result;
- double w5 = 1.0 / ((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y) + (quaternion2.Z * quaternion2.Z) + (quaternion2.W * quaternion2.W));
- double w4 = -quaternion2.X * w5;
- double w3 = -quaternion2.Y * w5;
- double w2 = -quaternion2.Z * w5;
- double w1 = quaternion2.W * w5;
- result.X = (float)((quaternion1.X * w1) + (w4 * quaternion1.W) + ((quaternion1.Y * w2) - (quaternion1.Z * w3)));
- result.Y = (float)((quaternion1.Y * w1) + (w3 * quaternion1.W) + ((quaternion1.Z * w4) - (quaternion1.X * w2)));
- result.Z = (float)((quaternion1.Z * w1) + (w2 * quaternion1.W) + ((quaternion1.X * w3) - (quaternion1.Y * w4)));
- result.W = (float)((quaternion1.W * quaternion2.W * w5) - ((quaternion1.X * w4) + (quaternion1.Y * w3) + (quaternion1.Z * w2)));
- return result;
- }
- public static bool operator ==(Quaternion quaternion1, Quaternion quaternion2)
- {
- return quaternion1.X == quaternion2.X
- && quaternion1.Y == quaternion2.Y
- && quaternion1.Z == quaternion2.Z
- && quaternion1.W == quaternion2.W;
- }
- public static bool operator !=(Quaternion quaternion1, Quaternion quaternion2)
- {
- return !(quaternion1 == quaternion2);
- }
- public static Quaternion operator *(Quaternion quaternion1, Quaternion quaternion2)
- {
- Quaternion result;
- double f12 = (quaternion1.Y * quaternion2.Z) - (quaternion1.Z * quaternion2.Y);
- double f11 = (quaternion1.Z * quaternion2.X) - (quaternion1.X * quaternion2.Z);
- double f10 = (quaternion1.X * quaternion2.Y) - (quaternion1.Y * quaternion2.X);
- double f9 = (quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y) + (quaternion1.Z * quaternion2.Z);
- result.X = (float)((quaternion1.X * quaternion2.W) + (quaternion2.X * quaternion1.W) + f12);
- result.Y = (float)((quaternion1.Y * quaternion2.W) + (quaternion2.Y * quaternion1.W) + f11);
- result.Z = (float)((quaternion1.Z * quaternion2.W) + (quaternion2.Z * quaternion1.W) + f10);
- result.W = (float)((quaternion1.W * quaternion2.W) - f9);
- return result;
- }
- public static Quaternion operator *(Quaternion quaternion1, float scaleFactor)
- {
- Quaternion result;
- result.X = quaternion1.X * scaleFactor;
- result.Y = quaternion1.Y * scaleFactor;
- result.Z = quaternion1.Z * scaleFactor;
- result.W = quaternion1.W * scaleFactor;
- return result;
- }
- public static Quaternion operator -(Quaternion quaternion1, Quaternion quaternion2)
- {
- return new Quaternion(quaternion1.X - quaternion2.X, quaternion1.Y - quaternion2.Y, quaternion1.Z - quaternion2.Z, quaternion1.W - quaternion2.W);
- }
- public static Quaternion operator -(Quaternion quaternion)
- {
- Quaternion q1;
- q1.X = -quaternion.X;
- q1.Y = -quaternion.Y;
- q1.Z = -quaternion.Z;
- q1.W = -quaternion.W;
- return q1;
- }
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder(32);
- sb.Append("{X:");
- sb.Append(this.X);
- sb.Append(" Y:");
- sb.Append(this.Y);
- sb.Append(" Z:");
- sb.Append(this.Z);
- sb.Append(" W:");
- sb.Append(this.W);
- sb.Append("}");
- return sb.ToString();
- }
- }
- }