Example #1
0
            private void FABRIKPass(Vector3 animatedPelvisPos, Vector3 rootUp)
            {
                Vector3 startPos    = Vector3.Lerp(pelvis.solverPosition, animatedPelvisPos, maintainPelvisPosition) + pelvisPositionOffset - chestPositionOffset;
                Vector3 endPos      = headPosition - chestPositionOffset;
                Vector3 startOffset = rootUp * (bones[bones.Length - 1].solverPosition - bones[0].solverPosition).magnitude;

                VirtualBone.SolveFABRIK(bones, startPos, endPos, 1f, 1f, 1, mag, startOffset);
            }
Example #2
0
            private void FABRIKPass(Vector3 animatedPelvisPos, Vector3 rootUp, float weight)
            {
                Vector3 startPos = Vector3.Lerp(pelvis.solverPosition, animatedPelvisPos, maintainPelvisPosition) + pelvisPositionOffset;// - chestPositionOffset;
                Vector3 endPos   = headPosition - chestPositionOffset;
                //Vector3 startOffset = rootUp * (bones[bones.Length - 1].solverPosition - bones[0].solverPosition).magnitude;
                Vector3 startOffset = Vector3.zero;// (bones[bones.Length - 1].solverPosition - bones[0].solverPosition) * weight;

                float dist = Vector3.Distance(bones[0].solverPosition, bones[bones.Length - 1].solverPosition);

                VirtualBone.SolveFABRIK(bones, startPos, endPos, weight, 1f, 1, dist, startOffset);
            }
            public void Solve(VirtualBone rootBone, Leg[] legs, Arm[] arms)
            {
                CalculateChestTargetRotation(rootBone, arms);

                // Root rotation
                if (maxRootAngle < 180f)
                {
                    Vector3 faceDirLocal = Quaternion.Inverse(rootBone.solverRotation) * faceDirection;
                    float   angle        = Mathf.Atan2(faceDirLocal.x, faceDirLocal.z) * Mathf.Rad2Deg;

                    float rotation = 0f;
                    float maxAngle = 25f;

                    if (angle > maxAngle)
                    {
                        rotation = angle - maxAngle;
                    }
                    if (angle < -maxAngle)
                    {
                        rotation = angle + maxAngle;
                    }

                    rootBone.solverRotation = Quaternion.AngleAxis(rotation, rootBone.readRotation * Vector3.up) * rootBone.solverRotation;
                }

                Vector3 animatedPelvisPos = pelvis.solverPosition;

                // Translate pelvis to make the head's position & rotation match with the head target
                TranslatePelvis(legs, headDeltaPosition, pelvisDeltaRotation);

                // Solve a FABRIK pass to squash/stretch the spine
                VirtualBone.SolveFABRIK(bones, Vector3.Lerp(pelvis.solverPosition, animatedPelvisPos, maintainPelvisPosition) + pelvisPositionOffset - chestPositionOffset, headPosition - chestPositionOffset, 1f, 1f, 1, mag);

                // Bend the spine to look towards chest target rotation
                Bend(bones, pelvisIndex, chestIndex, chestTargetRotation, chestRotationOffset, chestClampWeight, false, neckStiffness);

                if (chestGoalWeight > 0f)
                {
                    Quaternion c = Quaternion.FromToRotation(bones[chestIndex].solverRotation * chestForward, goalPositionChest - bones[chestIndex].solverPosition) * bones[chestIndex].solverRotation;
                    Bend(bones, pelvisIndex, chestIndex, c, chestRotationOffset, chestClampWeight, false, chestGoalWeight);
                }

                InverseTranslateToHead(legs, false, false, Vector3.zero, 1f);

                VirtualBone.SolveFABRIK(bones, Vector3.Lerp(pelvis.solverPosition, animatedPelvisPos, maintainPelvisPosition) + pelvisPositionOffset - chestPositionOffset, headPosition - chestPositionOffset, 1f, 1f, 1, mag);

                Bend(bones, neckIndex, headIndex, headRotation, headClampWeight, true, 1f);

                SolvePelvis();
            }