@@ -377,6 +377,41 @@ public void Sub(ref readonly Quaternion quaternion2)
377377 }
378378 }
379379
380+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
381+ public readonly Quaternion Multiply ( ref readonly Quaternion b )
382+ {
383+ //if (MathF.Abs(W) > (1.0f - 1e-6f))
384+ // return b;
385+
386+ return new Quaternion (
387+ W * b . X + X * b . W + Y * b . Z - Z * b . Y ,
388+ W * b . Y + Y * b . W + Z * b . X - X * b . Z ,
389+ W * b . Z + Z * b . W + X * b . Y - Y * b . X ,
390+ W * b . W - X * b . X - Y * b . Y - Z * b . Z
391+ ) ;
392+ }
393+
394+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
395+ public void MultiplySelf ( ref readonly Quaternion b )
396+ {
397+ if ( MathF . Abs ( W ) > ( 1.0f - 1e-6f ) )
398+
399+ {
400+ X = b . X ;
401+ Y = b . Y ;
402+ Z = b . Z ;
403+ W = b . W ;
404+ return ;
405+ }
406+ float x = W * b . X + X * b . W + Y * b . Z - Z * b . Y ;
407+ float y = W * b . Y + Y * b . W + Z * b . X - X * b . Z ;
408+ float z = W * b . Z + Z * b . W + X * b . Y - Y * b . X ;
409+ W = W * b . W - X * b . X - Y * b . Y - Z * b . Z ;
410+ X = x ;
411+ Y = y ;
412+ Z = z ;
413+ }
414+
380415 /// <summary>
381416 /// Builds a quaternion object from a byte array
382417 /// </summary>
@@ -701,11 +736,11 @@ public static Quaternion Add(ref readonly Quaternion quaternion1, ref readonly Q
701736 /// Returns the conjugate (spatial inverse) of a quaternion
702737 /// </summary>
703738 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
704- public static Quaternion Conjugate( in Quaternion quaternion )
739+ public static Quaternion Conjugate( ref readonly Quaternion quaternion )
705740 {
706741 if ( Sse . IsSupported )
707742 {
708- Vector128 < float > d = Unsafe. As< Quaternion, Vector128< float >> ( ref Unsafe . AsRef ( quaternion ) ) ;
743+ Vector128 < float > d = Unsafe. As< Quaternion, Vector128< float >> ( ref Unsafe . AsRef ( in quaternion ) ) ;
709744 Vector128 < float > Mask = Vector128. Create( 0x80000000 , 0x80000000 , 0x80000000 , 0 ) . AsSingle( ) ;
710745 d = Sse . Xor ( d , Mask ) ;
711746 return new Quaternion( ref d ) ;
@@ -733,13 +768,14 @@ public static Quaternion CreateFromAxisAngle(float axisX, float axisY, float axi
733768 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
734769 public static Quaternion CreateFromAxisAngle( Vector3 axis , float angle )
735770 {
736- axis. Normalize ( ) ;
737-
738771 angle *= 0.5f ;
739- float c = MathF. Cos ( angle ) ;
740772 float s = MathF. Sin ( angle ) ;
741773
742- return new Quaternion( axis . X * s , axis . Y * s , axis . Z * s , c ) ;
774+ axis. Normalize ( ) ;
775+ axis *= s;
776+
777+ float c = MathF. Cos ( angle ) ;
778+ return new Quaternion( axis . X , axis . Y , axis . Z , c ) ;
743779 }
744780
745781 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -834,7 +870,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix)
834870 }
835871 if ( ( matrix . M11 >= matrix . M22 ) && ( matrix . M11 >= matrix . M33 ) )
836872 {
837- num = MathF. Sqrt ( ( ( ( 1f + matrix . M11 ) - matrix . M22 ) - matrix . M33 ) ) ;
873+ num = MathF. Sqrt ( 1f + matrix . M11 - matrix . M22 - matrix . M33 ) ;
838874 n2 = 0.5f / num ;
839875 return new Quaternion (
840876 0.5f * num ,
@@ -844,7 +880,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix)
844880 }
845881 if ( matrix . M22 > matrix . M33 )
846882 {
847- num = MathF. Sqrt ( ( ( ( 1f + matrix . M22 ) - matrix . M11 ) - matrix . M33 ) ) ;
883+ num = MathF. Sqrt ( 1f - matrix . M11 + matrix . M22 - matrix . M33 ) ;
848884 n2 = 0.5f / num ;
849885 return new Quaternion (
850886 ( matrix . M21 + matrix . M12 ) * n2 ,
@@ -853,7 +889,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix3x3 matrix)
853889 ( matrix . M31 - matrix . M13 ) * n2 ) ;
854890 }
855891
856- num = MathF . Sqrt ( ( ( ( 1f + matrix . M33 ) - matrix . M11 ) - matrix . M22 ) ) ;
892+ num = MathF . Sqrt ( 1f - matrix . M11 - matrix . M22 + matrix . M33 ) ;
857893 n2 = 0.5f / num ;
858894 return new Quaternion (
859895 ( matrix . M31 + matrix . M13 ) * n2 ,
@@ -868,7 +904,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix)
868904 float n2 ;
869905 if ( num > = 0f )
870906 {
871- num = MathF . Sqrt ( ( num + 1f ) ) ;
907+ num = MathF . Sqrt ( 1f + num ) ;
872908 n2 = 0.5f / num ;
873909 return new Quaternion (
874910 ( matrix . M23 - matrix . M32 ) * n2 ,
@@ -878,7 +914,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix)
878914 }
879915 if ( ( matrix . M11 >= matrix . M22 ) && ( matrix . M11 >= matrix . M33 ) )
880916 {
881- num = MathF. Sqrt ( ( ( ( 1f + matrix . M11 ) - matrix . M22 ) - matrix . M33 ) ) ;
917+ num = MathF. Sqrt ( 1f + matrix . M11 - matrix . M22 - matrix . M33 ) ;
882918 n2 = 0.5f / num ;
883919 return new Quaternion (
884920 0.5f * num ,
@@ -888,7 +924,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix)
888924 }
889925 if ( matrix . M22 > matrix . M33 )
890926 {
891- num = MathF. Sqrt ( ( ( ( 1f + matrix . M22 ) - matrix . M11 ) - matrix . M33 ) ) ;
927+ num = MathF. Sqrt ( 1f - matrix . M11 + matrix . M22 - matrix . M33 ) ;
892928 n2 = 0.5f / num ;
893929 return new Quaternion (
894930 ( matrix . M21 + matrix . M12 ) * n2 ,
@@ -897,7 +933,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix)
897933 ( matrix . M31 - matrix . M13 ) * n2 ) ;
898934 }
899935
900- num = MathF . Sqrt ( ( ( ( 1f + matrix . M33 ) - matrix . M11 ) - matrix . M22 ) ) ;
936+ num = MathF . Sqrt ( 1f - matrix . M11 - matrix . M22 + matrix . M33 ) ;
901937 n2 = 0.5f / num ;
902938 return new Quaternion (
903939 ( matrix . M31 + matrix . M13 ) * n2 ,
@@ -909,7 +945,7 @@ public static Quaternion CreateFromRotationMatrix(Matrix4 matrix)
909945 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
910946 public static Quaternion Divide ( Quaternion q1 , Quaternion q2 )
911947 {
912- return Quaternion . Inverse( q1 ) * q2;
948+ return Inverse ( q1 ) * q2;
913949 }
914950
915951 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -932,9 +968,8 @@ public static float Dot(Quaternion q1, Quaternion q2)
932968 public static Quaternion Inverse( Quaternion quaternion )
933969 {
934970 float normsq = quaternion. LengthSquared ( ) ;
935-
936971 if ( normsq < 1e-6f )
937- return Quaternion . Identity ;
972+ return Identity;
938973
939974 float oonorm = - 1f / normsq ;
940975 return new Quaternion (
@@ -1008,7 +1043,7 @@ public static Quaternion Subtract(Quaternion quaternion1, Quaternion quaternion2
10081043 }
10091044
10101045 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1011- public static Quaternion Multiply( Quaternion a , Quaternion b )
1046+ public static Quaternion Multiply( ref readonly Quaternion a , ref readonly Quaternion b )
10121047 {
10131048 return new Quaternion (
10141049 a . W * b . X + a. X * b. W + a. Y * b. Z - a. Z * b. Y,
@@ -1019,7 +1054,7 @@ public static Quaternion Multiply(Quaternion a, Quaternion b)
10191054 }
10201055
10211056 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1022- public static Quaternion Multiply( Quaternion quaternion , float scaleFactor )
1057+ public static Quaternion Multiply( ref readonly Quaternion quaternion , float scaleFactor )
10231058 {
10241059 return new Quaternion (
10251060 quaternion . X * scaleFactor ,
@@ -1401,6 +1436,8 @@ public readonly string ToRawString()
14011436 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
14021437 public static Quaternion operator * ( Quaternion a , Quaternion b )
14031438 {
1439+ if ( MathF . Abs ( a . W ) > ( 1.0f - 1e-6f ) ) return b;
1440+ if ( MathF . Abs ( b . W ) > ( 1.0f - 1e-6f ) ) return a;
14041441 return new Quaternion(
14051442 a . W * b . X + a. X * b. W + a. Y * b. Z - a. Z * b. Y,
14061443 a . W * b . Y + a. Y * b. W + a. Z * b. X - a. X * b. Z,
0 commit comments