private bool firstFBBIKSolve; // Has the FBBIK already solved for this frame? In case it is solved more than once, for example when using the ShoulderRotator public void Update() { if (ik == null) { return; } if (ik.enabled) { ik.enabled = false; } if (lookAtTarget == null) { return; } // Interpolate the weight float add = Time.time < stopLookTime? weightSpeed: -weightSpeed; weight = Mathf.Clamp(weight + add * Time.deltaTime, 0f, 1f); // Set LookAtIK weight ik.solver.IKPositionWeight = Interp.Float(weight, InterpolationMode.InOutQuintic); // Set LookAtIK position ik.solver.IKPosition = Vector3.Lerp(ik.solver.IKPosition, lookAtTarget.position, lerpSpeed * Time.deltaTime); // Release the LookAtIK for other tasks once we're weighed out if (weight <= 0f) { lookAtTarget = null; } firstFBBIKSolve = true; }
public void Update() { if (this.ik == null) { return; } if (this.ik.enabled) { this.ik.enabled = false; } if (this.lookAtTarget == null) { return; } if (this.isPaused) { this.stopLookTime += Time.deltaTime; } float num = (Time.time < this.stopLookTime) ? this.weightSpeed : (-this.weightSpeed); this.weight = Mathf.Clamp(this.weight + num * Time.deltaTime, 0f, 1f); this.ik.solver.IKPositionWeight = Interp.Float(this.weight, InterpolationMode.InOutQuintic); this.ik.solver.IKPosition = Vector3.Lerp(this.ik.solver.IKPosition, this.lookAtTarget.position, this.lerpSpeed * Time.deltaTime); if (this.weight <= 0f) { this.lookAtTarget = null; } this.firstFBBIKSolve = true; }
public override void PreSolve(float scale) { if (headTarget != null) { IKPositionHead = headTarget.position; IKRotationHead = headTarget.rotation; } if (chestGoal != null) { goalPositionChest = chestGoal.position; } if (pelvisTarget != null) { IKPositionPelvis = pelvisTarget.position; IKRotationPelvis = pelvisTarget.rotation; } // Use animated head height range if (useAnimatedHeadHeightWeight > 0f && useAnimatedHeadHeightRange > 0f) { Vector3 rootUp = rootRotation * Vector3.up; if (animatedHeadHeightBlend > 0f) { float headTargetVOffset = V3Tools.ExtractVertical(IKPositionHead - head.solverPosition, rootUp, 1f).magnitude; float abs = Mathf.Abs(headTargetVOffset); abs = Mathf.Max(abs - useAnimatedHeadHeightRange * scale, 0f); float f = Mathf.Lerp(0f, 1f, abs / (animatedHeadHeightBlend * scale)); f = Interp.Float(1f - f, InterpolationMode.InOutSine); Vector3 toHeadPos = head.solverPosition - IKPositionHead; IKPositionHead += V3Tools.ExtractVertical(toHeadPos, rootUp, f * useAnimatedHeadHeightWeight); } else { IKPositionHead += V3Tools.ExtractVertical(head.solverPosition - IKPositionHead, rootUp, useAnimatedHeadHeightWeight); } } headPosition = V3Tools.Lerp(head.solverPosition, IKPositionHead, positionWeight); headRotation = QuaTools.Lerp(head.solverRotation, IKRotationHead, rotationWeight); pelvisRotation = QuaTools.Lerp(pelvis.solverRotation, IKRotationPelvis, rotationWeight); }
// Called when the PuppetMaster reads protected override void OnReadBehaviour(float deltaTime) { if (!enabled) { return; } if (!puppetMaster.isFrozen) { if (state == State.Unpinned && puppetMaster.isActive && !puppetMaster.isBlending && !puppetMaster.muscles[0].state.isDisconnected) { //if (state == State.Unpinned && puppetMaster.isActive && !puppetMaster.muscles[0].state.isDisconnected) { MoveTarget(puppetMaster.muscles[0].rigidbody.position); GroundTarget(groundLayers); getUpPosition = puppetMaster.targetRoot.position; } } // Prevents root motion from snapping the target to another position if (state == State.GetUp && getUpTimer < minGetUpDuration * 0.1f) { Vector3 y = Vector3.Project(puppetMaster.targetRoot.position - getUpPosition, puppetMaster.targetRoot.up); getUpPosition += y; MoveTarget(getUpPosition); } if (getupAnimationBlendWeight > 0f) { Vector3 y = Vector3.Project(puppetMaster.targetRoot.position - getUpPosition, puppetMaster.targetRoot.up); getUpPosition += y; MoveTarget(getUpPosition); getupAnimationBlendWeight = Mathf.MoveTowards(getupAnimationBlendWeight, 0f, deltaTime); if (getupAnimationBlendWeight < 0.01f) { getupAnimationBlendWeight = 0f; } // Lerps the target pose to last sampled mapped pose. Starting off from the ragdoll pose puppetMaster.FixTargetToSampledState(Interp.Float(getupAnimationBlendWeight, InterpolationMode.InOutCubic)); } getUpTargetFixed = true; }
private Vector3 GetModifiedBendNormal() { float num = this.bendModifierWeight; if (num <= 0f) { return(this.bendNormal); } switch (this.bendModifier) { case IKSolverLimb.BendModifier.Animation: if (!this.maintainBendFor1Frame) { this.MaintainBend(); } this.maintainBendFor1Frame = false; return(Vector3.Lerp(this.bendNormal, this.animationNormal, num)); case IKSolverLimb.BendModifier.Target: { Quaternion b = this.IKRotation * Quaternion.Inverse(this.bone3DefaultRotation); return(Quaternion.Slerp(Quaternion.identity, b, num) * this.bendNormal); } case IKSolverLimb.BendModifier.Parent: { if (this.bone1.transform.parent == null) { return(this.bendNormal); } Quaternion lhs = this.bone1.transform.parent.rotation * Quaternion.Inverse(this.parentDefaultRotation); return(Quaternion.Slerp(Quaternion.identity, lhs * Quaternion.Inverse(this.defaultRootRotation), num) * this.bendNormal); } case IKSolverLimb.BendModifier.Arm: { if (this.bone1.transform.parent == null) { return(this.bendNormal); } if (this.goal == AvatarIKGoal.LeftFoot || this.goal == AvatarIKGoal.RightFoot) { if (!Warning.logged) { base.LogWarning("Trying to use the 'Arm' bend modifier on a leg."); } return(this.bendNormal); } Vector3 vector = (this.IKPosition - this.bone1.transform.position).normalized; vector = Quaternion.Inverse(this.bone1.transform.parent.rotation * Quaternion.Inverse(this.parentDefaultRotation)) * vector; if (this.goal == AvatarIKGoal.LeftHand) { vector.x = -vector.x; } for (int i = 1; i < this.axisDirections.Length; i++) { this.axisDirections[i].dot = Mathf.Clamp(Vector3.Dot(this.axisDirections[i].direction, vector), 0f, 1f); this.axisDirections[i].dot = Interp.Float(this.axisDirections[i].dot, InterpolationMode.InOutQuintic); } Vector3 vector2 = this.axisDirections[0].axis; for (int j = 1; j < this.axisDirections.Length; j++) { vector2 = Vector3.Slerp(vector2, this.axisDirections[j].axis, this.axisDirections[j].dot); } if (this.goal == AvatarIKGoal.LeftHand) { vector2.x = -vector2.x; vector2 = -vector2; } Vector3 vector3 = this.bone1.transform.parent.rotation * Quaternion.Inverse(this.parentDefaultRotation) * vector2; if (num >= 1f) { return(vector3); } return(Vector3.Lerp(this.bendNormal, vector3, num)); } case IKSolverLimb.BendModifier.Goal: { if (this.bendGoal == null) { if (!Warning.logged) { base.LogWarning("Trying to use the 'Goal' Bend Modifier, but the Bend Goal is unassigned."); } return(this.bendNormal); } Vector3 vector4 = Vector3.Cross(this.bendGoal.position - this.bone1.transform.position, this.IKPosition - this.bone1.transform.position); if (vector4 == Vector3.zero) { return(this.bendNormal); } if (num >= 1f) { return(vector4); } return(Vector3.Lerp(this.bendNormal, vector4, num)); } default: return(this.bendNormal); } }
/* * Modifying bendNormal * */ private Vector3 GetModifiedBendNormal() { float weight = bendModifierWeight; if (weight <= 0) { return(bendNormal); } switch (bendModifier) { // Animation Bend Mode attempts to maintain the bend axis as it is in the animation case BendModifier.Animation: if (!maintainBendFor1Frame) { MaintainBend(); } maintainBendFor1Frame = false; return(Vector3.Lerp(bendNormal, animationNormal, weight)); // Bending relative to the parent of the first bone case BendModifier.Parent: if (bone1.transform.parent == null) { return(bendNormal); } Quaternion parentRotation = bone1.transform.parent.rotation * Quaternion.Inverse(parentDefaultRotation); return(Quaternion.Slerp(Quaternion.identity, parentRotation * Quaternion.Inverse(defaultRootRotation), weight) * bendNormal); // Bending relative to IKRotation case BendModifier.Target: Quaternion targetRotation = IKRotation * Quaternion.Inverse(bone3DefaultRotation); return(Quaternion.Slerp(Quaternion.identity, targetRotation, weight) * bendNormal); // Anatomic Arm case BendModifier.Arm: if (bone1.transform.parent == null) { return(bendNormal); } // Disabling this for legs if (goal == AvatarIKGoal.LeftFoot || goal == AvatarIKGoal.RightFoot) { if (!Warning.logged) { LogWarning("Trying to use the 'Arm' bend modifier on a leg."); } return(bendNormal); } Vector3 direction = (IKPosition - bone1.transform.position).normalized; // Converting direction to default world space direction = Quaternion.Inverse(bone1.transform.parent.rotation * Quaternion.Inverse(parentDefaultRotation)) * direction; // Inverting direction for left hand if (goal == AvatarIKGoal.LeftHand) { direction.x = -direction.x; } // Calculating dot products for all AxisDirections for (int i = 1; i < axisDirections.Length; i++) { axisDirections[i].dot = Mathf.Clamp(Vector3.Dot(axisDirections[i].direction, direction), 0f, 1f); axisDirections[i].dot = Interp.Float(axisDirections[i].dot, InterpolationMode.InOutQuintic); } // Summing up the arm bend axis Vector3 sum = axisDirections[0].axis; //for (int i = 1; i < axisDirections.Length; i++) sum = Vector3.Lerp(sum, axisDirections[i].axis, axisDirections[i].dot); for (int i = 1; i < axisDirections.Length; i++) { sum = Vector3.Slerp(sum, axisDirections[i].axis, axisDirections[i].dot); } // Inverting sum for left hand if (goal == AvatarIKGoal.LeftHand) { sum.x = -sum.x; sum = -sum; } // Converting sum back to parent space Vector3 armBendNormal = bone1.transform.parent.rotation * Quaternion.Inverse(parentDefaultRotation) * sum; if (weight >= 1) { return(armBendNormal); } return(Vector3.Lerp(bendNormal, armBendNormal, weight)); // Bending towards the bend goal Transform case BendModifier.Goal: if (bendGoal == null) { if (!Warning.logged) { LogWarning("Trying to use the 'Goal' Bend Modifier, but the Bend Goal is unassigned."); } return(bendNormal); } Vector3 normal = Vector3.Cross(bendGoal.position - bone1.transform.position, IKPosition - bone1.transform.position); if (normal == Vector3.zero) { return(bendNormal); } if (weight >= 1f) { return(normal); } return(Vector3.Lerp(bendNormal, normal, weight)); default: return(bendNormal); } }