// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts,
// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies.
// EdenAutoMorpherScript, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// Eden.AutoMorpher.PcaUtil
using System.Collections.Generic;
using UnityEngine;

public class PcaUtil
{
    public RegionStats ComputeRegionStats(IList<Vector3> points)
    {
        RegionStats result = default(RegionStats);
        if (points == null || points.Count == 0)
        {
            return result;
        }
        int count = points.Count;
        Vector3 zero = Vector3.zero;
        for (int i = 0; i < count; i++)
        {
            zero += points[i];
        }
        zero /= (float)count;
        float num = 0f;
        float num2 = 0f;
        float num3 = 0f;
        float num4 = 0f;
        float num5 = 0f;
        float num6 = 0f;
        for (int j = 0; j < count; j++)
        {
            Vector3 vector = points[j] - zero;
            num += vector.x * vector.x;
            num2 += vector.x * vector.y;
            num3 += vector.x * vector.z;
            num4 += vector.y * vector.y;
            num5 += vector.y * vector.z;
            num6 += vector.z * vector.z;
        }
        float num7 = 1f / (float)count;
        num *= num7;
        num2 *= num7;
        num3 *= num7;
        num4 *= num7;
        num5 *= num7;
        num6 *= num7;
        this.JacobiEigenDecomposition3x3(num, num2, num3, num4, num5, num6, out var eigenValues, out var eigenVectors);
        int num8 = 0;
        if (eigenValues[1] > eigenValues[num8])
        {
            num8 = 1;
        }
        if (eigenValues[2] > eigenValues[num8])
        {
            num8 = 2;
        }
        Vector3 normalized = eigenVectors[num8].normalized;
        float num9 = float.PositiveInfinity;
        float num10 = float.NegativeInfinity;
        float num11 = 0f;
        for (int k = 0; k < count; k++)
        {
            float num12 = Vector3.Dot(points[k] - zero, normalized);
            if (num12 < num9)
            {
                num9 = num12;
            }
            if (num12 > num10)
            {
                num10 = num12;
            }
            Vector3 vector2 = zero + normalized * num12;
            float magnitude = (points[k] - vector2).magnitude;
            num11 += magnitude;
        }
        result.center = zero;
        result.principalAxis = normalized;
        result.length = num10 - num9;
        result.avgRadius = num11 / (float)count;
        return result;
    }

    private void JacobiEigenDecomposition3x3(float c00, float c01, float c02, float c11, float c12, float c22, out float[] eigenValues, out Vector3[] eigenVectors)
    {
        float[,] array = new float[3, 3]
        {
            { c00, c01, c02 },
            { c01, c11, c12 },
            { c02, c12, c22 }
        };
        float[,] array2 = new float[3, 3]
        {
            { 1f, 0f, 0f },
            { 0f, 1f, 0f },
            { 0f, 0f, 1f }
        };
        for (int i = 0; i < 32; i++)
        {
            int num = 0;
            int num2 = 1;
            float num3 = Mathf.Abs(array[0, 1]);
            float num4 = Mathf.Abs(array[0, 2]);
            if (num4 > num3)
            {
                num3 = num4;
                num = 0;
                num2 = 2;
            }
            float num5 = Mathf.Abs(array[1, 2]);
            if (num5 > num3)
            {
                num3 = num5;
                num = 1;
                num2 = 2;
            }
            if (num3 < 1E-10f)
            {
                break;
            }
            float num6 = array[num, num];
            float num7 = array[num2, num2];
            float num8 = array[num, num2];
            float f = 0.5f * Mathf.Atan2(2f * num8, num7 - num6);
            float num9 = Mathf.Cos(f);
            float num10 = Mathf.Sin(f);
            for (int j = 0; j < 3; j++)
            {
                if (j != num && j != num2)
                {
                    float num11 = array[j, num];
                    float num12 = array[j, num2];
                    array[j, num] = num9 * num11 - num10 * num12;
                    array[num, j] = array[j, num];
                    array[j, num2] = num10 * num11 + num9 * num12;
                    array[num2, j] = array[j, num2];
                }
            }
            float num13 = num9 * num9 * num6 - 2f * num10 * num9 * num8 + num10 * num10 * num7;
            float num14 = num10 * num10 * num6 + 2f * num10 * num9 * num8 + num9 * num9 * num7;
            array[num, num] = num13;
            array[num2, num2] = num14;
            array[num, num2] = 0f;
            array[num2, num] = 0f;
            for (int k = 0; k < 3; k++)
            {
                float num15 = array2[k, num];
                float num16 = array2[k, num2];
                array2[k, num] = num9 * num15 - num10 * num16;
                array2[k, num2] = num10 * num15 + num9 * num16;
            }
        }
        eigenValues = new float[3];
        eigenVectors = new Vector3[3];
        eigenValues[0] = array[0, 0];
        eigenValues[1] = array[1, 1];
        eigenValues[2] = array[2, 2];
        eigenVectors[0] = new Vector3(array2[0, 0], array2[1, 0], array2[2, 0]);
        eigenVectors[1] = new Vector3(array2[0, 1], array2[1, 1], array2[2, 1]);
        eigenVectors[2] = new Vector3(array2[0, 2], array2[1, 2], array2[2, 2]);
    }
}
