// Check for possible warnings with the biped references setup
        private void CheckWarning(BipedReferences references, IKSolverFullBodyBiped solver, Transform context, bool log)
        {
            // Check for all the warnings common to all bipeds
            BipedReferences.CheckSetupWarning(script.references, log);

            // Check for warnings specific to FBBIK
            Vector3 toRightShoulder    = references.rightUpperArm.position - references.leftUpperArm.position;
            Vector3 shoulderToRootNode = solver.rootNode.position - references.leftUpperArm.position;
            float   dot = Vector3.Dot(toRightShoulder.normalized, shoulderToRootNode.normalized);

            if (dot > 0.95f)
            {
                if (log)
                {
                    Warning.Log("The root node, the left upper arm and the right upper arm bones should ideally form a triangle that is as close to equilateral as possible. " +
                                "Currently the root node bone seems to be very close to the line between the left upper arm and the right upper arm bones. This might cause unwanted behaviour like the spine turning upside down when pulled by a hand effector." +
                                "Please set the root node bone to be one of the lower bones in the spine.", context, true);
                }
            }

            Vector3 toRightThigh    = references.rightThigh.position - references.leftThigh.position;
            Vector3 thighToRootNode = solver.rootNode.position - references.leftThigh.position;

            dot = Vector3.Dot(toRightThigh.normalized, thighToRootNode.normalized);

            if (dot > 0.95f && log)
            {
                Warning.Log("The root node, the left thigh and the right thigh bones should ideally form a triangle that is as close to equilateral as possible. " +
                            "Currently the root node bone seems to be very close to the line between the left thigh and the right thigh bones. This might cause unwanted behaviour like the hip turning upside down when pulled by an effector." +
                            "Please set the root node bone to be one of the higher bones in the spine.", context, true);
            }
        }
 private void AutoDetectReferences()
 {
     this.references = new BipedReferences();
     BipedReferences.AutoDetectReferences(ref this.references, base.transform, new BipedReferences.AutoDetectParams(true, false));
     this.solver.rootNode = IKSolverFullBodyBiped.DetectRootNodeBone(this.references);
     this.solver.SetToReferences(this.references, this.solver.rootNode);
 }
Beispiel #3
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUILayout.Space();

            Inspector.AddContent(fixTransforms);

            // Editing References
            if (BipedReferencesInspector.AddModifiedInspector(references))
            {
                if (!Application.isPlaying)
                {
                    Warning.logged = false;
                    BipedReferences.CheckSetup(script.references);
                    script.InitiateBipedIK();
                }
            }

            // Editing Solvers
            BipedIKSolversInspector.AddInspector(solvers, solversProps, solverContents);

            EditorGUILayout.Space();

            serializedObject.ApplyModifiedProperties();
        }
Beispiel #4
0
            public References(BipedReferences b)
            {
                root   = b.root;
                pelvis = b.pelvis;
                spine  = b.spine[0];
                chest  = b.spine.Length > 1? b.spine[1]: null;
                head   = b.head;

                leftShoulder = b.leftUpperArm.parent;
                leftUpperArm = b.leftUpperArm;
                leftForearm  = b.leftForearm;
                leftHand     = b.leftHand;

                rightShoulder = b.rightUpperArm.parent;
                rightUpperArm = b.rightUpperArm;
                rightForearm  = b.rightForearm;
                rightHand     = b.rightHand;

                leftThigh = b.leftThigh;
                leftCalf  = b.leftCalf;
                leftFoot  = b.leftFoot;
                leftToes  = b.leftFoot.GetChild(0);

                rightThigh = b.rightThigh;
                rightCalf  = b.rightCalf;
                rightFoot  = b.rightFoot;
                rightToes  = b.rightFoot.GetChild(0);
            }
 public bool ReferencesError(ref string errorMessage)
 {
     if (BipedReferences.SetupError(this.references, ref errorMessage))
     {
         return(true);
     }
     if (this.references.spine.Length == 0)
     {
         errorMessage = "References has no spine bones assigned, can not initiate the solver.";
         return(true);
     }
     if (this.solver.rootNode == null)
     {
         errorMessage = "Root Node bone is null, can not initiate the solver.";
         return(true);
     }
     if (this.solver.rootNode != this.references.pelvis)
     {
         bool flag = false;
         for (int i = 0; i < this.references.spine.Length; i++)
         {
             if (this.solver.rootNode == this.references.spine[i])
             {
                 flag = true;
                 break;
             }
         }
         if (!flag)
         {
             errorMessage = "The Root Node has to be one of the bones in the Spine or the Pelvis, can not initiate the solver.";
             return(true);
         }
     }
     return(false);
 }
Beispiel #6
0
        /*
         * Initiates the %IK solver
         * */
        protected override void InitiateSolver()
        {
            string message = "";

            if (BipedReferences.SetupError(references, ref message))
            {
                Warning.Log(message, references.root, false);
                return;
            }
            solvers.AssignReferences(references);

            // Initiating solvers
            if (solvers.spine.bones.Length > 1)
            {
                solvers.spine.Initiate(transform);
            }
            solvers.lookAt.Initiate(transform);
            solvers.aim.Initiate(transform);
            foreach (IKSolverLimb limb in solvers.limbs)
            {
                limb.Initiate(transform);
            }

            // Initiating constraints
            solvers.pelvis.Initiate(references.pelvis);
        }
