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); }
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(); }