/// <summary>
        /// Translate a ModelMatrix in two-dimensional space.
        /// </summary>
        /// <param name="m"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        public static ModelMatrixDouble operator -(ModelMatrixDouble m, Vertex2d v)
        {
            ModelMatrixDouble res = new ModelMatrixDouble(m);

            res.Translate(-v);

            return(res);
        }
        /// <summary>
        /// Accumulate a translation on this ModelMatrixDouble.
        /// </summary>
        /// <param name="x">
        /// A <see cref="Double"/> indicating the translation on X axis.
        /// </param>
        /// <param name="y">
        /// A <see cref="Double"/> indicating the translation on Y axis.
        /// </param>
        public void Translate(double x, double y)
        {
            ModelMatrixDouble translationMatrix = new ModelMatrixDouble();

            translationMatrix[3, 0] = x;
            translationMatrix[3, 1] = y;

            Set(this * translationMatrix);
        }
        /// <summary>
        /// Accumulate a translation on this ModelMatrixDouble.
        /// </summary>
        /// <param name="p">
        /// A <see cref="Vertex2d"/> that specify the translation.
        /// </param>
        public void Translate(Vertex2d p)
        {
            ModelMatrixDouble translationMatrix = new ModelMatrixDouble();

            translationMatrix[3, 0] = p.x;
            translationMatrix[3, 1] = p.y;

            Set(this * translationMatrix);
        }
        /// <summary>
        /// Accumulate a scaling to this model matrix.
        /// </summary>
        /// <param name="x">
        /// A <see cref="Double"/> holding the scaling factor on X axis.
        /// </param>
        /// <param name="y">
        /// A <see cref="Double"/> holding the scaling factor on Y axis.
        /// </param>
        public void Scale(double x, double y)
        {
            ModelMatrixDouble scaleModel = new ModelMatrixDouble();

            scaleModel[0, 0] = x;
            scaleModel[1, 1] = y;

            Set(this * scaleModel);
        }
        /// <summary>
        /// Accumulate a scaling to this model matrix.
        /// </summary>
        /// <param name="s">
        /// A <see cref="Vertex2d"/> holding the scaling factors on three dimensions.
        /// </param>
        public void Scale(Vertex2d s)
        {
            ModelMatrixDouble scaleModel = new ModelMatrixDouble();

            scaleModel[0, 0] = s.x;
            scaleModel[1, 1] = s.y;

            Set(this * scaleModel);
        }
        /// <summary>
        /// Compute the product of two ModelMatrix.
        /// </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 ModelMatrixDouble operator *(ModelMatrixDouble m1, ModelMatrixDouble m2)
        {
            // Allocate product matrix
            ModelMatrixDouble prod = new ModelMatrixDouble();

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

            return(prod);
        }
        /// <summary>
        /// Accumulate a scaling to this model matrix.
        /// </summary>
        /// <param name="s">
        /// A <see cref="Double"/> holding the scaling factor on X, Y and Z axes.
        /// </param>
        public void Scale(double s)
        {
            ModelMatrixDouble scaleModel = new ModelMatrixDouble();

            scaleModel[0, 0] = s;
            scaleModel[1, 1] = s;
            scaleModel[2, 2] = s;

            Set(this * scaleModel);
        }
        /// <summary>
        /// Accumulate a rotation on Z axis to this ModelMatrixDouble.
        /// </summary>
        /// <param name="angle">
        /// A <see cref="Double"/> representing the rotation angle, in degrees.
        /// </param>
        public void RotateZ(double angle)
        {
            ModelMatrixDouble rotationMatrix = new ModelMatrixDouble();
            double            cosa           = Math.Cos(Angle.ToRadians(angle));
            double            sina           = Math.Sin(Angle.ToRadians(angle));

            rotationMatrix[0, 0] = +cosa;
            rotationMatrix[1, 0] = -sina;
            rotationMatrix[0, 1] = +sina;
            rotationMatrix[1, 1] = +cosa;

            Set((MatrixDouble4x4)this * (MatrixDouble4x4)rotationMatrix);
        }
        /// <summary>
        /// Compute the transpose of this ModelMatrix.
        /// </summary>
        /// <returns>
        /// A <see cref="ModelMatrix"/> which hold the transpose of this ModelMatrix.
        /// </returns>
        public new ModelMatrixDouble Transpose()
        {
            ModelMatrixDouble transpose = new ModelMatrixDouble();

            // 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>
        /// Multiply this IModelMatrix with another IModelMatrix.
        /// </summary>
        /// <param name="a">
        /// A <see cref="IModelMatrix"/> that specify the right multiplication operand.
        /// </param>
        /// <returns>
        /// A <see cref="IModelMatrix"/> resulting from the product of this matrix and the matrix <paramref name="a"/>.
        /// </returns>
        IModelMatrix IModelMatrix.Multiply(IModelMatrix a)
        {
            ModelMatrixDouble rModelMatrix = new ModelMatrixDouble();

            ModelMatrixDouble modelMatrixDouble = a as ModelMatrixDouble;

            if (modelMatrixDouble != null)
            {
                ComputeMatrixProduct(rModelMatrix, this, modelMatrixDouble);
                return(rModelMatrix);
            }

            ModelMatrix modelMatrix = a as ModelMatrix;

            if (modelMatrix != null)
            {
                ComputeMatrixProduct(rModelMatrix, this, modelMatrix);
                return(rModelMatrix);
            }

            throw new NotSupportedException(String.Format("multiplication of {0} by {1} is not supported", GetType(), a.GetType()));
        }
Exemple #11
0
        /// <summary>
        /// Setup this matrix to view the universe in a certain direction.
        /// </summary>
        /// <param name="eyePosition">
        /// A <see cref="Vertex3f"/> that specify the eye position, in local coordinates.
        /// </param>
        /// <param name="forwardVector">
        /// A <see cref="Vertex3f"/> that specify the direction of the view. It will be normalized.
        /// </param>
        /// <param name="upVector">
        /// A <see cref="Vertex3f"/> that specify the up vector of the view camera abstraction. It will be normalized
        /// </param>
        /// <returns>
        /// It returns a view transformation matrix used to transform the world coordinate, in order to view
        /// the world from <paramref name="eyePosition"/>, looking at <paramref name="forwardVector"/> having
        /// an up direction equal to <paramref name="upVector"/>.
        /// </returns>
        public void LookAtDirection(Vertex3d eyePosition, Vertex3d forwardVector, Vertex3d upVector)
        {
            Vertex3d rightVector;

            // Normalize forward vector
            forwardVector.Normalize();
            // Normalize up vector (it should already be normalized)
            upVector.Normalize();
            // Compute the right vector (cross-product between forward and up vectors; right is perperndicular to the plane)
            rightVector = forwardVector ^ upVector;
            rightVector.Normalize();
            // Derive up vector
            upVector = rightVector ^ forwardVector;

            // Compute view matrix
            ModelMatrixDouble lookatMatrix = new ModelMatrixDouble(), positionMatrix = new ModelMatrixDouble();

            // Row 0: right vector
            lookatMatrix[0, 0] = rightVector.x;
            lookatMatrix[0, 1] = rightVector.y;
            lookatMatrix[0, 2] = rightVector.z;
            // Row 1: up vector
            lookatMatrix[1, 0] = upVector.x;
            lookatMatrix[1, 1] = upVector.y;
            lookatMatrix[1, 2] = upVector.z;
            // Row 2: opposite of forward vector
            lookatMatrix[2, 0] = -forwardVector.x;
            lookatMatrix[2, 1] = -forwardVector.y;
            lookatMatrix[2, 2] = -forwardVector.z;

            // Eye position
            positionMatrix.Translate(eyePosition);

            // Complete look-at matrix
            Set(positionMatrix * lookatMatrix);
        }
        /// <summary>
        /// Setup this matrix to view the universe in a certain direction.
        /// </summary>
        /// <param name="eyePosition">
        /// A <see cref="Vertex3f"/> that specify the eye position, in local coordinates.
        /// </param>
        /// <param name="forwardVector">
        /// A <see cref="Vertex3f"/> that specify the direction of the view. It will be normalized.
        /// </param>
        /// <param name="upVector">
        /// A <see cref="Vertex3f"/> that specify the up vector of the view camera abstraction. It will be normalized
        /// </param>
        /// <returns>
        /// It returns a view transformation matrix used to transform the world coordinate, in order to view
        /// the world from <paramref name="eyePosition"/>, looking at <paramref name="forwardVector"/> having
        /// an up direction equal to <paramref name="upVector"/>.
        /// </returns>
        public void LookAtDirection(Vertex3d eyePosition, Vertex3d forwardVector, Vertex3d upVector)
        {
            Vertex3d rightVector;

            forwardVector.Normalize();
            upVector.Normalize();
            rightVector = forwardVector ^ upVector;
            rightVector.Normalize();
            if (rightVector.Module() <= 0.0f)
            {
                rightVector = Vertex3f.UnitX;
            }
            upVector = rightVector ^ forwardVector;

            // Compute view matrix
            ModelMatrixDouble lookatMatrix = new ModelMatrixDouble();

            // Row 0: right vector
            lookatMatrix[0, 0] = rightVector.x;
            lookatMatrix[0, 1] = rightVector.y;
            lookatMatrix[0, 2] = rightVector.z;
            // Row 1: up vector
            lookatMatrix[1, 0] = upVector.x;
            lookatMatrix[1, 1] = upVector.y;
            lookatMatrix[1, 2] = upVector.z;
            // Row 2: opposite of forward vector
            lookatMatrix[2, 0] = -forwardVector.x;
            lookatMatrix[2, 1] = -forwardVector.y;
            lookatMatrix[2, 2] = -forwardVector.z;

            // Eye position
            lookatMatrix.Translate(eyePosition);

            // Complete look-at matrix
            Set(lookatMatrix);
        }
		/// <summary>
		/// Accumulate a rotation on Y axis to this ModelMatrixDouble.
		/// </summary>
		/// <param name="angle">
		/// A <see cref="Double"/> representing the rotation angle, in degrees.
		/// </param>
		public void RotateY(double angle)
		{
			ModelMatrixDouble rotationMatrix = new ModelMatrixDouble();
			double cosa = Math.Cos(Angle.ToRadians(angle));
			double sina = Math.Sin(Angle.ToRadians(angle));

			rotationMatrix[0, 0] = +cosa;
			rotationMatrix[2, 0] = +sina;
			rotationMatrix[0, 2] = -sina;
			rotationMatrix[2, 2] = +cosa;

			Set((MatrixDouble4x4)this * (MatrixDouble4x4)rotationMatrix);
		}
 /// <summary>
 /// ModelMatrixDouble copy constructor.
 /// </summary>
 /// <param name="m">
 /// A <see cref="ModelMatrix"/> to be copied.
 /// </param>
 public ModelMatrixDouble(ModelMatrixDouble m)
     : base(m)
 {
 }
		/// <summary>
		/// Compute the product of two ModelMatrix.
		/// </summary>
		/// <param name="m1">
		/// A <see cref="Matrix4x4"/> that specifies the left multiplication operand.
		/// </param>
		/// <param name="m2">
		/// A <see cref="Matrix4x4"/> that specifies 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 ModelMatrixDouble operator *(ModelMatrixDouble m1, ModelMatrixDouble m2)
		{
			// Allocate product matrix
			ModelMatrixDouble prod = new ModelMatrixDouble();

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

			return (prod);
		}
		/// <summary>
		/// Accumulate a translation on this ModelMatrixDouble.
		/// </summary>
		/// <param name="x">
		/// A <see cref="System.Double"/> indicating the translation on X axis.
		/// </param>
		/// <param name="y">
		/// A <see cref="System.Double"/> indicating the translation on Y axis.
		/// </param>
		/// <param name="z">
		/// A <see cref="System.Double"/> indicating the translation on Z axis.
		/// </param>
		public void Translate(double x, double y, double z)
		{
			ModelMatrixDouble translationMatrix = new ModelMatrixDouble();

			translationMatrix[3, 0] = x;
			translationMatrix[3, 1] = y;
			translationMatrix[3, 2] = z;

			Set(this * translationMatrix);
		}
		/// <summary>
		/// Compute the transpose of this ModelMatrix.
		/// </summary>
		/// <returns>
		/// A <see cref="ModelMatrix"/> which hold the transpose of this ModelMatrix.
		/// </returns>
		public new ModelMatrixDouble Transpose()
		{
			ModelMatrixDouble transpose = new ModelMatrixDouble();

			// 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>
		/// Accumulate a rotation on Z axis to this ModelMatrixDouble.
		/// </summary>
		/// <param name="angle">
		/// A <see cref="System.Double"/> representing the rotation angle, in degrees.
		/// </param>
		public void RotateZ(double angle)
		{
			ModelMatrixDouble rotationMatrix = new ModelMatrixDouble();
			double cosa = Math.Cos(angle * Angle.DegreeToRadian);
			double sina = Math.Sin(angle * Angle.DegreeToRadian);

			rotationMatrix[0, 0] = +cosa;
			rotationMatrix[1, 0] = -sina;
			rotationMatrix[0, 1] = +sina;
			rotationMatrix[1, 1] = +cosa;

			Set((MatrixDouble4x4)this * (MatrixDouble4x4)rotationMatrix);
		}
		/// <summary>
		/// Accumulate a translation on this ModelMatrixDouble.
		/// </summary>
		/// <param name="p">
		/// A <see cref="Vertex3d"/> that specifies the translation.
		/// </param>
		public void Translate(Vertex3d p)
		{
			ModelMatrixDouble translationMatrix = new ModelMatrixDouble();

			translationMatrix[3, 0] = p.x;
			translationMatrix[3, 1] = p.y;
			translationMatrix[3, 2] = p.z;

			Set(this * translationMatrix);
		}
		/// <summary>
		/// Accumulate a scaling to this model matrix.
		/// </summary>
		/// <param name="x">
		/// A <see cref="System.Double"/> holding the scaling factor on X axis.
		/// </param>
		/// <param name="y">
		/// A <see cref="System.Double"/> holding the scaling factor on Y axis.
		/// </param>
		/// <param name="z">
		/// A <see cref="System.Double"/> holding the scaling factor on Z axis.
		/// </param>
		public void Scale(double x, double y, double z)
		{
			ModelMatrixDouble scaleModel = new ModelMatrixDouble();

			scaleModel[0, 0] = x;
			scaleModel[1, 1] = y;
			scaleModel[2, 2] = z;

			Set(this * scaleModel);
		}
		/// <summary>
		/// Accumulate a scaling to this model matrix.
		/// </summary>
		/// <param name="s">
		/// A <see cref="System.Double"/> holding the scaling factor on X, Y and Z axes.
		/// </param>
		public void Scale(double s)
		{
			ModelMatrixDouble scaleModel = new ModelMatrixDouble();

			scaleModel[0, 0] = s;
			scaleModel[1, 1] = s;
			scaleModel[2, 2] = s;

			Set(this * scaleModel);
		}
		/// <summary>
		/// Accumulate a scaling to this model matrix.
		/// </summary>
		/// <param name="s">
		/// A <see cref="Vertex3d"/> holding the scaling factors on three dimensions.
		/// </param>
		public void Scale(Vertex3d s)
		{
			ModelMatrixDouble scaleModel = new ModelMatrixDouble();

			scaleModel[0, 0] = s.x;
			scaleModel[1, 1] = s.y;
			scaleModel[2, 2] = s.z;

			Set(this * scaleModel);
		}
		/// <summary>
		/// Setup this matrix to view the universe in a certain direction.
		/// </summary>
		/// <param name="eyePosition">
		/// A <see cref="Vertex3f"/> that specify the eye position, in local coordinates.
		/// </param>
		/// <param name="forwardVector">
		/// A <see cref="Vertex3f"/> that specify the direction of the view. It will be normalized.
		/// </param>
		/// <param name="upVector">
		/// A <see cref="Vertex3f"/> that specify the up vector of the view camera abstraction. It will be normalized
		/// </param>
		/// <returns>
		/// It returns a view transformation matrix used to transform the world coordinate, in order to view
		/// the world from <paramref name="eyePosition"/>, looking at <paramref name="forwardVector"/> having
		/// an up direction equal to <paramref name="upVector"/>.
		/// </returns>
		public void LookAtDirection(Vertex3d eyePosition, Vertex3d forwardVector, Vertex3d upVector)
		{
			Vertex3d rightVector;

			// Normalize forward vector
			forwardVector.Normalize();
			// Normalize up vector (it should already be normalized)
			upVector.Normalize();
			// Compute the right vector (cross-product between forward and up vectors; right is perperndicular to the plane)
			rightVector = forwardVector ^ upVector;
			rightVector.Normalize();
			// Derive up vector
			upVector = rightVector ^ forwardVector;

			// Compute view matrix
			ModelMatrixDouble lookatMatrix = new ModelMatrixDouble(), positionMatrix = new ModelMatrixDouble();

			// Row 0: right vector
			lookatMatrix[0, 0] = rightVector.x;
			lookatMatrix[0, 1] = rightVector.y;
			lookatMatrix[0, 2] = rightVector.z;
			// Row 1: up vector
			lookatMatrix[1, 0] = upVector.x;
			lookatMatrix[1, 1] = upVector.y;
			lookatMatrix[1, 2] = upVector.z;
			// Row 2: opposite of forward vector
			lookatMatrix[2, 0] = -forwardVector.x;
			lookatMatrix[2, 1] = -forwardVector.y;
			lookatMatrix[2, 2] = -forwardVector.z;

			// Eye position
			positionMatrix.Translate(eyePosition);

			// Complete look-at matrix
			Set(positionMatrix * lookatMatrix);
		}
		/// <summary>
		/// Translate a ModelMatrix in two-dimensional space.
		/// </summary>
		/// <param name="m"></param>
		/// <param name="v"></param>
		/// <returns></returns>
		public static ModelMatrixDouble operator -(ModelMatrixDouble m, Vertex2d v)
		{
			ModelMatrixDouble res = new ModelMatrixDouble(m);

			res.Translate(-v);

			return (res);
		}
		/// <summary>
		/// Multiply this IModelMatrix with another IModelMatrix.
		/// </summary>
		/// <param name="a">
		/// A <see cref="IModelMatrix"/> that specifies the right multiplication operand.
		/// </param>
		/// <returns>
		/// A <see cref="IModelMatrix"/> resulting from the product of this matrix and the matrix <paramref name="a"/>.
		/// </returns>
		IModelMatrix IModelMatrix.Multiply(IModelMatrix a)
		{
			ModelMatrixDouble rModelMatrix = new ModelMatrixDouble();

			ModelMatrixDouble modelMatrixDouble = a as ModelMatrixDouble;
			if (modelMatrixDouble != null) {
				ComputeMatrixProduct(rModelMatrix, this, modelMatrixDouble);
				return (rModelMatrix);
			}

			ModelMatrix modelMatrix = a as ModelMatrix;
			if (modelMatrix != null) {
				ComputeMatrixProduct(rModelMatrix, this, modelMatrix);
				return (rModelMatrix);
			}

			throw new NotSupportedException(String.Format("multiplication of {0} by {1} is not supported", GetType(), a.GetType()));
		}
		/// <summary>
		/// ModelMatrixDouble copy constructor.
		/// </summary>
		/// <param name="m">
		/// A <see cref="ModelMatrix"/> to be copied.
		/// </param>
		public ModelMatrixDouble(ModelMatrixDouble m)
			: base(m)
		{

		}