Beispiel #7
0
        public void OnCharacterCompleted(UMAData umaData)
        {
            // Add the BipedIK component
            BipedIK bipedIK = umaData.gameObject.AddComponent <BipedIK>() as BipedIK;

            // Setup the bone references
            if (umaData.animator != null)
            {
                BipedReferences.AssignHumanoidReferences(ref bipedIK.references, umaData.animator, BipedReferences.AutoDetectParams.Default);
            }
            else
            {
                BipedReferences.AutoDetectReferences(ref bipedIK.references, umaData.umaRoot.transform, BipedReferences.AutoDetectParams.Default);
            }

            // Zero out the initial IK weights
            bipedIK.SetLookAtWeight(0f, 0f, 0f, 0f, 0f, 0f, 0f);
            bipedIK.SetSpineWeight(0f);

            bipedIK.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 0f);
            bipedIK.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 0f);
            bipedIK.SetIKPositionWeight(AvatarIKGoal.RightFoot, 0f);
            bipedIK.SetIKRotationWeight(AvatarIKGoal.RightFoot, 0f);

            bipedIK.SetIKPositionWeight(AvatarIKGoal.LeftHand, 0f);
            bipedIK.SetIKRotationWeight(AvatarIKGoal.LeftHand, 0f);
            bipedIK.GetGoalIK(AvatarIKGoal.LeftHand).bendModifier = IKSolverLimb.BendModifier.Arm;

            bipedIK.SetIKPositionWeight(AvatarIKGoal.RightHand, 0f);
            bipedIK.SetIKRotationWeight(AvatarIKGoal.RightHand, 0f);
            bipedIK.GetGoalIK(AvatarIKGoal.RightHand).bendModifier = IKSolverLimb.BendModifier.Arm;
        }
Beispiel #8
0
        public bool ReferencesWarning(ref string warningMessage)
        {
            if (BipedReferences.SetupWarning(this.references, ref warningMessage))
            {
                return(true);
            }
            Vector3 vector  = this.references.rightUpperArm.position - this.references.leftUpperArm.position;
            Vector3 vector2 = this.solver.rootNode.position - this.references.leftUpperArm.position;
            float   num     = Vector3.Dot(vector.normalized, vector2.normalized);

            if (num > 0.95f)
            {
                warningMessage = "The root node, the left upper arm and the right upper arm bones should ideally form a triangle that is as close to equilateral as possible. Currently the root node bone seems to be very close to the line between the left upper arm and the right upper arm bones. This might cause unwanted behaviour like the spine turning upside down when pulled by a hand effector.Please set the root node bone to be one of the lower bones in the spine.";
                return(true);
            }
            Vector3 vector3 = this.references.rightThigh.position - this.references.leftThigh.position;
            Vector3 vector4 = this.solver.rootNode.position - this.references.leftThigh.position;

            num = Vector3.Dot(vector3.normalized, vector4.normalized);
            if (num > 0.95f)
            {
                warningMessage = "The root node, the left thigh and the right thigh bones should ideally form a triangle that is as close to equilateral as possible. Currently the root node bone seems to be very close to the line between the left thigh and the right thigh bones. This might cause unwanted behaviour like the hip turning upside down when pulled by an effector.Please set the root node bone to be one of the higher bones in the spine.";
                return(true);
            }
            return(false);
        }
Beispiel #9
0
        public void OnEnable()
        {
            if (serializedObject == null)
            {
                return;
            }

            // Store the MonoScript for changing script execution order
            if (!Application.isPlaying)
            {
                MonoScript monoScript = MonoScript.FromMonoBehaviour(script);

                // Changing the script execution order to make sure BipedIK always executes after any other script except FullBodyBipedIK
                int executionOrder = MonoImporter.GetExecutionOrder(monoScript);
                if (executionOrder != 9998)
                {
                    MonoImporter.SetExecutionOrder(monoScript, 9998);
                }
            }

            references    = serializedObject.FindProperty("references");
            solvers       = serializedObject.FindProperty("solvers");
            solversProps  = BipedIKSolversInspector.FindProperties(solvers);
            fixTransforms = new SerializedContent(serializedObject.FindProperty("fixTransforms"), new GUIContent("Fix Transforms", "If true, will fix all the Transforms used by the solver to their initial state in each Update. This prevents potential problems with unanimated bones and animator culling with a small cost of performance."));

            // Automatically detecting references
            if (!Application.isPlaying)
            {
                if (script.references.isEmpty)
                {
                    BipedReferences.AutoDetectReferences(ref script.references, script.transform, new BipedReferences.AutoDetectParams(false, true));

                    references.isExpanded = true;
                    solvers.isExpanded    = false;
                    for (int i = 0; i < solversProps.Length; i++)
                    {
                        solversProps[i].isExpanded = false;
                    }

                    // Setting default values and initiating
                    script.InitiateBipedIK();
                    script.SetToDefaults();
                    EditorUtility.SetDirty(script);
                }
                else
                {
                    script.InitiateBipedIK();
                }

                Warning.logged = false;

                if (Application.isPlaying)
                {
                    if (ReferencesValid(true))
                    {
                        BipedReferences.CheckSetupWarning(script.references, true);
                    }
                }
            }
        }
        public static void InitIKTarget(OCIChar _ociChar, bool _addInfo)
        {
            IKSolverFullBodyBiped solver     = (IKSolverFullBodyBiped)_ociChar.finalIK.solver;
            BipedReferences       references = (BipedReferences)_ociChar.finalIK.references;

            _ociChar.ikCtrl = _ociChar.preparation.IKCtrl;
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 0, solver.get_bodyEffector(), false, (Transform)references.pelvis);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 1, solver.get_leftShoulderEffector(), false, (Transform)references.leftUpperArm);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 2, solver.get_leftArmChain(), false, (Transform)references.leftForearm);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 3, solver.get_leftHandEffector(), true, (Transform)references.leftHand);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 4, solver.get_rightShoulderEffector(), false, (Transform)references.rightUpperArm);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 5, solver.get_rightArmChain(), false, (Transform)references.rightForearm);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 6, solver.get_rightHandEffector(), true, (Transform)references.rightHand);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 7, solver.get_leftThighEffector(), false, (Transform)references.leftThigh);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 8, solver.get_leftLegChain(), false, (Transform)references.leftCalf);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 9, solver.get_leftFootEffector(), true, (Transform)references.leftFoot);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 10, solver.get_rightThighEffector(), false, (Transform)references.rightThigh);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 11, solver.get_rightLegChain(), false, (Transform)references.rightCalf);
            AddObjectAssist.AddIKTarget(_ociChar, _ociChar.ikCtrl, 12, solver.get_rightFootEffector(), true, (Transform)references.rightFoot);
            if (!_addInfo)
            {
                return;
            }
            _ociChar.ikCtrl.InitTarget();
        }
