Beispiel #1
0
        static Arm GetArm(Node shoulder)
        {
            var bones = shoulder.Traverse().ToArray();

            switch (bones.Length)
            {
            case 0:
            case 1:
            case 2:
                throw new NotImplementedException();

            case 3:
                return(new Arm
                {
                    UpperArm = bones[0],
                    LowerArm = bones[1],
                    Hand = bones[2],
                });

            default:
                return(new Arm
                {
                    Shoulder = bones[0],
                    UpperArm = bones[1],
                    LowerArm = bones[2],
                    Hand = bones[3],
                });
            }
        }
Beispiel #2
0
        static public Dictionary <HumanoidBones, Node> DetectByName(Node root, Dictionary <string, HumanoidBones> map)
        {
            var dictionary = new Dictionary <HumanoidBones, Node>();

            foreach (var bone in root.Traverse())
            {
                if (map.TryGetValue(bone.Name, out HumanoidBones humanbone))
                {
                    if (humanbone != HumanoidBones.unknown)
                    {
                        dictionary.Add(humanbone, bone);
                    }
                }
                else if (Enum.TryParse <HumanoidBones>(bone.Name, true, out HumanoidBones result))
                {
                    humanbone = (HumanoidBones)result;
                    dictionary.Add(humanbone, bone);
                }
                else
                {
                    // throw new NotImplementedException();
                }
            }
            return(dictionary);
        }
Beispiel #3
0
        static Leg GetLeg(Node leg)
        {
            var bones = leg.Traverse().Where(x => string.IsNullOrEmpty(x.Name) || !x.Name.ToLower().Contains("buttock")).ToArray();

            switch (bones.Length)
            {
            case 0:
            case 1:
            case 2:
                throw new NotImplementedException();

            case 3:
                return(new Leg
                {
                    UpperLeg = bones[0],
                    LowerLeg = bones[1],
                    Foot = bones[2],
                });

            default:
                return(new Leg
                {
                    UpperLeg = bones[bones.Length - 4],
                    LowerLeg = bones[bones.Length - 3],
                    Foot = bones[bones.Length - 2],
                    Toes = bones[bones.Length - 1],
                });
            }
        }
Beispiel #4
0
        static ValueTuple <Node, Node> GetUpperLower(Node root)
        {
            var legL = root.Traverse().FirstOrDefault(x => x.HumanoidBone == HumanoidBones.leftUpperLeg);
            var legR = root.Traverse().FirstOrDefault(x => x.HumanoidBone == HumanoidBones.rightUpperLeg);
            var head = root.Traverse().FirstOrDefault(x => x.HumanoidBone == HumanoidBones.head);

            var parentL = legL.Parent;
            var parentR = legR.Parent;

            if (parentL != parentR)
            {
                throw new Exception("different leftLeg parent and rightLeg parent");
            }
            var lower = parentL;

            var upperAncestors = head.Ancestors().ToList();

            if (upperAncestors.Any(x => x == lower))
            {
                throw new Exception("lower is ancestor of head");
            }

            var lowerAncestors = legL.Ancestors().ToList();

            while (true)
            {
                if (upperAncestors.Last() != lowerAncestors.Last())
                {
                    break;
                }
                upperAncestors.RemoveAt(upperAncestors.Count - 1);
                lowerAncestors.RemoveAt(lowerAncestors.Count - 1);
            }

            return(upperAncestors.Last(), lowerAncestors.Last());
        }
Beispiel #5
0
 public Dictionary <HumanoidBones, Node> GetBoneMap()
 {
     return(Root.Traverse()
            .Where(x => x.HumanoidBone.HasValue)
            .ToDictionary(x => x.HumanoidBone.Value, x => x));
 }
