Пример #1
0
        /// <summary>
        /// Detects the references based on naming and hierarchy.
        /// </summary>
        public static void DetectReferencesByNaming(ref BipedReferences references, Transform root, AutoDetectParams autoDetectParams)
        {
            if (references == null)
            {
                references = new BipedReferences();
            }

            Transform[] children = root.GetComponentsInChildren <Transform>();

            // Find limbs
            DetectLimb(BipedNaming.BoneType.Arm, BipedNaming.BoneSide.Left, ref references.leftUpperArm, ref references.leftForearm, ref references.leftHand, children);
            DetectLimb(BipedNaming.BoneType.Arm, BipedNaming.BoneSide.Right, ref references.rightUpperArm, ref references.rightForearm, ref references.rightHand, children);
            DetectLimb(BipedNaming.BoneType.Leg, BipedNaming.BoneSide.Left, ref references.leftThigh, ref references.leftCalf, ref references.leftFoot, children);
            DetectLimb(BipedNaming.BoneType.Leg, BipedNaming.BoneSide.Right, ref references.rightThigh, ref references.rightCalf, ref references.rightFoot, children);

            // Find head bone
            references.head = BipedNaming.GetBone(children, BipedNaming.BoneType.Head);

            // Find Pelvis
            references.pelvis = BipedNaming.GetNamingMatch(children, BipedNaming.pelvis);

            // If pelvis is not an ancestor of a leg, it is not a valid pelvis
            if (references.pelvis == null || !Hierarchy.IsAncestor(references.leftThigh, references.pelvis))
            {
                if (references.leftThigh != null)
                {
                    references.pelvis = references.leftThigh.parent;
                }
            }

            // Find spine and head bones
            if (references.leftUpperArm != null && references.rightUpperArm != null && references.pelvis != null && references.leftThigh != null)
            {
                Transform neck = Hierarchy.GetFirstCommonAncestor(references.leftUpperArm, references.rightUpperArm);

                if (neck != null)
                {
                    Transform[] inverseSpine = new Transform[1] {
                        neck
                    };
                    Hierarchy.AddAncestors(inverseSpine[0], references.pelvis, ref inverseSpine);

                    references.spine = new Transform[0];
                    for (int i = inverseSpine.Length - 1; i > -1; i--)
                    {
                        if (AddBoneToSpine(inverseSpine[i], ref references, autoDetectParams))
                        {
                            Array.Resize(ref references.spine, references.spine.Length + 1);
                            references.spine[references.spine.Length - 1] = inverseSpine[i];
                        }
                    }

                    // Head
                    if (references.head == null)
                    {
                        for (int i = 0; i < neck.childCount; i++)
                        {
                            Transform child = neck.GetChild(i);

                            if (!Hierarchy.ContainsChild(child, references.leftUpperArm) && !Hierarchy.ContainsChild(child, references.rightUpperArm))
                            {
                                references.head = child;
                                break;
                            }
                        }
                    }
                }
            }

            // Find eye bones
            Transform[] eyes = BipedNaming.GetBonesOfType(BipedNaming.BoneType.Eye, children);
            references.eyes = new Transform[0];

            if (autoDetectParams.includeEyes)
            {
                for (int i = 0; i < eyes.Length; i++)
                {
                    if (AddBoneToEyes(eyes[i], ref references, autoDetectParams))
                    {
                        Array.Resize(ref references.eyes, references.eyes.Length + 1);
                        references.eyes[references.eyes.Length - 1] = eyes[i];
                    }
                }
            }
        }
Пример #2
0
 private static bool IsNeckBone(Transform bone, Transform leftUpperArm)
 {
     return((!(leftUpperArm.parent != null) || !(leftUpperArm.parent == bone)) && !Hierarchy.IsAncestor(leftUpperArm, bone));
 }
Пример #3
0
 private static bool AddBoneToEyes(Transform bone, ref BipedReferences references, BipedReferences.AutoDetectParams autoDetectParams)
 {
     return((!(references.head != null) || Hierarchy.IsAncestor(bone, references.head)) && !(bone.GetComponent <SkinnedMeshRenderer>() != null));
 }
