您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

112 行
3.4 KiB

using UnityEngine;
namespace Unity.UIWidgets.flow {
public class MatrixDecomposition {
public MatrixDecomposition(Matrix4x4 matrix) {
if (matrix[3, 3] == 0) {
return;
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
matrix[j, i] /= matrix[3, 3];
}
}
Matrix4x4 perpectiveMatrix = matrix;
for (int i = 0; i < 3; i++) {
perpectiveMatrix[3, i] = 0;
}
perpectiveMatrix[3, 3] = 1;
if (perpectiveMatrix.determinant == 0) {
return;
}
if (matrix[3, 0] != 0 || matrix[3, 1] != 0 || matrix[3, 2] != 0) {
Vector4 rightHandSide = new Vector4(matrix[3, 0], matrix[3, 1], matrix[3, 2], matrix[3, 3]);
this.perspective = perpectiveMatrix.inverse.transpose * rightHandSide;
matrix[3, 0] = 0;
matrix[3, 1] = 0;
matrix[3, 2] = 0;
matrix[3, 3] = 1;
}
this.translation = new Vector3(matrix[0, 3], matrix[1, 3], matrix[2, 3]);
matrix[0, 3] = 0;
matrix[1, 3] = 0;
matrix[2, 3] = 0;
Vector3[] row = new Vector3[3];
for (int i = 0; i < 3; i++) {
row[i] = matrix.GetRow(i);
}
this.scale.x = row[0].magnitude;
row[0] = row[0].normalized;
this.shear.x = Vector3.Dot(row[0], row[1]);
row[1] += row[0] * -this.shear.x;
this.scale.y = row[1].magnitude;
row[1] = row[1].normalized;
this.shear.x /= this.scale.y;
this.shear.y = Vector3.Dot(row[0], row[2]);
row[2] += row[0] * -this.shear.y;
this.shear.z = Vector3.Dot(row[1], row[2]);
row[2] += row[1] * -this.shear.z;
this.scale.z = row[2].magnitude;
row[2] = row[2].normalized;
this.shear.y /= this.scale.z;
this.shear.z /= this.scale.z;
if (Vector3.Dot(row[0], Vector3.Cross(row[1], row[2])) < 0) {
this.scale.x *= -1;
this.scale.y *= -1;
this.scale.z *= -1;
for (int i = 0; i < 3; i++) {
row[i].x *= -1;
row[i].y *= -1;
row[i].z *= -1;
}
}
this.rotation = new Vector4(
0.5f * Mathf.Sqrt(Mathf.Max(1.0f + row[0].x - row[1].y - row[2].z, 0.0f)),
0.5f * Mathf.Sqrt(Mathf.Max(1.0f - row[0].x + row[1].y - row[2].z, 0.0f)),
0.5f * Mathf.Sqrt(Mathf.Max(1.0f - row[0].x - row[1].y + row[2].z, 0.0f)),
0.5f * Mathf.Sqrt(Mathf.Max(1.0f + row[0].x + row[1].y + row[2].z, 0.0f)));
if (row[2].y > row[1].z) {
this.rotation.x = -this.rotation.x;
}
if (row[0].z > row[2].x) {
this.rotation.y = -this.rotation.y;
}
if (row[1].x > row[0].y) {
this.rotation.z = -this.rotation.z;
}
this.valid = true;
}
public readonly bool valid;
public readonly Vector3 translation;
public readonly Vector3 scale;
public readonly Vector3 shear;
public readonly Vector4 perspective;
public readonly Vector4 rotation;
}
}