// 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.VertexMoverUtil
using UnityEngine;

public class VertexMoverUtil
{
    public Vector3[] MoveVertices(ClothInstance cloth, Vector3 targetPoint, bool centerIsLeftLeg, bool centerIsRightLeg, float maxRadius, float param, Vector3 vertexMovement)
    {
        if (cloth == null || cloth.worldVertices == null)
        {
            throw new AutoMorpherException("Cloth or World Vertices are Missing", "[MoveVertices] MoveVertices\n - cloth is null or cloth.worldVertices is null");
        }
        Vector3[] worldVertices = cloth.worldVertices;
        int num = worldVertices.Length;
        bool[] isInboundVerts;
        float[] array = this.ComputeEuclideanDistances(worldVertices, targetPoint, maxRadius, out isInboundVerts);
        if (array == null)
        {
            return null;
        }
        float[] array2 = this.ComputeKernelWeights(array, isInboundVerts, maxRadius, WeightKernel.Gaussian, param);
        Vector3[] array3 = new Vector3[num];
        bool[] isLeftLegVertex = cloth.isLeftLegVertex;
        bool[] isRightLegVertex = cloth.isRightLegVertex;
        for (int i = 0; i < num; i++)
        {
            if (!isInboundVerts[i])
            {
                array3[i] = Vector3.zero;
                continue;
            }
            if (centerIsLeftLeg && this.IsRightLegVertex(isRightLegVertex, i))
            {
                array3[i] = Vector3.zero;
                continue;
            }
            if (centerIsRightLeg && this.IsLeftLegVertex(isLeftLegVertex, i))
            {
                array3[i] = Vector3.zero;
                continue;
            }
            float num2 = array2[i];
            array3[i] = vertexMovement * num2;
        }
        return array3;
    }

    public Vector3[] MoveVertices(ClothInstance cloth, int targetVertexIdx, bool centerIsLeftLeg, bool centerIsRightLeg, float maxRadius, float param, Vector3 vertexMovement)
    {
        if (cloth == null || cloth.worldVertices == null)
        {
            throw new AutoMorpherException("Cloth or World Vertices are Missing", "[MoveVertices] MoveVertices\n - cloth is null or cloth.worldVertices is null");
        }
        Vector3[] worldVertices = cloth.worldVertices;
        int num = worldVertices.Length;
        bool[] isInboundVerts;
        float[] array = this.ComputeEuclideanDistances(worldVertices, targetVertexIdx, maxRadius, out isInboundVerts);
        if (array == null)
        {
            return null;
        }
        float[] array2 = this.ComputeKernelWeights(array, isInboundVerts, maxRadius, WeightKernel.Gaussian, param);
        Vector3[] array3 = new Vector3[num];
        bool[] isLeftLegVertex = cloth.isLeftLegVertex;
        bool[] isRightLegVertex = cloth.isRightLegVertex;
        for (int i = 0; i < num; i++)
        {
            if (!isInboundVerts[i])
            {
                array3[i] = Vector3.zero;
                continue;
            }
            if (centerIsLeftLeg && this.IsRightLegVertex(isRightLegVertex, i))
            {
                array3[i] = Vector3.zero;
                continue;
            }
            if (centerIsRightLeg && this.IsLeftLegVertex(isLeftLegVertex, i))
            {
                array3[i] = Vector3.zero;
                continue;
            }
            float num2 = array2[i];
            array3[i] = vertexMovement * num2;
        }
        return array3;
    }

    private float[] ComputeEuclideanDistances(Vector3[] verts, int targetVertIdx, float maxRadius, out bool[] isInboundVerts)
    {
        return this.ComputeEuclideanDistances(verts, verts[targetVertIdx], maxRadius, out isInboundVerts);
    }

    private float[] ComputeEuclideanDistances(Vector3[] verts, Vector3 targetVert, float maxRadius, out bool[] isInboundVerts)
    {
        int num = verts.Length;
        float[] array = new float[num];
        isInboundVerts = new bool[num];
        bool flag = false;
        for (int i = 0; i < num; i++)
        {
            array[i] = Vector3.Distance(verts[i], targetVert);
            isInboundVerts[i] = array[i] <= maxRadius;
            flag |= isInboundVerts[i];
        }
        if (!flag)
        {
            return null;
        }
        return array;
    }

    private float ComputeGaussianWeight(float distance, float alpah)
    {
        return Mathf.Exp((0f - distance * distance) / (2f * alpah * alpah));
    }

    private float ComputeLaplacianWeight(float distance, float beta)
    {
        return Mathf.Exp(0f - distance / beta);
    }

    private float[] ComputeKernelWeights(float[] dist, bool[] isInboundVerts, float maxRadius, WeightKernel kernel, float param)
    {
        int num = dist.Length;
        float[] array = new float[num];
        float num2 = Mathf.Max(1E-08f, param);
        for (int i = 0; i < num; i++)
        {
            if (!isInboundVerts[i])
            {
                array[i] = 0f;
                continue;
            }
            switch (kernel)
            {
                case WeightKernel.Gaussian:
                    array[i] = this.ComputeGaussianWeight(dist[i], num2);
                    break;
                case WeightKernel.Laplacian:
                    array[i] = this.ComputeLaplacianWeight(dist[i], num2);
                    break;
                default:
                    array[i] = 0f;
                    break;
            }
            float num3 = 1f - dist[i] / maxRadius;
            array[i] *= num3 * num3;
        }
        return array;
    }

    private bool IsLeftLegVertex(bool[] leftMask, int index)
    {
        if (leftMask != null && index >= 0 && index < leftMask.Length)
        {
            return leftMask[index];
        }
        return false;
    }

    private bool IsRightLegVertex(bool[] rightMask, int index)
    {
        if (rightMask != null && index >= 0 && index < rightMask.Length)
        {
            return rightMask[index];
        }
        return false;
    }
}
