Esempio n. 1
0
		/// <summary>
		/// Construct a matrix which is a copy of another matrix.
		/// </summary>
		/// <param name="m">
		/// A <see cref="Matrix3x3"/> to be copied.
		/// </param>
		/// <exception cref="ArgumentNullException">
		/// Exception throw if <paramref name="m"/> is null.
		/// </exception>
		public Matrix3x3(Matrix3x3 m)
			: base(m)
		{

		}
Esempio n. 2
0
		/// <summary>
		/// Compute the transpose of this Matrix3x3.
		/// </summary>
		/// <returns>
		/// A <see cref="Matrix3x3"/> which hold the transpose of this Matrix3x3.
		/// </returns>
		public new Matrix3x3 Transpose()
		{
			Matrix3x3 t = new Matrix3x3();

			// Transpose matrix
			for (uint c = 0; c < 3; c++)
				for (uint r = 0; r < 3; r++)
					t[r, c] = this[c, r];

			return (t);
		}
Esempio n. 3
0
		/// <summary>
		/// Inverse Matrix of this Matrix.
		/// </summary>
		/// <returns>
		/// A <see cref="Matrix"/> representing the inverse matrix of this Matrix.
		/// </returns>
		/// <exception cref="InvalidOperationException">
		/// The exception is thrown if this Matrix is not square, or it's determinant is 0.0 (i.e. non-invertible).
		/// </exception>
		public new Matrix3x3 GetInverseMatrix()
		{
			//        | a b c |
			// m    = | d e f |
			//        | g h k |
			//
			//        | A B C |(T)
			// m^-1 = | D E F |    * (1 / det(m))
			//        | G H K |
			// 
			// A = +(e * k - f * h) = (e * k - f * h)
			// B = -(d * k - f * g) = (f * g - d * k)
			// C = +(d * h - e * g) = (d * h - e * g)
			// D = -(b * k - c * h) = (c * h - b * k)
			// E = +(a * k - c * g) = (a * k - c * g)
			// F = -(a * h - b * g) = (b * g - a * h)
			// G = +(b * f - c * e) = (b * f - c * e)
			// H = -(a * f - c * d) = (c * d - a * f)
			// K = +(a * e - b * d) = (a * e - b * d)

			float determinant = GetDeterminant();

			if (Math.Abs(determinant) < Single.Epsilon)
				throw new InvalidOperationException("non-invertible");

			Matrix3x3 inverse = new Matrix3x3();
			float inv = 1.0f / determinant;

			unsafe {
				fixed (float* m = MatrixBuffer) {
				fixed (float* mi = inverse.MatrixBuffer) {
						float a = m[0], b = m[3], c = m[6];
						float d = m[1], e = m[4], f = m[7];
						float g = m[2], h = m[5], k = m[8];

						mi[0] = (e * k - f * h) * inv;
						mi[1] = (f * g - d * k) * inv;
						mi[2] = (d * h - e * g) * inv;
						mi[3] = (c * h - b * k) * inv;
						mi[4] = (a * k - c * g) * inv;
						mi[5] = (b * g - a * h) * inv;
						mi[6] = (b * f - c * e) * inv;
						mi[7] = (c * d - a * f) * inv;
						mi[8] = (a * e - b * d) * inv;
				}
				}
			}

			return (inverse);
		}
Esempio n. 4
0
		/// <summary>
		/// Compute the product of two Matrix3x3.
		/// </summary>
		/// <param name="result">
		/// A <see cref="Matrix3x3"/> that stores the matrix multiplication result.
		/// </param>
		/// <param name="m">
		/// A <see cref="Matrix3x3"/> that specify the left multiplication operand.
		/// </param>
		/// <param name="n">
		/// A <see cref="Matrix3x3"/> that specify the right multiplication operand.
		/// </param>
		/// <exception cref="ArgumentNullException">
		/// Exception thrown if <paramref name="result"/>, <paramref name="m"/> or <paramref name="n"/> is null.
		/// </exception>
		private static void ComputeMatrixProduct(Matrix3x3 result, Matrix3x3 m, Matrix3x3 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 (float* pn = n.MatrixBuffer) {
					prodFix[0] = pm[0] * pn[0] + pm[3] * pn[1] + pm[6] * pn[2];
					prodFix[3] = pm[0] * pn[3] + pm[3] * pn[4] + pm[6] * pn[5];
					prodFix[6] = pm[0] * pn[6] + pm[3] * pn[7] + pm[6] * pn[8];

					prodFix[1] = pm[1] * pn[0] + pm[4] * pn[1] + pm[7] * pn[2];
					prodFix[4] = pm[1] * pn[3] + pm[4] * pn[4] + pm[7] * pn[5];
					prodFix[7] = pm[1] * pn[6] + pm[4] * pn[7] + pm[7] * pn[8];

					prodFix[2] = pm[2] * pn[0] + pm[5] * pn[1] + pm[8] * pn[2];
					prodFix[5] = pm[2] * pn[3] + pm[5] * pn[4] + pm[8] * pn[5];
					prodFix[8] = pm[2] * pn[6] + pm[5] * pn[7] + pm[8] * pn[8];
				}
			}
		}
