예제 #1
0
        public Skeleton Detect(IList <IBone> bones)
        {
            //
            // search bones
            //
            var root = GetRoot(bones);
            var hips = root.Traverse().First(x => x.Children.Count == 3);

            IBone spine, hip_L, hip_R;

            GetSpineAndHips(hips, out spine, out hip_L, out hip_R);
            var legLeft  = GetLeg(hip_L);
            var legRight = GetLeg(hip_R);

            var spineToChest = new List <IBone>();

            foreach (var x in spine.Traverse())
            {
                spineToChest.Add(x);
                if (x.Children.Count == 3)
                {
                    break;
                }
            }

            IBone neck, shoulder_L, shoulder_R;

            GetNeckAndArms(spineToChest.Last(), out neck, out shoulder_L, out shoulder_R);
            var armLeft  = GetArm(shoulder_L);
            var armRight = GetArm(shoulder_R);

            var neckToHead = neck.Traverse().ToArray();

            //
            //  set result
            //
            var skeleton = new Skeleton();

            skeleton.Set(HumanBodyBones.Hips, bones, hips);

            switch (spineToChest.Count)
            {
            case 0:
                throw new Exception();

            case 1:
                skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]);
                break;

            case 2:
                skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]);
                skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]);
                break;

#if UNITY_5_6_OR_NEWER
            case 3:
                skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]);
                skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]);
                skeleton.Set(HumanBodyBones.UpperChest, bones, spineToChest[2]);
                break;
#endif

            default:
                skeleton.Set(HumanBodyBones.Spine, bones, spineToChest[0]);
#if UNITY_5_6_OR_NEWER
                skeleton.Set(HumanBodyBones.Chest, bones, spineToChest[1]);
                skeleton.Set(HumanBodyBones.UpperChest, bones, spineToChest.Last());
#else
                skeleton.Set(HumanBodyBones.Chest, bones, spineToChest.Last());
#endif
                break;
            }

            switch (neckToHead.Length)
            {
            case 0:
                throw new Exception();

            case 1:
                skeleton.Set(HumanBodyBones.Head, bones, neckToHead[0]);
                break;

            case 2:
                skeleton.Set(HumanBodyBones.Neck, bones, neckToHead[0]);
                skeleton.Set(HumanBodyBones.Head, bones, neckToHead[1]);
                break;

            default:
                skeleton.Set(HumanBodyBones.Neck, bones, neckToHead[0]);
                skeleton.Set(HumanBodyBones.Head, bones, neckToHead.Where(x => x.Parent.Children.Count == 1).Last());
                break;
            }

            skeleton.Set(HumanBodyBones.LeftUpperLeg, bones, legLeft.UpperLeg);
            skeleton.Set(HumanBodyBones.LeftLowerLeg, bones, legLeft.LowerLeg);
            skeleton.Set(HumanBodyBones.LeftFoot, bones, legLeft.Foot);
            skeleton.Set(HumanBodyBones.LeftToes, bones, legLeft.Toes);

            skeleton.Set(HumanBodyBones.RightUpperLeg, bones, legRight.UpperLeg);
            skeleton.Set(HumanBodyBones.RightLowerLeg, bones, legRight.LowerLeg);
            skeleton.Set(HumanBodyBones.RightFoot, bones, legRight.Foot);
            skeleton.Set(HumanBodyBones.RightToes, bones, legRight.Toes);

            skeleton.Set(HumanBodyBones.LeftShoulder, bones, armLeft.Shoulder);
            skeleton.Set(HumanBodyBones.LeftUpperArm, bones, armLeft.UpperArm);
            skeleton.Set(HumanBodyBones.LeftLowerArm, bones, armLeft.LowerArm);
            skeleton.Set(HumanBodyBones.LeftHand, bones, armLeft.Hand);

            skeleton.Set(HumanBodyBones.RightShoulder, bones, armRight.Shoulder);
            skeleton.Set(HumanBodyBones.RightUpperArm, bones, armRight.UpperArm);
            skeleton.Set(HumanBodyBones.RightLowerArm, bones, armRight.LowerArm);
            skeleton.Set(HumanBodyBones.RightHand, bones, armRight.Hand);

            return(skeleton);
        }