/// <summary> /// Transforms a vector using a matrix. /// </summary> /// <param name="v">Vector to transform.</param> /// <param name="matrix">Transform to apply to the vector.</param> /// <returns>Transformed vector.</returns> public static fix4 Transform(fix3 v, fix4x4 matrix) { fix4 toReturn; Transform(v, matrix, out toReturn); return(toReturn); }
/// <summary> /// Creates a view matrix pointing from a position to a target with the given up vector. /// </summary> /// <param name="position">Position of the camera.</param> /// <param name="target">Target of the camera.</param> /// <param name="upVector">Up vector of the camera.</param> /// <param name="viewMatrix">Look at matrix.</param> public static void CreateLookAtRH(fix3 position, fix3 target, fix3 upVector, out fix4x4 viewMatrix) { fix3 forward; fix3.Subtract(target, position, out forward); CreateViewRH(position, forward, upVector, out viewMatrix); }
/// <summary> /// Transforms a vector using the transpose of a matrix. /// </summary> /// <param name="v">Vector to transform.</param> /// <param name="matrix">Transform to tranpose and apply to the vector.</param> /// <returns>Transformed vector.</returns> public static fix4 TransformTranspose(fix4 v, fix4x4 matrix) { fix4 toReturn; TransformTranspose(v, matrix, out toReturn); return(toReturn); }
/// <summary> /// Inverts the matrix using a process that only works for rigid transforms. /// </summary> /// <param name="m">FixMatrix to invert.</param> /// <param name="inverted">Inverted version of the matrix.</param> public static void InvertRigid(fix4x4 m, out fix4x4 inverted) { //Invert (transpose) the upper left 3x3 rotation. fix intermediate = m.M21; inverted.M21 = m.M12; inverted.M12 = intermediate; intermediate = m.M31; inverted.M31 = m.M13; inverted.M13 = intermediate; intermediate = m.M32; inverted.M32 = m.M23; inverted.M23 = intermediate; inverted.M11 = m.M11; inverted.M22 = m.M22; inverted.M33 = m.M33; //Translation component var vX = m.M14; var vY = m.M24; var vZ = m.M34; inverted.M14 = -(vX * inverted.M11 + vY * inverted.M12 + vZ * inverted.M13); inverted.M24 = -(vX * inverted.M21 + vY * inverted.M22 + vZ * inverted.M23); inverted.M34 = -(vX * inverted.M31 + vY * inverted.M32 + vZ * inverted.M33); //Last chunk. inverted.M41 = F64.C0; inverted.M42 = F64.C0; inverted.M43 = F64.C0; inverted.M44 = F64.C1; }
/// <summary> /// Transforms a vector using a matrix. /// </summary> /// <param name="v">Vector to transform.</param> /// <param name="matrix">Transform to apply to the vector.</param> /// <param name="result">Transformed vector.</param> public static void Transform(fix3 v, fix4x4 matrix, out fix4 result) { result.x = v.x * matrix.M11 + v.y * matrix.M12 + v.z * matrix.M13 + matrix.M14; result.y = v.x * matrix.M21 + v.y * matrix.M22 + v.z * matrix.M23 + matrix.M24; result.z = v.x * matrix.M31 + v.y * matrix.M32 + v.z * matrix.M33 + matrix.M34; result.w = v.x * matrix.M41 + v.y * matrix.M42 + v.z * matrix.M43 + matrix.M44; }
/// <summary> /// Transforms a postion using a matrix. /// </summary> /// <param name="v">Position to transform.</param> /// <param name="matrix">Transform to apply to the vector.</param> /// <returns>Transformed vector.</returns> public static fix3 TransformPoint(fix3 v, fix4x4 matrix) { fix4 result; Transform(v, matrix, out result); return(new fix3(result.x / result.w, result.y / result.w, result.z / result.w)); }
/// <summary> /// Creates a matrix representing the given axis and angle rotation. /// </summary> /// <param name="axis">Axis around which to rotate.</param> /// <param name="angle">Angle to rotate around the axis.</param> /// <param name="result">FixMatrix created from the axis and angle.</param> public static void CreateFromAxisAngle(fix3 axis, fix angle, out fix4x4 result) { fix xx = axis.x * axis.x; fix yy = axis.y * axis.y; fix zz = axis.z * axis.z; fix xy = axis.x * axis.y; fix xz = axis.x * axis.z; fix yz = axis.y * axis.z; fix sinAngle = fix.Sin(angle); fix oneMinusCosAngle = F64.C1 - fix.Cos(angle); result.M11 = F64.C1 + oneMinusCosAngle * (xx - F64.C1); result.M12 = -axis.z * sinAngle + oneMinusCosAngle * xy; result.M13 = axis.y * sinAngle + oneMinusCosAngle * xz; result.M14 = F64.C0; result.M21 = axis.z * sinAngle + oneMinusCosAngle * xy; result.M22 = F64.C1 + oneMinusCosAngle * (yy - F64.C1); result.M23 = -axis.x * sinAngle + oneMinusCosAngle * yz; result.M24 = F64.C0; result.M31 = -axis.y * sinAngle + oneMinusCosAngle * xz; result.M32 = axis.x * sinAngle + oneMinusCosAngle * yz; result.M33 = F64.C1 + oneMinusCosAngle * (zz - F64.C1); result.M34 = F64.C0; result.M41 = F64.C0; result.M42 = F64.C0; result.M43 = F64.C0; result.M44 = F64.C1; }
/// <summary> /// Transforms a vector using the transpose of a matrix. /// </summary> /// <param name="v">Vector to transform.</param> /// <param name="matrix">Transform to tranpose and apply to the vector.</param> /// <param name="result">Transformed vector.</param> public static void TransformTranspose(fix3 v, fix4x4 matrix, out fix4 result) { result.x = v.x * matrix.M11 + v.y * matrix.M21 + v.z * matrix.M31 + matrix.M41; result.y = v.x * matrix.M12 + v.y * matrix.M22 + v.z * matrix.M32 + matrix.M42; result.z = v.x * matrix.M13 + v.y * matrix.M23 + v.z * matrix.M33 + matrix.M43; result.w = v.x * matrix.M14 + v.y * matrix.M24 + v.z * matrix.M34 + matrix.M44; }
/// <summary> /// Transposes the matrix. /// </summary> /// <param name="m">FixMatrix to transpose.</param> /// <param name="transposed">FixMatrix to transpose.</param> public static void Transpose(fix4x4 m, out fix4x4 transposed) { fix intermediate = m.M21; transposed.M21 = m.M12; transposed.M12 = intermediate; intermediate = m.M31; transposed.M31 = m.M13; transposed.M13 = intermediate; intermediate = m.M41; transposed.M41 = m.M14; transposed.M14 = intermediate; intermediate = m.M32; transposed.M32 = m.M23; transposed.M23 = intermediate; intermediate = m.M42; transposed.M42 = m.M24; transposed.M24 = intermediate; intermediate = m.M43; transposed.M43 = m.M34; transposed.M34 = intermediate; transposed.M11 = m.M11; transposed.M22 = m.M22; transposed.M33 = m.M33; transposed.M44 = m.M44; }
/// <summary> /// Transforms a vector using the transpose of a matrix. /// </summary> /// <param name="v">Vector to transform.</param> /// <param name="matrix">Transform to tranpose and apply to the vector.</param> /// <returns>Transformed vector.</returns> public static fix3 TransformNormalTranspose(fix3 v, fix4x4 matrix) { fix3 toReturn; TransformNormalTranspose(v, matrix, out toReturn); return(toReturn); }
/// <summary> /// Multiplies two matrices together. /// </summary> /// <param name="a">First matrix to multiply.</param> /// <param name="b">Second matrix to multiply.</param> /// <returns>Combined transformation.</returns> public static fix4x4 Multiply(fix4x4 a, fix4x4 b) { fix4x4 result; Multiply(a, b, out result); return(result); }
/// <summary> /// Inverts the matrix. /// </summary> /// <param name="m">FixMatrix to invert.</param> /// <returns>Inverted version of the matrix.</returns> public static fix4x4 Invert(fix4x4 m) { fix4x4 inverted; Invert(m, out inverted); return(inverted); }
/// <summary> /// Creates a rotation matrix from a quaternion. /// </summary> /// <param name="quaternion">FixQuaternion to convert.</param> /// <param name="result">Rotation matrix created from the quaternion.</param> public static void CreateFromQuaternion(fixQuaternion quaternion, out fix4x4 result) { fix qX2 = quaternion.x + quaternion.x; fix qY2 = quaternion.y + quaternion.y; fix qZ2 = quaternion.z + quaternion.z; fix XX = qX2 * quaternion.x; fix YY = qY2 * quaternion.y; fix ZZ = qZ2 * quaternion.z; fix XY = qX2 * quaternion.y; fix XZ = qX2 * quaternion.z; fix XW = qX2 * quaternion.w; fix YZ = qY2 * quaternion.z; fix YW = qY2 * quaternion.w; fix ZW = qZ2 * quaternion.w; result.M11 = F64.C1 - YY - ZZ; result.M12 = XY - ZW; result.M13 = XZ + YW; result.M14 = F64.C0; result.M21 = XY + ZW; result.M22 = F64.C1 - XX - ZZ; result.M23 = YZ - XW; result.M24 = F64.C0; result.M31 = XZ - YW; result.M32 = YZ + XW; result.M33 = F64.C1 - XX - YY; result.M34 = F64.C0; result.M41 = F64.C0; result.M42 = F64.C0; result.M43 = F64.C0; result.M44 = F64.C1; }
/// <summary> /// Creates a world matrix pointing from a position to a target with the given up vector. /// </summary> /// <param name="position">Position of the transform.</param> /// <param name="forward">Forward direction of the transformation.</param> /// <param name="upVector">Up vector which is crossed against the forward vector to compute the transform's basis.</param> /// <param name="worldMatrix">World matrix.</param> public static void CreateWorldRH(fix3 position, fix3 forward, fix3 upVector, out fix4x4 worldMatrix) { fix3 z; fix length = forward.length; fix3.Divide(forward, -length, out z); fix3 x; fix3.Cross(upVector, z, out x); x.Normalize(); fix3 y; fix3.Cross(z, x, out y); worldMatrix.M11 = x.x; worldMatrix.M21 = x.y; worldMatrix.M31 = x.z; worldMatrix.M41 = F64.C0; worldMatrix.M12 = y.x; worldMatrix.M22 = y.y; worldMatrix.M32 = y.z; worldMatrix.M42 = F64.C0; worldMatrix.M13 = z.x; worldMatrix.M23 = z.y; worldMatrix.M33 = z.z; worldMatrix.M43 = F64.C0; worldMatrix.M14 = position.x; worldMatrix.M24 = position.y; worldMatrix.M34 = position.z; worldMatrix.M44 = F64.C1; }
/// <summary> /// Creates a view matrix pointing in a direction with a given up vector. /// </summary> /// <param name="position">Position of the camera.</param> /// <param name="forward">Forward direction of the camera.</param> /// <param name="upVector">Up vector of the camera.</param> /// <param name="viewMatrix">Look at matrix.</param> public static void CreateViewRH(fix3 position, fix3 forward, fix3 upVector, out fix4x4 viewMatrix) { fix3 z; fix length = forward.length; fix3.Divide(forward, -length, out z); fix3 x; fix3.Cross(upVector, z, out x); x.Normalize(); fix3 y; fix3.Cross(z, x, out y); viewMatrix.M11 = x.x; viewMatrix.M21 = y.x; viewMatrix.M31 = z.x; viewMatrix.M41 = F64.C0; viewMatrix.M12 = x.y; viewMatrix.M22 = y.y; viewMatrix.M32 = z.y; viewMatrix.M42 = F64.C0; viewMatrix.M13 = x.z; viewMatrix.M23 = y.z; viewMatrix.M33 = z.z; viewMatrix.M43 = F64.C0; fix3.Dot(x, position, out viewMatrix.M14); fix3.Dot(y, position, out viewMatrix.M24); fix3.Dot(z, position, out viewMatrix.M34); viewMatrix.M14 = -viewMatrix.M14; viewMatrix.M24 = -viewMatrix.M24; viewMatrix.M34 = -viewMatrix.M34; viewMatrix.M44 = F64.C1; }
/// <summary> /// Creates a matrix representing the given axis aligned scale. /// </summary> /// <param name="scale">Scale to be represented by the matrix.</param> /// <param name="scaleMatrix">FixMatrix representing the given scale.</param> public static void CreateScale(fix3 scale, out fix4x4 scaleMatrix) { scaleMatrix = new fix4x4 { M11 = scale.x, M22 = scale.y, M33 = scale.z, M44 = F64.C1 }; }
/// <summary> /// Creates a matrix representing the given axis aligned scale. /// </summary> /// <param name="x">Scale along the x axis.</param> /// <param name="y">Scale along the y axis.</param> /// <param name="z">Scale along the z axis.</param> /// <param name="scaleMatrix">FixMatrix representing the given scale.</param> public static void CreateScale(fix x, fix y, fix z, out fix4x4 scaleMatrix) { scaleMatrix = new fix4x4 { M11 = x, M22 = y, M33 = z, M44 = F64.C1 }; }
/// <summary> /// Transforms a vector using the transpose of a matrix. /// </summary> /// <param name="v">Vector to transform.</param> /// <param name="matrix">Transform to tranpose and apply to the vector.</param> /// <param name="result">Transformed vector.</param> public static void TransformNormalTranspose(fix3 v, fix4x4 matrix, out fix3 result) { fix vX = v.x; fix vY = v.y; fix vZ = v.z; result.x = vX * matrix.M11 + vY * matrix.M21 + vZ * matrix.M31; result.y = vX * matrix.M12 + vY * matrix.M22 + vZ * matrix.M32; result.z = vX * matrix.M13 + vY * matrix.M23 + vZ * matrix.M33; }
/// <summary> /// Transforms a vector using a matrix. /// </summary> /// <param name="v">Vector to transform.</param> /// <param name="matrix">Transform to apply to the vector.</param> /// <param name="result">Transformed vector.</param> public static void Transform(fix3 v, fix4x4 matrix, out fix3 result) { fix vX = v.x; fix vY = v.y; fix vZ = v.z; result.x = vX * matrix.M11 + vY * matrix.M12 + vZ * matrix.M13 + matrix.M14; result.y = vX * matrix.M21 + vY * matrix.M22 + vZ * matrix.M23 + matrix.M24; result.z = vX * matrix.M31 + vY * matrix.M32 + vZ * matrix.M33 + matrix.M34; }
/// <summary> /// Transforms a vector using the transpose of a matrix. /// </summary> /// <param name="v">Vector to transform.</param> /// <param name="matrix">Transform to tranpose and apply to the vector.</param> /// <param name="result">Transformed vector.</param> public static void TransformTranspose(fix4 v, fix4x4 matrix, out fix4 result) { fix vX = v.x; fix vY = v.y; fix vZ = v.z; fix vW = v.w; result.x = vX * matrix.M11 + vY * matrix.M21 + vZ * matrix.M31 + vW * matrix.M41; result.y = vX * matrix.M12 + vY * matrix.M22 + vZ * matrix.M32 + vW * matrix.M42; result.z = vX * matrix.M13 + vY * matrix.M23 + vZ * matrix.M33 + vW * matrix.M43; result.w = vX * matrix.M14 + vY * matrix.M24 + vZ * matrix.M34 + vW * matrix.M44; }
/// <summary> /// Creates a matrix representing a translation. /// </summary> /// <param name="translation">Translation to be represented by the matrix.</param> /// <param name="translationMatrix">FixMatrix representing the given translation.</param> public static void CreateTranslation(fix3 translation, out fix4x4 translationMatrix) { translationMatrix = new fix4x4 { M11 = F64.C1, M22 = F64.C1, M33 = F64.C1, M44 = F64.C1, M14 = translation.x, M24 = translation.y, M34 = translation.z }; }
/// <summary> /// Creates a 3x3 matrix from an XNA 4x4 matrix. /// </summary> /// <param name="matrix4X4">FixMatrix to extract a 3x3 matrix from.</param> /// <param name="matrix3X3">Upper 3x3 matrix extracted from the XNA matrix.</param> public static void CreateFromMatrix(fix4x4 matrix4X4, out fix3x3 matrix3X3) { matrix3X3.M11 = matrix4X4.M11; matrix3X3.M12 = matrix4X4.M21; matrix3X3.M13 = matrix4X4.M31; matrix3X3.M21 = matrix4X4.M12; matrix3X3.M22 = matrix4X4.M22; matrix3X3.M23 = matrix4X4.M32; matrix3X3.M31 = matrix4X4.M13; matrix3X3.M32 = matrix4X4.M23; matrix3X3.M33 = matrix4X4.M33; }
/// <summary> /// Adds the two matrices together on a per-element basis. /// </summary> /// <param name="a">First matrix to add.</param> /// <param name="b">Second matrix to add.</param> /// <param name="result">Sum of the two matrices.</param> public static void Add(ref fix4x4 a, ref fix2x2 b, out fix2x2 result) { fix m11 = a.M11 + b.M11; fix m12 = a.M21 + b.M12; fix m21 = a.M12 + b.M21; fix m22 = a.M22 + b.M22; result.M11 = m11; result.M12 = m12; result.M21 = m21; result.M22 = m22; }
/// <summary> /// Multiplies the two matrices. /// </summary> /// <param name="a">First matrix to multiply.</param> /// <param name="b">Second matrix to multiply.</param> /// <param name="result">Product of the multiplication.</param> public static void Multiply(ref fix4x4 a, ref fix2x2 b, out fix2x2 result) { fix resultM11 = a.M11 * b.M11 + a.M21 * b.M21; fix resultM12 = a.M11 * b.M12 + a.M21 * b.M22; fix resultM21 = a.M12 * b.M11 + a.M22 * b.M21; fix resultM22 = a.M12 * b.M12 + a.M22 * b.M22; result.M11 = resultM11; result.M12 = resultM12; result.M21 = resultM21; result.M22 = resultM22; }
/// <summary> /// Creates a transform matrix with the given positon, rotation and scale /// </summary> public static void CreateTRS(fix3 position, fixQuaternion rotation, fix3 scale, out fix4x4 worldMatrix) { fix4x4 mat; // Scale CreateScale(scale, out worldMatrix); // Rotation CreateFromQuaternion(rotation, out mat); worldMatrix *= mat; // Translation CreateTranslation(position, out mat); worldMatrix *= mat; }
/// <summary> /// Creates a 3x3 matrix from an XNA 4x4 matrix. /// </summary> /// <param name="matrix4X4">FixMatrix to extract a 3x3 matrix from.</param> /// <returns>Upper 3x3 matrix extracted from the XNA matrix.</returns> public static fix3x3 CreateFromMatrix(fix4x4 matrix4X4) { fix3x3 matrix3X3; matrix3X3.M11 = matrix4X4.M11; matrix3X3.M12 = matrix4X4.M21; matrix3X3.M13 = matrix4X4.M31; matrix3X3.M21 = matrix4X4.M12; matrix3X3.M22 = matrix4X4.M22; matrix3X3.M23 = matrix4X4.M32; matrix3X3.M31 = matrix4X4.M13; matrix3X3.M32 = matrix4X4.M23; matrix3X3.M33 = matrix4X4.M33; return(matrix3X3); }
/// <summary> /// Multiplies the two matrices. /// </summary> /// <param name="a">First matrix to multiply.</param> /// <param name="b">Second matrix to multiply.</param> /// <param name="result">Product of the multiplication.</param> public static void Multiply(ref fix2x3 a, ref fix4x4 b, out fix2x3 result) { fix resultM11 = a.M11 * b.M11 + a.M12 * b.M12 + a.M13 * b.M13; fix resultM12 = a.M11 * b.M21 + a.M12 * b.M22 + a.M13 * b.M23; fix resultM13 = a.M11 * b.M31 + a.M12 * b.M32 + a.M13 * b.M33; fix resultM21 = a.M21 * b.M11 + a.M22 * b.M12 + a.M23 * b.M13; fix resultM22 = a.M21 * b.M21 + a.M22 * b.M22 + a.M23 * b.M23; fix resultM23 = a.M21 * b.M31 + a.M22 * b.M32 + a.M23 * b.M33; result.M11 = resultM11; result.M12 = resultM12; result.M13 = resultM13; result.M21 = resultM21; result.M22 = resultM22; result.M23 = resultM23; }
/// <summary> /// Computes the transposed matrix of a matrix. /// </summary> /// <param name="matrix">FixMatrix to transpose.</param> /// <param name="result">Transposed matrix.</param> public static void Transpose(fix4x4 matrix, out fix3x3 result) { fix m21 = matrix.M21; fix m31 = matrix.M31; fix m12 = matrix.M12; fix m32 = matrix.M32; fix m13 = matrix.M13; fix m23 = matrix.M23; result.M11 = matrix.M11; result.M12 = m12; result.M13 = m13; result.M21 = m21; result.M22 = matrix.M22; result.M23 = m23; result.M31 = m31; result.M32 = m32; result.M33 = matrix.M33; }
/// <summary> /// Multiplies two matrices together. /// </summary> /// <param name="a">First matrix to multiply.</param> /// <param name="b">Second matrix to multiply.</param> /// <param name="result">Combined transformation.</param> public static void Multiply(fix4x4 a, fix4x4 b, out fix4x4 result) { fix resultM11 = a.M11 * b.M11 + a.M21 * b.M12 + a.M31 * b.M13 + a.M41 * b.M14; fix resultM12 = a.M11 * b.M21 + a.M21 * b.M22 + a.M31 * b.M23 + a.M41 * b.M24; fix resultM13 = a.M11 * b.M31 + a.M21 * b.M32 + a.M31 * b.M33 + a.M41 * b.M34; fix resultM14 = a.M11 * b.M41 + a.M21 * b.M42 + a.M31 * b.M43 + a.M41 * b.M44; fix resultM21 = a.M12 * b.M11 + a.M22 * b.M12 + a.M32 * b.M13 + a.M42 * b.M14; fix resultM22 = a.M12 * b.M21 + a.M22 * b.M22 + a.M32 * b.M23 + a.M42 * b.M24; fix resultM23 = a.M12 * b.M31 + a.M22 * b.M32 + a.M32 * b.M33 + a.M42 * b.M34; fix resultM24 = a.M12 * b.M41 + a.M22 * b.M42 + a.M32 * b.M43 + a.M42 * b.M44; fix resultM31 = a.M13 * b.M11 + a.M23 * b.M12 + a.M33 * b.M13 + a.M43 * b.M14; fix resultM32 = a.M13 * b.M21 + a.M23 * b.M22 + a.M33 * b.M23 + a.M43 * b.M24; fix resultM33 = a.M13 * b.M31 + a.M23 * b.M32 + a.M33 * b.M33 + a.M43 * b.M34; fix resultM34 = a.M13 * b.M41 + a.M23 * b.M42 + a.M33 * b.M43 + a.M43 * b.M44; fix resultM41 = a.M14 * b.M11 + a.M24 * b.M12 + a.M34 * b.M13 + a.M44 * b.M14; fix resultM42 = a.M14 * b.M21 + a.M24 * b.M22 + a.M34 * b.M23 + a.M44 * b.M24; fix resultM43 = a.M14 * b.M31 + a.M24 * b.M32 + a.M34 * b.M33 + a.M44 * b.M34; fix resultM44 = a.M14 * b.M41 + a.M24 * b.M42 + a.M34 * b.M43 + a.M44 * b.M44; result.M11 = resultM11; result.M21 = resultM12; result.M31 = resultM13; result.M41 = resultM14; result.M12 = resultM21; result.M22 = resultM22; result.M32 = resultM23; result.M42 = resultM24; result.M13 = resultM31; result.M23 = resultM32; result.M33 = resultM33; result.M43 = resultM34; result.M14 = resultM41; result.M24 = resultM42; result.M34 = resultM43; result.M44 = resultM44; }
/// <summary> /// Scales all components of the matrix. /// </summary> /// <param name="matrix">FixMatrix to scale.</param> /// <param name="scale">Amount to scale.</param> /// <param name="result">Scaled matrix.</param> public static void Multiply(fix4x4 matrix, fix scale, out fix4x4 result) { result.M11 = matrix.M11 * scale; result.M21 = matrix.M21 * scale; result.M31 = matrix.M31 * scale; result.M41 = matrix.M41 * scale; result.M12 = matrix.M12 * scale; result.M22 = matrix.M22 * scale; result.M32 = matrix.M32 * scale; result.M42 = matrix.M42 * scale; result.M13 = matrix.M13 * scale; result.M23 = matrix.M23 * scale; result.M33 = matrix.M33 * scale; result.M43 = matrix.M43 * scale; result.M14 = matrix.M14 * scale; result.M24 = matrix.M24 * scale; result.M34 = matrix.M34 * scale; result.M44 = matrix.M44 * scale; }