/// <summary> /// Compute the product of two Matrix4x4. /// </summary> /// <param name="result"> /// A <see cref="Matrix4x4"/> that stores the matrix multiplication result. /// </param> /// <param name="m"> /// A <see cref="Matrix4x4"/> that specify the left multiplication operand. /// </param> /// <param name="n"> /// A <see cref="Matrix4x4"/> that specify the right multiplication operand. /// </param> protected static void ComputeMatrixProduct(MatrixDouble4x4 result, MatrixDouble4x4 m, MatrixDouble4x4 n) { unsafe { fixed(double *prodFix = result.MatrixBuffer) fixed(double *pm = m.MatrixBuffer) fixed(double *pn = n.MatrixBuffer) { prodFix[0x0] = pm[0x0] * pn[0x0] + pm[0x4] * pn[0x1] + pm[0x8] * pn[0x2] + pm[0xC] * pn[0x3]; prodFix[0x4] = pm[0x0] * pn[0x4] + pm[0x4] * pn[0x5] + pm[0x8] * pn[0x6] + pm[0xC] * pn[0x7]; prodFix[0x8] = pm[0x0] * pn[0x8] + pm[0x4] * pn[0x9] + pm[0x8] * pn[0xA] + pm[0xC] * pn[0xB]; prodFix[0xC] = pm[0x0] * pn[0xC] + pm[0x4] * pn[0xD] + pm[0x8] * pn[0xE] + pm[0xC] * pn[0xF]; prodFix[0x1] = pm[0x1] * pn[0x0] + pm[0x5] * pn[0x1] + pm[0x9] * pn[0x2] + pm[0xD] * pn[0x3]; prodFix[0x5] = pm[0x1] * pn[0x4] + pm[0x5] * pn[0x5] + pm[0x9] * pn[0x6] + pm[0xD] * pn[0x7]; prodFix[0x9] = pm[0x1] * pn[0x8] + pm[0x5] * pn[0x9] + pm[0x9] * pn[0xA] + pm[0xD] * pn[0xB]; prodFix[0xD] = pm[0x1] * pn[0xC] + pm[0x5] * pn[0xD] + pm[0x9] * pn[0xE] + pm[0xD] * pn[0xF]; prodFix[0x2] = pm[0x2] * pn[0x0] + pm[0x6] * pn[0x1] + pm[0xA] * pn[0x2] + pm[0xE] * pn[0x3]; prodFix[0x6] = pm[0x2] * pn[0x4] + pm[0x6] * pn[0x5] + pm[0xA] * pn[0x6] + pm[0xE] * pn[0x7]; prodFix[0xA] = pm[0x2] * pn[0x8] + pm[0x6] * pn[0x9] + pm[0xA] * pn[0xA] + pm[0xE] * pn[0xB]; prodFix[0xE] = pm[0x2] * pn[0xC] + pm[0x6] * pn[0xD] + pm[0xA] * pn[0xE] + pm[0xE] * pn[0xF]; prodFix[0x3] = pm[0x3] * pn[0x0] + pm[0x7] * pn[0x1] + pm[0xB] * pn[0x2] + pm[0xF] * pn[0x3]; prodFix[0x7] = pm[0x3] * pn[0x4] + pm[0x7] * pn[0x5] + pm[0xB] * pn[0x6] + pm[0xF] * pn[0x7]; prodFix[0xB] = pm[0x3] * pn[0x8] + pm[0x7] * pn[0x9] + pm[0xB] * pn[0xA] + pm[0xF] * pn[0xB]; prodFix[0xF] = pm[0x3] * pn[0xC] + pm[0x7] * pn[0xD] + pm[0xB] * pn[0xE] + pm[0xF] * pn[0xF]; } } }
/// <summary> /// Rotate a Matrix4x4 in three-dimensional space using Quaternion. /// </summary> /// <param name="m"></param> /// <param name="q"></param> /// <returns></returns> public static MatrixDouble4x4 operator *(MatrixDouble4x4 m, Quaternion q) { MatrixDouble4x4 prod = new MatrixDouble4x4(); // COmpute product ComputeMatrixProduct(prod, m, (MatrixDouble4x4)q); return(prod); }
/// <summary> /// Compute the product of two Matrix4x4. /// </summary> /// <param name="m1"> /// A <see cref="Matrix4x4"/> that specify the left multiplication operand. /// </param> /// <param name="m2"> /// A <see cref="Matrix4x4"/> that specify the right multiplication operand. /// </param> /// <returns> /// A <see cref="Matrix4x4"/> resulting from the product of the matrix <paramref name="m1"/> and /// the matrix <paramref name="m2"/>. This operator is used to concatenate successive transformations. /// </returns> public static MatrixDouble4x4 operator *(MatrixDouble4x4 m1, MatrixDouble4x4 m2) { MatrixDouble4x4 prod = new MatrixDouble4x4(); // Compute product ComputeMatrixProduct(prod, m1, m2); return(prod); }
/// <summary> /// Compute the transpose of this Matrix4x4. /// </summary> /// <returns> /// A <see cref="Matrix4x4"/> which hold the transpose of this Matrix4x4. /// </returns> public new MatrixDouble4x4 Transpose() { MatrixDouble4x4 transpose = new MatrixDouble4x4(); // Transpose matrix for (uint c = 0; c < 4; c++) { for (uint r = 0; r < 4; r++) { transpose[r, c] = this[c, r]; } } return(transpose); }
/// <summary> /// Compute the product of Matrix4x4 by MatrixDouble4x4. /// </summary> /// <param name="result"> /// A <see cref="Matrix4x4"/> that stores the matrix multiplication result. /// </param> /// <param name="m"> /// A <see cref="Matrix4x4"/> that specify the left multiplication operand. /// </param> /// <param name="n"> /// A <see cref="MatrixDouble4x4"/> that specify the right multiplication operand. /// </param> /// <remarks> /// If you to store the result in a <see cref="Matrix4x4"/>, use the <see cref="Matrix4x4.ComputeMatrixProduct(Matrix4x4,Matrix4x4,MatrixDouble4x4)"/>. /// </remarks> protected static void ComputeMatrixProduct(MatrixDouble4x4 result, MatrixDouble4x4 m, Matrix4x4 n) { if (result == null) { throw new ArgumentNullException("result"); } if (m == null) { throw new ArgumentNullException("m"); } if (n == null) { throw new ArgumentNullException("n"); } unsafe { fixed(double *prodFix = result.MatrixBuffer) fixed(double *pm = m.MatrixBuffer) fixed(float *pn = n.MatrixBuffer) { prodFix[0x0] = pm[0x0] * pn[0x0] + pm[0x4] * pn[0x1] + pm[0x8] * pn[0x2] + pm[0xC] * pn[0x3]; prodFix[0x4] = pm[0x0] * pn[0x4] + pm[0x4] * pn[0x5] + pm[0x8] * pn[0x6] + pm[0xC] * pn[0x7]; prodFix[0x8] = pm[0x0] * pn[0x8] + pm[0x4] * pn[0x9] + pm[0x8] * pn[0xA] + pm[0xC] * pn[0xB]; prodFix[0xC] = pm[0x0] * pn[0xC] + pm[0x4] * pn[0xD] + pm[0x8] * pn[0xE] + pm[0xC] * pn[0xF]; prodFix[0x1] = pm[0x1] * pn[0x0] + pm[0x5] * pn[0x1] + pm[0x9] * pn[0x2] + pm[0xD] * pn[0x3]; prodFix[0x5] = pm[0x1] * pn[0x4] + pm[0x5] * pn[0x5] + pm[0x9] * pn[0x6] + pm[0xD] * pn[0x7]; prodFix[0x9] = pm[0x1] * pn[0x8] + pm[0x5] * pn[0x9] + pm[0x9] * pn[0xA] + pm[0xD] * pn[0xB]; prodFix[0xD] = pm[0x1] * pn[0xC] + pm[0x5] * pn[0xD] + pm[0x9] * pn[0xE] + pm[0xD] * pn[0xF]; prodFix[0x2] = pm[0x2] * pn[0x0] + pm[0x6] * pn[0x1] + pm[0xA] * pn[0x2] + pm[0xE] * pn[0x3]; prodFix[0x6] = pm[0x2] * pn[0x4] + pm[0x6] * pn[0x5] + pm[0xA] * pn[0x6] + pm[0xE] * pn[0x7]; prodFix[0xA] = pm[0x2] * pn[0x8] + pm[0x6] * pn[0x9] + pm[0xA] * pn[0xA] + pm[0xE] * pn[0xB]; prodFix[0xE] = pm[0x2] * pn[0xC] + pm[0x6] * pn[0xD] + pm[0xA] * pn[0xE] + pm[0xE] * pn[0xF]; prodFix[0x3] = pm[0x3] * pn[0x0] + pm[0x7] * pn[0x1] + pm[0xB] * pn[0x2] + pm[0xF] * pn[0x3]; prodFix[0x7] = pm[0x3] * pn[0x4] + pm[0x7] * pn[0x5] + pm[0xB] * pn[0x6] + pm[0xF] * pn[0x7]; prodFix[0xB] = pm[0x3] * pn[0x8] + pm[0x7] * pn[0x9] + pm[0xB] * pn[0xA] + pm[0xF] * pn[0xB]; prodFix[0xF] = pm[0x3] * pn[0xC] + pm[0x7] * pn[0xD] + pm[0xB] * pn[0xE] + pm[0xF] * pn[0xF]; } } }
/// <summary> /// Set uniform state variable (variant type). /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for operations. /// </param> /// <param name="uniformName"> /// A <see cref="String"/> that specify the variable name in the shader source. /// </param> /// <param name="m"> /// A <see cref="Matrix4x4"/> holding the uniform variabile data. /// </param> public void SetVariantUniform(GraphicsContext ctx, string uniformName, MatrixDouble4x4 m) { if (ctx == null) { throw new ArgumentNullException("ctx"); } UniformBinding uniform = GetUniform(uniformName); switch (uniform.UniformType) { case ShaderUniformType.Mat4x4: SetUniform(ctx, uniformName, (Matrix4x4)m); break; case ShaderUniformType.DoubleMat4x4: SetUniform(ctx, uniformName, m); break; default: throw new ShaderException("unable to set double-precision floating-point matrix 4x4 data to uniform of type {0}", uniform.UniformType); } }
/// <summary> /// Compute the product of this IMatrix with another IMatrix. /// </summary> /// <param name="a"> /// A <see cref="IMatrix4x4"/> that specify the right multiplication operand. /// </param> /// <returns> /// A <see cref="IMatrix"/> resulting from the product of this matrix and the matrix <paramref name="a"/>. /// </returns> IMatrix4x4 IMatrix4x4.Multiply(IMatrix4x4 a) { if (a == null) { throw new ArgumentNullException("a"); } MatrixDouble4x4 otherMatrix = a as MatrixDouble4x4; if (otherMatrix != null) { return(this * otherMatrix); } Matrix4x4 otherMatrix4x4 = a as Matrix4x4; if (otherMatrix4x4 != null) { return(this * (MatrixDouble4x4)otherMatrix4x4); } throw new NotSupportedException("unknown IMatrix4x4 implementation"); }
/// <summary> /// Compute the product of Matrix4x4 by MatrixDouble4x4. /// </summary> /// <param name="result"> /// A <see cref="Matrix4x4"/> that stores the matrix multiplication result. /// </param> /// <param name="m"> /// A <see cref="Matrix4x4"/> that specifies the left multiplication operand. /// </param> /// <param name="n"> /// A <see cref="MatrixDouble4x4"/> that specifies the right multiplication operand. /// </param> /// <remarks> /// If you to store the result in a <see cref="MatrixDouble4x4"/>, use the <see cref="MatrixDouble4x4.ComputeMatrixProduct(MatrixDouble4x4,MatrixDouble4x4,Matrix4x4)"/>. /// </remarks> protected static void ComputeMatrixProduct(Matrix4x4 result, Matrix4x4 m, MatrixDouble4x4 n) { if (result == null) throw new ArgumentNullException("result"); if (m == null) throw new ArgumentNullException("m"); if (n == null) throw new ArgumentNullException("n"); unsafe { fixed (float* prodFix = result.MatrixBuffer) fixed (float* pm = m.MatrixBuffer) fixed (double* pn = n.MatrixBuffer) { prodFix[0x0] = (float)(pm[0x0]*pn[0x0] + pm[0x4]*pn[0x1] + pm[0x8]*pn[0x2] + pm[0xC]*pn[0x3]); prodFix[0x4] = (float)(pm[0x0]*pn[0x4] + pm[0x4]*pn[0x5] + pm[0x8]*pn[0x6] + pm[0xC]*pn[0x7]); prodFix[0x8] = (float)(pm[0x0]*pn[0x8] + pm[0x4]*pn[0x9] + pm[0x8]*pn[0xA] + pm[0xC]*pn[0xB]); prodFix[0xC] = (float)(pm[0x0]*pn[0xC] + pm[0x4]*pn[0xD] + pm[0x8]*pn[0xE] + pm[0xC]*pn[0xF]); prodFix[0x1] = (float)(pm[0x1]*pn[0x0] + pm[0x5]*pn[0x1] + pm[0x9]*pn[0x2] + pm[0xD]*pn[0x3]); prodFix[0x5] = (float)(pm[0x1]*pn[0x4] + pm[0x5]*pn[0x5] + pm[0x9]*pn[0x6] + pm[0xD]*pn[0x7]); prodFix[0x9] = (float)(pm[0x1]*pn[0x8] + pm[0x5]*pn[0x9] + pm[0x9]*pn[0xA] + pm[0xD]*pn[0xB]); prodFix[0xD] = (float)(pm[0x1]*pn[0xC] + pm[0x5]*pn[0xD] + pm[0x9]*pn[0xE] + pm[0xD]*pn[0xF]); prodFix[0x2] = (float)(pm[0x2]*pn[0x0] + pm[0x6]*pn[0x1] + pm[0xA]*pn[0x2] + pm[0xE]*pn[0x3]); prodFix[0x6] = (float)(pm[0x2]*pn[0x4] + pm[0x6]*pn[0x5] + pm[0xA]*pn[0x6] + pm[0xE]*pn[0x7]); prodFix[0xA] = (float)(pm[0x2]*pn[0x8] + pm[0x6]*pn[0x9] + pm[0xA]*pn[0xA] + pm[0xE]*pn[0xB]); prodFix[0xE] = (float)(pm[0x2]*pn[0xC] + pm[0x6]*pn[0xD] + pm[0xA]*pn[0xE] + pm[0xE]*pn[0xF]); prodFix[0x3] = (float)(pm[0x3]*pn[0x0] + pm[0x7]*pn[0x1] + pm[0xB]*pn[0x2] + pm[0xF]*pn[0x3]); prodFix[0x7] = (float)(pm[0x3]*pn[0x4] + pm[0x7]*pn[0x5] + pm[0xB]*pn[0x6] + pm[0xF]*pn[0x7]); prodFix[0xB] = (float)(pm[0x3]*pn[0x8] + pm[0x7]*pn[0x9] + pm[0xB]*pn[0xA] + pm[0xF]*pn[0xB]); prodFix[0xF] = (float)(pm[0x3]*pn[0xC] + pm[0x7]*pn[0xD] + pm[0xB]*pn[0xE] + pm[0xF]*pn[0xF]); } } }
/// <summary> /// Compute the product of two Matrix4x4. /// </summary> /// <param name="m1"> /// A <see cref="Matrix4x4"/> that specify the left multiplication operand. /// </param> /// <param name="m2"> /// A <see cref="Matrix4x4"/> that specify the right multiplication operand. /// </param> /// <returns> /// A <see cref="Matrix4x4"/> resulting from the product of the matrix <paramref name="m1"/> and /// the matrix <paramref name="m2"/>. This operator is used to concatenate successive transformations. /// </returns> public static MatrixDouble4x4 operator *(MatrixDouble4x4 m1, MatrixDouble4x4 m2) { MatrixDouble4x4 prod = new MatrixDouble4x4(); // Compute product ComputeMatrixProduct(prod, m1, m2); return (prod); }
/// <summary> /// Construct ModelMatrixDouble from a <see cref="MatrixDouble4x4"/>. /// </summary> /// <param name="m"> /// A <see cref="MatrixDouble4x4"/> to be copied. /// </param> public ModelMatrixDouble(MatrixDouble4x4 m) : base(m) { }
/// <summary> /// Compute the transpose of this Matrix4x4. /// </summary> /// <returns> /// A <see cref="Matrix4x4"/> which hold the transpose of this Matrix4x4. /// </returns> public new MatrixDouble4x4 Transpose() { MatrixDouble4x4 transpose = new MatrixDouble4x4(); // Transpose matrix for (uint c = 0; c < 4; c++) for (uint r = 0; r < 4; r++) transpose[r, c] = this[c, r]; return (transpose); }
/// <summary> /// Rotate a Matrix4x4 in three-dimensional space using Quaternion. /// </summary> /// <param name="m"></param> /// <param name="q"></param> /// <returns></returns> public static MatrixDouble4x4 operator *(MatrixDouble4x4 m, Quaternion q) { MatrixDouble4x4 prod = new MatrixDouble4x4(); // COmpute product ComputeMatrixProduct(prod, m, (MatrixDouble4x4)q); return (prod); }
/// <summary> /// Matrix copy constructor. /// </summary> /// <param name="m"> /// A <see cref="Matrix"/> /// </param> public MatrixDouble4x4(MatrixDouble4x4 m) : base(m) { }
/// <summary> /// Construct a complement matrix of a <see cref="Matrix4x4"/>. /// </summary> /// <param name="m"> /// A <see cref="Matrix4x4"/> on which is computed the complement matrix. /// </param> /// <param name="c"> /// A <see cref="UInt32"/> that specify the index of the column that is excluded for /// computing the complement matrix. /// </param> /// <param name="r"> /// A <see cref="UInt32"/> that specify the index of the row that is excluded for /// computing the complement matrix. /// </param> /// <exception cref="ArgumentNullException"> /// Exception throw if <paramref name="m"/> is null. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// Exception throw if <paramref name="c"/> is greater or equal to <paramref name="m"/> column count, /// or if <paramref name="r"/> is greater or equal to <paramref name="m"/> row count. /// </exception> public MatrixDouble3x3(MatrixDouble4x4 m, uint c, uint r) : base(m, c, r) { }
/// <summary> /// Set uniform state variable (variant type). /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for operations. /// </param> /// <param name="uniformName"> /// A <see cref="String"/> that specify the variable name in the shader source. /// </param> /// <param name="m"> /// A <see cref="Matrix4x4"/> holding the uniform variabile data. /// </param> public void SetVariantUniform(GraphicsContext ctx, string uniformName, MatrixDouble4x4 m) { if (ctx == null) throw new ArgumentNullException("ctx"); UniformBinding uniform = GetUniform(uniformName); switch (uniform.UniformType) { case ShaderUniformType.Mat4x4: SetUniform(ctx, uniformName, (Matrix4x4)m); break; case ShaderUniformType.DoubleMat4x4: SetUniform(ctx, uniformName, m); break; default: throw new ShaderException("unable to set double-precision floating-point matrix 4x4 data to uniform of type {0}", uniform.UniformType); } }
/// <summary> /// Set uniform state variable (dmat4 variable). /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for operations. /// </param> /// <param name="uniformName"> /// A <see cref="String"/> that specify the variable name in the shader source. /// </param> /// <param name="m"> /// A <see cref="MatrixDouble4x4"/> holding the uniform variabile data. /// </param> public void SetUniform(GraphicsContext ctx, string uniformName, MatrixDouble4x4 m) { if (ctx == null) throw new ArgumentNullException("ctx"); UniformBinding uniform = GetUniform(uniformName); CheckProgramBinding(); CheckUniformType(uniform, Gl.FLOAT_MAT4); // Set uniform value Gl.UniformMatrix4(uniform.Location, 1, false, m.MatrixBuffer); }