2 Copyright (c) 2006 - 2008 The Open Toolkit library.
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in
6 the Software without restriction, including without limitation the rights to
7 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 of the Software, and to permit persons to whom the Software is furnished to do
9 so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 using System.Runtime.InteropServices;
29 /// Represents a 3x3 matrix containing 3D rotation and scale.
32 [StructLayout(LayoutKind.Sequential)]
33 public struct Matrix3 : IEquatable<Matrix3>
36 /// First row of the matrix.
41 /// Second row of the matrix.
46 /// Third row of the matrix.
51 /// The identity matrix.
53 public static readonly Matrix3 Identity = new Matrix3(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ);
58 public static readonly Matrix3 Zero = new Matrix3(Vector3.Zero, Vector3.Zero, Vector3.Zero);
63 /// Constructs a new instance.
65 /// <param name="row0">Top row of the matrix</param>
66 /// <param name="row1">Second row of the matrix</param>
67 /// <param name="row2">Bottom row of the matrix</param>
68 public Matrix3(Vector3 row0, Vector3 row1, Vector3 row2)
76 /// Constructs a new instance.
78 /// <param name="m00">First item of the first row of the matrix.</param>
79 /// <param name="m01">Second item of the first row of the matrix.</param>
80 /// <param name="m02">Third item of the first row of the matrix.</param>
81 /// <param name="m10">First item of the second row of the matrix.</param>
82 /// <param name="m11">Second item of the second row of the matrix.</param>
83 /// <param name="m12">Third item of the second row of the matrix.</param>
84 /// <param name="m20">First item of the third row of the matrix.</param>
85 /// <param name="m21">Second item of the third row of the matrix.</param>
86 /// <param name="m22">Third item of the third row of the matrix.</param>
88 float m00, float m01, float m02,
89 float m10, float m11, float m12,
90 float m20, float m21, float m22)
92 Row0 = new Vector3(m00, m01, m02);
93 Row1 = new Vector3(m10, m11, m12);
94 Row2 = new Vector3(m20, m21, m22);
98 /// Constructs a new instance.
100 /// <param name="matrix">A Matrix4 to take the upper-left 3x3 from.</param>
101 public Matrix3(Matrix4 matrix)
103 Row0 = matrix.Row0.Xyz;
104 Row1 = matrix.Row1.Xyz;
105 Row2 = matrix.Row2.Xyz;
112 /// Gets the determinant of this matrix.
114 public float Determinant
118 float m11 = Row0.X, m12 = Row0.Y, m13 = Row0.Z,
119 m21 = Row1.X, m22 = Row1.Y, m23 = Row1.Z,
120 m31 = Row2.X, m32 = Row2.Y, m33 = Row2.Z;
122 return m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32
123 - m13 * m22 * m31 - m11 * m23 * m32 - m12 * m21 * m33;
128 /// Gets the first column of this matrix.
130 public Vector3 Column0
132 get { return new Vector3(Row0.X, Row1.X, Row2.X); }
136 /// Gets the second column of this matrix.
138 public Vector3 Column1
140 get { return new Vector3(Row0.Y, Row1.Y, Row2.Y); }
144 /// Gets the third column of this matrix.
146 public Vector3 Column2
148 get { return new Vector3(Row0.Z, Row1.Z, Row2.Z); }
152 /// Gets or sets the value at row 1, column 1 of this instance.
154 public float M11 { get { return Row0.X; } set { Row0.X = value; } }
157 /// Gets or sets the value at row 1, column 2 of this instance.
159 public float M12 { get { return Row0.Y; } set { Row0.Y = value; } }
162 /// Gets or sets the value at row 1, column 3 of this instance.
164 public float M13 { get { return Row0.Z; } set { Row0.Z = value; } }
167 /// Gets or sets the value at row 2, column 1 of this instance.
169 public float M21 { get { return Row1.X; } set { Row1.X = value; } }
172 /// Gets or sets the value at row 2, column 2 of this instance.
174 public float M22 { get { return Row1.Y; } set { Row1.Y = value; } }
177 /// Gets or sets the value at row 2, column 3 of this instance.
179 public float M23 { get { return Row1.Z; } set { Row1.Z = value; } }
182 /// Gets or sets the value at row 3, column 1 of this instance.
184 public float M31 { get { return Row2.X; } set { Row2.X = value; } }
187 /// Gets or sets the value at row 3, column 2 of this instance.
189 public float M32 { get { return Row2.Y; } set { Row2.Y = value; } }
192 /// Gets or sets the value at row 3, column 3 of this instance.
194 public float M33 { get { return Row2.Z; } set { Row2.Z = value; } }
197 /// Gets or sets the values along the main diagonal of the matrix.
199 public Vector3 Diagonal
203 return new Vector3(Row0.X, Row1.Y, Row2.Z);
214 /// Gets the trace of the matrix, the sum of the values along the diagonal.
216 public float Trace { get { return Row0.X + Row1.Y + Row2.Z; } }
220 /// Gets or sets the value at a specified row and column.
222 public float this[int rowIndex, int columnIndex]
228 return Row0[columnIndex];
230 else if (rowIndex == 1)
232 return Row1[columnIndex];
234 else if (rowIndex == 2)
236 return Row2[columnIndex];
238 throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")");
244 Row0[columnIndex] = value;
246 else if (rowIndex == 1)
248 Row1[columnIndex] = value;
250 else if (rowIndex == 2)
252 Row2[columnIndex] = value;
256 throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")");
262 /// Converts this instance into its inverse.
266 this = Matrix3.Invert(this);
272 /// Converts this instance into its transpose.
274 public void Transpose()
276 this = Matrix3.Transpose(this);
281 /// Returns a normalised copy of this instance.
283 public Matrix3 Normalized()
291 /// Divides each element in the Matrix by the <see cref="Determinant"/>.
293 public void Normalize()
295 var determinant = this.Determinant;
302 /// Returns an inverted copy of this instance.
304 public Matrix3 Inverted()
307 if (m.Determinant != 0)
315 /// Returns a copy of this Matrix3 without scale.
317 public Matrix3 ClearScale()
320 m.Row0 = m.Row0.Normalized();
321 m.Row1 = m.Row1.Normalized();
322 m.Row2 = m.Row2.Normalized();
326 /// Returns a copy of this Matrix3 without rotation.
328 public Matrix3 ClearRotation()
331 m.Row0 = new Vector3(m.Row0.Length, 0, 0);
332 m.Row1 = new Vector3(0, m.Row1.Length, 0);
333 m.Row2 = new Vector3(0, 0, m.Row2.Length);
338 /// Returns the scale component of this instance.
340 public Vector3 ExtractScale() { return new Vector3(Row0.Length, Row1.Length, Row2.Length); }
343 /// Returns the rotation component of this instance. Quite slow.
345 /// <param name="row_normalise">Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.</param>
346 public Quaternion ExtractRotation(bool row_normalise = true)
354 row0 = row0.Normalized();
355 row1 = row1.Normalized();
356 row2 = row2.Normalized();
359 // code below adapted from Blender
361 Quaternion q = new Quaternion();
362 double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
366 double sq = Math.Sqrt(trace);
369 sq = 1.0 / (4.0 * sq);
370 q.X = (float)((row1[2] - row2[1]) * sq);
371 q.Y = (float)((row2[0] - row0[2]) * sq);
372 q.Z = (float)((row0[1] - row1[0]) * sq);
374 else if (row0[0] > row1[1] && row0[0] > row2[2])
376 double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]);
378 q.X = (float)(0.25 * sq);
380 q.W = (float)((row2[1] - row1[2]) * sq);
381 q.Y = (float)((row1[0] + row0[1]) * sq);
382 q.Z = (float)((row2[0] + row0[2]) * sq);
384 else if (row1[1] > row2[2])
386 double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]);
388 q.Y = (float)(0.25 * sq);
390 q.W = (float)((row2[0] - row0[2]) * sq);
391 q.X = (float)((row1[0] + row0[1]) * sq);
392 q.Z = (float)((row2[1] + row1[2]) * sq);
396 double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]);
398 q.Z = (float)(0.25 * sq);
400 q.W = (float)((row1[0] - row0[1]) * sq);
401 q.X = (float)((row2[0] + row0[2]) * sq);
402 q.Y = (float)((row2[1] + row1[2]) * sq);
412 /// Build a rotation matrix from the specified axis/angle rotation.
414 /// <param name="axis">The axis to rotate about.</param>
415 /// <param name="angle">Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).</param>
416 /// <param name="result">A matrix instance.</param>
417 public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix3 result)
419 //normalize and create a local copy of the vector.
421 float axisX = axis.X, axisY = axis.Y, axisZ = axis.Z;
424 float cos = (float)System.Math.Cos(-angle);
425 float sin = (float)System.Math.Sin(-angle);
426 float t = 1.0f - cos;
428 //do the conversion math once
429 float tXX = t * axisX * axisX,
430 tXY = t * axisX * axisY,
431 tXZ = t * axisX * axisZ,
432 tYY = t * axisY * axisY,
433 tYZ = t * axisY * axisZ,
434 tZZ = t * axisZ * axisZ;
436 float sinX = sin * axisX,
440 result.Row0.X = tXX + cos;
441 result.Row0.Y = tXY - sinZ;
442 result.Row0.Z = tXZ + sinY;
443 result.Row1.X = tXY + sinZ;
444 result.Row1.Y = tYY + cos;
445 result.Row1.Z = tYZ - sinX;
446 result.Row2.X = tXZ - sinY;
447 result.Row2.Y = tYZ + sinX;
448 result.Row2.Z = tZZ + cos;
452 /// Build a rotation matrix from the specified axis/angle rotation.
454 /// <param name="axis">The axis to rotate about.</param>
455 /// <param name="angle">Angle in radians to rotate counter-clockwise (looking in the direction of the given axis).</param>
456 /// <returns>A matrix instance.</returns>
457 public static Matrix3 CreateFromAxisAngle(Vector3 axis, float angle)
460 CreateFromAxisAngle(axis, angle, out result);
467 /// Build a rotation matrix from the specified quaternion.
469 /// <param name="q">Quaternion to translate.</param>
470 /// <param name="result">Matrix result.</param>
471 public static void CreateFromQuaternion(ref Quaternion q, out Matrix3 result)
475 q.ToAxisAngle(out axis, out angle);
476 CreateFromAxisAngle(axis, angle, out result);
480 /// Build a rotation matrix from the specified quaternion.
482 /// <param name="q">Quaternion to translate.</param>
483 /// <returns>A matrix instance.</returns>
484 public static Matrix3 CreateFromQuaternion(Quaternion q)
487 CreateFromQuaternion(ref q, out result);
494 /// Builds a rotation matrix for a rotation around the x-axis.
496 /// <param name="angle">The counter-clockwise angle in radians.</param>
497 /// <param name="result">The resulting Matrix3 instance.</param>
498 public static void CreateRotationX(float angle, out Matrix3 result)
500 float cos = (float)System.Math.Cos(angle);
501 float sin = (float)System.Math.Sin(angle);
506 result.Row2.Y = -sin;
511 /// Builds a rotation matrix for a rotation around the x-axis.
513 /// <param name="angle">The counter-clockwise angle in radians.</param>
514 /// <returns>The resulting Matrix3 instance.</returns>
515 public static Matrix3 CreateRotationX(float angle)
518 CreateRotationX(angle, out result);
523 /// Builds a rotation matrix for a rotation around the y-axis.
525 /// <param name="angle">The counter-clockwise angle in radians.</param>
526 /// <param name="result">The resulting Matrix3 instance.</param>
527 public static void CreateRotationY(float angle, out Matrix3 result)
529 float cos = (float)System.Math.Cos(angle);
530 float sin = (float)System.Math.Sin(angle);
534 result.Row0.Z = -sin;
540 /// Builds a rotation matrix for a rotation around the y-axis.
542 /// <param name="angle">The counter-clockwise angle in radians.</param>
543 /// <returns>The resulting Matrix3 instance.</returns>
544 public static Matrix3 CreateRotationY(float angle)
547 CreateRotationY(angle, out result);
552 /// Builds a rotation matrix for a rotation around the z-axis.
554 /// <param name="angle">The counter-clockwise angle in radians.</param>
555 /// <param name="result">The resulting Matrix3 instance.</param>
556 public static void CreateRotationZ(float angle, out Matrix3 result)
558 float cos = (float)System.Math.Cos(angle);
559 float sin = (float)System.Math.Sin(angle);
564 result.Row1.X = -sin;
569 /// Builds a rotation matrix for a rotation around the z-axis.
571 /// <param name="angle">The counter-clockwise angle in radians.</param>
572 /// <returns>The resulting Matrix3 instance.</returns>
573 public static Matrix3 CreateRotationZ(float angle)
576 CreateRotationZ(angle, out result);
583 /// Creates a scale matrix.
585 /// <param name="scale">Single scale factor for the x, y, and z axes.</param>
586 /// <returns>A scale matrix.</returns>
587 public static Matrix3 CreateScale(float scale)
590 CreateScale(scale, out result);
595 /// Creates a scale matrix.
597 /// <param name="scale">Scale factors for the x, y, and z axes.</param>
598 /// <returns>A scale matrix.</returns>
599 public static Matrix3 CreateScale(Vector3 scale)
602 CreateScale(ref scale, out result);
607 /// Creates a scale matrix.
609 /// <param name="x">Scale factor for the x axis.</param>
610 /// <param name="y">Scale factor for the y axis.</param>
611 /// <param name="z">Scale factor for the z axis.</param>
612 /// <returns>A scale matrix.</returns>
613 public static Matrix3 CreateScale(float x, float y, float z)
616 CreateScale(x, y, z, out result);
621 /// Creates a scale matrix.
623 /// <param name="scale">Single scale factor for the x, y, and z axes.</param>
624 /// <param name="result">A scale matrix.</param>
625 public static void CreateScale(float scale, out Matrix3 result)
628 result.Row0.X = scale;
629 result.Row1.Y = scale;
630 result.Row2.Z = scale;
634 /// Creates a scale matrix.
636 /// <param name="scale">Scale factors for the x, y, and z axes.</param>
637 /// <param name="result">A scale matrix.</param>
638 public static void CreateScale(ref Vector3 scale, out Matrix3 result)
641 result.Row0.X = scale.X;
642 result.Row1.Y = scale.Y;
643 result.Row2.Z = scale.Z;
647 /// Creates a scale matrix.
649 /// <param name="x">Scale factor for the x axis.</param>
650 /// <param name="y">Scale factor for the y axis.</param>
651 /// <param name="z">Scale factor for the z axis.</param>
652 /// <param name="result">A scale matrix.</param>
653 public static void CreateScale(float x, float y, float z, out Matrix3 result)
663 /// Adds two instances.
665 /// <param name="left">The left operand of the addition.</param>
666 /// <param name="right">The right operand of the addition.</param>
667 /// <returns>A new instance that is the result of the addition.</returns>
668 public static Matrix3 Add(Matrix3 left, Matrix3 right)
671 Add(ref left, ref right, out result);
676 /// Adds two instances.
678 /// <param name="left">The left operand of the addition.</param>
679 /// <param name="right">The right operand of the addition.</param>
680 /// <param name="result">A new instance that is the result of the addition.</param>
681 public static void Add(ref Matrix3 left, ref Matrix3 right, out Matrix3 result)
683 Vector3.Add(ref left.Row0, ref right.Row0, out result.Row0);
684 Vector3.Add(ref left.Row1, ref right.Row1, out result.Row1);
685 Vector3.Add(ref left.Row2, ref right.Row2, out result.Row2);
689 /// Multiplies two instances.
691 /// <param name="left">The left operand of the multiplication.</param>
692 /// <param name="right">The right operand of the multiplication.</param>
693 /// <returns>A new instance that is the result of the multiplication</returns>
694 public static Matrix3 Mult(Matrix3 left, Matrix3 right)
697 Mult(ref left, ref right, out result);
702 /// Multiplies two instances.
704 /// <param name="left">The left operand of the multiplication.</param>
705 /// <param name="right">The right operand of the multiplication.</param>
706 /// <param name="result">A new instance that is the result of the multiplication</param>
707 public static void Mult(ref Matrix3 left, ref Matrix3 right, out Matrix3 result)
709 float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z,
710 lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z,
711 lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z,
712 rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z,
713 rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z,
714 rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z;
716 result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31);
717 result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32);
718 result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33);
719 result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31);
720 result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32);
721 result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33);
722 result.Row2.X = ((lM31 * rM11) + (lM32 * rM21)) + (lM33 * rM31);
723 result.Row2.Y = ((lM31 * rM12) + (lM32 * rM22)) + (lM33 * rM32);
724 result.Row2.Z = ((lM31 * rM13) + (lM32 * rM23)) + (lM33 * rM33);
730 /// Calculate the inverse of the given matrix
732 /// <param name="mat">The matrix to invert</param>
733 /// <param name="result">The inverse of the given matrix if it has one, or the input if it is singular</param>
734 /// <exception cref="InvalidOperationException">Thrown if the Matrix3 is singular.</exception>
735 public static void Invert(ref Matrix3 mat, out Matrix3 result)
737 int[] colIdx = { 0, 0, 0 };
738 int[] rowIdx = { 0, 0, 0 };
739 int[] pivotIdx = { -1, -1, -1 };
741 float[,] inverse = {{mat.Row0.X, mat.Row0.Y, mat.Row0.Z},
742 {mat.Row1.X, mat.Row1.Y, mat.Row1.Z},
743 {mat.Row2.X, mat.Row2.Y, mat.Row2.Z}};
747 for (int i = 0; i < 3; i++)
749 float maxPivot = 0.0f;
750 for (int j = 0; j < 3; j++)
752 if (pivotIdx[j] != 0)
754 for (int k = 0; k < 3; ++k)
756 if (pivotIdx[k] == -1)
758 float absVal = System.Math.Abs(inverse[j, k]);
759 if (absVal > maxPivot)
766 else if (pivotIdx[k] > 0)
779 for (int k = 0; k < 3; ++k)
781 float f = inverse[irow, k];
782 inverse[irow, k] = inverse[icol, k];
783 inverse[icol, k] = f;
790 float pivot = inverse[icol, icol];
794 throw new InvalidOperationException("Matrix is singular and cannot be inverted.");
797 float oneOverPivot = 1.0f / pivot;
798 inverse[icol, icol] = 1.0f;
799 for (int k = 0; k < 3; ++k)
801 inverse[icol, k] *= oneOverPivot;
804 for (int j = 0; j < 3; ++j)
808 float f = inverse[j, icol];
809 inverse[j, icol] = 0.0f;
810 for (int k = 0; k < 3; ++k)
812 inverse[j, k] -= inverse[icol, k] * f;
818 for (int j = 2; j >= 0; --j)
822 for (int k = 0; k < 3; ++k)
824 float f = inverse[k, ir];
825 inverse[k, ir] = inverse[k, ic];
830 result.Row0.X = inverse[0, 0];
831 result.Row0.Y = inverse[0, 1];
832 result.Row0.Z = inverse[0, 2];
833 result.Row1.X = inverse[1, 0];
834 result.Row1.Y = inverse[1, 1];
835 result.Row1.Z = inverse[1, 2];
836 result.Row2.X = inverse[2, 0];
837 result.Row2.Y = inverse[2, 1];
838 result.Row2.Z = inverse[2, 2];
842 /// Calculate the inverse of the given matrix
844 /// <param name="mat">The matrix to invert</param>
845 /// <returns>The inverse of the given matrix if it has one, or the input if it is singular</returns>
846 /// <exception cref="InvalidOperationException">Thrown if the Matrix4 is singular.</exception>
847 public static Matrix3 Invert(Matrix3 mat)
850 Invert(ref mat, out result);
857 /// Calculate the transpose of the given matrix
859 /// <param name="mat">The matrix to transpose</param>
860 /// <returns>The transpose of the given matrix</returns>
861 public static Matrix3 Transpose(Matrix3 mat)
863 return new Matrix3(mat.Column0, mat.Column1, mat.Column2);
867 /// Calculate the transpose of the given matrix
869 /// <param name="mat">The matrix to transpose</param>
870 /// <param name="result">The result of the calculation</param>
871 public static void Transpose(ref Matrix3 mat, out Matrix3 result)
873 result.Row0.X = mat.Row0.X;
874 result.Row0.Y = mat.Row1.X;
875 result.Row0.Z = mat.Row2.X;
876 result.Row1.X = mat.Row0.Y;
877 result.Row1.Y = mat.Row1.Y;
878 result.Row1.Z = mat.Row2.Y;
879 result.Row2.X = mat.Row0.Z;
880 result.Row2.Y = mat.Row1.Z;
881 result.Row2.Z = mat.Row2.Z;
888 /// Matrix multiplication
890 /// <param name="left">left-hand operand</param>
891 /// <param name="right">right-hand operand</param>
892 /// <returns>A new Matrix3d which holds the result of the multiplication</returns>
893 public static Matrix3 operator *(Matrix3 left, Matrix3 right)
895 return Matrix3.Mult(left, right);
899 /// Compares two instances for equality.
901 /// <param name="left">The first instance.</param>
902 /// <param name="right">The second instance.</param>
903 /// <returns>True, if left equals right; false otherwise.</returns>
904 public static bool operator ==(Matrix3 left, Matrix3 right)
906 return left.Equals(right);
910 /// Compares two instances for inequality.
912 /// <param name="left">The first instance.</param>
913 /// <param name="right">The second instance.</param>
914 /// <returns>True, if left does not equal right; false otherwise.</returns>
915 public static bool operator !=(Matrix3 left, Matrix3 right)
917 return !left.Equals(right);
924 /// Returns a System.String that represents the current Matrix3d.
926 /// <returns>The string representation of the matrix.</returns>
927 public override string ToString()
929 return String.Format("{0}\n{1}\n{2}", Row0, Row1, Row2);
935 /// Returns the hashcode for this instance.
937 /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
938 public override int GetHashCode()
942 var hashCode = this.Row0.GetHashCode();
943 hashCode = (hashCode * 397) ^ this.Row1.GetHashCode();
944 hashCode = (hashCode * 397) ^ this.Row2.GetHashCode();
952 /// Indicates whether this instance and a specified object are equal.
954 /// <param name="obj">The object to compare to.</param>
955 /// <returns>True if the instances are equal; false otherwise.</returns>
956 public override bool Equals(object obj)
958 if (!(obj is Matrix3))
963 return this.Equals((Matrix3)obj);
970 /// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
971 /// <param name="other">A matrix to compare with this matrix.</param>
972 /// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
973 public bool Equals(Matrix3 other)
976 Row0 == other.Row0 &&
977 Row1 == other.Row1 &&