using System; using System.Collections.Generic; using UnityEngine; internal class BoneDistanceToSkinMgr { public BoneDistanceToSkinMgr(TMorphSkin morph, SkinThickness skinThick, Transform t) { BoneDistanceToSkinMgr $this = this; Action action = delegate(SkinThickness.Group grp) { Transform start = CMT.SearchObjName(t, grp.startBoneName, false); Transform end = CMT.SearchObjName(t, grp.endBoneName, false); BoneDistanceToSkinMgr.Group group = new BoneDistanceToSkinMgr.Group(morph, start, end); $this.m_BoneDistanceToSkin[grp.groupName] = group; BoneDistanceToSkinMgr.Group group2 = group; foreach (SkinThickness.Group.Point point in grp.points) { Transform target = CMT.SearchObjName(t, point.targetBoneName, false); group2.AddPoint(point, target); } }; if (skinThick.use) { foreach (KeyValuePair keyValuePair in skinThick.groups) { action(keyValuePair.Value); } } } public void Update() { foreach (KeyValuePair keyValuePair in this.m_BoneDistanceToSkin) { keyValuePair.Value.UpdateDisntace(); } } public float GetDistanceToSkinByAngle(string groupName, float ratio, float angle, out float defaultDistance) { return this.m_BoneDistanceToSkin[groupName].GetDistanceToSkinByAngle(ratio, angle, out defaultDistance); } private Dictionary m_BoneDistanceToSkin = new Dictionary(); private class Group { public Group(TMorphSkin morph, Transform start, Transform end) { this.m_morph = morph; this.m_start = start; this.m_end = end; } public void AddPoint(SkinThickness.Group.Point point, Transform target) { this.m_points.Add(new BoneDistanceToSkinMgr.Group.Point(this, point, target)); } public void UpdateDisntace() { foreach (BoneDistanceToSkinMgr.Group.Point point in this.m_points) { point.UpdateDisntace(); } } public float GetDistanceToSkinByAngle(float ratio, float angle, out float defaultDistance) { float result = 0f; BoneDistanceToSkinMgr.Group.Point point = this.m_points[0]; BoneDistanceToSkinMgr.Group.Point point2 = this.m_points[this.m_points.Count - 1]; angle %= 360f; if (angle < 0f) { angle = 360f + angle; } if (ratio <= point.m_distRatioNow) { float num = MathCM.SignedAngle(this.m_start.up, point.m_target.up, this.m_start.right); result = point.GetNearAngleDistance(angle - num, out defaultDistance); } else if (point2.m_distRatioNow <= ratio) { float num2 = MathCM.SignedAngle(this.m_start.up, point2.m_target.up, this.m_start.right); result = point2.GetNearAngleDistance(angle - num2, out defaultDistance); } else { defaultDistance = 0f; for (int i = 0; i < this.m_points.Count - 1; i++) { point = this.m_points[i]; point2 = this.m_points[i + 1]; if (point.m_distRatioNow <= ratio && ratio <= point2.m_distRatioNow) { float num3 = (ratio - point.m_distRatioNow) / (point2.m_distRatioNow - point.m_distRatioNow); float num4 = MathCM.SignedAngle(this.m_start.up, point.m_target.up, this.m_start.right); float num5 = MathCM.SignedAngle(this.m_start.up, point2.m_target.up, this.m_start.right); float num6 = num4 + (num5 - num4) * num3; float num7; float nearAngleDistance = point.GetNearAngleDistance(angle - num6, out num7); float num8; float nearAngleDistance2 = point2.GetNearAngleDistance(angle - num6, out num8); result = nearAngleDistance + (nearAngleDistance2 - nearAngleDistance) * num3; defaultDistance = num7 + (num8 - num7) * num3; break; } } } return result; } private TMorphSkin m_morph; private Transform m_start; private Transform m_end; private List m_points = new List(); private class Point { public Point(BoneDistanceToSkinMgr.Group group, SkinThickness.Group.Point point, Transform target) { this.m_group = group; this.m_pointDef = point; this.m_target = target; this.m_distRatioDef = this.m_pointDef.ratioSegmentStartToEnd; foreach (SkinThickness.Group.Point.DefPerAngle defPerAngle in this.m_pointDef.distanceParAngle) { this.m_angleDistance.Add(new BoneDistanceToSkinMgr.Group.Point.AngleDist { angle = defPerAngle.angleDgree, defDisntace = defPerAngle.defaultDistance, vidx = defPerAngle.vidx }); } } public void UpdateDisntace() { this.m_distRatioNow = Vector3.Distance(this.m_group.m_start.position, this.m_target.position) / Vector3.Distance(this.m_group.m_start.position, this.m_group.m_end.position); foreach (BoneDistanceToSkinMgr.Group.Point.AngleDist angleDist in this.m_angleDistance) { Vector3 zero = Vector3.zero; this.m_group.m_morph.CalcVidxToPos(angleDist.vidx, ref zero); angleDist.nowDistance = (this.m_target.position - zero).magnitude; } } public float GetNearAngleDistance(float angle, out float defDistance) { angle %= 360f; float num = 360f; int index = -1; for (int i = 0; i < this.m_angleDistance.Count; i++) { float num2 = Mathf.Abs((float)this.m_angleDistance[i].angle - angle); if (num2 < num) { num = num2; index = i; } } BoneDistanceToSkinMgr.Group.Point.AngleDist angleDist = this.m_angleDistance[index]; float nowDistance = angleDist.nowDistance; defDistance = angleDist.defDisntace; return nowDistance; } private BoneDistanceToSkinMgr.Group m_group; public SkinThickness.Group.Point m_pointDef; public Transform m_target; public float m_distRatioDef; public float m_distRatioNow; private List m_angleDistance = new List(); private class AngleDist { public int angle; public float nowDistance; public float defDisntace; public int vidx; } } } }