Пример #4
0
 public static void DetectReferencesByNaming(ref BipedReferences references, Transform root, BipedReferences.AutoDetectParams autoDetectParams)
 {
     if (references == null)
     {
         references = new BipedReferences();
     }
     Transform[] componentsInChildren = root.GetComponentsInChildren <Transform>();
     BipedReferences.DetectLimb(BipedNaming.BoneType.Arm, BipedNaming.BoneSide.Left, ref references.leftUpperArm, ref references.leftForearm, ref references.leftHand, componentsInChildren);
     BipedReferences.DetectLimb(BipedNaming.BoneType.Arm, BipedNaming.BoneSide.Right, ref references.rightUpperArm, ref references.rightForearm, ref references.rightHand, componentsInChildren);
     BipedReferences.DetectLimb(BipedNaming.BoneType.Leg, BipedNaming.BoneSide.Left, ref references.leftThigh, ref references.leftCalf, ref references.leftFoot, componentsInChildren);
     BipedReferences.DetectLimb(BipedNaming.BoneType.Leg, BipedNaming.BoneSide.Right, ref references.rightThigh, ref references.rightCalf, ref references.rightFoot, componentsInChildren);
     references.head   = BipedNaming.GetBone(componentsInChildren, BipedNaming.BoneType.Head, BipedNaming.BoneSide.Center, Array.Empty <string[]>());
     references.pelvis = BipedNaming.GetNamingMatch(componentsInChildren, new string[][]
     {
         BipedNaming.pelvis
     });
     if ((references.pelvis == null || !Hierarchy.IsAncestor(references.leftThigh, references.pelvis)) && references.leftThigh != null)
     {
         references.pelvis = references.leftThigh.parent;
     }
     if (references.leftUpperArm != null && references.rightUpperArm != null && references.pelvis != null && references.leftThigh != null)
     {
         Transform firstCommonAncestor = Hierarchy.GetFirstCommonAncestor(references.leftUpperArm, references.rightUpperArm);
         if (firstCommonAncestor != null)
         {
             Transform[] array = new Transform[]
             {
                 firstCommonAncestor
             };
             Hierarchy.AddAncestors(array[0], references.pelvis, ref array);
             references.spine = new Transform[0];
             for (int i = array.Length - 1; i > -1; i--)
             {
                 if (BipedReferences.AddBoneToSpine(array[i], ref references, autoDetectParams))
                 {
                     Array.Resize <Transform>(ref references.spine, references.spine.Length + 1);
                     references.spine[references.spine.Length - 1] = array[i];
                 }
             }
             if (references.head == null)
             {
                 for (int j = 0; j < firstCommonAncestor.childCount; j++)
                 {
                     Transform child = firstCommonAncestor.GetChild(j);
                     if (!Hierarchy.ContainsChild(child, references.leftUpperArm) && !Hierarchy.ContainsChild(child, references.rightUpperArm))
                     {
                         references.head = child;
                         break;
                     }
                 }
             }
         }
     }
     Transform[] bonesOfType = BipedNaming.GetBonesOfType(BipedNaming.BoneType.Eye, componentsInChildren);
     references.eyes = new Transform[0];
     if (autoDetectParams.includeEyes)
     {
         for (int k = 0; k < bonesOfType.Length; k++)
         {
             if (BipedReferences.AddBoneToEyes(bonesOfType[k], ref references, autoDetectParams))
             {
                 Array.Resize <Transform>(ref references.eyes, references.eyes.Length + 1);
                 references.eyes[references.eyes.Length - 1] = bonesOfType[k];
             }
         }
     }
 }
Пример #5
0
        /*
         * Check if the limb is properly set up
         * */
        private static bool CheckLimb(Transform bone1, Transform bone2, Transform bone3, bool log)
        {
            if (bone2.position == bone1.position)
            {
                if (log)
                {
                    Warning.Log("Second bone's position equals first bone's position in the biped's limb.", bone2, true);
                }
                return(false);
            }

            if (bone3.position == bone2.position)
            {
                if (log)
                {
                    Warning.Log("Third bone's position equals second bone's position in the biped's limb.", bone3, true);
                }
                return(false);
            }

            Transform duplicate = (Transform)Hierarchy.ContainsDuplicate(new Transform[3] {
                bone1, bone2, bone3
            });

            if (duplicate != null)
            {
                if (log)
                {
                    Warning.Log(duplicate.name + " is represented multiple times in the same BipedReferences limb.", bone1, true);
                }
                return(false);
            }

            if (!Hierarchy.HierarchyIsValid(new Transform[3] {
                bone1, bone2, bone3
            }))
            {
                if (log)
                {
                    Warning.Log(
                        "BipedReferences limb hierarchy is invalid. Bone transforms in a limb do not belong to the same ancestry. Please make sure the bones are parented to each other. " +
                        "Bones: " + bone1.name + ", " + bone2.name + ", " + bone3.name,
                        bone1,
                        true);
                }
                return(false);
            }

            Vector3 cross = Vector3.Cross(bone2.position - bone1.position, bone3.position - bone1.position);

            if (cross == Vector3.zero)
            {
                if (log)
                {
                    Warning.Log(
                        "BipedReferences limb is completely stretched out in the initial pose. IK solver can not calculate the default bend plane for the limb. " +
                        "Please make sure you character's limbs are at least slightly bent in the initial pose. " +
                        "First bone: " + bone1.name + ", second bone: " + bone2.name + ".",
                        bone1,
                        true);
                }
                return(false);
            }

            return(true);
        }
