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

public class BodyPoseMatch_Leg
{
    private readonly BodyPoseMatch_CommonUtil poseMatchCommonUtil;

    public BodyPoseMatch_Leg()
    {
        this.poseMatchCommonUtil = new BodyPoseMatch_CommonUtil();
    }

    public void AlignBothUpperLegs(GameObject proxyObject, IReadOnlyList<BakedBodyMesh> proxyBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> proxyBoneMap, GameObject targetObject, IReadOnlyList<BakedBodyMesh> targetBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap)
    {
        if (proxyObject == null || targetObject == null)
        {
            throw new AutoMorpherException("Proxy or Target Object is Missing", "[BodyPoseMatch_Leg] AlignBothUpperLegs\n - proxyObject or targetObject is null");
        }
        this.AlignUpperLeg_BodyMatch(proxyObject, proxyBakedBodyMeshes, proxyBoneMap, targetObject, targetBakedBodyMeshes, targetBoneMap, isLeft: true);
        this.AlignUpperLeg_BodyMatch(proxyObject, proxyBakedBodyMeshes, proxyBoneMap, targetObject, targetBakedBodyMeshes, targetBoneMap, isLeft: false);
    }

    public void AlignBothUpperLegs(Transform targetTransform, IReadOnlyList<BakedBodyMesh> targetBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap, Transform clothesTransform, Dictionary<HumanBodyBones, HashSet<Transform>> clothBoneMap, ProfileData profileData, Vector3 comprehensiveScale)
    {
        this.AlignUpperLeg_Profile(targetTransform, targetBakedBodyMeshes, targetBoneMap, clothesTransform, clothBoneMap, profileData, comprehensiveScale, isLeft: true);
        this.AlignUpperLeg_Profile(targetTransform, targetBakedBodyMeshes, targetBoneMap, clothesTransform, clothBoneMap, profileData, comprehensiveScale, isLeft: false);
    }

