// 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.ClothHumanoidMaskUtil
using System.Collections.Generic;
using UnityEngine;

public class ClothHumanoidMaskUtil
{
    public void BuildExcludedVertexMaskForHandsAndHead(ClothInstance clothInstance, bool excludeHandRoot = false, bool excludeThumbRoot = false)
    {
        if (clothInstance == null || clothInstance.smr == null)
        {
            Debug.LogWarning("[ClothHumanoidMaskUtil] clothInstance / smr 가 null");
            return;
        }
        SkinnedMeshRenderer smr = clothInstance.smr;
        Mesh mesh = clothInstance.editableMesh ?? smr.sharedMesh;
        if (mesh == null)
        {
            Debug.LogWarning("[ClothHumanoidMaskUtil] mesh 가 null");
            return;
        }
        BoneWeight[] boneWeights = mesh.boneWeights;
        Transform[] bones = smr.bones;
        if (boneWeights == null || boneWeights.Length == 0 || bones == null || bones.Length == 0)
        {
            Debug.LogWarning("[ClothHumanoidMaskUtil] boneWeights 또는 bones 비어있음");
            return;
        }
        if (clothInstance.humanoidMatchedBones == null || clothInstance.humanoidMatchedBones.Count == 0)
        {
            Debug.LogWarning("[ClothHumanoidMaskUtil] humanoidMatchedBones 가 비어있음 (BodyToClothPoseApplier에서 매칭 안 되었을 가능성)");
            return;
        }
        int num = mesh.vertexCount;
        if (boneWeights.Length != num)
        {
            num = Mathf.Min(num, boneWeights.Length);
        }
        HashSet<Transform> excludedBones = new HashSet<Transform>();
        Dictionary<HumanBodyBones, HashSet<Transform>> humanoidMatchedBones = clothInstance.humanoidMatchedBones;
        if (humanoidMatchedBones.TryGetValue(HumanBodyBones.Head, out var value) && value != null)
        {
            foreach (Transform item in value)
            {
                if (!(item == null))
                {
                    AddHierarchy(item, includeRoot: true);
                }
            }
        }
        if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftHand, out var value2) && value2 != null)
        {
            foreach (Transform item2 in value2)
            {
                if (!(item2 == null))
                {
                    AddHierarchy(item2, excludeHandRoot);
                }
            }
        }
        if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightHand, out var value3) && value3 != null)
        {
            foreach (Transform item3 in value3)
            {
                if (!(item3 == null))
                {
                    AddHierarchy(item3, excludeHandRoot);
                }
            }
        }
        if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftThumbProximal, out var value4) && value4 != null)
        {
            foreach (Transform item4 in value4)
            {
                if (!(item4 == null))
                {
                    if (excludeThumbRoot)
                    {
                        excludedBones.Add(item4);
                    }
                    else
                    {
                        excludedBones.Remove(item4);
                    }
                }
            }
        }
        if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightThumbProximal, out var value5) && value5 != null)
        {
            foreach (Transform item5 in value5)
            {
                if (!(item5 == null))
                {
                    if (excludeThumbRoot)
                    {
                        excludedBones.Add(item5);
                    }
                    else
                    {
                        excludedBones.Remove(item5);
                    }
                }
            }
        }
        bool[] boneIndexExcluded = new bool[bones.Length];
        for (int i = 0; i < bones.Length; i++)
        {
            Transform transform = bones[i];
            if (transform != null && excludedBones.Contains(transform))
            {
                boneIndexExcluded[i] = true;
            }
        }
        bool[] array = new bool[num];
        for (int j = 0; j < num; j++)
        {
            BoneWeight boneWeight = boneWeights[j];
            float excludedWeightSum = 0f;
            AddExcludedWeight(boneWeight.weight0, boneWeight.boneIndex0);
            AddExcludedWeight(boneWeight.weight1, boneWeight.boneIndex1);
            AddExcludedWeight(boneWeight.weight2, boneWeight.boneIndex2);
            AddExcludedWeight(boneWeight.weight3, boneWeight.boneIndex3);
            array[j] = excludedWeightSum >= 0.8f;
            void AddExcludedWeight(float w, int bi)
            {
                if (!(w <= 0f) && bi >= 0 && bi < boneIndexExcluded.Length && boneIndexExcluded[bi])
                {
                    excludedWeightSum += w;
                }
            }
        }
        clothInstance.excludedVertices = array;
        this.BuildLegVertexMasks(clothInstance);
        void AddHierarchy(Transform root, bool includeRoot)
        {
            if (!(root == null))
            {
                Stack<Transform> stack = new Stack<Transform>();
                if (includeRoot)
                {
                    stack.Push(root);
                }
                else
                {
                    for (int k = 0; k < root.childCount; k++)
                    {
                        stack.Push(root.GetChild(k));
                    }
                }
                while (stack.Count > 0)
                {
                    Transform transform2 = stack.Pop();
                    if (!(transform2 == null) && excludedBones.Add(transform2))
                    {
                        for (int l = 0; l < transform2.childCount; l++)
                        {
                            stack.Push(transform2.GetChild(l));
                        }
                    }
                }
            }
        }
    }

    public void BuildLegVertexMasks(ClothInstance clothInstance)
    {
        if (clothInstance == null || clothInstance.smr == null)
        {
            Debug.LogWarning("[ClothHumanoidMaskUtil] clothInstance / smr 가 null");
            return;
        }
        SkinnedMeshRenderer smr = clothInstance.smr;
        Mesh mesh = clothInstance.editableMesh ?? smr.sharedMesh;
        if (mesh == null)
        {
            Debug.LogWarning("[ClothHumanoidMaskUtil] mesh 가 null");
            return;
        }
        BoneWeight[] boneWeights = mesh.boneWeights;
        Transform[] bones = smr.bones;
        if (boneWeights == null || boneWeights.Length == 0 || bones == null || bones.Length == 0)
        {
            Debug.LogWarning("[ClothHumanoidMaskUtil] boneWeights 또는 bones 비어있음");
            return;
        }
        if (clothInstance.humanoidMatchedBones == null || clothInstance.humanoidMatchedBones.Count == 0)
        {
            Debug.LogWarning("[ClothHumanoidMaskUtil] humanoidMatchedBones 가 비어있음 (BodyToClothPoseApplier에서 매칭 필요)");
            return;
        }
        int num = mesh.vertexCount;
        if (boneWeights.Length != num)
        {
            num = Mathf.Min(num, boneWeights.Length);
        }
        Dictionary<HumanBodyBones, HashSet<Transform>> humanoidMatchedBones = clothInstance.humanoidMatchedBones;
        HashSet<Transform> hashSet = new HashSet<Transform>();
        HashSet<Transform> hashSet2 = new HashSet<Transform>();
        if (humanoidMatchedBones.TryGetValue(HumanBodyBones.LeftUpperLeg, out var value) && value != null)
        {
            foreach (Transform item in value)
            {
                if (!(item == null))
                {
                    CollectHierarchy(item, hashSet);
                }
            }
        }
        if (humanoidMatchedBones.TryGetValue(HumanBodyBones.RightUpperLeg, out var value2) && value2 != null)
        {
            foreach (Transform item2 in value2)
            {
                if (!(item2 == null))
                {
                    CollectHierarchy(item2, hashSet2);
                }
            }
        }
        bool[] boneIsLeftLeg = new bool[bones.Length];
        bool[] boneIsRightLeg = new bool[bones.Length];
        for (int i = 0; i < bones.Length; i++)
        {
            Transform transform = bones[i];
            if (!(transform == null))
            {
                if (hashSet.Contains(transform))
                {
                    boneIsLeftLeg[i] = true;
                }
                if (hashSet2.Contains(transform))
                {
                    boneIsRightLeg[i] = true;
                }
            }
        }
        bool[] array = new bool[num];
        bool[] array2 = new bool[num];
        for (int j = 0; j < num; j++)
        {
            BoneWeight boneWeight = boneWeights[j];
            float leftWeight = 0f;
            float rightWeight = 0f;
            Check(boneWeight.boneIndex0, boneWeight.weight0);
            Check(boneWeight.boneIndex1, boneWeight.weight1);
            Check(boneWeight.boneIndex2, boneWeight.weight2);
            Check(boneWeight.boneIndex3, boneWeight.weight3);
            if (leftWeight > 0.8f)
            {
                array[j] = true;
                array2[j] = false;
            }
            else if (rightWeight > 0.8f)
            {
                array[j] = false;
                array2[j] = true;
            }
            else
            {
                array[j] = false;
                array2[j] = false;
            }
            void Check(int bi, float w)
            {
                if (bi >= 0 && bi < bones.Length && !(w <= 0f))
                {
                    if (boneIsLeftLeg[bi])
                    {
                        leftWeight += w;
                    }
                    if (boneIsRightLeg[bi])
                    {
                        rightWeight += w;
                    }
                }
            }
        }
        clothInstance.isLeftLegVertex = array;
        clothInstance.isRightLegVertex = array2;
        static void CollectHierarchy(Transform root, HashSet<Transform> set)
        {
            if (!(root == null))
            {
                Stack<Transform> stack = new Stack<Transform>();
                stack.Push(root);
                while (stack.Count > 0)
                {
                    Transform transform2 = stack.Pop();
                    if (!(transform2 == null) && set.Add(transform2))
                    {
                        for (int k = 0; k < transform2.childCount; k++)
                        {
                            stack.Push(transform2.GetChild(k));
                        }
                    }
                }
            }
        }
    }
}