Beispiel #6
0
        static public Dictionary <HumanoidBones, Node> DetectByPosition(Node root)
        {
            var hips = root.Traverse().First(x =>
            {
                // 3分岐以上で
                //
                // 子孫が以下の構成持ちうるもの
                //
                // spine, head, (upper, lower, hand) x 2
                // (upper, lower, foot)
                // (upper, lower, foot)
                return(x.Children.Where(y => y.Traverse().Count() >= 3).Count() >= 3);
            });

            Node spine, hip_L, hip_R;

            GetSpineAndHips(hips, out spine, out hip_L, out hip_R);
            if (hip_L.Equals(hip_R))
            {
                throw new Exception();
            }
            var legLeft  = GetLeg(hip_L);
            var legRight = GetLeg(hip_R);

            var spineToChest = new List <Node>();

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

            Func <Vector3, Vector3, bool> isLeft = default(Func <Vector3, Vector3, bool>);

            if (legLeft.UpperLeg.SkeletonLocalPosition.Z == legRight.UpperLeg.SkeletonLocalPosition.Z)
            {
                isLeft = (l, r) => l.X < r.X;
            }
            else
            {
                isLeft = (l, r) => l.Z < r.Z;
            }

            Node neck, shoulder_L, shoulder_R;

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

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

            //
            //  set result
            //
            var skeleton = new Dictionary <HumanoidBones, Node>();
            Action <HumanoidBones, Node> AddBoneToSkeleton = (b, t) =>
            {
                if (t != null)
                {
                    t.HumanoidBone = b;
                    skeleton[b]    = t;
                }
            };

            AddBoneToSkeleton(HumanoidBones.hips, hips);

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

            case 1:
                AddBoneToSkeleton(HumanoidBones.spine, spineToChest[0]);
                break;

            case 2:
                AddBoneToSkeleton(HumanoidBones.spine, spineToChest[0]);
                AddBoneToSkeleton(HumanoidBones.chest, spineToChest[1]);
                break;

            case 3:
                AddBoneToSkeleton(HumanoidBones.spine, spineToChest[0]);
                AddBoneToSkeleton(HumanoidBones.chest, spineToChest[1]);
                AddBoneToSkeleton(HumanoidBones.upperChest, spineToChest[2]);
                break;

            default:
                AddBoneToSkeleton(HumanoidBones.spine, spineToChest[0]);
                AddBoneToSkeleton(HumanoidBones.chest, spineToChest[1]);
                AddBoneToSkeleton(HumanoidBones.upperChest, spineToChest.Last());
                break;
            }

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

            case 1:
                AddBoneToSkeleton(HumanoidBones.head, neckToHead[0]);
                break;

            case 2:
                AddBoneToSkeleton(HumanoidBones.neck, neckToHead[0]);
                AddBoneToSkeleton(HumanoidBones.head, neckToHead[1]);
                break;

            default:
                AddBoneToSkeleton(HumanoidBones.neck, neckToHead[0]);
                AddBoneToSkeleton(HumanoidBones.head, neckToHead.Where(x => x.Parent.Children.Count == 1).Last());
                break;
            }

            AddBoneToSkeleton(HumanoidBones.leftUpperLeg, legLeft.UpperLeg);
            AddBoneToSkeleton(HumanoidBones.leftLowerLeg, legLeft.LowerLeg);
            AddBoneToSkeleton(HumanoidBones.leftFoot, legLeft.Foot);
            AddBoneToSkeleton(HumanoidBones.leftToes, legLeft.Toes);

            AddBoneToSkeleton(HumanoidBones.rightUpperLeg, legRight.UpperLeg);
            AddBoneToSkeleton(HumanoidBones.rightLowerLeg, legRight.LowerLeg);
            AddBoneToSkeleton(HumanoidBones.rightFoot, legRight.Foot);
            AddBoneToSkeleton(HumanoidBones.rightToes, legRight.Toes);

            AddBoneToSkeleton(HumanoidBones.leftShoulder, armLeft.Shoulder);
            AddBoneToSkeleton(HumanoidBones.leftUpperArm, armLeft.UpperArm);
            AddBoneToSkeleton(HumanoidBones.leftLowerArm, armLeft.LowerArm);
            AddBoneToSkeleton(HumanoidBones.leftHand, armLeft.Hand);

            AddBoneToSkeleton(HumanoidBones.rightShoulder, armRight.Shoulder);
            AddBoneToSkeleton(HumanoidBones.rightUpperArm, armRight.UpperArm);
            AddBoneToSkeleton(HumanoidBones.rightLowerArm, armRight.LowerArm);
            AddBoneToSkeleton(HumanoidBones.rightHand, armRight.Hand);

            return(skeleton);
        }