private void ApplyLimbData(AnimationHumanStream stream, IKLimbData.JobData data, AvatarIKGoal goal, AvatarIKHint hint) { if (data.positionWeight > 0) { if (data.positionWeight >= 1) { stream.SetGoalPosition(goal, data.position); stream.SetGoalWeightPosition(goal, 1f); } else { var position = Vector3.Lerp(stream.GetGoalPosition(goal), data.position, data.positionWeight); var positionWeight = Mathf.Lerp(stream.GetGoalWeightPosition(goal), 1f, data.positionWeight); stream.SetGoalPosition(goal, position); stream.SetGoalWeightPosition(goal, positionWeight); } } else { // For some reason, IK will be broken if same values are not reapplied before SolveIK is called stream.SetGoalPosition(goal, stream.GetGoalPosition(goal)); stream.SetGoalWeightPosition(goal, stream.GetGoalWeightPosition(goal)); } if (data.rotationWeight > 0) { if (data.rotationWeight >= 1) { stream.SetGoalRotation(goal, data.rotation); stream.SetGoalWeightRotation(goal, 1f); } else { var rotation = Quaternion.Slerp(stream.GetGoalRotation(goal), data.rotation, data.rotationWeight); var rotationWeight = Mathf.Lerp(stream.GetGoalWeightRotation(goal), 1f, data.rotationWeight); stream.SetGoalRotation(goal, rotation); stream.SetGoalWeightRotation(goal, rotationWeight); } } else { // Same as above stream.SetGoalRotation(goal, stream.GetGoalRotation(goal)); stream.SetGoalWeightRotation(goal, stream.GetGoalWeightRotation(goal)); } if (data.hintWeight > 0) { if (data.hintWeight >= 1) { stream.SetHintPosition(hint, data.hintPosition); stream.SetHintWeightPosition(hint, 1f); } else { var hintPosition = Vector3.Lerp(stream.GetHintPosition(hint), data.hintPosition, data.hintWeight); var hintWeight = Mathf.Lerp(stream.GetHintWeightPosition(hint), 1f, data.hintWeight); stream.SetHintPosition(hint, hintPosition); stream.SetHintWeightPosition(hint, hintWeight); } } else { // Same as above stream.SetHintPosition(hint, stream.GetHintPosition(hint)); stream.SetHintWeightPosition(hint, stream.GetHintWeightPosition(hint)); } }
private void SyncIKFromPose() { var selectedTransform = Selection.transforms; var stream = new AnimationStream(); if (m_Animator.OpenAnimationStream(ref stream)) { AnimationHumanStream humanStream = stream.AsHuman(); // don't sync if transform is currently selected if (!Array.Exists(selectedTransform, tr => tr == m_LeftFootEffector.transform)) { m_LeftFootEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.LeftFoot); m_LeftFootEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.LeftFoot); } if (!Array.Exists(selectedTransform, tr => tr == m_RightFootEffector.transform)) { m_RightFootEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.RightFoot); m_RightFootEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.RightFoot); } if (!Array.Exists(selectedTransform, tr => tr == m_LeftHandEffector.transform)) { m_LeftHandEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.LeftHand); m_LeftHandEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.LeftHand); } if (!Array.Exists(selectedTransform, tr => tr == m_RightHandEffector.transform)) { m_RightHandEffector.transform.position = humanStream.GetGoalPositionFromPose(AvatarIKGoal.RightHand); m_RightHandEffector.transform.rotation = humanStream.GetGoalRotationFromPose(AvatarIKGoal.RightHand); } if (!Array.Exists(selectedTransform, tr => tr == m_LeftKneeHintEffector.transform)) { m_LeftKneeHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.LeftKnee); } if (!Array.Exists(selectedTransform, tr => tr == m_RightKneeHintEffector.transform)) { m_RightKneeHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.RightKnee); } if (!Array.Exists(selectedTransform, tr => tr == m_LeftElbowHintEffector.transform)) { m_LeftElbowHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.LeftElbow); } if (!Array.Exists(selectedTransform, tr => tr == m_RightElbowHintEffector.transform)) { m_RightElbowHintEffector.transform.position = humanStream.GetHintPosition(AvatarIKHint.RightElbow); } if (!Array.Exists(selectedTransform, tr => tr == m_BodyRotationEffector.transform)) { m_BodyRotationEffector.transform.position = humanStream.bodyPosition; m_BodyRotationEffector.transform.rotation = humanStream.bodyRotation; } m_Animator.CloseAnimationStream(ref stream); } }
public static void MirrorPose(this AnimationHumanStream humanStream) { // mirror body for (int i = 0; i < (int)BodyDof.LastBodyDof; i++) { humanStream.MultMuscle(new MuscleHandle((BodyDof)i), BodyDoFMirror[i]); } // mirror head for (int i = 0; i < (int)HeadDof.LastHeadDof; i++) { humanStream.MultMuscle(new MuscleHandle((HeadDof)i), HeadDoFMirror[i]); } // swap arms for (int i = 0; i < (int)ArmDof.LastArmDof; i++) { humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftArm, (ArmDof)i), new MuscleHandle(HumanPartDof.RightArm, (ArmDof)i)); } // swap legs for (int i = 0; i < (int)LegDof.LastLegDof; i++) { humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftLeg, (LegDof)i), new MuscleHandle(HumanPartDof.RightLeg, (LegDof)i)); } // swap fingers for (int i = 0; i < (int)FingerDof.LastFingerDof; i++) { humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftThumb, (FingerDof)i), new MuscleHandle(HumanPartDof.RightThumb, (FingerDof)i)); humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftIndex, (FingerDof)i), new MuscleHandle(HumanPartDof.RightIndex, (FingerDof)i)); humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftMiddle, (FingerDof)i), new MuscleHandle(HumanPartDof.RightMiddle, (FingerDof)i)); humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftRing, (FingerDof)i), new MuscleHandle(HumanPartDof.RightRing, (FingerDof)i)); humanStream.SwapMuscles( new MuscleHandle(HumanPartDof.LeftLittle, (FingerDof)i), new MuscleHandle(HumanPartDof.RightLittle, (FingerDof)i)); } humanStream.bodyLocalPosition = Mirrored(humanStream.bodyLocalPosition); // mirror rotation (invert Y axis angle) humanStream.bodyLocalRotation = Mirrored(humanStream.bodyLocalRotation); // swap ik Vector3[] goalPositions = new Vector3[4]; Quaternion[] goalRotations = new Quaternion[4]; float[] goalWeightPositons = new float[4]; float[] goalWeightRotations = new float[4]; Vector3[] hintPositions = new Vector3[4]; float[] hintWeightPositions = new float[4]; for (int i = 0; i < 4; i++) { goalPositions[i] = humanStream.GetGoalLocalPosition(AvatarIKGoal.LeftFoot + i); goalRotations[i] = humanStream.GetGoalLocalRotation(AvatarIKGoal.LeftFoot + i); goalWeightPositons[i] = humanStream.GetGoalWeightPosition(AvatarIKGoal.LeftFoot + i); goalWeightRotations[i] = humanStream.GetGoalWeightRotation(AvatarIKGoal.LeftFoot + i); hintPositions[i] = humanStream.GetHintPosition(AvatarIKHint.LeftKnee + i); hintWeightPositions[i] = humanStream.GetHintWeightPosition(AvatarIKHint.LeftKnee + i); } for (int i = 0; i < 4; i++) { int j = (i + 1) % 2 + (i / 2) * 2; // make [1, 0, 3, 2] humanStream.SetGoalLocalPosition(AvatarIKGoal.LeftFoot + i, Mirrored(goalPositions[j])); humanStream.SetGoalLocalRotation(AvatarIKGoal.LeftFoot + i, Mirrored(goalRotations[j])); humanStream.SetGoalWeightPosition(AvatarIKGoal.LeftFoot + i, goalWeightPositons[j]); humanStream.SetGoalWeightRotation(AvatarIKGoal.LeftFoot + i, goalWeightRotations[j]); humanStream.SetHintPosition(AvatarIKHint.LeftKnee + i, hintPositions[j]); humanStream.SetHintWeightPosition(AvatarIKHint.LeftKnee + i, hintWeightPositions[j]); } }