/// <summary> /// Transforms the ray by the specified affine matrix. /// </summary> /// <param name="matrix">Affine matrix to transform the ray by.</param> public void TransformAffine(Matrix4 matrix) { Vector3 end = this * 1.0f; origin = matrix.MultiplyDirection(origin); end = matrix.MultiplyDirection(end); direction = Vector3.Normalize(end - origin); }
/// <summary> /// Calculates the inverse of the matrix. Matrix must be affine. /// </summary> public void InvertAffine() { float t00 = m22 * m11 - m21 * m12; float t10 = m20 * m12 - m22 * m10; float t20 = m21 * m10 - m20 * m11; float invDet = 1 / (m00 * t00 + m01 * t10 + m02 * t20); t00 *= invDet; t10 *= invDet; t20 *= invDet; m00 *= invDet; m01 *= invDet; m02 *= invDet; float r00 = t00; float r01 = m02 * m21 - m01 * m22; float r02 = m01 * m12 - m02 * m11; float r10 = t10; float r11 = m00 * m22 - m02 * m20; float r12 = m02 * m10 - m00 * m12; float r20 = t20; float r21 = m01 * m20 - m00 * m21; float r22 = m00 * m11 - m01 * m10; float r03 = -(r00 * m03 + r01 * m13 + r02 * m23); float r13 = -(r10 * m03 + r11 * m13 + r12 * m23); float r23 = -(r20 * m03 + r21 * m13 + r22 * m23); this = new Matrix4( r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, 0, 0, 0, 1); }
/// <summary> /// Transforms the bounding box by the given matrix. /// /// As the resulting box will no longer be axis aligned, an axis align box is instead created by encompassing the /// transformed oriented bounding box. Retrieving the value as an actual OBB would provide a tighter fit. /// </summary> /// <param name="tfrm">Affine matrix to transform the box with.</param> public void TransformAffine(Matrix4 tfrm) { Vector3 center = Center; Vector3 halfSize = Size*0.5f; Vector3 newCenter = tfrm.MultiplyAffine(center); Vector3 newHalfSize = new Vector3( MathEx.Abs(tfrm.m00) * halfSize.x + MathEx.Abs(tfrm.m01) * halfSize.y + MathEx.Abs(tfrm.m02) * halfSize.z, MathEx.Abs(tfrm.m10) * halfSize.x + MathEx.Abs(tfrm.m11) * halfSize.y + MathEx.Abs(tfrm.m12) * halfSize.z, MathEx.Abs(tfrm.m20) * halfSize.x + MathEx.Abs(tfrm.m21) * halfSize.y + MathEx.Abs(tfrm.m22) * halfSize.z); minimum = newCenter - newHalfSize; maximum = newCenter + newHalfSize; }
/// <summary> /// Creates a new matrix that performs translation, rotation and scale. /// </summary> /// <param name="translation">Offset to translate by.</param> /// <param name="rotation">Rotation quaternion.</param> /// <param name="scale">Non-uniform scale factors.</param> /// <returns>Matrix that performs scale, followed by rotation, followed by translation. </returns> public static Matrix4 TRS(Vector3 translation, Quaternion rotation, Vector3 scale) { Matrix3 rot3x3 = rotation.ToRotationMatrix(); Matrix4 mat = new Matrix4(); mat.m00 = scale.x * rot3x3.m00; mat.m01 = scale.y * rot3x3.m01; mat.m02 = scale.z * rot3x3.m02; mat.m03 = translation.x; mat.m10 = scale.x * rot3x3.m10; mat.m11 = scale.y * rot3x3.m11; mat.m12 = scale.z * rot3x3.m12; mat.m13 = translation.y; mat.m20 = scale.x * rot3x3.m20; mat.m21 = scale.y * rot3x3.m21; mat.m22 = scale.z * rot3x3.m22; mat.m23 = translation.z; // No projection term mat.m30 = 0; mat.m31 = 0; mat.m32 = 0; mat.m33 = 1; return mat; }
/// <summary> /// Calculates the inverse of the matrix. If matrix is affine use <see cref="InvertAffine()"/> as it is faster. /// </summary> public void Invert() { float v0 = m20 * m31 - m21 * m30; float v1 = m20 * m32 - m22 * m30; float v2 = m20 * m33 - m23 * m30; float v3 = m21 * m32 - m22 * m31; float v4 = m21 * m33 - m23 * m31; float v5 = m22 * m33 - m23 * m32; float t00 = +(v5 * m11 - v4 * m12 + v3 * m13); float t10 = -(v5 * m10 - v2 * m12 + v1 * m13); float t20 = +(v4 * m10 - v2 * m11 + v0 * m13); float t30 = -(v3 * m10 - v1 * m11 + v0 * m12); float invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03); float d00 = t00 * invDet; float d10 = t10 * invDet; float d20 = t20 * invDet; float d30 = t30 * invDet; float d01 = -(v5 * m01 - v4 * m02 + v3 * m03) * invDet; float d11 = +(v5 * m00 - v2 * m02 + v1 * m03) * invDet; float d21 = -(v4 * m00 - v2 * m01 + v0 * m03) * invDet; float d31 = +(v3 * m00 - v1 * m01 + v0 * m02) * invDet; v0 = m10 * m31 - m11 * m30; v1 = m10 * m32 - m12 * m30; v2 = m10 * m33 - m13 * m30; v3 = m11 * m32 - m12 * m31; v4 = m11 * m33 - m13 * m31; v5 = m12 * m33 - m13 * m32; float d02 = +(v5 * m01 - v4 * m02 + v3 * m03) * invDet; float d12 = -(v5 * m00 - v2 * m02 + v1 * m03) * invDet; float d22 = +(v4 * m00 - v2 * m01 + v0 * m03) * invDet; float d32 = -(v3 * m00 - v1 * m01 + v0 * m02) * invDet; v0 = m21 * m10 - m20 * m11; v1 = m22 * m10 - m20 * m12; v2 = m23 * m10 - m20 * m13; v3 = m22 * m11 - m21 * m12; v4 = m23 * m11 - m21 * m13; v5 = m23 * m12 - m22 * m13; float d03 = -(v5 * m01 - v4 * m02 + v3 * m03) * invDet; float d13 = +(v5 * m00 - v2 * m02 + v1 * m03) * invDet; float d23 = -(v4 * m00 - v2 * m01 + v0 * m03) * invDet; float d33 = +(v3 * m00 - v1 * m01 + v0 * m02) * invDet; this = new Matrix4( d00, d01, d02, d03, d10, d11, d12, d13, d20, d21, d22, d23, d30, d31, d32, d33); }
/// <summary> /// Returns the rotation/scaling parts of a 4x4 matrix. /// </summary> /// <param name="mat">Matrix to extract the rotation/scaling from.</param> /// <returns>3x3 matrix representing an upper left portion of the provided matrix.</returns> public static Matrix3 ToMatrix3(Matrix4 mat) { return new Matrix3( mat.m00, mat.m01, mat.m02, mat.m10, mat.m11, mat.m12, mat.m20, mat.m21, mat.m22); }
/// <summary> /// Returns a transpose of the matrix (switched columns and rows). /// </summary> public static Matrix4 Transpose(Matrix4 mat) { Matrix4 copy = mat; copy.Transpose(); return copy; }
/// <summary> /// Returns the inverse of the affine matrix. Faster than <see cref="Invert(Matrix4)"/>. /// </summary> /// <param name="mat">Affine matrix to take inverse of.</param> /// <returns>Inverse of the provided matrix.</returns> public static Matrix4 InvertAffine(Matrix4 mat) { Matrix4 copy = mat; copy.InvertAffine(); return copy; }
private static extern void Internal_SetMatrix4(IntPtr nativeInstance, string name, ref Matrix4 value);
/// <summary> /// Assigns a 4x4 matrix to the shader parameter with the specified name. /// </summary> /// <param name="name">Name of the shader parameter.</param> /// <param name="value">Value of the parameter.</param> public void SetMatrix4(string name, Matrix4 value) { Internal_SetMatrix4(mCachedPtr, name, ref value); }
private static extern void Internal_GetViewMatrixInv(IntPtr instance, out Matrix4 output);
private static extern void Internal_GetProjMatrix(IntPtr instance, out Matrix4 output);