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);
}
}
}