Beispiel #11
0
		void AutoDetectReferences() {
			references = new BipedReferences();
			BipedReferences.AutoDetectReferences(ref references, transform, new BipedReferences.AutoDetectParams(true, false));

			solver.rootNode = IKSolverFullBodyBiped.DetectRootNodeBone(references);
			
			solver.SetToReferences(references, solver.rootNode);
		}
Beispiel #12
0
 private static Transform GetRightClavicle(BipedReferences references)
 {
     if (!Contains(references.spine, references.rightUpperArm.parent))
     {
         return(references.rightUpperArm.parent);
     }
     return(null);
 }
        void OnEnable()
        {
            if (script == null)
            {
                return;
            }
            if (Application.isPlaying)
            {
                return;
            }

            // Autodetection
            if (script.references.IsEmpty(false))
            {
                Animator animator = script.gameObject.GetComponent <Animator>();

                if (animator == null && script.references.root != null)
                {
                    animator = script.references.root.GetComponentInChildren <Animator>();
                    if (animator == null)
                    {
                        animator = GetAnimatorInParents(script.references.root);
                    }
                }

                if (animator != null)
                {
                    script.references = BipedRagdollReferences.FromAvatar(animator);
                }
                else
                {
                    BipedReferences r = new BipedReferences();
                    BipedReferences.AutoDetectReferences(ref r, script.transform, BipedReferences.AutoDetectParams.Default);
                    if (r.isFilled)
                    {
                        script.references = BipedRagdollReferences.FromBipedReferences(r);
                    }
                }

                if (!OnRoot())
                {
                    Debug.LogWarning("BipedRagdollCreator must be added to the root of the character. Destroying the component.");
                    DestroyImmediate(script);
                    return;
                }

                string msg = string.Empty;
                if (script.references.IsValid(ref msg))
                {
                    script.options = BipedRagdollCreator.AutodetectOptions(script.references);
                    //BipedRagdollCreator.Create(script.references, script.options);

                    //if (animator != null) DestroyImmediate(animator);
                    //if (script.GetComponent<Animation>() != null) DestroyImmediate(script.GetComponent<Animation>());
                }
            }
        }
        void AutoDetectReferences()
        {
            references = new BipedReferences();
            BipedReferences.AutoDetectReferences(ref references, transform, new BipedReferences.AutoDetectParams(true, false));

            solver.rootNode = IKSolverFullBodyBiped.DetectRootNodeBone(references);

            solver.SetToReferences(references, solver.rootNode);
        }
        // Checks the biped references for errors
        private bool CheckError(BipedReferences references, IKSolverFullBodyBiped solver, Transform context, bool log)
        {
            // All the errors common to all bipeds
            if (!BipedReferences.CheckSetupError(script.references, log))
            {
                if (log)
                {
                    Warning.Log("Invalid references, can't initiate the solver.", context, true);
                }
                return(false);
            }

            // All the errors specific to FBBIK
            if (references.spine.Length == 0)
            {
                if (log)
                {
                    Warning.Log("Biped has no spine bones, can't initiate the solver.", context, true);
                }
                return(false);
            }

            if (solver.rootNode == null)
            {
                if (log)
                {
                    Warning.Log("Root Node bone is null, can't initiate the solver.", context, true);
                }
                return(false);
            }

            if (solver.rootNode != references.pelvis)
            {
                bool inSpine = false;

                for (int i = 0; i < references.spine.Length; i++)
                {
                    if (solver.rootNode == references.spine[i])
                    {
                        inSpine = true;
                        break;
                    }
                }

                if (!inSpine)
                {
                    if (log)
                    {
                        Warning.Log("The Root Node has to be one of the bones in the Spine or the Pelvis, can't initiate the solver.", context, true);
                    }
                }
            }

            return(true);
        }
Beispiel #16
0
        private static void AddFBBIK(GameObject go, VrmLoadSetting setting, BipedReferences reference)
        {
            var fbbik = go.AddComponent <FullBodyBipedIK>();

            fbbik.SetReferences(reference, null);

            fbbik.solver.leftHandEffector.target         = setting.leftHandTarget;
            fbbik.solver.leftHandEffector.positionWeight = 1.0f;

            fbbik.solver.rightHandEffector.target         = setting.rightHandTarget;
            fbbik.solver.rightHandEffector.positionWeight = 1.0f;
        }
 private static Transform GetRightClavicle(BipedReferences references)
 {
     if (references.rightUpperArm == null)
     {
         return(null);
     }
     if (!IKSolverFullBodyBiped.Contains(references.spine, references.rightUpperArm.parent))
     {
         return(references.rightUpperArm.parent);
     }
     return(null);
 }
Beispiel #18
0
 public void AssignReferences(BipedReferences references)
 {
     this.leftHand.SetChain(references.leftUpperArm, references.leftForearm, references.leftHand, references.root);
     this.rightHand.SetChain(references.rightUpperArm, references.rightForearm, references.rightHand, references.root);
     this.leftFoot.SetChain(references.leftThigh, references.leftCalf, references.leftFoot, references.root);
     this.rightFoot.SetChain(references.rightThigh, references.rightCalf, references.rightFoot, references.root);
     this.spine.SetChain(references.spine, references.root);
     this.lookAt.SetChain(references.spine, references.head, references.eyes, references.root);
     this.aim.SetChain(references.spine, references.root);
     this.leftFoot.goal  = AvatarIKGoal.LeftFoot;
     this.rightFoot.goal = AvatarIKGoal.RightFoot;
     this.leftHand.goal  = AvatarIKGoal.LeftHand;
     this.rightHand.goal = AvatarIKGoal.RightHand;
 }
