using System; using System.Collections.Generic; using System.Linq; using UnityEngine.Experimental.Rendering; namespace UnityEngine.Rendering { using UnityObject = UnityEngine.Object; /// /// Set of utility functions for the Core Scriptable Render Pipeline Library related to Matrix operations /// public static class CoreMatrixUtils { /// /// This function provides the equivalent of multiplying matrix parameter inOutMatrix with a translation matrix defined by the parameter translation. /// The order of the equivalent multiplication is inOutMatrix * translation. /// /// Matrix to multiply with translation. /// Translation component to multiply to the matrix. public static void MatrixTimesTranslation(ref Matrix4x4 inOutMatrix, Vector3 translation) { inOutMatrix.m03 += (inOutMatrix.m00 * translation.x + inOutMatrix.m01 * translation.y + inOutMatrix.m02 * translation.z); inOutMatrix.m13 += (inOutMatrix.m10 * translation.x + inOutMatrix.m11 * translation.y + inOutMatrix.m12 * translation.z); inOutMatrix.m23 += (inOutMatrix.m20 * translation.x + inOutMatrix.m21 * translation.y + inOutMatrix.m22 * translation.z); } /// /// This function provides the equivalent of multiplying a translation matrix defined by the parameter translation with the matrix specified by the parameter inOutMatrix. /// The order of the equivalent multiplication is translation * inOutMatrix. /// /// Matrix to multiply with translation. /// Translation component to multiply to the matrix. public static void TranslationTimesMatrix(ref Matrix4x4 inOutMatrix, Vector3 translation) { inOutMatrix.m00 += translation.x * inOutMatrix.m30; inOutMatrix.m01 += translation.x * inOutMatrix.m31; inOutMatrix.m02 += translation.x * inOutMatrix.m32; inOutMatrix.m03 += translation.x * inOutMatrix.m33; inOutMatrix.m10 += translation.y * inOutMatrix.m30; inOutMatrix.m11 += translation.y * inOutMatrix.m31; inOutMatrix.m12 += translation.y * inOutMatrix.m32; inOutMatrix.m13 += translation.y * inOutMatrix.m33; inOutMatrix.m20 += translation.z * inOutMatrix.m30; inOutMatrix.m21 += translation.z * inOutMatrix.m31; inOutMatrix.m22 += translation.z * inOutMatrix.m32; inOutMatrix.m23 += translation.z * inOutMatrix.m33; } /// /// Multiplies a matrix with a perspective matrix. This function is faster than performing the full matrix multiplication. /// The operation order is perspective * rhs. /// /// The perspective matrix to multiply with rhs. /// A matrix to be multiply to perspective. /// Returns the matrix that is the result of the multiplication. public static Matrix4x4 MultiplyPerspectiveMatrix(Matrix4x4 perspective, Matrix4x4 rhs) { Matrix4x4 outMat; outMat.m00 = perspective.m00 * rhs.m00; outMat.m01 = perspective.m00 * rhs.m01; outMat.m02 = perspective.m00 * rhs.m02; outMat.m03 = perspective.m00 * rhs.m03; outMat.m10 = perspective.m11 * rhs.m10; outMat.m11 = perspective.m11 * rhs.m11; outMat.m12 = perspective.m11 * rhs.m12; outMat.m13 = perspective.m11 * rhs.m13; outMat.m20 = perspective.m22 * rhs.m20 + perspective.m23 * rhs.m30; outMat.m21 = perspective.m22 * rhs.m21 + perspective.m23 * rhs.m31; outMat.m22 = perspective.m22 * rhs.m22 + perspective.m23 * rhs.m32; outMat.m23 = perspective.m22 * rhs.m23 + perspective.m23 * rhs.m33; outMat.m30 = -rhs.m20; outMat.m31 = -rhs.m21; outMat.m32 = -rhs.m22; outMat.m33 = -rhs.m23; return outMat; } // An orthographic projection is centered if (right+left) == 0 and (top+bottom) == 0 private static Matrix4x4 MultiplyOrthoMatrixCentered(Matrix4x4 ortho, Matrix4x4 rhs) { Matrix4x4 outMat; outMat.m00 = ortho.m00 * rhs.m00; outMat.m01 = ortho.m00 * rhs.m01; outMat.m02 = ortho.m00 * rhs.m02; outMat.m03 = ortho.m00 * rhs.m03; outMat.m10 = ortho.m11 * rhs.m10; outMat.m11 = ortho.m11 * rhs.m11; outMat.m12 = ortho.m11 * rhs.m12; outMat.m13 = ortho.m11 * rhs.m13; outMat.m20 = ortho.m22 * rhs.m20 + ortho.m23 * rhs.m30; outMat.m21 = ortho.m22 * rhs.m21 + ortho.m23 * rhs.m31; outMat.m22 = ortho.m22 * rhs.m22 + ortho.m23 * rhs.m32; outMat.m23 = ortho.m22 * rhs.m23 + ortho.m23 * rhs.m33; outMat.m30 = rhs.m20; outMat.m31 = rhs.m21; outMat.m32 = rhs.m22; outMat.m33 = rhs.m23; return outMat; } // General case has m03 and m13 != 0 private static Matrix4x4 MultiplyGenericOrthoMatrix(Matrix4x4 ortho, Matrix4x4 rhs) { Matrix4x4 outMat; outMat.m00 = ortho.m00 * rhs.m00 + ortho.m03 * rhs.m30; outMat.m01 = ortho.m00 * rhs.m01 + ortho.m03 * rhs.m31; outMat.m02 = ortho.m00 * rhs.m02 + ortho.m03 * rhs.m32; outMat.m03 = ortho.m00 * rhs.m03 + ortho.m03 * rhs.m33; outMat.m10 = ortho.m11 * rhs.m10 + ortho.m13 * rhs.m30; outMat.m11 = ortho.m11 * rhs.m11 + ortho.m13 * rhs.m31; outMat.m12 = ortho.m11 * rhs.m12 + ortho.m13 * rhs.m32; outMat.m13 = ortho.m11 * rhs.m13 + ortho.m13 * rhs.m33; outMat.m20 = ortho.m22 * rhs.m20 + ortho.m23 * rhs.m30; outMat.m21 = ortho.m22 * rhs.m21 + ortho.m23 * rhs.m31; outMat.m22 = ortho.m22 * rhs.m22 + ortho.m23 * rhs.m32; outMat.m23 = ortho.m22 * rhs.m23 + ortho.m23 * rhs.m33; outMat.m30 = rhs.m20; outMat.m31 = rhs.m21; outMat.m32 = rhs.m22; outMat.m33 = rhs.m23; return outMat; } /// /// Multiplies a matrix with an orthographic matrix. This function is faster than performing the full matrix multiplication. /// The operation order is ortho * rhs. /// /// The ortho matrix to multiply with rhs. /// A matrix to be multiply to perspective. /// If true, it means that right and left are equivalently distant from center and similarly top/bottom are equivalently distant from center. /// Returns the matrix that is the result of the multiplication. public static Matrix4x4 MultiplyOrthoMatrix(Matrix4x4 ortho, Matrix4x4 rhs, bool centered) { return centered ? MultiplyGenericOrthoMatrix(ortho, rhs) : MultiplyOrthoMatrixCentered(ortho, rhs); } /// /// Multiplies a matrix with a projection matrix. This function is faster than performing the full matrix multiplication. /// The operation order is projMatrix * rhs. /// /// The projection matrix to multiply with rhs. /// A matrix to be multiply to perspective. /// If true, the projection matrix is a centered ( right+left == top+bottom == 0) orthographic projection, otherwise it is a perspective matrix.. /// Returns the matrix that is the result of the multiplication. public static Matrix4x4 MultiplyProjectionMatrix(Matrix4x4 projMatrix, Matrix4x4 rhs, bool orthoCentered) { return orthoCentered ? MultiplyOrthoMatrixCentered(projMatrix, rhs) : MultiplyPerspectiveMatrix(projMatrix, rhs); } } }