Files
AutoMorpherDecompiled/Assets/@Eden_Tools/Eden_AutoMorpher/Script/PcaUtil.cs

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