Beispiel #19
0
        /*
         * Tries to guess which bone should be the root node
         * */
        public static Transform DetectRootNodeBone(BipedReferences references)
        {
            if (!references.isValid)
            {
                return(null);
            }
            if (references.spine.Length < 1)
            {
                return(null);
            }

            int spineLength = references.spine.Length;

            if (spineLength == 1)
            {
                return(references.spine[0]);
            }

            Vector3 hip       = Vector3.Lerp(references.leftThigh.position, references.rightThigh.position, 0.5f);
            Vector3 neck      = Vector3.Lerp(references.leftUpperArm.position, references.rightUpperArm.position, 0.5f);
            Vector3 toNeck    = neck - hip;
            float   toNeckMag = toNeck.magnitude;

            if (references.spine.Length < 2)
            {
                return(references.spine[0]);
            }

            int rootNodeBone = 0;

            for (int i = 1; i < spineLength; i++)
            {
                Vector3 hipToBone  = references.spine[i].position - hip;
                Vector3 projection = Vector3.Project(hipToBone, toNeck);

                float dot = Vector3.Dot(projection.normalized, toNeck.normalized);
                if (dot > 0)
                {
                    float mag = projection.magnitude / toNeckMag;
                    if (mag < 0.5f)
                    {
                        rootNodeBone = i;
                    }
                }
            }

            return(references.spine[rootNodeBone]);
        }
        public static Transform DetectRootNodeBone(BipedReferences references)
        {
            if (!references.isFilled)
            {
                return(null);
            }
            if (references.spine.Length < 1)
            {
                return(null);
            }
            int num = references.spine.Length;

            if (num == 1)
            {
                return(references.spine[0]);
            }
            Vector3 b         = Vector3.Lerp(references.leftThigh.position, references.rightThigh.position, 0.5f);
            Vector3 a         = Vector3.Lerp(references.leftUpperArm.position, references.rightUpperArm.position, 0.5f);
            Vector3 onNormal  = a - b;
            float   magnitude = onNormal.magnitude;

            if (references.spine.Length < 2)
            {
                return(references.spine[0]);
            }
            int num2 = 0;

            for (int i = 1; i < num; i++)
            {
                Vector3 vector  = references.spine[i].position - b;
                Vector3 vector2 = Vector3.Project(vector, onNormal);
                float   num3    = Vector3.Dot(vector2.normalized, onNormal.normalized);
                if (num3 > 0f)
                {
                    float num4 = vector2.magnitude / magnitude;
                    if (num4 < 0.5f)
                    {
                        num2 = i;
                    }
                }
            }
            return(references.spine[num2]);
        }
        /// <summary>
        /// Checks the biped references for errors. Returns true if error found.
        /// </summary>
        public bool ReferencesError(ref string errorMessage)
        {
            // All the errors common to all bipeds
            if (BipedReferences.SetupError(references, ref errorMessage))
            {
                return(true);
            }

            // All the errors specific to FBBIK
            if (references.spine.Length == 0)
            {
                errorMessage = "References has no spine bones assigned, can not initiate the solver.";
                return(true);
            }

            if (solver.rootNode == null)
            {
                errorMessage = "Root Node bone is null, can not initiate the solver.";
                return(true);
            }

            if (solver.rootNode != references.pelvis)
            {
                bool inSpine = false;

                for (int i = 0; i < references.spine.Length; i++)
                {
                    if (solver.rootNode == references.spine[i])
                    {
                        inSpine = true;
                        break;
                    }
                }

                if (!inSpine)
                {
                    errorMessage = "The Root Node has to be one of the bones in the Spine or the Pelvis, can not initiate the solver.";
                    return(true);
                }
            }

            return(false);
        }
        protected override void OnEnableVirtual()
        {
            references = serializedObject.FindProperty("references");

            // Autodetecting References
            if (script.references.IsEmpty(false) && script.enabled)
            {
                BipedReferences.AutoDetectReferences(ref script.references, script.transform, new BipedReferences.AutoDetectParams(true, false));

                script.solver.rootNode = IKSolverFullBodyBiped.DetectRootNodeBone(script.references);

                Initiate();

                if (Application.isPlaying)
                {
                    Warning.Log("Biped references were auto-detected on a FullBodyBipedIK component that was added in runtime. Note that this only happens in the Editor and if the GameObject is selected (for quick and convenient debugging). If you want to add FullBodyBipedIK dynamically in runtime via script, you will have to use BipedReferences.AutodetectReferences() for automatic biped detection.", script.transform);
                }

                references.isExpanded = !script.references.isValid;
            }
        }
		public void AssignReferences(BipedReferences references) {
			// Assigning limbs from references
			leftHand.SetChain(references.leftUpperArm, references.leftForearm, references.leftHand, references.root);
			rightHand.SetChain(references.rightUpperArm, references.rightForearm, references.rightHand, references.root);
			leftFoot.SetChain(references.leftThigh, references.leftCalf, references.leftFoot, references.root);
			rightFoot.SetChain(references.rightThigh, references.rightCalf, references.rightFoot, references.root);

			// Assigning spine bones from references
			spine.SetChain(references.spine, references.root);

			// Assigning lookAt bones from references
			lookAt.SetChain(references.spine, references.head, references.eyes, references.root);

			// Assigning Aim bones from references
			aim.SetChain(references.spine, references.root);

			leftFoot.goal = AvatarIKGoal.LeftFoot;
			rightFoot.goal = AvatarIKGoal.RightFoot;
			leftHand.goal = AvatarIKGoal.LeftHand;
			rightHand.goal = AvatarIKGoal.RightHand;
		}
