185 lines
7.4 KiB
C#
185 lines
7.4 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: Eden.AutoMorpher.PcaUtil
|
|
// Assembly: EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
|
// MVID: D39968B3-E151-4276-BDB4-E82752BBAFF0
|
|
// Assembly location: D:\dev\AutoMorpher\Assets\@Eden_Tools\Eden_AutoMorpher\Script\EdenAutoMorpherScript.dll
|
|
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Eden.AutoMorpher
|
|
{
|
|
public class PcaUtil
|
|
{
|
|
public RegionStats ComputeRegionStats(IList<Vector3> points)
|
|
{
|
|
RegionStats regionStats = new RegionStats();
|
|
if (points == null || points.Count == 0)
|
|
return regionStats;
|
|
int count = points.Count;
|
|
Vector3 vector3_1 = Vector3.zero;
|
|
for (int index = 0; index < count; ++index)
|
|
vector3_1 = Vector3.op_Addition(vector3_1, points[index]);
|
|
Vector3 vector3_2 = Vector3.op_Division(vector3_1, (float)count);
|
|
float num1 = 0.0f;
|
|
float num2 = 0.0f;
|
|
float num3 = 0.0f;
|
|
float num4 = 0.0f;
|
|
float num5 = 0.0f;
|
|
float num6 = 0.0f;
|
|
for (int index = 0; index < count; ++index)
|
|
{
|
|
Vector3 vector3_3 = Vector3.op_Subtraction(points[index], vector3_2);
|
|
num1 += vector3_3.x * vector3_3.x;
|
|
num2 += vector3_3.x * vector3_3.y;
|
|
num3 += vector3_3.x * vector3_3.z;
|
|
num4 += vector3_3.y * vector3_3.y;
|
|
num5 += vector3_3.y * vector3_3.z;
|
|
num6 += vector3_3.z * vector3_3.z;
|
|
}
|
|
float num7 = 1f / (float)count;
|
|
float[] eigenValues;
|
|
Vector3[] eigenVectors;
|
|
this.JacobiEigenDecomposition3x3(num1 * num7, num2 * num7, num3 * num7, num4 * num7, num5 * num7, num6 * num7, out eigenValues, out eigenVectors);
|
|
int index1 = 0;
|
|
if ((double)eigenValues[1] > (double)eigenValues[index1])
|
|
index1 = 1;
|
|
if ((double)eigenValues[2] > (double)eigenValues[index1])
|
|
index1 = 2;
|
|
Vector3 normalized = ((Vector3)ref eigenVectors[index1]).normalized;
|
|
float num8 = float.PositiveInfinity;
|
|
float num9 = float.NegativeInfinity;
|
|
float num10 = 0.0f;
|
|
for (int index2 = 0; index2 < count; ++index2)
|
|
{
|
|
float num11 = Vector3.Dot(Vector3.op_Subtraction(points[index2], vector3_2), normalized);
|
|
if ((double)num11 < (double)num8)
|
|
num8 = num11;
|
|
if ((double)num11 > (double)num9)
|
|
num9 = num11;
|
|
Vector3 vector3_4 = Vector3.op_Addition(vector3_2, Vector3.op_Multiply(normalized, num11));
|
|
Vector3 vector3_5 = Vector3.op_Subtraction(points[index2], vector3_4);
|
|
float magnitude = ((Vector3)ref vector3_5).magnitude;
|
|
num10 += magnitude;
|
|
}
|
|
regionStats.center = vector3_2;
|
|
regionStats.principalAxis = normalized;
|
|
regionStats.length = num9 - num8;
|
|
regionStats.avgRadius = num10 / (float)count;
|
|
return regionStats;
|
|
}
|
|
|
|
private void JacobiEigenDecomposition3x3(
|
|
float c00,
|
|
float c01,
|
|
float c02,
|
|
float c11,
|
|
float c12,
|
|
float c22,
|
|
out float[] eigenValues,
|
|
out Vector3[] eigenVectors)
|
|
{
|
|
float[,] numArray1 = new float[3, 3]
|
|
{
|
|
{
|
|
c00,
|
|
c01,
|
|
c02
|
|
},
|
|
{
|
|
c01,
|
|
c11,
|
|
c12
|
|
},
|
|
{
|
|
c02,
|
|
c12,
|
|
c22
|
|
}
|
|
};
|
|
float[,] numArray2 = new float[3, 3]
|
|
{
|
|
{
|
|
1f,
|
|
0.0f,
|
|
0.0f
|
|
},
|
|
{
|
|
0.0f,
|
|
1f,
|
|
0.0f
|
|
},
|
|
{
|
|
0.0f,
|
|
0.0f,
|
|
1f
|
|
}
|
|
};
|
|
for (int index1 = 0; index1 < 32 /*0x20*/; ++index1)
|
|
{
|
|
int index2 = 0;
|
|
int index3 = 1;
|
|
float num1 = Mathf.Abs(numArray1[0, 1]);
|
|
float num2 = Mathf.Abs(numArray1[0, 2]);
|
|
if ((double)num2 > (double)num1)
|
|
{
|
|
num1 = num2;
|
|
index2 = 0;
|
|
index3 = 2;
|
|
}
|
|
float num3 = Mathf.Abs(numArray1[1, 2]);
|
|
if ((double)num3 > (double)num1)
|
|
{
|
|
num1 = num3;
|
|
index2 = 1;
|
|
index3 = 2;
|
|
}
|
|
if ((double)num1 >= 1.000000013351432E-10)
|
|
{
|
|
float num4 = numArray1[index2, index2];
|
|
float num5 = numArray1[index3, index3];
|
|
float num6 = numArray1[index2, index3];
|
|
double num7 = 0.5 * (double)Mathf.Atan2(2f * num6, num5 - num4);
|
|
float num8 = Mathf.Cos((float)num7);
|
|
float num9 = Mathf.Sin((float)num7);
|
|
for (int index4 = 0; index4 < 3; ++index4)
|
|
{
|
|
if (index4 != index2 && index4 != index3)
|
|
{
|
|
float num10 = numArray1[index4, index2];
|
|
float num11 = numArray1[index4, index3];
|
|
numArray1[index4, index2] = (float)((double)num8 * (double)num10 - (double)num9 * (double)num11);
|
|
numArray1[index2, index4] = numArray1[index4, index2];
|
|
numArray1[index4, index3] = (float)((double)num9 * (double)num10 + (double)num8 * (double)num11);
|
|
numArray1[index3, index4] = numArray1[index4, index3];
|
|
}
|
|
}
|
|
float num12 = (float)((double)num8 * (double)num8 * (double)num4 - 2.0 * (double)num9 * (double)num8 * (double)num6 + (double)num9 * (double)num9 * (double)num5);
|
|
float num13 = (float)((double)num9 * (double)num9 * (double)num4 + 2.0 * (double)num9 * (double)num8 * (double)num6 + (double)num8 * (double)num8 * (double)num5);
|
|
numArray1[index2, index2] = num12;
|
|
numArray1[index3, index3] = num13;
|
|
numArray1[index2, index3] = 0.0f;
|
|
numArray1[index3, index2] = 0.0f;
|
|
for (int index5 = 0; index5 < 3; ++index5)
|
|
{
|
|
float num14 = numArray2[index5, index2];
|
|
float num15 = numArray2[index5, index3];
|
|
numArray2[index5, index2] = (float)((double)num8 * (double)num14 - (double)num9 * (double)num15);
|
|
numArray2[index5, index3] = (float)((double)num9 * (double)num14 + (double)num8 * (double)num15);
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
eigenValues = new float[3];
|
|
eigenVectors = new Vector3[3];
|
|
eigenValues[0] = numArray1[0, 0];
|
|
eigenValues[1] = numArray1[1, 1];
|
|
eigenValues[2] = numArray1[2, 2];
|
|
eigenVectors[0] = new Vector3(numArray2[0, 0], numArray2[1, 0], numArray2[2, 0]);
|
|
eigenVectors[1] = new Vector3(numArray2[0, 1], numArray2[1, 1], numArray2[2, 1]);
|
|
eigenVectors[2] = new Vector3(numArray2[0, 2], numArray2[1, 2], numArray2[2, 2]);
|
|
}
|
|
}
|
|
}
|