Пример #6
0
        // Check if spine is properly set up
        private static bool CheckSpineError(BipedReferences references, bool log)
        {
            if (references.spine.Length == 0)
            {
                return(true);
            }

            for (int i = 0; i < references.spine.Length; i++)
            {
                if (references.spine[i] == null)
                {
                    if (log)
                    {
                        Warning.Log("BipedReferences spine bone at index " + i + " is null.", references.root, true);
                    }
                    return(false);
                }
            }

            Transform duplicate = (Transform)Hierarchy.ContainsDuplicate(references.spine);

            if (duplicate != null)
            {
                if (log)
                {
                    Warning.Log(duplicate.name + " is represented multiple times in BipedReferences spine.", references.spine[0], true);
                }
                return(false);
            }

            if (!Hierarchy.HierarchyIsValid(references.spine))
            {
                if (log)
                {
                    Warning.Log("BipedReferences spine hierarchy is invalid. Bone transforms in the spine do not belong to the same ancestry. Please make sure the bones are parented to each other.", references.spine[0], true);
                }
                return(false);
            }

            for (int i = 0; i < references.spine.Length; i++)
            {
                bool matchesParentPosition = false;
                if (i == 0 && references.spine[i].position == references.pelvis.position)
                {
                    matchesParentPosition = true;
                }
                if (i != 0 && references.spine.Length > 1 && references.spine[i].position == references.spine[i - 1].position)
                {
                    matchesParentPosition = true;
                }

                if (matchesParentPosition)
                {
                    if (log)
                    {
                        Warning.Log("Biped's spine bone nr " + i + " position is the same as it's parent spine/pelvis bone's position. Please remove this bone from the spine.", references.spine[i], true);
                    }
                    return(false);
                }
            }

            return(true);
        }
Пример #7
0
        // Check if the limb is properly set up
        private static bool CheckLimbError(Transform bone1, Transform bone2, Transform bone3, bool log)
        {
            if (bone1 == null)
            {
                if (log)
                {
                    Warning.Log("Bone 1 of a BipedReferences limb is null.", bone2, true);
                }
                return(false);
            }

            if (bone2 == null)
            {
                if (log)
                {
                    Warning.Log("Bone 2 of a BipedReferences limb is null.", bone3, true);
                }
                return(false);
            }

            if (bone3 == null)
            {
                if (log)
                {
                    Warning.Log("Bone 3 of a BipedReferences limb is null.", bone1, true);
                }
                return(false);
            }

            if (bone2.position == bone1.position)
            {
                if (log)
                {
                    Warning.Log("Second bone's position equals first bone's position in the biped's limb.", bone2, true);
                }
                return(false);
            }

            if (bone3.position == bone2.position)
            {
                if (log)
                {
                    Warning.Log("Third bone's position equals second bone's position in the biped's limb.", bone3, true);
                }
                return(false);
            }

            Transform duplicate = (Transform)Hierarchy.ContainsDuplicate(new Transform[3] {
                bone1, bone2, bone3
            });

            if (duplicate != null)
            {
                if (log)
                {
                    Warning.Log(duplicate.name + " is represented multiple times in the same BipedReferences limb.", bone1, true);
                }
                return(false);
            }

            if (!Hierarchy.HierarchyIsValid(new Transform[3] {
                bone1, bone2, bone3
            }))
            {
                if (log)
                {
                    Warning.Log(
                        "BipedReferences limb hierarchy is invalid. Bone transforms in a limb do not belong to the same ancestry. Please make sure the bones are parented to each other. " +
                        "Bones: " + bone1.name + ", " + bone2.name + ", " + bone3.name,
                        bone1,
                        true);
                }
                return(false);
            }

            return(true);
        }
Пример #8
0
 public static bool IsAncestor(Transform transform, Transform ancestor)
 {
     return(transform == null || ancestor == null || (!(transform.parent == null) && (transform.parent == ancestor || Hierarchy.IsAncestor(transform.parent, ancestor))));
 }