    public void AlignUpperLeg_BodyMatch(GameObject proxyObject, IReadOnlyList<BakedBodyMesh> proxyBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> proxyBoneMap, GameObject targetObject, IReadOnlyList<BakedBodyMesh> targetBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap, bool isLeft)
    {
        if (proxyObject == null || targetObject == null)
        {
            throw new AutoMorpherException("Proxy or Target Object is Missing", "[BodyPoseMatch_Leg] AlignUpperLeg_BodyMatch\n - proxyObject or targetObject is null");
        }
        RegionStats regionStats = this.ComputeLegRegionStats(proxyObject.transform, proxyBakedBodyMeshes, proxyBoneMap, isLeft);
        RegionStats regionStats2 = this.ComputeLegRegionStats(targetObject.transform, targetBakedBodyMeshes, targetBoneMap, isLeft);
        if (regionStats.length < 0.0001f || regionStats2.length < 0.0001f)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] AlignUpperLeg_BodyMatch: leg PCA 통계가 비정상입니다.");
            return;
        }
        HumanBodyBones key = (isLeft ? HumanBodyBones.LeftUpperLeg : HumanBodyBones.RightUpperLeg);
        if (proxyBoneMap == null || !proxyBoneMap.TryGetValue(key, out var value) || value == null || value.Count == 0)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] AlignUpperLeg_BodyMatch: proxy UpperLeg 본을 찾지 못했습니다.");
        }
        else
        {
            this.AlignUpperLegCore(value, regionStats.center, regionStats2.center);
        }
    }

    public void AlignUpperLeg_Profile(Transform targetTransform, IReadOnlyList<BakedBodyMesh> targetBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap, Transform clothesTransform, Dictionary<HumanBodyBones, HashSet<Transform>> clothBoneMap, ProfileData profileData, Vector3 comprehensiveScale, bool isLeft)
    {
        if (targetTransform == null)
        {
            throw new AutoMorpherException("Target Object is Missing", "[BodyPoseMatch_Leg] AlignUpperLeg_Profile\n - targetObject is null");
        }
        HumanBodyBones key = (isLeft ? HumanBodyBones.LeftUpperLeg : HumanBodyBones.RightUpperLeg);
        BoneSpatialData boneSpatialData = (isLeft ? profileData.LeftUpperLegSpatialData : profileData.RightUpperLegSpatialData);
        if (boneSpatialData == null || boneSpatialData.pcaData == null)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] AlignUpperLeg: " + (isLeft ? "Left" : "Right") + " spatial data missing.");
            return;
        }
        Vector3 profilePcaCenterWorld = this.poseMatchCommonUtil.GetProfilePcaCenterWorld(clothBoneMap, boneSpatialData, comprehensiveScale);
        RegionStats regionStats = this.ComputeLegRegionStats(targetTransform, targetBakedBodyMeshes, targetBoneMap, isLeft);
        HashSet<Transform> value;
        if (regionStats.length < 0.0001f)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] AlignUpperLeg: Target leg PCA 통계가 비정상입니다.");
        }
        else if (clothBoneMap == null || !clothBoneMap.TryGetValue(key, out value) || value == null || value.Count == 0)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] AlignUpperLeg: clothes UpperLeg 본을 찾지 못했습니다.");
        }
        else
        {
            this.AlignUpperLegCore(value, profilePcaCenterWorld, regionStats.center);
        }
    }

    private void AlignUpperLegCore(IReadOnlyCollection<Transform> upperLegSet, Vector3 sourceLegCenterWorld, Vector3 targetLegCenterWorld)
    {
        if (upperLegSet == null || upperLegSet.Count == 0)
        {
            return;
        }
        Vector3 vector = targetLegCenterWorld - sourceLegCenterWorld;
        vector.y = 0f;
        foreach (Transform item in upperLegSet)
        {
            if (!(item == null))
            {
                item.position += vector;
            }
        }
    }

    public RegionStats ComputeLegRegionStats(Transform avatarTransform, IReadOnlyList<BakedBodyMesh> avatarBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> avatarBoneMap, bool isLeft)
    {
        HumanBodyBones[] targetHumanBones = ((!isLeft) ? new HumanBodyBones[2]
        {
            HumanBodyBones.RightUpperLeg,
            HumanBodyBones.RightLowerLeg
        } : new HumanBodyBones[2]
        {
            HumanBodyBones.LeftUpperLeg,
            HumanBodyBones.LeftLowerLeg
        });
        List<Vector3> list = this.poseMatchCommonUtil.CollectHumanoidVerticesWorld(targetHumanBones, avatarBakedBodyMeshes, avatarBoneMap);
        if (list == null || list.Count == 0)
        {
            Debug.LogWarning($"[BodyPoseMatch_Leg] ComputeLegRegionStats: leg vertices 0개. avatar={avatarTransform?.name}, isLeft={isLeft}");
            return default(RegionStats);
        }
        RegionStats result = new PcaUtil().ComputeRegionStats(list);
        Transform boneFromBoneMap = this.poseMatchCommonUtil.GetBoneFromBoneMap(avatarBoneMap, isLeft ? HumanBodyBones.LeftUpperLeg : HumanBodyBones.RightUpperLeg);
        Transform boneFromBoneMap2 = this.poseMatchCommonUtil.GetBoneFromBoneMap(avatarBoneMap, isLeft ? HumanBodyBones.LeftLowerLeg : HumanBodyBones.RightLowerLeg);
        if (boneFromBoneMap != null && boneFromBoneMap2 != null)
        {
            Vector3 normalized = (boneFromBoneMap2.position - boneFromBoneMap.position).normalized;
            Vector3 vector = result.principalAxis.normalized;
            if (Vector3.Dot(vector, normalized) < 0f)
            {
                vector = -vector;
            }
            result.principalAxis = vector;
        }
        return result;
    }

    public void ScalingBothLegsAndFoots(GameObject proxyObject, IReadOnlyList<BakedBodyMesh> proxyBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> proxyBoneMap, GameObject targetObject, IReadOnlyList<BakedBodyMesh> targetBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap, bool autoDetectAxis = true, int forceAxisIndex = 1)
    {
        this.ScalingLeg(proxyBoneMap, targetBoneMap, isLeft: true, autoDetectAxis, forceAxisIndex);
        this.ScalingLeg(proxyBoneMap, targetBoneMap, isLeft: false, autoDetectAxis, forceAxisIndex);
        if (proxyBakedBodyMeshes != null)
        {
            foreach (BakedBodyMesh proxyBakedBodyMesh in proxyBakedBodyMeshes)
            {
                proxyBakedBodyMesh?.ReBakeMesh();
            }
        }
        this.ScalingFoot(proxyObject, proxyBakedBodyMeshes, proxyBoneMap, targetObject, targetBakedBodyMeshes, targetBoneMap, isLeft: true);
        this.ScalingFoot(proxyObject, proxyBakedBodyMeshes, proxyBoneMap, targetObject, targetBakedBodyMeshes, targetBoneMap, isLeft: false);
    }

    public void ScalingBothLegsAndFoots(Transform targetTransform, IReadOnlyList<BakedBodyMesh> targetBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap, Transform clothTransform, Dictionary<HumanBodyBones, HashSet<Transform>> clothBoneMap, ProfileData profileData, Vector3 comprehensiveScale, bool autoDetectAxis = true, int forceAxisIndex = 1)
    {
        this.ScalingLeg(clothBoneMap, targetBoneMap, isLeft: true, autoDetectAxis, forceAxisIndex);
        this.ScalingLeg(clothBoneMap, targetBoneMap, isLeft: false, autoDetectAxis, forceAxisIndex);
        this.ScalingFoot(profileData, comprehensiveScale, clothBoneMap, targetTransform, targetBakedBodyMeshes, targetBoneMap, isLeft: true);
        this.ScalingFoot(profileData, comprehensiveScale, clothBoneMap, targetTransform, targetBakedBodyMeshes, targetBoneMap, isLeft: false);
    }

    public void ScalingLeg(Dictionary<HumanBodyBones, HashSet<Transform>> proxyBoneMap, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap, bool isLeft, bool autoDetectAxis = true, int forceAxisIndex = 1)
    {
        HumanBodyBones humanBodyBones = (isLeft ? HumanBodyBones.LeftUpperLeg : HumanBodyBones.RightUpperLeg);
        HumanBodyBones bone = (isLeft ? HumanBodyBones.LeftLowerLeg : HumanBodyBones.RightLowerLeg);
        Transform boneFromBoneMap = this.poseMatchCommonUtil.GetBoneFromBoneMap(proxyBoneMap, humanBodyBones);
        Transform boneFromBoneMap2 = this.poseMatchCommonUtil.GetBoneFromBoneMap(proxyBoneMap, bone);
        Transform boneFromBoneMap3 = this.poseMatchCommonUtil.GetBoneFromBoneMap(targetBoneMap, humanBodyBones);
        Transform boneFromBoneMap4 = this.poseMatchCommonUtil.GetBoneFromBoneMap(targetBoneMap, bone);
        if (boneFromBoneMap == null || boneFromBoneMap2 == null || boneFromBoneMap3 == null || boneFromBoneMap4 == null)
        {
            Debug.LogWarning("[AvatarBodyMatchUtil] ScalingLeg: some leg bones are null");
            return;
        }
        if (proxyBoneMap == null || !proxyBoneMap.TryGetValue(humanBodyBones, out var value) || value == null || value.Count == 0)
        {
            Debug.LogWarning("[AvatarBodyMatchUtil] ScalingLeg: proxy upperLeg bone set missing");
            return;
        }
        this.poseMatchCommonUtil.BoneLengthAdjust(boneFromBoneMap, boneFromBoneMap2, boneFromBoneMap3, boneFromBoneMap4, value, autoDetectAxis, forceAxisIndex);
        HumanBodyBones humanBodyBones2 = (isLeft ? HumanBodyBones.LeftFoot : HumanBodyBones.RightFoot);
        Transform boneFromBoneMap5 = this.poseMatchCommonUtil.GetBoneFromBoneMap(proxyBoneMap, humanBodyBones2);
        Transform boneFromBoneMap6 = this.poseMatchCommonUtil.GetBoneFromBoneMap(targetBoneMap, humanBodyBones2);
        if (boneFromBoneMap5 == null || boneFromBoneMap6 == null)
        {
            Debug.LogWarning("[AvatarBodyMatchUtil] ScalingFoot: proxyFoot or targetFoot is null");
            return;
        }
        float y = boneFromBoneMap5.position.y;
        float num = boneFromBoneMap6.position.y - y;
        if (!(Mathf.Abs(num) > 1E-06f))
        {
            return;
        }
        Vector3 vector = new Vector3(0f, num, 0f);
        if (proxyBoneMap == null || !proxyBoneMap.TryGetValue(humanBodyBones2, out var value2) || value2 == null || value2.Count <= 0)
        {
            return;
        }
        foreach (Transform item in value2)
        {
            if (!(item == null))
            {
                item.position += vector;
            }
        }
    }

    private void ScalingFootCore(Transform proxyHip, Transform targetFoot, bool isLeft, HashSet<Transform> footBoneSet, float proxyToeF, float proxyHeelF, float proxySideMin, float proxySideMax, float proxySoleY, float targetToeF, float targetHeelF, float targetSideMin, float targetSideMax, float targetSoleY)
    {
        if (proxyHip == null || targetFoot == null)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] ScalingFootCore: proxyHip or targetFoot is null");
            return;
        }
        if (footBoneSet == null || footBoneSet.Count == 0)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] ScalingFootCore: footBoneSet is null or empty");
            return;
        }
        Dictionary<Transform, List<Transform>> dictionary = new Dictionary<Transform, List<Transform>>();
        foreach (Transform item in footBoneSet)
        {
            if (!(item == null))
            {
                Transform parent = item.parent;
                if (!dictionary.TryGetValue(parent, out var value))
                {
                    value = new List<Transform>();
                    dictionary.Add(parent, value);
                }
                value.Add(item);
            }
        }
        foreach (KeyValuePair<Transform, List<Transform>> item2 in dictionary)
        {
            Transform key = item2.Key;
            List<Transform> value2 = item2.Value;
            if (key == null || value2 == null || value2.Count == 0)
            {
                continue;
            }
            Transform transform = value2[0];
            if (!(transform == null))
            {
                TempBoneMarker tempBoneMarker;
                Transform transform2 = this.poseMatchCommonUtil.CreateTempMarker("scaleSupportBone", key, value2, transform.position, Quaternion.identity, transform.localScale, out tempBoneMarker);
                if (!(transform2 == null))
                {
                    this.ScaleAndAlignAlongAxis(proxyHip, proxyHip.forward, proxyHip.up, transform2, proxyToeF, proxyHeelF, targetFoot, targetToeF, targetHeelF);
                    this.ScaleAndAlignAlongAxis(proxyHip, proxyHip.right, proxyHip.up, transform2, isLeft ? proxySideMin : proxySideMax, isLeft ? proxySideMax : proxySideMin, targetFoot, isLeft ? targetSideMin : targetSideMax, isLeft ? targetSideMax : targetSideMin);
                    this.ScaleAndAlignAlongAxis(proxyHip, proxyHip.up, proxyHip.forward, transform2, 0f, proxySoleY, targetFoot, 0f, targetSoleY);
                }
            }
        }
    }

    public void ScalingFoot(GameObject proxyObject, IReadOnlyList<BakedBodyMesh> proxyBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> proxyBoneMap, GameObject targetObject, IReadOnlyList<BakedBodyMesh> targetBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap, bool isLeft)
    {
        if (proxyObject == null || targetObject == null)
        {
            throw new AutoMorpherException("Proxy or Target Object is Missing", "[BodyPoseMatch_Leg] ScalingFoot\n - proxyObject or targetObject is null");
        }
        HumanBodyBones humanBodyBones = (isLeft ? HumanBodyBones.LeftFoot : HumanBodyBones.RightFoot);
        Transform boneFromBoneMap = this.poseMatchCommonUtil.GetBoneFromBoneMap(proxyBoneMap, humanBodyBones);
        Transform boneFromBoneMap2 = this.poseMatchCommonUtil.GetBoneFromBoneMap(targetBoneMap, humanBodyBones);
        if (boneFromBoneMap == null || boneFromBoneMap2 == null)
        {
            Debug.LogWarning("[AvatarBodyMatchUtil] ScalingFoot: proxyFoot or targetFoot is null");
            return;
        }
        if (!this.TryGetFootSpatialData(proxyObject.transform, proxyBakedBodyMeshes, proxyBoneMap, isLeft, out var _, out var footMinUp, out var heelF, out var toeF, out var sideMin, out var sideMax) || !this.TryGetFootSpatialData(targetObject.transform, targetBakedBodyMeshes, targetBoneMap, isLeft, out var _, out var footMinUp2, out var heelF2, out var toeF2, out var sideMin2, out var sideMax2))
        {
            Debug.LogWarning("[AvatarBodyMatchUtil] ScalingFoot: foot spatial data 계산 실패");
            return;
        }
        Transform boneFromBoneMap3 = this.poseMatchCommonUtil.GetBoneFromBoneMap(proxyBoneMap, HumanBodyBones.Hips);
        HashSet<Transform> value;
        if (boneFromBoneMap3 == null)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] ScalingFoot: proxyHip is null");
        }
        else if (proxyBoneMap == null || !proxyBoneMap.TryGetValue(humanBodyBones, out value) || value == null || value.Count == 0)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] ScalingFoot: footBoneSet is missing");
        }
        else
        {
            this.ScalingFootCore(boneFromBoneMap3, boneFromBoneMap2, isLeft, value, toeF, heelF, sideMin, sideMax, footMinUp, toeF2, heelF2, sideMin2, sideMax2, footMinUp2);
        }
    }

    public void ScalingFoot(ProfileData profileData, Vector3 comprehensiveScale, Dictionary<HumanBodyBones, HashSet<Transform>> clothBoneMap, Transform targetTransform, IReadOnlyList<BakedBodyMesh> targetBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> targetBoneMap, bool isLeft)
    {
        if (targetTransform == null)
        {
            throw new AutoMorpherException("Target Transform is Missing", "[BodyPoseMatch_Leg] ScalingFoot\n - targetTransform is null");
        }
        HumanBodyBones humanBodyBones = (isLeft ? HumanBodyBones.LeftFoot : HumanBodyBones.RightFoot);
        Transform boneFromBoneMap = this.poseMatchCommonUtil.GetBoneFromBoneMap(clothBoneMap, humanBodyBones);
        Transform boneFromBoneMap2 = this.poseMatchCommonUtil.GetBoneFromBoneMap(targetBoneMap, humanBodyBones);
        if (boneFromBoneMap == null || boneFromBoneMap2 == null)
        {
            Debug.LogWarning("[AvatarBodyMatchUtil] ScalingFoot: proxyFoot or targetFoot is null");
            return;
        }
        if (!this.TryGetFootSpatialData(targetTransform.transform, targetBakedBodyMeshes, targetBoneMap, isLeft, out var _, out var footMinUp, out var heelF, out var toeF, out var sideMin, out var sideMax))
        {
            Debug.LogWarning("[AvatarBodyMatchUtil] ScalingFoot: foot spatial data 계산 실패");
            return;
        }
        Transform boneFromBoneMap3 = this.poseMatchCommonUtil.GetBoneFromBoneMap(clothBoneMap, HumanBodyBones.Hips);
        BoneSpatialData boneSpatialData = (isLeft ? profileData.LeftFootSpatialData : profileData.RightFootSpatialData);
        if (boneSpatialData == null)
        {
            Debug.LogWarning("[AvatarBodyMatchUtil] AlignNeckCenterByPcaWithHipZ: Profile FootSpatialData Data is Not exist.");
            return;
        }
        Transform boneFromBoneMap4 = this.poseMatchCommonUtil.GetBoneFromBoneMap(clothBoneMap, boneSpatialData.refBone);
        if (boneFromBoneMap4 == null)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] ScalingFoot: clothRefBone is null");
            return;
        }
        BodyPoseMatch_CommonUtil bodyPoseMatch_CommonUtil = new BodyPoseMatch_CommonUtil();
        float proxyToeF = Vector3.Distance(boneFromBoneMap4.position, bodyPoseMatch_CommonUtil.GetProfileVolumeMaxWorld(clothBoneMap, boneSpatialData, 0, comprehensiveScale));
        float proxyHeelF = 0f - Vector3.Distance(boneFromBoneMap4.position, bodyPoseMatch_CommonUtil.GetProfileVolumeMinWorld(clothBoneMap, boneSpatialData, 0, comprehensiveScale));
        float proxySideMax = Vector3.Distance(boneFromBoneMap4.position, bodyPoseMatch_CommonUtil.GetProfileVolumeMaxWorld(clothBoneMap, boneSpatialData, 1, comprehensiveScale));
        float proxySideMin = 0f - Vector3.Distance(boneFromBoneMap4.position, bodyPoseMatch_CommonUtil.GetProfileVolumeMinWorld(clothBoneMap, boneSpatialData, 1, comprehensiveScale));
        float proxySoleY = 0f - Vector3.Distance(boneFromBoneMap4.position, bodyPoseMatch_CommonUtil.GetProfileVolumeMinWorld(clothBoneMap, boneSpatialData, 2, comprehensiveScale));
        if (clothBoneMap == null || !clothBoneMap.TryGetValue(humanBodyBones, out var value) || value == null || value.Count == 0)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] ScalingFoot: cloth footBoneSet is missing");
        }
        else
        {
            this.ScalingFootCore(boneFromBoneMap3, boneFromBoneMap2, isLeft, value, proxyToeF, proxyHeelF, proxySideMin, proxySideMax, proxySoleY, toeF, heelF, sideMin, sideMax, footMinUp);
        }
    }

    private void ScaleAndAlignAlongAxis(Transform baseTransform, Vector3 targetWorldAxis, Vector3 targetWorldUpAxis, Transform proxyFoot, float proxyMaxF, float proxyMinF, Transform targetFoot, float targetMaxF, float targetMinF)
    {
        float num = proxyMaxF - proxyMinF;
        float num2 = targetMaxF - targetMinF;
        if (Mathf.Abs(num) < 0.0001f || Mathf.Abs(num2) < 0.0001f)
        {
            Debug.LogWarning("[AdjustFootForwardScale] foot span too small.");
            return;
        }
        float num3 = num2 / num;
        if (!float.IsFinite(num3) || num3 <= 0f)
        {
            Debug.LogWarning($"[ScaleAndAlignAlongAxis] invalid scaleF: {num3}");
            return;
        }
        Vector3 position = proxyFoot.position + targetWorldAxis * proxyMinF;
        Vector3 position2 = targetFoot.position + targetWorldAxis * targetMinF;
        GameObject gameObject = new GameObject("proxyAnchor");
        gameObject.transform.SetParent(proxyFoot);
        gameObject.transform.position = position;
        GameObject gameObject2 = new GameObject("targetAnchor");
        gameObject2.transform.SetParent(targetFoot);
        gameObject2.transform.position = position2;
        Transform parent = proxyFoot.parent;
        Vector3 position3 = proxyFoot.position;
        Transform transform = new GameObject("ScaleParnet").transform;
        transform.SetParent(parent);
        transform.position = position3;
        transform.rotation = Quaternion.LookRotation(targetWorldAxis, targetWorldUpAxis);
        proxyFoot.SetParent(transform, worldPositionStays: true);
        proxyFoot.localPosition = Vector3.zero;
        Vector3 localScale = transform.localScale;
        localScale.z *= num3;
        transform.localScale = localScale;
        proxyFoot.SetParent(parent, worldPositionStays: true);
        proxyFoot.position = position3;
        float num4 = Vector3.Dot(gameObject2.transform.position - gameObject.transform.position, targetWorldAxis);
        Vector3 vector = targetWorldAxis * num4;
        proxyFoot.position += vector;
        Object.DestroyImmediate(transform.gameObject);
        Object.DestroyImmediate(gameObject);
        Object.DestroyImmediate(gameObject2);
    }

    private bool TryGetFootSpatialData(Transform avatarTransform, IReadOnlyList<BakedBodyMesh> avatarBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> avatarBoneMap, bool isLeft, out float footMaxUp, out float footMinUp, out float heelF, out float toeF, out float sideMin, out float sideMax, float weightThreshold = 0.15f, int sampleStep = 1)
    {
        footMaxUp = float.NegativeInfinity;
        footMinUp = float.PositiveInfinity;
        heelF = float.PositiveInfinity;
        toeF = float.NegativeInfinity;
        sideMin = float.PositiveInfinity;
        sideMax = float.NegativeInfinity;
        if (avatarTransform == null || avatarBakedBodyMeshes == null || avatarBoneMap == null || avatarBoneMap.Count == 0)
        {
            return false;
        }
        HumanBodyBones key = (isLeft ? HumanBodyBones.LeftFoot : HumanBodyBones.RightFoot);
        if (!avatarBoneMap.TryGetValue(key, out var value) || value == null || value.Count == 0)
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] TryGetFootSpatialData\n - foot bone set is missing");
            return false;
        }
        Vector3 up = Vector3.up;
        Vector3 forward = Vector3.forward;
        Vector3 right = Vector3.right;
        HashSet<Transform> hashSet = new HashSet<Transform>();
        Transform transform = null;
        foreach (Transform item in value)
        {
            if (item == null)
            {
                continue;
            }
            if (transform == null)
            {
                transform = item;
            }
            Stack<Transform> stack = new Stack<Transform>();
            stack.Push(item);
            while (stack.Count > 0)
            {
                Transform transform2 = stack.Pop();
                if (!(transform2 == null) && hashSet.Add(transform2))
                {
                    for (int i = 0; i < transform2.childCount; i++)
                    {
                        stack.Push(transform2.GetChild(i));
                    }
                }
            }
        }
        if (transform == null || hashSet.Count == 0)
        {
            return false;
        }
        List<Vector3> list = this.poseMatchCommonUtil.CollectWeightedVerticesWorld(avatarBakedBodyMeshes, hashSet, weightThreshold, sampleStep);
        if (list == null || list.Count == 0)
        {
            return false;
        }
        for (int j = 0; j < list.Count; j++)
        {
            Vector3 lhs = list[j] - transform.position;
            float num = Vector3.Dot(lhs, up);
            if (num < footMinUp)
            {
                footMinUp = num;
            }
            if (num > footMaxUp)
            {
                footMaxUp = num;
            }
            float num2 = Vector3.Dot(lhs, forward);
            if (num2 < heelF)
            {
                heelF = num2;
            }
            if (num2 > toeF)
            {
                toeF = num2;
            }
            float num3 = Vector3.Dot(lhs, right);
            if (num3 < sideMin)
            {
                sideMin = num3;
            }
            if (num3 > sideMax)
            {
                sideMax = num3;
            }
        }
        return true;
    }

    public void DrawLegPcaDebug(GameObject avatarObject, IReadOnlyList<BakedBodyMesh> avatarBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> avatarBoneMap, bool isLeft, Color centerColor, Color axisColor, float axisScale = 1f, float duration = 1f)
    {
        if (!(avatarObject == null))
        {
            RegionStats regionStats = this.ComputeLegRegionStats(avatarObject.transform, avatarBakedBodyMeshes, avatarBoneMap, isLeft);
            if (regionStats.length < 0.0001f)
            {
                Debug.LogWarning($"[AvatarBodyMatchUtil] DrawLegPcaDebug: PCA length too small (avatar={avatarObject.name}, isLeft={isLeft})");
                return;
            }
            Vector3 center = regionStats.center;
            Vector3 normalized = regionStats.principalAxis.normalized;
            float num = 0.03f * axisScale;
            Debug.DrawLine(center + Vector3.up * num, center - Vector3.up * num, centerColor, duration);
            Debug.DrawLine(center + Vector3.right * num, center - Vector3.right * num, centerColor, duration);
            Debug.DrawLine(center + Vector3.forward * num, center - Vector3.forward * num, centerColor, duration);
            float num2 = regionStats.length * 0.5f * axisScale;
            Vector3 start = center - normalized * num2;
            Vector3 end = center + normalized * num2;
            Debug.DrawLine(start, end, axisColor, duration);
            Debug.Log($"[DrawLegPcaDebug] avatar={avatarObject.name}, isLeft={isLeft}, " + $"center={center}, axis={normalized}, len={regionStats.length}, avgRadius={regionStats.avgRadius}");
        }
    }

    public void DrawFootSpatialDebug(GameObject avatarObject, IReadOnlyList<BakedBodyMesh> avatarBakedBodyMeshes, Dictionary<HumanBodyBones, HashSet<Transform>> avatarBoneMap, bool isLeft, Color centerColor, Color axisColor, Color boxColor, float axisScale = 0.1f, float duration = 1f, float weightThreshold = 0.15f, int sampleStep = 1)
    {
        if (avatarObject == null)
        {
            return;
        }
        if (!this.TryGetFootSpatialData(avatarObject.transform, avatarBakedBodyMeshes, avatarBoneMap, isLeft, out var footMaxUp, out var footMinUp, out var heelF, out var toeF, out var sideMin, out var sideMax, weightThreshold, sampleStep))
        {
            Debug.LogWarning("[BodyPoseMatch_Leg] DrawFootSpatialDebug" + $"\n - Failed to compute Foot Spatial Data (avatar={avatarObject.name}, isLeft={isLeft})");
        }
        else
        {
            if (avatarBoneMap == null || avatarBoneMap.Count == 0)
            {
                return;
            }
            HumanBodyBones humanBodyBones = (isLeft ? HumanBodyBones.LeftFoot : HumanBodyBones.RightFoot);
            if (!avatarBoneMap.TryGetValue(humanBodyBones, out var value) || value == null || value.Count == 0)
            {
                return;
            }
            Transform transform = null;
            foreach (Transform item in value)
            {
                if (item != null)
                {
                    transform = item;
                    break;
                }
            }
            if (transform == null)
            {
                return;
            }
            Vector3 position = transform.position;
            Transform boneFromBoneMap = this.poseMatchCommonUtil.GetBoneFromBoneMap(avatarBoneMap, HumanBodyBones.Hips);
            Vector3 vector = ((boneFromBoneMap != null) ? boneFromBoneMap.forward : avatarObject.transform.forward);
            vector.y = 0f;
            if (vector.sqrMagnitude < 1E-06f)
            {
                vector = Vector3.forward;
            }
            vector.Normalize();
            Vector3 vector2 = Vector3.Cross(Vector3.up, vector);
            if (vector2.sqrMagnitude < 1E-06f)
            {
                vector2 = Vector3.right;
            }
            vector2.Normalize();
            Vector3 vector3 = ((boneFromBoneMap != null) ? boneFromBoneMap.up : avatarObject.transform.up);
            if (vector3.sqrMagnitude < 1E-06f)
            {
                vector3 = Vector3.up;
            }
            vector3.Normalize();
            float num = Mathf.Max(0.0001f, axisScale * 0.5f);
            DrawCross(position, vector3, vector2, centerColor, num, duration);
            DrawCross(position, vector3, vector, centerColor, num, duration);
            float len = Mathf.Max(0.0001f, axisScale * 2f);
            DrawAxisLine(position, vector3, len, axisColor, duration);
            DrawAxisLine(position, vector, len, axisColor, duration);
            DrawAxisLine(position, vector2, len, axisColor, duration);
            Vector3[] array = new Vector3[8];
            int num2 = 0;
            for (int i = 0; i < 2; i++)
            {
                float num3 = ((i == 0) ? footMinUp : footMaxUp);
                for (int j = 0; j < 2; j++)
                {
                    float num4 = ((j == 0) ? heelF : toeF);
                    for (int k = 0; k < 2; k++)
                    {
                        float num5 = ((k == 0) ? sideMin : sideMax);
                        array[num2++] = position + vector3 * num3 + vector * num4 + vector2 * num5;
                    }
                }
            }
            DrawBoxEdges(array, boxColor, duration);
            float size = Mathf.Max(5E-05f, num * 0.6f);
            for (int l = 0; l < array.Length; l++)
            {
                DrawCross(array[l], vector, vector2, boxColor, size, duration);
            }
            Debug.Log($"[DrawFootSpatialDebug] avatar={avatarObject.name}, isLeft={isLeft}\n" + $" - footBone={humanBodyBones}, footRoot={transform.name}\n" + $" - up(min,max)=({footMinUp:F4},{footMaxUp:F4})\n" + $" - forward(heel,toe)=({heelF:F4},{toeF:F4})\n" + $" - side(min,max)=({sideMin:F4},{sideMax:F4})\n" + $" - forwardDir={vector}, rightDir={vector2}, upDir={vector3}");
        }
        static void DrawAxisLine(Vector3 start, Vector3 dir, float num6, Color color, float d)
        {
            if (!(dir.sqrMagnitude < 1E-10f))
            {
                dir.Normalize();
                Debug.DrawLine(start, start + dir * num6, color, d);
            }
        }
        static void DrawBoxEdges(Vector3[] c, Color color, float d)
        {
            DrawSegment(c[0], c[1], color, d);
            DrawSegment(c[1], c[3], color, d);
            DrawSegment(c[3], c[2], color, d);
            DrawSegment(c[2], c[0], color, d);
            DrawSegment(c[4], c[5], color, d);
            DrawSegment(c[5], c[7], color, d);
            DrawSegment(c[7], c[6], color, d);
            DrawSegment(c[6], c[4], color, d);
            DrawSegment(c[0], c[4], color, d);
            DrawSegment(c[1], c[5], color, d);
            DrawSegment(c[2], c[6], color, d);
            DrawSegment(c[3], c[7], color, d);
        }
        static void DrawCross(Vector3 pos, Vector3 axisA, Vector3 axisB, Color color, float num6, float d)
        {
            if (axisA.sqrMagnitude < 1E-10f)
            {
                axisA = Vector3.up;
            }
            if (axisB.sqrMagnitude < 1E-10f)
            {
                axisB = Vector3.right;
            }
            axisA.Normalize();
            axisB.Normalize();
            Debug.DrawLine(pos - axisA * num6, pos + axisA * num6, color, d);
            Debug.DrawLine(pos - axisB * num6, pos + axisB * num6, color, d);
        }
        static void DrawSegment(Vector3 p0, Vector3 p1, Color color, float d)
        {
            Debug.DrawLine(p0, p1, color, d);
        }
    }
}
