Index: Source/OpenTK/Math/Matrix3.cs =================================================================== --- Source/OpenTK/Math/Matrix3.cs (revision 0) +++ Source/OpenTK/Math/Matrix3.cs (revision 0) @@ -0,0 +1,691 @@ +#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 OpenTK; + +namespace OpenTK +{ + /// + /// Represents a 3x3 Matrix. + /// + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Matrix3 : IEquatable + { + #region Fields + + /// + /// Top row of the matrix + /// + public Vector3 Row0; + /// + /// 2nd row of the matrix + /// + public Vector3 Row1; + /// + /// 3rd row of the matrix + /// + public Vector3 Row2; + + /// + /// The identity matrix + /// + public static Matrix3 Identity = new Matrix3(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ); + + #endregion + + #region Constructors + + /// + /// Constructs a new instance. + /// + /// Top row of the matrix + /// Second row of the matrix + /// Third row of the matrix + public Matrix3(Vector3 row0, Vector3 row1, Vector3 row2) + { + Row0 = row0; + Row1 = row1; + Row2 = row2; + } + + /// + /// Constructs a new instance. + /// + /// First item of the first row of the matrix. + /// Second item of the first row of the matrix. + /// Third item of the first row of the matrix. + /// First item of the second row of the matrix. + /// Second item of the second row of the matrix. + /// Third item of the second row of the matrix. + /// First item of the third row of the matrix. + /// Second item of the third row of the matrix. + /// Third item of the third row of the matrix. + public Matrix3( + float m00, float m01, float m02, + float m10, float m11, float m12, + float m20, float m21, float m22) + { + Row0 = new Vector3(m00, m01, m02); + Row1 = new Vector3(m10, m11, m12); + Row2 = new Vector3(m20, m21, m22); + } + + #endregion + + #region Public Members + + #region Properties + + /// + /// Not implemented! + /// + /// The determinant of this matrix + /// + public float Determinant + { + get + { + throw new NotImplementedException(); + /*return + Row0.X * Row1.Y * Row2.Z * Row3.W - Row0.X * Row1.Y * Row2.W * Row3.Z + Row0.X * Row1.Z * Row2.W * Row3.Y - Row0.X * Row1.Z * Row2.Y * Row3.W + + Row0.X * Row1.W * Row2.Y * Row3.Z - Row0.X * Row1.W * Row2.Z * Row3.Y - Row0.Y * Row1.Z * Row2.W * Row3.X + Row0.Y * Row1.Z * Row2.X * Row3.W + - Row0.Y * Row1.W * Row2.X * Row3.Z + Row0.Y * Row1.W * Row2.Z * Row3.X - Row0.Y * Row1.X * Row2.Z * Row3.W + Row0.Y * Row1.X * Row2.W * Row3.Z + + Row0.Z * Row1.W * Row2.X * Row3.Y - Row0.Z * Row1.W * Row2.Y * Row3.X + Row0.Z * Row1.X * Row2.Y * Row3.W - Row0.Z * Row1.X * Row2.W * Row3.Y + + Row0.Z * Row1.Y * Row2.W * Row3.X - Row0.Z * Row1.Y * Row2.X * Row3.W - Row0.W * Row1.X * Row2.Y * Row3.Z + Row0.W * Row1.X * Row2.Z * Row3.Y + - Row0.W * Row1.Y * Row2.Z * Row3.X + Row0.W * Row1.Y * Row2.X * Row3.Z - Row0.W * Row1.Z * Row2.X * Row3.Y + Row0.W * Row1.Z * Row2.Y * Row3.X;*/ + } + } + + /// + /// The first column of this matrix + /// + public Vector3 Column0 + { + get { return new Vector3(Row0.X, Row1.X, Row2.X); } + } + + /// + /// The second column of this matrix + /// + public Vector3 Column1 + { + get { return new Vector3(Row0.Y, Row1.Y, Row2.Y); } + } + + /// + /// The third column of this matrix + /// + public Vector3 Column2 + { + get { return new Vector3(Row0.Z, Row1.Z, Row2.Z); } + } + + /// + /// Gets or sets the value at row 1, column 1 of this instance. + /// + public float M11 { get { return Row0.X; } set { Row0.X = value; } } + + /// + /// Gets or sets the value at row 1, column 2 of this instance. + /// + public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } + + /// + /// Gets or sets the value at row 1, column 3 of this instance. + /// + public float M13 { get { return Row0.Z; } set { Row0.Z = value; } } + + /// + /// Gets or sets the value at row 2, column 1 of this instance. + /// + public float M21 { get { return Row1.X; } set { Row1.X = value; } } + + /// + /// Gets or sets the value at row 2, column 2 of this instance. + /// + public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } + + /// + /// Gets or sets the value at row 2, column 3 of this instance. + /// + public float M23 { get { return Row1.Z; } set { Row1.Z = value; } } + + /// + /// Gets or sets the value at row 3, column 1 of this instance. + /// + public float M31 { get { return Row2.X; } set { Row2.X = value; } } + + /// + /// Gets or sets the value at row 3, column 2 of this instance. + /// + public float M32 { get { return Row2.Y; } set { Row2.Y = value; } } + + /// + /// Gets or sets the value at row 3, column 3 of this instance. + /// + public float M33 { get { return Row2.Z; } set { Row2.Z = value; } } + + #endregion + + #region Instance + + #region public void Invert() + + /// + /// Converts this instance into its inverse. + /// + public void Invert() + { + this = Matrix3.Invert(this); + } + + #endregion + + #region public void Transpose() + + /// + /// Converts this instance into its transpose. + /// + public void Transpose() + { + this = Matrix3.Transpose(this); + } + + #endregion + + #endregion + + #region Static + + #region CreateFromAxisAngle + + /// + /// Build a rotation matrix from the specified axis/angle rotation. + /// + /// The axis to rotate about. + /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). + /// A matrix instance. + public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix3 result) + { + float cos = (float)System.Math.Cos(-angle); + float sin = (float)System.Math.Sin(-angle); + float t = 1.0f - cos; + + axis.Normalize(); + + result = new Matrix3(t * axis.X * axis.X + cos, t * axis.X * axis.Y - sin * axis.Z, t * axis.X * axis.Z + sin * axis.Y, + t * axis.X * axis.Y + sin * axis.Z, t * axis.Y * axis.Y + cos, t * axis.Y * axis.Z - sin * axis.X, + t * axis.X * axis.Z - sin * axis.Y, t * axis.Y * axis.Z + sin * axis.X, t * axis.Z * axis.Z + cos); + } + + /// + /// Build a rotation matrix from the specified axis/angle rotation. + /// + /// The axis to rotate about. + /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). + /// A matrix instance. + public static Matrix3 CreateFromAxisAngle(Vector3 axis, float angle) + { + Matrix3 result; + CreateFromAxisAngle(axis, angle, out result); + return result; + } + + #endregion + + #region CreateRotation[XYZ] + + /// + /// Builds a rotation matrix for a rotation around the x-axis. + /// + /// The counter-clockwise angle in radians. + /// The resulting Matrix3 instance. + public static void CreateRotationX(float angle, out Matrix3 result) + { + float cos = (float)System.Math.Cos(angle); + float sin = (float)System.Math.Sin(angle); + + result.Row0 = Vector3.UnitX; + result.Row1 = new Vector3(0.0f, cos, sin); + result.Row2 = new Vector3(0.0f, -sin, cos); + } + + /// + /// Builds a rotation matrix for a rotation around the x-axis. + /// + /// The counter-clockwise angle in radians. + /// The resulting Matrix3 instance. + public static Matrix3 CreateRotationX(float angle) + { + Matrix3 result; + CreateRotationX(angle, out result); + return result; + } + + /// + /// Builds a rotation matrix for a rotation around the y-axis. + /// + /// The counter-clockwise angle in radians. + /// The resulting Matrix3 instance. + public static void CreateRotationY(float angle, out Matrix3 result) + { + float cos = (float)System.Math.Cos(angle); + float sin = (float)System.Math.Sin(angle); + + result.Row0 = new Vector3(cos, 0.0f, -sin); + result.Row1 = Vector3.UnitY; + result.Row2 = new Vector3(sin, 0.0f, cos); + } + + /// + /// Builds a rotation matrix for a rotation around the y-axis. + /// + /// The counter-clockwise angle in radians. + /// The resulting Matrix3 instance. + public static Matrix3 CreateRotationY(float angle) + { + Matrix3 result; + CreateRotationY(angle, out result); + return result; + } + + /// + /// Builds a rotation matrix for a rotation around the z-axis. + /// + /// The counter-clockwise angle in radians. + /// The resulting Matrix3 instance. + public static void CreateRotationZ(float angle, out Matrix3 result) + { + float cos = (float)System.Math.Cos(angle); + float sin = (float)System.Math.Sin(angle); + + result.Row0 = new Vector3(cos, sin, 0.0f); + result.Row1 = new Vector3(-sin, cos, 0.0f); + result.Row2 = Vector3.UnitZ; + } + + /// + /// Builds a rotation matrix for a rotation around the z-axis. + /// + /// The counter-clockwise angle in radians. + /// The resulting Matrix3 instance. + public static Matrix3 CreateRotationZ(float angle) + { + Matrix3 result; + CreateRotationZ(angle, out result); + return result; + } + + #endregion + + #region CreateTranslation + + /// + /// Creates a translation matrix. + /// + /// X translation. + /// Y translation. + /// The resulting Matrix3 instance. + public static void CreateTranslation(float x, float y, out Matrix3 result) + { + result = Identity; + result.Row2 = new Vector3(x, y, 1); + } + + /// + /// Creates a translation matrix. + /// + /// The translation vector. + /// The resulting Matrix3 instance. + public static void CreateTranslation(ref Vector2 vector, out Matrix3 result) + { + result = Identity; + result.Row2 = new Vector3(vector.X, vector.Y, 1); + } + + /// + /// Creates a translation matrix. + /// + /// X translation. + /// Y translation. + /// The resulting Matrix3 instance. + public static Matrix3 CreateTranslation(float x, float y) + { + Matrix3 result; + CreateTranslation(x, y, out result); + return result; + } + + /// + /// Creates a translation matrix. + /// + /// The translation vector. + /// The resulting Matrix3 instance. + public static Matrix3 CreateTranslation(Vector2 vector) + { + Matrix3 result; + CreateTranslation(vector.X, vector.Y, out result); + return result; + } + + #endregion + + #region Scale Functions + + /// + /// Build a scaling matrix + /// + /// Single scale factor for x,y and z axes + /// A scaling matrix + public static Matrix3 Scale(float scale) + { + return Scale(scale, scale, scale); + } + + /// + /// Build a scaling matrix + /// + /// Scale factors for x,y and z axes + /// A scaling matrix + public static Matrix3 Scale(Vector3 scale) + { + return Scale(scale.X, scale.Y, scale.Z); + } + + /// + /// Build a scaling matrix + /// + /// Scale factors for x and y axes + /// A scaling matrix + public static Matrix3 Scale(Vector2 scale) + { + return Scale(scale.X, scale.Y, 1); + } + + /// + /// Build a scaling matrix + /// + /// Scale factor for x-axis + /// Scale factor for y-axis + /// Scale factor for z-axis + /// A scaling matrix + public static Matrix3 Scale(float x, float y, float z) + { + Matrix3 result; + result.Row0 = Vector3.UnitX * x; + result.Row1 = Vector3.UnitY * y; + result.Row2 = Vector3.UnitZ * z; + return result; + } + + #endregion + + #region Rotation Functions + + /// + /// Build a rotation matrix from a quaternion + /// + /// the quaternion + /// A rotation matrix + public static Matrix3 Rotate(Quaternion q) + { + Vector3 axis; + float angle; + q.ToAxisAngle(out axis, out angle); + return CreateFromAxisAngle(axis, angle); + } + + #endregion + + #region Multiply Functions + + /// + /// Multiplies two instances. + /// + /// The left operand of the multiplication. + /// The right operand of the multiplication. + /// A new instance that is the result of the multiplication + public static Matrix3 Mult(Matrix3 left, Matrix3 right) + { + Matrix3 result; + Mult(ref left, ref right, out result); + return result; + } + + /// + /// Multiplies two instances. + /// + /// The left operand of the multiplication. + /// The right operand of the multiplication. + /// A new instance that is the result of the multiplication + public static void Mult(ref Matrix3 left, ref Matrix3 right, out Matrix3 result) + { + float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, + lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, + lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, + rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, + rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, + rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z; + + result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)); + result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)); + result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)); + result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)); + result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)); + result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)); + result.Row2.X = (((lM31 * rM11) + (lM32 * rM21)) + (lM33 * rM31)); + result.Row2.Y = (((lM31 * rM12) + (lM32 * rM22)) + (lM33 * rM32)); + result.Row2.Z = (((lM31 * rM13) + (lM32 * rM23)) + (lM33 * rM33)); + } + + /// + /// Multiplies a Matrix3 with a Vector3. + /// + /// The left operand of the multiplication. + /// The right operand of the multiplication. + /// A new Vector3 that is the result of the multiplication + public static Vector3 Mult(Matrix3 left, Vector3 right) { + Vector3 result; + Mult (ref left, ref right, out result); + return result; + } + + /// + /// Multiplies a Matrix3 with a Vector3. + /// + /// The left operand of the multiplication. + /// The right operand of the multiplication. + /// A new Vector3 that is the result of the multiplication + public static void Mult(ref Matrix3 left, ref Vector3 right, out Vector3 result) { + + result.X = left.M11 * right.X + left.M21 * right.Y + left.M31 * right.Z; + result.Y = left.M12 * right.X + left.M22 * right.Y + left.M32 * right.Z; + result.Z = left.M13 * right.X + left.M23 * right.Y + left.M33 * right.Z; + } + + #endregion + + #region Invert Functions + + /// + /// Not implemented! + /// + /// Calculate the inverse of the given matrix + /// + /// The matrix to invert + /// The inverse of the given matrix if it has one, or the input if it is singular + /// Thrown if the Matrix4 is singular. + public static Matrix3 Invert(Matrix3 mat) + { + //see Matrix4 for an implementation + throw new NotImplementedException(); + } + + #endregion + + #region Transpose + + /// + /// Calculate the transpose of the given matrix + /// + /// The matrix to transpose + /// The transpose of the given matrix + public static Matrix3 Transpose(Matrix3 mat) + { + return new Matrix3(mat.Column0, mat.Column1, mat.Column2); + } + + + /// + /// Calculate the transpose of the given matrix + /// + /// The matrix to transpose + /// The result of the calculation + public static void Transpose(ref Matrix3 mat, out Matrix3 result) + { + result.Row0 = mat.Column0; + result.Row1 = mat.Column1; + result.Row2 = mat.Column2; + } + + #endregion + + #endregion + + #region Operators + + /// + /// Matrix multiplication + /// + /// left-hand operand + /// right-hand operand + /// A new Matrix33 which holds the result of the multiplication + public static Matrix3 operator *(Matrix3 left, Matrix3 right) + { + return Matrix3.Mult(left, right); + } + + /// + /// Matrix - Vector multiplication + /// + /// left-hand operand + /// right-hand operand + /// A new Vector3 which holds the result of the multiplication + public static Vector3 operator *(Matrix3 left, Vector3 right) + { + return Matrix3.Mult(left, right); + } + + /// + /// Compares two instances for equality. + /// + /// The first instance. + /// The second instance. + /// True, if left equals right; false otherwise. + public static bool operator ==(Matrix3 left, Matrix3 right) + { + return left.Equals(right); + } + + /// + /// Compares two instances for inequality. + /// + /// The first instance. + /// The second instance. + /// True, if left does not equal right; false otherwise. + public static bool operator !=(Matrix3 left, Matrix3 right) + { + return !left.Equals(right); + } + + #endregion + + #region Overrides + + #region public override string ToString() + + /// + /// Returns a System.String that represents the current Matrix33. + /// + /// + public override string ToString() + { + return String.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); + } + + #endregion + + #region public override int GetHashCode() + + /// + /// Returns the hashcode for this instance. + /// + /// A System.Int32 containing the unique hashcode for this instance. + public override int GetHashCode() + { + return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); + } + + #endregion + + #region public override bool Equals(object obj) + + /// + /// Indicates whether this instance and a specified object are equal. + /// + /// The object to compare tresult. + /// True if the instances are equal; false otherwise. + public override bool Equals(object obj) + { + if (!(obj is Matrix3)) + return false; + + return this.Equals((Matrix4)obj); + } + + #endregion + + #endregion + + #endregion + + #region IEquatable Members + + /// Indicates whether the current matrix is equal to another matrix. + /// An matrix to compare with this matrix. + /// true if the current matrix is equal to the matrix parameter; otherwise, false. + public bool Equals(Matrix3 other) + { + return + Row0 == other.Row0 && + Row1 == other.Row1 && + Row2 == other.Row2; + } + + #endregion + } +} \ No newline at end of file Index: Source/OpenTK/Graphics/OpenGL/GLHelper.cs =================================================================== --- Source/OpenTK/Graphics/OpenGL/GLHelper.cs (revision 3123) +++ Source/OpenTK/Graphics/OpenGL/GLHelper.cs (working copy) @@ -299,6 +299,17 @@ } } } + + public static void UniformMatrix3(int location, bool transpose, ref Matrix3 matrix) + { + unsafe + { + fixed (float* matrix_ptr = &matrix.Row0.X) + { + GL.UniformMatrix3(location, 1, transpose, matrix_ptr); + } + } + } public static void UniformMatrix4(int location, bool transpose, ref Matrix4 matrix) {