Beispiel #24
0
        private void WarningBox()
        {
            // Warning box
            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal("Box");

            EditorGUILayout.LabelField("Invalid/incomplete setup, can't initiate solver.");

            if (GUILayout.Button("What's wrong?"))
            {
                Warning.logged = false;

                if (ReferencesValid(true))
                {
                    BipedReferences.CheckSetupWarning(script.references, true);
                }
            }

            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
        }
Beispiel #25
0
 protected override void InitiateSolver()
 {
     if (!BipedReferences.CheckSetupError(this.references, Application.isPlaying))
     {
         return;
     }
     this.solvers.AssignReferences(this.references);
     if (this.solvers.spine.bones.Length > 1)
     {
         this.solvers.spine.Initiate(base.transform);
     }
     this.solvers.lookAt.Initiate(base.transform);
     this.solvers.aim.Initiate(base.transform);
     IKSolverLimb[] limbs = this.solvers.limbs;
     for (int i = 0; i < limbs.Length; i++)
     {
         IKSolverLimb iKSolverLimb = limbs[i];
         iKSolverLimb.Initiate(base.transform);
     }
     this.solvers.pelvis.Initiate(this.references.pelvis);
 }
Beispiel #26
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUILayout.Space();

            Inspector.AddContent(fixTransforms);

            // Editing References
            if (BipedReferencesInspector.AddModifiedInspector(references))
            {
                if (!Application.isPlaying)
                {
                    Warning.logged = false;

                    if (ReferencesValid(false))
                    {
                        BipedReferences.CheckSetupWarning(script.references, true);

                        // Initiate only when inspector changed
                        script.InitiateBipedIK();
                    }
                }
            }

            if (ReferencesValid(Application.isPlaying))
            {
                // Editing Solvers
                BipedIKSolversInspector.AddInspector(solvers, solversProps);
            }
            else
            {
                // Warning box
                WarningBox();
            }

            EditorGUILayout.Space();

            serializedObject.ApplyModifiedProperties();
        }
        public void AssignReferences(BipedReferences references)
        {
            // Assigning limbs from references
            leftHand.SetChain(references.leftUpperArm, references.leftForearm, references.leftHand, references.root);
            rightHand.SetChain(references.rightUpperArm, references.rightForearm, references.rightHand, references.root);
            leftFoot.SetChain(references.leftThigh, references.leftCalf, references.leftFoot, references.root);
            rightFoot.SetChain(references.rightThigh, references.rightCalf, references.rightFoot, references.root);

            // Assigning spine bones from references
            spine.SetChain(references.spine, references.root);

            // Assigning lookAt bones from references
            lookAt.SetChain(references.spine, references.head, references.eyes, references.root);

            // Assigning Aim bones from references
            aim.SetChain(references.spine, references.root);

            leftFoot.goal  = AvatarIKGoal.LeftFoot;
            rightFoot.goal = AvatarIKGoal.RightFoot;
            leftHand.goal  = AvatarIKGoal.LeftHand;
            rightHand.goal = AvatarIKGoal.RightHand;
        }
Beispiel #28
0
        protected override void InitiateSolver()
        {
            string empty = string.Empty;

            if (BipedReferences.SetupError(this.references, ref empty))
            {
                Warning.Log(empty, this.references.root, false);
                return;
            }
            this.solvers.AssignReferences(this.references);
            if (this.solvers.spine.bones.Length > 1)
            {
                this.solvers.spine.Initiate(base.transform);
            }
            this.solvers.lookAt.Initiate(base.transform);
            this.solvers.aim.Initiate(base.transform);
            foreach (IKSolverLimb iksolverLimb in this.solvers.limbs)
            {
                iksolverLimb.Initiate(base.transform);
            }
            this.solvers.pelvis.Initiate(this.references.pelvis);
        }
Beispiel #29
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUILayout.Space();

            Inspector.AddContent(fixTransforms);
            string message = string.Empty;

            // Editing References
            if (BipedReferencesInspector.AddModifiedInspector(references))
            {
                if (!Application.isPlaying)
                {
                    Warning.logged = false;

                    if (!BipedReferences.SetupError(script.references, ref message))
                    {
                        script.InitiateBipedIK();
                    }
                }
            }

            if (BipedReferences.SetupError(script.references, ref message))
            {
                // Warning box
                AddWarningBox(message);
                Warning.Log(message, script.transform, false);
            }
            else
            {
                // Editing Solvers
                BipedIKSolversInspector.AddInspector(solvers, solversProps);
            }

            EditorGUILayout.Space();

            serializedObject.ApplyModifiedProperties();
        }
Beispiel #30
0
        private static void AddFBBIK(GameObject go, VrmLoadSetting setting, BipedReferences reference)
        {
            var fbbik = go.AddComponent <FullBodyBipedIK>();

            fbbik.SetReferences(reference, null);

            //weightを仕込んでも最初でいきなり動かないようにする。
            //このとき、bodyTarget自体は(呼吸ライクに動かしたいので)別のスクリプトが入ってるため、親を移動する
            setting.bodyTarget.parent.position       = reference.spine[0].position;
            fbbik.solver.bodyEffector.target         = setting.bodyTarget;
            fbbik.solver.bodyEffector.positionWeight = 0.5f;
            //Editorで "FBBIK > Body > Mapping > Maintain Head Rot"を選んだ時の値を↓で入れてる(デフォルト0、ある程度大きくするとLook Atの見栄えがよい)
            fbbik.solver.boneMappings[0].maintainRotationWeight = 0.7f;

            fbbik.solver.leftHandEffector.target         = setting.leftHandTarget;
            fbbik.solver.leftHandEffector.positionWeight = 1.0f;
            fbbik.solver.leftHandEffector.rotationWeight = 1.0f;

            fbbik.solver.rightHandEffector.target         = setting.rightHandTarget;
            fbbik.solver.rightHandEffector.positionWeight = 1.0f;
            fbbik.solver.rightHandEffector.rotationWeight = 1.0f;
        }
