using UnityEngine; using UnityEngine.Animations; using UnityEngine.Animations.Rigging; namespace UnityEditor.Animations.Rigging { /// /// The TwoBoneIK inverse constraint job. /// [Unity.Burst.BurstCompile] public struct TwoBoneIKInverseConstraintJob : IWeightedAnimationJob { const float k_SqrEpsilon = 1e-8f; /// The transform handle for the root transform. public ReadOnlyTransformHandle root; /// The transform handle for the mid transform. public ReadOnlyTransformHandle mid; /// The transform handle for the tip transform. public ReadOnlyTransformHandle tip; /// The transform handle for the hint transform. public ReadWriteTransformHandle hint; /// The transform handle for the target transform. public ReadWriteTransformHandle target; /// The offset applied to the target transform if maintainTargetPositionOffset or maintainTargetRotationOffset is enabled. public AffineTransform targetOffset; /// The weight for which target position has an effect on IK calculations. This is a value in between 0 and 1. public FloatProperty targetPositionWeight; /// The weight for which target rotation has an effect on IK calculations. This is a value in between 0 and 1. public FloatProperty targetRotationWeight; /// The weight for which hint transform has an effect on IK calculations. This is a value in between 0 and 1. public FloatProperty hintWeight; /// public FloatProperty jobWeight { get; set; } /// /// Defines what to do when processing the root motion. /// /// The animation stream to work on. public void ProcessRootMotion(AnimationStream stream) { } /// /// Defines what to do when processing the animation. /// /// The animation stream to work on. public void ProcessAnimation(AnimationStream stream) { jobWeight.Set(stream, 1f); AnimationRuntimeUtils.InverseSolveTwoBoneIK(stream, root, mid, tip, target, hint, targetPositionWeight.Get(stream), targetRotationWeight.Get(stream), hintWeight.Get(stream), targetOffset); } } /// /// The TwoBoneIK inverse constraint job binder. /// /// The constraint data type public class TwoBoneIKInverseConstraintJobBinder : AnimationJobBinder where T : struct, IAnimationJobData, ITwoBoneIKConstraintData { /// public override TwoBoneIKInverseConstraintJob Create(Animator animator, ref T data, Component component) { var job = new TwoBoneIKInverseConstraintJob(); job.root = ReadOnlyTransformHandle.Bind(animator, data.root); job.mid = ReadOnlyTransformHandle.Bind(animator, data.mid); job.tip = ReadOnlyTransformHandle.Bind(animator, data.tip); job.target = ReadWriteTransformHandle.Bind(animator, data.target); if (data.hint != null) job.hint = ReadWriteTransformHandle.Bind(animator, data.hint); job.targetOffset = AffineTransform.identity; if (data.maintainTargetPositionOffset) job.targetOffset.translation = -(data.tip.position - data.target.position); if (data.maintainTargetRotationOffset) job.targetOffset.rotation = Quaternion.Inverse(data.tip.rotation) * data.target.rotation; job.targetPositionWeight = FloatProperty.Bind(animator, component, data.targetPositionWeightFloatProperty); job.targetRotationWeight = FloatProperty.Bind(animator, component, data.targetRotationWeightFloatProperty); job.hintWeight = FloatProperty.Bind(animator, component, data.hintWeightFloatProperty); return job; } /// public override void Destroy(TwoBoneIKInverseConstraintJob job) { } } }