/// <summary> /// Make an orthogonal matrix /// </summary> /// <param name="left">Left value</param> /// <param name="right">Right value</param> /// <param name="bottom">Bottom value</param> /// <param name="top">Top value</param> /// <param name="zNear">Near z plane distance</param> /// <param name="zFar">Far z plane distance</param> /// <returns>Frustrum matrix</returns> public static GLMatrix4D Orthogonal(double left, double right, double bottom, double top, double zNear, double zFar) { GLMatrix4D ret = new GLMatrix4D(); ret.m[0] = 2 / (right - left); ret.m[1] = 0; ret.m[2] = 0; ret.m[3] = 0; ret.m[4] = 0; ret.m[5] = 2 / (top - bottom); ret.m[6] = 0; ret.m[7] = 0; ret.m[8] = 0; ret.m[9] = 0; ret.m[10] = -2 / (zFar - zNear); ret.m[11] = 0; ret.m[12] = -(right + left) / (right - left); ret.m[13] = -(top + bottom) / (top - bottom); ret.m[14] = -(zFar + zNear) / (zFar - zNear); ret.m[15] = 1; return(ret); }
/// <summary> /// Get the matrix dot product, the most commonly used form of matrix multiplication /// </summary> /// <param name="one">Left Matrix</param> /// <param name="two">Right Matrix</param> /// <returns>New resulting matrix</returns> public static GLMatrix4D operator*(GLMatrix4D one, GLMatrix4D two) { GLMatrix4D ret = new GLMatrix4D(); for (byte j = 0; j < 4; ++j) { ret.m[j] = one.m[j] * two.m[0] + one.m[j + 4] * two.m[1] + one.m[j + 8] * two.m[2] + one.m[j + 12] * two.m[3]; ret.m[j + 4] = one.m[j] * two.m[4] + one.m[j + 4] * two.m[5] + one.m[j + 8] * two.m[6] + one.m[j + 12] * two.m[7]; ret.m[j + 8] = one.m[j] * two.m[8] + one.m[j + 4] * two.m[9] + one.m[j + 8] * two.m[10] + one.m[j + 12] * two.m[11]; ret.m[j + 12] = one[j] * two.m[12] + one[j + 4] * two.m[13] + one[j + 8] * two.m[14] + one[j + 12] * two.m[15]; } return(ret); }
/// <summary> /// Get the adjoint matrix /// </summary> /// <returns>A new matrix that is adjoint to this one</returns> public GLMatrix4D adjoint() { GLMatrix4D ret = new GLMatrix4D(); ret.m[0] = CofactorM0(); ret.m[1] = -CofactorM4(); ret.m[2] = CofactorM8(); ret.m[3] = -CofactorM12(); ret.m[4] = -CofactorM1(); ret.m[5] = CofactorM5(); ret.m[6] = -CofactorM9(); ret.m[7] = CofactorM13(); ret.m[8] = CofactorM2(); ret.m[9] = -CofactorM6(); ret.m[10] = CofactorM10(); ret.m[11] = -CofactorM14(); ret.m[12] = -CofactorM3(); ret.m[13] = CofactorM7(); ret.m[14] = -CofactorM11(); ret.m[15] = CofactorM15(); return(ret); }
/// <summary> /// Create a frustrum matrix /// </summary> /// <param name="left">Left value</param> /// <param name="right">Right value</param> /// <param name="bottom">Bottom value</param> /// <param name="top">Top value</param> /// <param name="zNear">Near z plane distance</param> /// <param name="zFar">Far z plane distance</param> /// <returns>Frustrum matrix</returns> public static GLMatrix4D glFrustrum(double left, double right, double bottom, double top, double zNear, double zFar) { GLMatrix4D ret = new GLMatrix4D(); ret.m[0] = 2 * zNear / (right - left); ret.m[1] = 0; ret.m[2] = 0; ret.m[3] = 0; ret.m[4] = 0; ret.m[5] = 2 * zNear / (top - bottom); ret.m[6] = 0; ret.m[7] = 0; ret.m[8] = (right + left) / (right - left); ret.m[9] = (top + bottom) / (top - bottom); ret.m[10] = -(zFar + zNear) / (zFar - zNear); ret.m[11] = -1; ret.m[12] = 0; ret.m[13] = 0; ret.m[14] = -2 * zFar * zNear / (zFar - zNear); ret.m[15] = 0; return(ret); }
public static void ApplyRotToGLMatrix4d( ref GLMatrix4D matrix, Rot rot ) { double fRotAngle = 0; Vector3 vAxis = new Vector3(); mvMath.Rot2AxisAngle( ref vAxis, ref fRotAngle, rot ); matrix.applyRotate( (float)( fRotAngle / mvMath.PiOver180 ), (float)vAxis.x, (float)vAxis.y, (float)vAxis.z ); }
/// <summary> /// Apply a rotation to this matrix /// </summary> /// <param name="angle">Angle of rotation</param> /// <param name="x">X value of the rotation vector</param> /// <param name="y">Y value of the rotation vector</param> /// <param name="z">Z value of the rotation vector</param> /// <returns>This matrix</returns> public GLMatrix4D applyRotate(double angle, double x, double y, double z) { GLMatrix4D temp = new GLMatrix4D(); temp.LoadRotate(angle, x, y, z); return(Multiply3By3(temp)); }
/// <summary> /// Apply a Z rotation to this matrix /// </summary> /// <param name="angle">Angle of rotation</param> /// <returns>This matrix</returns> /// <remarks>Apply rotate[X,Y,Z,XYZ] specialisations by sebastien bloc</remarks> public GLMatrix4D ApplyRotateZ(double angle) { GLMatrix4D temp = new GLMatrix4D(); temp.loadRotateZ(angle); return(Multiply3By3(temp)); }
/// <summary> /// Identity matrix /// </summary> /// <returns>A new identity matrix</returns> public static GLMatrix4D Identity() { GLMatrix4D ret = new GLMatrix4D(); ret.m[0] = 1; ret.m[4] = 0; ret.m[8] = 0; ret.m[12] = 0; ret.m[1] = 0; ret.m[5] = 1; ret.m[9] = 0; ret.m[13] = 0; ret.m[2] = 0; ret.m[6] = 0; ret.m[10] = 1; ret.m[14] = 0; ret.m[3] = 0; ret.m[7] = 0; ret.m[11] = 0; ret.m[15] = 1; return(ret); }
/// <summary> /// Subtract one matrix from another /// </summary> /// <param name="one">Left Matrix</param> /// <param name="two">Right Matrix</param> /// <returns>New resulting matrix</returns> public static GLMatrix4D operator-(GLMatrix4D one, GLMatrix4D two) { GLMatrix4D result = new GLMatrix4D(); for (byte i = 0; i < 16; ++i) { result.m[i] = one.m[i] - two.m[i]; } return(result); }
/// <summary> /// Divide this matrix by a scalar /// </summary> /// <param name="mat">Matrix</param> /// <param name="val">Scalar</param> /// <returns>New resulting matrix</returns> public static GLMatrix4D operator/(GLMatrix4D mat, double val) { GLMatrix4D result = new GLMatrix4D(); for (byte i = 0; i < 16; ++i) { result.m[i] = mat.m[i] / val; } return(result); }
/// <summary> /// Adjoint method inverse, constant time inversion implementation /// </summary> /// <returns>A new matrix that is inverse to this one</returns> public GLMatrix4D inverse() { GLMatrix4D ret = new GLMatrix4D(adjoint()); double determinant = m[0] * ret[0] + m[1] * ret[4] + m[2] * ret[8] + m[3] * ret[12]; //assert(determinant!=0 && "Singular matrix has no inverse"); ret /= determinant; return(ret); }
/// <summary> /// Apply a XYZ rotation to this matrix /// </summary> /// <param name="angle">Angle of rotation around X axis</param> /// <param name="angle">Angle of rotation around Y axis</param> /// <param name="angle">Angle of rotation around Z axis</param> /// <returns>This matrix</returns> /// <remarks>Apply rotate[X,Y,Z,XYZ] specialisations by sebastien bloc</remarks> public GLMatrix4D ApplyRotateXYZ(double x, double y, double z) { GLMatrix4D temp = new GLMatrix4D(); temp.LoadRotateX(x); Multiply3By3(temp); temp.loadRotateY(y); Multiply3By3(temp); temp.loadRotateZ(z); return(Multiply3By3(temp)); }
/// <summary> /// Equality function override /// </summary> /// <param name="twoobject">Matrix object</param> /// <returns>True if they are equal, false otherwise</returns> public override bool Equals(object twoobject) { GLMatrix4D two = twoobject as GLMatrix4D; for (int i = 0; i < 16; i++) { if (m[i] != two.m[i]) { return(false); } } return(true); }
//!Return the transpose /// <summary> /// Get a transposed matrix /// </summary> /// <returns>A new matrix that is the transposed form of this</returns> public GLMatrix4D GetTranspose() { GLMatrix4D temp = new GLMatrix4D(); for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { temp.m[j + i * 4] = m[i + j * 4]; } } return(temp); }
/// <summary> /// Apply the matrix dot product to this matrix /// </summary> /// <param name="mat">Right Side Matrix</param> /// <returns>This Matrix</returns> /// <remarks>unrolling by sebastien bloc</remarks> public GLMatrix4D Multiply3By3(GLMatrix4D mat) { GLMatrix4D temp = new GLMatrix4D(this); m[0] = temp.m[0] * mat.m[0] + temp.m[4] * mat.m[1] + temp.m[8] * mat.m[2]; m[4] = temp.m[0] * mat.m[4] + temp.m[4] * mat.m[5] + temp.m[8] * mat.m[6]; m[8] = temp.m[0] * mat.m[8] + temp.m[4] * mat.m[9] + temp.m[8] * mat.m[10]; m[1] = temp.m[1] * mat.m[0] + temp.m[5] * mat.m[1] + temp.m[9] * mat.m[2]; m[5] = temp.m[1] * mat.m[4] + temp.m[5] * mat.m[5] + temp.m[9] * mat.m[6]; m[9] = temp.m[1] * mat.m[8] + temp.m[5] * mat.m[9] + temp.m[9] * mat.m[10]; m[2] = temp.m[2] * mat.m[0] + temp.m[6] * mat.m[1] + temp.m[10] * mat.m[2]; m[6] = temp.m[2] * mat.m[4] + temp.m[6] * mat.m[5] + temp.m[10] * mat.m[6]; m[10] = temp.m[2] * mat.m[8] + temp.m[6] * mat.m[9] + temp.m[10] * mat.m[10]; m[3] = temp.m[3] * mat.m[0] + temp.m[7] * mat.m[1] + temp.m[11] * mat.m[2]; m[7] = temp.m[3] * mat.m[4] + temp.m[7] * mat.m[5] + temp.m[11] * mat.m[6]; m[11] = temp.m[3] * mat.m[8] + temp.m[7] * mat.m[9] + temp.m[11] * mat.m[10]; return(this); }
/// <summary> /// Apply a rotation to this matrix /// </summary> /// <param name="angle">Angle of rotation</param> /// <param name="x">X value of the rotation vector</param> /// <param name="y">Y value of the rotation vector</param> /// <param name="z">Z value of the rotation vector</param> /// <returns>This matrix</returns> public GLMatrix4D applyRotate( double angle, double x, double y, double z ) { GLMatrix4D temp = new GLMatrix4D(); temp.LoadRotate( angle,x,y,z ); return Multiply3By3( temp ); }
/// <summary> /// Get the adjoint matrix /// </summary> /// <returns>A new matrix that is adjoint to this one</returns> public GLMatrix4D adjoint() { GLMatrix4D ret = new GLMatrix4D(); ret.m[0] = CofactorM0(); ret.m[1] = -CofactorM4(); ret.m[2] = CofactorM8(); ret.m[3] = -CofactorM12(); ret.m[4] = -CofactorM1(); ret.m[5] = CofactorM5(); ret.m[6] = -CofactorM9(); ret.m[7] = CofactorM13(); ret.m[8] = CofactorM2(); ret.m[9] = -CofactorM6(); ret.m[10] = CofactorM10(); ret.m[11] = -CofactorM14(); ret.m[12] = -CofactorM3(); ret.m[13] = CofactorM7(); ret.m[14] = -CofactorM11(); ret.m[15] = CofactorM15(); return ret; }
/// <summary> /// Make an orthogonal matrix /// </summary> /// <param name="left">Left value</param> /// <param name="right">Right value</param> /// <param name="bottom">Bottom value</param> /// <param name="top">Top value</param> /// <param name="zNear">Near z plane distance</param> /// <param name="zFar">Far z plane distance</param> /// <returns>Frustrum matrix</returns> public static GLMatrix4D Orthogonal( double left, double right, double bottom, double top, double zNear, double zFar ) { GLMatrix4D ret = new GLMatrix4D(); ret.m[0] = 2/(right-left); ret.m[1] = 0; ret.m[2] = 0; ret.m[3] = 0; ret.m[4] = 0; ret.m[5] = 2/(top-bottom); ret.m[6] = 0; ret.m[7] = 0; ret.m[8] = 0; ret.m[9] = 0; ret.m[10] = -2/(zFar-zNear); ret.m[11] = 0; ret.m[12] = -(right+left)/(right-left); ret.m[13] = -(top+bottom)/(top-bottom); ret.m[14] = -(zFar+zNear)/(zFar-zNear); ret.m[15] = 1; return ret; }
/// <summary> /// Identity matrix /// </summary> /// <returns>A new identity matrix</returns> public static GLMatrix4D Identity() { GLMatrix4D ret = new GLMatrix4D(); ret.m[0] = 1; ret.m[4] = 0; ret.m[8] = 0; ret.m[12] = 0; ret.m[1] = 0; ret.m[5] = 1; ret.m[9] = 0; ret.m[13] = 0; ret.m[2] = 0; ret.m[6] = 0; ret.m[10] = 1; ret.m[14] = 0; ret.m[3] = 0; ret.m[7] = 0; ret.m[11] = 0; ret.m[15] = 1; return ret; }
/// <summary> /// Create a frustrum matrix /// </summary> /// <param name="left">Left value</param> /// <param name="right">Right value</param> /// <param name="bottom">Bottom value</param> /// <param name="top">Top value</param> /// <param name="zNear">Near z plane distance</param> /// <param name="zFar">Far z plane distance</param> /// <returns>Frustrum matrix</returns> public static GLMatrix4D glFrustrum( double left, double right, double bottom, double top, double zNear, double zFar ) { GLMatrix4D ret = new GLMatrix4D(); ret.m[0] = 2*zNear/(right-left); ret.m[1] = 0; ret.m[2] = 0; ret.m[3] = 0; ret.m[4] = 0; ret.m[5] = 2*zNear/(top-bottom); ret.m[6] = 0; ret.m[7] = 0; ret.m[8] = (right+left)/(right-left); ret.m[9] = (top+bottom)/(top-bottom); ret.m[10] = -(zFar+zNear)/(zFar-zNear); ret.m[11] = -1; ret.m[12] = 0; ret.m[13] = 0; ret.m[14] = -2*zFar*zNear/(zFar-zNear); ret.m[15] = 0; return ret; }
/// <summary> /// Divide this matrix by a scalar /// </summary> /// <param name="mat">Matrix</param> /// <param name="val">Scalar</param> /// <returns>New resulting matrix</returns> public static GLMatrix4D operator /( GLMatrix4D mat, double val) { GLMatrix4D result = new GLMatrix4D(); for( byte i = 0; i < 16; ++i ) { result.m[i] = mat.m[i] / val; } return result; }
/// <summary> /// Subtract one matrix from another /// </summary> /// <param name="one">Left Matrix</param> /// <param name="two">Right Matrix</param> /// <returns>New resulting matrix</returns> public static GLMatrix4D operator -( GLMatrix4D one, GLMatrix4D two) { GLMatrix4D result = new GLMatrix4D(); for( byte i = 0; i < 16; ++i ) { result.m[i] = one.m[i] - two.m[i]; } return result; }
/// <summary> /// Get the matrix dot product, the most commonly used form of matrix multiplication /// </summary> /// <param name="one">Left Matrix</param> /// <param name="two">Right Matrix</param> /// <returns>New resulting matrix</returns> public static GLMatrix4D operator *( GLMatrix4D one, GLMatrix4D two ) { GLMatrix4D ret = new GLMatrix4D(); for( byte j = 0; j < 4; ++j ) { ret.m[j] = one.m[j]*two.m[0] + one.m[j+4]*two.m[1] + one.m[j+8]*two.m[2] + one.m[j+12]*two.m[3]; ret.m[j+4] = one.m[j]*two.m[4] + one.m[j+4]*two.m[5] + one.m[j+8]*two.m[6] + one.m[j+12]*two.m[7]; ret.m[j+8] = one.m[j]*two.m[8] + one.m[j+4]*two.m[9] + one.m[j+8]*two.m[10] + one.m[j+12]*two.m[11]; ret.m[j+12] = one[j]*two.m[12] + one[j+4]*two.m[13] + one[j+8]*two.m[14] + one[j+12]*two.m[15]; } return ret; }
/// <summary> /// Copy a matrix /// </summary> /// <param name="mat">Source matrix to copy from</param> public GLMatrix4D(GLMatrix4D mat) { Buffer.BlockCopy( mat.m, 0, m, 0, Buffer.ByteLength( mat.m ) ); return; }
/// <summary> /// Apply a XYZ rotation to this matrix /// </summary> /// <param name="angle">Angle of rotation around X axis</param> /// <param name="angle">Angle of rotation around Y axis</param> /// <param name="angle">Angle of rotation around Z axis</param> /// <returns>This matrix</returns> /// <remarks>Apply rotate[X,Y,Z,XYZ] specialisations by sebastien bloc</remarks> public GLMatrix4D ApplyRotateXYZ( double x,double y,double z ) { GLMatrix4D temp = new GLMatrix4D(); temp.LoadRotateX( x ); Multiply3By3( temp ); temp.loadRotateY( y ); Multiply3By3( temp ); temp.loadRotateZ( z ); return Multiply3By3( temp ); }
//!Return the transpose /// <summary> /// Get a transposed matrix /// </summary> /// <returns>A new matrix that is the transposed form of this</returns> public GLMatrix4D GetTranspose() { GLMatrix4D temp = new GLMatrix4D(); for( int i = 0; i < 4; ++i) { for( int j = 0; j < 4; ++j) { temp.m[j+i*4] = m[i+j*4]; } } return temp; }
/// <summary> /// Apply a Z rotation to this matrix /// </summary> /// <param name="angle">Angle of rotation</param> /// <returns>This matrix</returns> /// <remarks>Apply rotate[X,Y,Z,XYZ] specialisations by sebastien bloc</remarks> public GLMatrix4D ApplyRotateZ( double angle ) { GLMatrix4D temp = new GLMatrix4D(); temp.loadRotateZ( angle ); return Multiply3By3( temp ); }
/// <summary> /// Apply the matrix dot product to this matrix /// </summary> /// <param name="mat">Right Side Matrix</param> /// <returns>This Matrix</returns> /// <remarks>unrolling by sebastien bloc</remarks> public GLMatrix4D Multiply3By3( GLMatrix4D mat ) { GLMatrix4D temp = new GLMatrix4D( this ); m[0] = temp.m[0]*mat.m[0]+temp.m[4]*mat.m[1]+temp.m[8]*mat.m[2]; m[4] = temp.m[0]*mat.m[4]+temp.m[4]*mat.m[5]+temp.m[8]*mat.m[6]; m[8] = temp.m[0]*mat.m[8]+temp.m[4]*mat.m[9]+temp.m[8]*mat.m[10]; m[1] = temp.m[1]*mat.m[0]+temp.m[5]*mat.m[1]+temp.m[9]*mat.m[2]; m[5] = temp.m[1]*mat.m[4]+temp.m[5]*mat.m[5]+temp.m[9]*mat.m[6]; m[9] = temp.m[1]*mat.m[8]+temp.m[5]*mat.m[9]+temp.m[9]*mat.m[10]; m[2] = temp.m[2]*mat.m[0]+temp.m[6]*mat.m[1]+temp.m[10]*mat.m[2]; m[6] = temp.m[2]*mat.m[4]+temp.m[6]*mat.m[5]+temp.m[10]*mat.m[6]; m[10] = temp.m[2]*mat.m[8]+temp.m[6]*mat.m[9]+temp.m[10]*mat.m[10]; m[3] = temp.m[3]*mat.m[0]+temp.m[7]*mat.m[1]+temp.m[11]*mat.m[2]; m[7] = temp.m[3]*mat.m[4]+temp.m[7]*mat.m[5]+temp.m[11]*mat.m[6]; m[11] = temp.m[3]*mat.m[8]+temp.m[7]*mat.m[9]+temp.m[11]*mat.m[10]; return this; }
/// <summary> /// Adjoint method inverse, constant time inversion implementation /// </summary> /// <returns>A new matrix that is inverse to this one</returns> public GLMatrix4D inverse() { GLMatrix4D ret = new GLMatrix4D(adjoint()); double determinant = m[0]*ret[0] + m[1]*ret[4] + m[2]*ret[8] + m[3]*ret[12]; //assert(determinant!=0 && "Singular matrix has no inverse"); ret /= determinant; return ret; }
/// <summary> /// Copy a matrix /// </summary> /// <param name="mat">Source matrix to copy from</param> public GLMatrix4D(GLMatrix4D mat) { Buffer.BlockCopy(mat.m, 0, m, 0, Buffer.ByteLength(mat.m)); return; }