Esempio n. 5
0
		/// <summary>
		/// Compute the product of two Matrix4x4.
		/// </summary>
		/// <param name="m1">
		/// A <see cref="Matrix3x3"/> that specify the left multiplication operand.
		/// </param>
		/// <param name="m2">
		/// A <see cref="Matrix3x3"/> that specify the right multiplication operand.
		/// </param>
		/// <returns>
		/// A <see cref="Matrix3x3"/> 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>
		/// <exception cref="ArgumentNullException">
		/// Exception thrown if <paramref name="m1"/> or <paramref name="m2"/> is null.
		/// </exception>
		public static Matrix3x3 operator *(Matrix3x3 m1, Matrix3x3 m2)
		{
			// Allocate product matrix
			Matrix3x3 prod = new Matrix3x3();

			// COmpute product
			ComputeMatrixProduct(prod, m1, m2);

			return (prod);
		}
Esempio n. 6
0
		/// <summary>
		/// Inverse Matrix of this Matrix.
		/// </summary>
		/// <returns>
		/// A <see cref="Matrix"/> representing the inverse matrix of this Matrix.
		/// </returns>
		/// <exception cref="InvalidOperationException">
		/// The exception is thrown if this Matrix is not square, or it's determinant is 0.0.
		/// </exception>
		public new Matrix4x4 GetInverseMatrix()
		{
#if XXX
			float px = Math.Abs(this[0, 3]), py = Math.Abs(this[1, 3]), pz = Math.Abs(this[2, 3]), ps = Math.Abs(this[3, 3] - 1.0f);

			if ((px > Single.Epsilon) || (py > Single.Epsilon) || (pz > Single.Epsilon) || (ps > Single.Epsilon))
#endif
				return ((Matrix4x4)base.GetInverseMatrix());	// Most general case, but rare
#if XXX
			else {
				Matrix3x3 rotMatrix = new Matrix3x3(this, 3, 3);
				Matrix4x4 inverseMatrix = (Matrix4x4) Clone();

				// Invert rotation matrix
				rotMatrix = rotMatrix.GetInverseMatrix();
				
				unsafe {
					fixed (float* src = rotMatrix.MatrixBuffer)
					fixed (float* dst = inverseMatrix.MatrixBuffer) {

						// Copy rotation matrix into the inverse
						dst[0] = src[0]; dst[4] = src[3]; dst[8]  = src[6];
						dst[1] = src[1]; dst[5] = src[4]; dst[9]  = src[7];
						dst[2] = src[2]; dst[6] = src[5]; dst[10] = src[8];
						dst[3] = 0.0f;   dst[7] = 0.0f;   dst[11] = 0.0f;   dst[15] = 1.0f;
					}

					fixed (float* src = MatrixBuffer)
					fixed (float* dst = inverseMatrix.MatrixBuffer) {

						// Negate translation
						dst[12] = -src[12];
						dst[13] = -src[13];
						dst[14] = -src[14];

					}
				}

				return (inverseMatrix);
			}
#endif
		}
		/// <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="Matrix3x3"/> holding the uniform variabile data.
		/// </param>
		public void SetVariantUniform(GraphicsContext ctx, string uniformName, Matrix3x3 m)
		{
			if (ctx == null)
				throw new ArgumentNullException("ctx");

			UniformBinding uniform = GetUniform(uniformName);

			switch (uniform.UniformType) {
				case ShaderUniformType.Mat3x3:
					SetUniform(ctx, uniformName, m);
					break;
				case ShaderUniformType.DoubleMat3x3:
					SetUniform(ctx, uniformName, (MatrixDouble3x3)m);
					break;
				default:
					throw new ShaderException("unable to set single-precision floating-point matrix 3x3 data to uniform of type {0}", uniform.UniformType);
			}
		}
		/// <summary>
		/// Set uniform state variable (mat3 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="Matrix3x3"/> holding the uniform variabile data.
		/// </param>
		public void SetUniform(GraphicsContext ctx, string uniformName, Matrix3x3 m)
		{
			if (ctx == null)
				throw new ArgumentNullException("ctx");
			if (m == null)
				throw new ArgumentNullException("m");

			UniformBinding uniform = GetUniform(uniformName);

			CheckProgramBinding();
			CheckUniformType(uniform, Gl.FLOAT_MAT3);

			// Set uniform value
			Gl.UniformMatrix3(uniform.Location, 1, false, m.MatrixBuffer);
		}