您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
112 行
3.4 KiB
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;
|
|
}
|
|
}
|