Beispiel #31
0
        protected override void InitiateSolver()
        {
            string message = "";

            if (BipedReferences.SetupError(this.references, ref message))
            {
                Warning.Log(message, this.references.root, false);
                return;
            }
            this.solvers.AssignReferences(this.references);
            if (this.solvers.spine.bones.Length > 1)
            {
                this.solvers.spine.Initiate(base.transform);
            }
            this.solvers.lookAt.Initiate(base.transform);
            this.solvers.aim.Initiate(base.transform);
            IKSolverLimb[] limbs = this.solvers.limbs;
            for (int i = 0; i < limbs.Length; i++)
            {
                limbs[i].Initiate(base.transform);
            }
            this.solvers.pelvis.Initiate(this.references.pelvis);
        }
Beispiel #32
0
        public static BipedRagdollReferences FromBipedReferences(BipedReferences biped)
        {
            BipedRagdollReferences r = new BipedRagdollReferences();

            r.root = biped.root;

            r.hips = biped.pelvis;

            if (biped.spine != null && biped.spine.Length > 0)
            {
                r.spine = biped.spine[0];
                if (biped.spine.Length > 1)
                {
                    r.chest = biped.spine[biped.spine.Length - 1];
                }
            }

            r.head = biped.head;

            r.leftUpperArm = biped.leftUpperArm;
            r.leftLowerArm = biped.leftForearm;
            r.leftHand     = biped.leftHand;

            r.rightUpperArm = biped.rightUpperArm;
            r.rightLowerArm = biped.rightForearm;
            r.rightHand     = biped.rightHand;

            r.leftUpperLeg = biped.leftThigh;
            r.leftLowerLeg = biped.leftCalf;
            r.leftFoot     = biped.leftFoot;

            r.rightUpperLeg = biped.rightThigh;
            r.rightLowerLeg = biped.rightCalf;
            r.rightFoot     = biped.rightFoot;

            return(r);
        }
Beispiel #33
0
 /// <summary>
 /// Sets the solver to new biped references.
 /// </summary>
 /// /// <param name="references">Biped references.</param>
 /// <param name="rootNode">Root node. if null, will try to detect the root node bone automatically. </param>
 public void SetReferences(BipedReferences references, Transform rootNode)
 {
     this.references = references;
     solver.SetToReferences(this.references, rootNode);
 }
		// Checks the biped references for errors
		private bool CheckError(BipedReferences references, IKSolverFullBodyBiped solver, Transform context, bool log) {
			// All the errors common to all bipeds
			if (!BipedReferences.CheckSetupError(script.references, log)) {
				if (log) Warning.Log("Invalid references, can't initiate the solver.", context, true);
				return false;
			}

			// All the errors specific to FBBIK
			if (references.spine.Length == 0) {
				if (log) Warning.Log("Biped has no spine bones, can't initiate the solver.", context, true);
				return false;
			}

			if (solver.rootNode == null) {
				if (log) Warning.Log("Root Node bone is null, can't initiate the solver.", context, true);
				return false;
			}

			if (solver.rootNode != references.pelvis) {
				bool inSpine = false;

				for (int i = 0; i < references.spine.Length; i++) {
					if (solver.rootNode == references.spine[i]) {
						inSpine = true;
						break;
					}
				}

				if (!inSpine) {
					if (log) Warning.Log("The Root Node has to be one of the bones in the Spine or the Pelvis, can't initiate the solver.", context, true);
				}
			}

			return true;
		}
		// Check for possible warnings with the biped references setup
		private void CheckWarning(BipedReferences references, IKSolverFullBodyBiped solver, Transform context, bool log) {
			// Check for all the warnings common to all bipeds
			BipedReferences.CheckSetupWarning(script.references, log);

			// Check for warnings specific to FBBIK
			Vector3 toRightShoulder = references.rightUpperArm.position - references.leftUpperArm.position;
			Vector3 shoulderToRootNode = solver.rootNode.position - references.leftUpperArm.position;
			float dot = Vector3.Dot(toRightShoulder.normalized, shoulderToRootNode.normalized);
			
			if (dot > 0.95f) {
				if (log) Warning.Log ("The root node, the left upper arm and the right upper arm bones should ideally form a triangle that is as close to equilateral as possible. " +
					"Currently the root node bone seems to be very close to the line between the left upper arm and the right upper arm bones. This might cause unwanted behaviour like the spine turning upside down when pulled by a hand effector." +
					"Please set the root node bone to be one of the lower bones in the spine.", context, true);
			}
			
			Vector3 toRightThigh = references.rightThigh.position - references.leftThigh.position;
			Vector3 thighToRootNode = solver.rootNode.position - references.leftThigh.position;
			dot = Vector3.Dot(toRightThigh.normalized, thighToRootNode.normalized);
			
			if (dot > 0.95f && log) {
				Warning.Log ("The root node, the left thigh and the right thigh bones should ideally form a triangle that is as close to equilateral as possible. " +
					"Currently the root node bone seems to be very close to the line between the left thigh and the right thigh bones. This might cause unwanted behaviour like the hip turning upside down when pulled by an effector." +
					"Please set the root node bone to be one of the higher bones in the spine.", context, true);
			}
		}
Beispiel #36
0
        public void AssignReferences(BipedReferences references)
        {
            // Assigning limbs from references
            leftFoot.bone1.transform = references.leftThigh;
            leftFoot.bone2.transform = references.leftCalf;
            leftFoot.bone3.transform = references.leftFoot;

            rightFoot.bone1.transform = references.rightThigh;
            rightFoot.bone2.transform = references.rightCalf;
            rightFoot.bone3.transform = references.rightFoot;

            leftHand.bone1.transform = references.leftUpperArm;
            leftHand.bone2.transform = references.leftForearm;
            leftHand.bone3.transform = references.leftHand;

            rightHand.bone1.transform = references.rightUpperArm;
            rightHand.bone2.transform = references.rightForearm;
            rightHand.bone3.transform = references.rightHand;

            // Assigning spine bones from references
            Array.Resize(ref spine.bones, references.spine.Length);
            for (int i = 0; i < references.spine.Length; i++) {
                if (spine.bones[i] == null) spine.bones[i] = new IKSolver.Bone();
                spine.bones[i].transform = references.spine[i];
            }

            // Assigning lookAt bones from references
            Array.Resize(ref lookAt.spine, references.spine.Length);
            for (int i = 0; i < references.spine.Length; i++) {
                if (lookAt.spine[i] == null) lookAt.spine[i] = new IKSolverLookAt.LookAtBone();
                lookAt.spine[i].transform = references.spine[i];
            }

            // Assigning eye bones from references
            Array.Resize(ref lookAt.eyes, references.eyes.Length);
            for (int i = 0; i < references.eyes.Length; i++) {
                if (lookAt.eyes[i] == null) lookAt.eyes[i] = new IKSolverLookAt.LookAtBone();
                lookAt.eyes[i].transform = references.eyes[i];
            }

            // Assigning head bone from references
            lookAt.head.transform = references.head;

            // Assigning Aim bones from references
            Array.Resize(ref aim.bones, references.spine.Length);
            for (int i = 0; i < references.spine.Length; i++) {
                if (aim.bones[i] == null) aim.bones[i] = new IKSolver.Bone();
                aim.bones[i].transform = references.spine[i];
            }

            leftFoot.goal = AvatarIKGoal.LeftFoot;
            rightFoot.goal = AvatarIKGoal.RightFoot;
            leftHand.goal = AvatarIKGoal.LeftHand;
            rightHand.goal = AvatarIKGoal.RightHand;
        }
		private static Transform GetRightClavicle(BipedReferences references) {
			if (references.rightUpperArm == null) return null;
			if (!Contains(references.spine, references.rightUpperArm.parent)) return references.rightUpperArm.parent;
			return null;
		}
		/*
		 * Tries to guess which bone should be the root node
		 * */
		public static Transform DetectRootNodeBone(BipedReferences references) {
			if (!references.isValid) return null;
			if (references.spine.Length < 1) return null;

			int spineLength = references.spine.Length;
			if (spineLength == 1) return references.spine[0];
			
			Vector3 hip = Vector3.Lerp(references.leftThigh.position, references.rightThigh.position, 0.5f);
			Vector3 neck = Vector3.Lerp(references.leftUpperArm.position, references.rightUpperArm.position, 0.5f);
			Vector3 toNeck = neck - hip;
			float toNeckMag = toNeck.magnitude;
			
			if (references.spine.Length < 2) return references.spine[0];

			int rootNodeBone = 0;

			for (int i = 1; i < spineLength; i++) {
				Vector3 hipToBone = references.spine[i].position - hip;
				Vector3 projection = Vector3.Project(hipToBone, toNeck);
				
				float dot = Vector3.Dot(projection.normalized, toNeck.normalized);
				if (dot > 0) {
					float mag = projection.magnitude / toNeckMag;
					if (mag < 0.5f) rootNodeBone = i;
				}
			}

			return references.spine[rootNodeBone];
		}
		/// <summary>
		/// Sets up the solver to BipedReferences and reinitiates (if in runtime).
		/// </summary>
		/// <param name="references">Biped references.</param>
		/// <param name="rootNode">Root node (optional). if null, will try to detect the root node bone automatically. </param>
		public void SetToReferences(BipedReferences references, Transform rootNode = null) {
			root = references.root;

			if (rootNode == null) rootNode = DetectRootNodeBone(references);
			this.rootNode = rootNode;
			
			// Root Node
			if (chain == null || chain.Length != 5) chain = new FBIKChain[5];
			for (int i = 0; i < chain.Length; i++) {
				if (chain[i] == null) {
					chain[i] = new FBIKChain();
				}
			}

			chain[0].pin = 0f;
			chain[0].SetNodes(rootNode);
			chain[0].children = new int[4] { 1, 2, 3, 4 };
			
			// Left Arm
			chain[1].SetNodes(references.leftUpperArm, references.leftForearm, references.leftHand);
			
			// Right Arm
			chain[2].SetNodes(references.rightUpperArm, references.rightForearm, references.rightHand);
			
			// Left Leg
			chain[3].SetNodes(references.leftThigh, references.leftCalf, references.leftFoot);
			
			// Right Leg
			chain[4].SetNodes(references.rightThigh, references.rightCalf, references.rightFoot);
			
			// Effectors
			if (effectors.Length != 9) effectors = new IKEffector[9] {
				new IKEffector(), new IKEffector(), new IKEffector(), new IKEffector(), new IKEffector(), new IKEffector(), new IKEffector(), new IKEffector(), new IKEffector()
			};
			
			effectors[0].bone = rootNode;
			effectors[0].childBones = new Transform[2] { references.leftThigh, references.rightThigh };
			
			effectors[1].bone = references.leftUpperArm;
			effectors[2].bone = references.rightUpperArm;
			effectors[3].bone = references.leftThigh;
			effectors[4].bone = references.rightThigh;
			effectors[5].bone = references.leftHand;
			effectors[6].bone = references.rightHand;
			effectors[7].bone = references.leftFoot;
			effectors[8].bone = references.rightFoot;
			
			effectors[5].planeBone1 = references.leftUpperArm;
			effectors[5].planeBone2 = references.rightUpperArm;
			effectors[5].planeBone3 = rootNode;

			effectors[6].planeBone1 = references.rightUpperArm;
			effectors[6].planeBone2 = references.leftUpperArm;
			effectors[6].planeBone3 = rootNode;

			effectors[7].planeBone1 = references.leftThigh;
			effectors[7].planeBone2 = references.rightThigh;
			effectors[7].planeBone3 = rootNode;

			effectors[8].planeBone1 = references.rightThigh;
			effectors[8].planeBone2 = references.leftThigh;
			effectors[8].planeBone3 = rootNode;
			
			// Child Constraints
			chain[0].childConstraints = new FBIKChain.ChildConstraint[4] {
				new FBIKChain.ChildConstraint(references.leftUpperArm, references.rightThigh, 0f, 1f),
				new FBIKChain.ChildConstraint(references.rightUpperArm, references.leftThigh, 0f, 1f),
				new FBIKChain.ChildConstraint(references.leftUpperArm, references.rightUpperArm),
				new FBIKChain.ChildConstraint(references.leftThigh, references.rightThigh)
				
			};
			
			// IKMappingSpine
			Transform[] spineBones = new Transform[references.spine.Length + 1];
			spineBones[0] = references.pelvis;
			for (int i = 0; i < references.spine.Length; i++) {
				spineBones[i + 1] = references.spine[i];
			}
			
			if (spineMapping == null) {
				spineMapping = new IKMappingSpine();
				spineMapping.iterations = 3;
			}
			spineMapping.SetBones(spineBones, references.leftUpperArm, references.rightUpperArm, references.leftThigh, references.rightThigh);
			
			// IKMappingBone
			int boneMappingsCount = references.head != null? 1: 0;
			
			if (boneMappings.Length != boneMappingsCount) {
				boneMappings = new IKMappingBone[boneMappingsCount];
				for (int i = 0; i < boneMappings.Length; i++) {
					boneMappings[i] = new IKMappingBone();
				}
				if (boneMappingsCount == 1) boneMappings[0].maintainRotationWeight = 0f;
			}
			
			if (boneMappings.Length > 0) boneMappings[0].bone = references.head;
			
			// IKMappingLimb
			if (limbMappings.Length != 4) {
				limbMappings = new IKMappingLimb[4] {
					new IKMappingLimb(), new IKMappingLimb(), new IKMappingLimb(), new IKMappingLimb()
				};
				
				limbMappings[2].maintainRotationWeight = 1f;
				limbMappings[3].maintainRotationWeight = 1f;
			}
			
			limbMappings[0].SetBones(references.leftUpperArm, references.leftForearm, references.leftHand, GetLeftClavicle(references));
			limbMappings[1].SetBones(references.rightUpperArm, references.rightForearm, references.rightHand, GetRightClavicle(references));
			limbMappings[2].SetBones(references.leftThigh, references.leftCalf, references.leftFoot);
			limbMappings[3].SetBones(references.rightThigh, references.rightCalf, references.rightFoot);

			if (Application.isPlaying) Initiate(references.root);
		}
        private bool BipedIsValid(BipedReferences references, IKSolverFullBodyBiped solver, Transform context, bool log)
        {
            BipedReferences.CheckSetup(script.references);

            if (!references.isValid) {
                //if (log) Warning.Log("BipedReferences contains one or more missing Transforms.", context, true);
                return false;
            }
            if (references.spine.Length == 0) {
                //if (log) Warning.Log("Biped has no spine bones.", context, true);
                return false;
            }

            if (solver.rootNode == null) {
                //if (log) Warning.Log("Root Node bone is null.", context, true);
                return false;
            }

            Vector3 toRightShoulder = references.rightUpperArm.position - references.leftUpperArm.position;
            Vector3 shoulderToRootNode = solver.rootNode.position - references.leftUpperArm.position;
            float dot = Vector3.Dot(toRightShoulder.normalized, shoulderToRootNode.normalized);

            if (dot > 0.95f) {
                if (log) Warning.Log ("The root node, the left upper arm and the right upper arm bones should ideally form a triangle that is as close to equilateral as possible. " +
                    "Currently the root node bone seems to be very close to the line between the left upper arm and the right upper arm bones. This might cause unwanted behaviour like the spine turning upside down when pulled by a hand effector." +
                    "Please set the root node bone to be one of the lower bones in the spine.", context, true);
            }

            Vector3 toRightThigh = references.rightThigh.position - references.leftThigh.position;
            Vector3 thighToRootNode = solver.rootNode.position - references.leftThigh.position;
            dot = Vector3.Dot(toRightThigh.normalized, thighToRootNode.normalized);

            if (dot > 0.95f && log) {
                Warning.Log ("The root node, the left thigh and the right thigh bones should ideally form a triangle that is as close to equilateral as possible. " +
                    "Currently the root node bone seems to be very close to the line between the left thigh and the right thigh bones. This might cause unwanted behaviour like the hip turning upside down when pulled by an effector." +
                    "Please set the root node bone to be one of the higher bones in the spine.", context, true);
            }

            /*
            Vector3 shoulderCross = Vector3.Cross(toRightShoulder, shoulderToRootNode);
            Vector3 charCross = Vector3.Cross(references.rightHand.position - references.leftHand.position, references.rightFoot.position - references.leftHand.position);

            float shoulderInvertDot = Vector3.Dot(shoulderCross.normalized, charCross.normalized);

            if (shoulderInvertDot < 0 && log) {
                Warning.Log("The triangle formed by the root node, left upper arm and right upper arm bones seems to be flipped. The root node bone should be below the upper arm bones.", context, true);
            }

            Vector3 thighCross = Vector3.Cross(toRightThigh, thighToRootNode);

            float thighInvertDot = Vector3.Dot(thighCross.normalized, charCross.normalized);

            if (thighInvertDot > 0 && log) {
                Warning.Log("The triangle formed by the root node, left thigh and right thigh bones seems to be flipped. The root node bone should be above the thigh bones.", context, true);
            }
            */

            return true;
        }
 private static Transform GetLeftClavicle(BipedReferences references)
 {
     if (!Contains(references.spine, references.leftUpperArm.parent)) return references.leftUpperArm.parent;
     return null;
 }