/// <summary> /// Defines what to do when processing the animation. /// </summary> /// <param name="stream">The animation stream to work on.</param> public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { if (twistTransforms.Length == 0) { return; } AnimationStreamHandleUtility.ReadFloats(stream, twistWeights, weightBuffer); Quaternion twistRot = TwistRotation(axisMask, sourceInverseBindRotation * source.GetLocalRotation(stream)); Quaternion invTwistRot = Quaternion.Inverse(twistRot); for (int i = 0; i < twistTransforms.Length; ++i) { ReadWriteTransformHandle twistTransform = twistTransforms[i]; float twistWeight = Mathf.Clamp(weightBuffer[i], -1f, 1f); Quaternion rot = Quaternion.Lerp(Quaternion.identity, Mathf.Sign(twistWeight) < 0f ? invTwistRot : twistRot, Mathf.Abs(twistWeight)); twistTransform.SetLocalRotation(stream, Quaternion.Lerp(twistBindRotations[i], rot, w)); // Required to update handles with binding info. twistTransforms[i] = twistTransform; } } else { for (int i = 0; i < twistTransforms.Length; ++i) { AnimationRuntimeUtils.PassThrough(stream, twistTransforms[i]); } } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { if (blendPosition.Get(stream)) { Vector3 posBlend = Vector3.Lerp( sourceA.GetPosition(stream) + sourceAOffset.translation, sourceB.GetPosition(stream) + sourceBOffset.translation, positionWeight.Get(stream) ); driven.SetPosition(stream, Vector3.Lerp(driven.GetPosition(stream), posBlend, w)); } else { driven.SetLocalPosition(stream, driven.GetLocalPosition(stream)); } if (blendRotation.Get(stream)) { Quaternion rotBlend = Quaternion.Lerp( sourceA.GetRotation(stream) * sourceAOffset.rotation, sourceB.GetRotation(stream) * sourceBOffset.rotation, rotationWeight.Get(stream) ); driven.SetRotation(stream, Quaternion.Lerp(driven.GetRotation(stream), rotBlend, w)); } else { driven.SetLocalRotation(stream, driven.GetLocalRotation(stream)); } } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
/// <summary> /// Defines what to do when processing the animation. /// </summary> /// <param name="stream">The animation stream to work on.</param> public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationStreamHandleUtility.ReadFloats(stream, sourceWeights, weightBuffer); float sumWeights = AnimationRuntimeUtils.Sum(weightBuffer); if (sumWeights < k_Epsilon) { AnimationRuntimeUtils.PassThrough(stream, driven); return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; float accumWeights = 0f; Quaternion accumRot = QuaternionExt.zero; for (int i = 0; i < sourceTransforms.Length; ++i) { var normalizedWeight = weightBuffer[i] * weightScale; if (normalizedWeight < k_Epsilon) { continue; } ReadOnlyTransformHandle sourceTransform = sourceTransforms[i]; accumRot = QuaternionExt.Add(accumRot, QuaternionExt.Scale(sourceTransform.GetRotation(stream) * sourceOffsets[i], normalizedWeight)); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; accumWeights += normalizedWeight; } accumRot = QuaternionExt.NormalizeSafe(accumRot); if (accumWeights < 1f) { accumRot = Quaternion.Lerp(driven.GetRotation(stream), accumRot, accumWeights); } // Convert accumRot to local space if (drivenParent.IsValid(stream)) { accumRot = Quaternion.Inverse(drivenParent.GetRotation(stream)) * accumRot; } Quaternion currentLRot = driven.GetLocalRotation(stream); if (Vector3.Dot(axesMask, axesMask) < 3f) { accumRot = Quaternion.Euler(AnimationRuntimeUtils.Lerp(currentLRot.eulerAngles, accumRot.eulerAngles, axesMask)); } var offset = drivenOffset.Get(stream); if (Vector3.Dot(offset, offset) > 0f) { accumRot *= Quaternion.Euler(offset); } driven.SetLocalRotation(stream, Quaternion.Lerp(currentLRot, accumRot, w)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationStreamHandleUtility.ReadFloats(stream, sourceWeights, weightBuffer); float sumWeights = AnimationRuntimeUtils.Sum(weightBuffer); if (sumWeights < k_Epsilon) { AnimationRuntimeUtils.PassThrough(stream, driven); return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; Vector2 minMaxAngles = new Vector2(minLimit.Get(stream), maxLimit.Get(stream)); var drivenWPos = driven.GetPosition(stream); var drivenLRot = driven.GetLocalRotation(stream); var drivenParentInvRot = Quaternion.Inverse(drivenParent.GetRotation(stream)); Quaternion accumDeltaRot = QuaternionExt.zero; var fromDir = drivenLRot * aimAxis; float accumWeights = 0f; for (int i = 0; i < sourceTransforms.Length; ++i) { var normalizedWeight = weightBuffer[i] * weightScale; if (normalizedWeight < k_Epsilon) { continue; } ReadOnlyTransformHandle sourceTransform = sourceTransforms[i]; var toDir = drivenParentInvRot * (sourceTransform.GetPosition(stream) - drivenWPos); if (toDir.sqrMagnitude < k_Epsilon) { continue; } var crossDir = Vector3.Cross(fromDir, toDir).normalized; if (Vector3.Dot(axesMask, axesMask) < 3f) { crossDir = AnimationRuntimeUtils.Select(Vector3.zero, crossDir, axesMask).normalized; if (Vector3.Dot(crossDir, crossDir) > k_Epsilon) { fromDir = AnimationRuntimeUtils.ProjectOnPlane(fromDir, crossDir); toDir = AnimationRuntimeUtils.ProjectOnPlane(toDir, crossDir); } else { toDir = fromDir; } } var rotToSource = Quaternion.AngleAxis( Mathf.Clamp(Vector3.Angle(fromDir, toDir), minMaxAngles.x, minMaxAngles.y), crossDir ); accumDeltaRot = QuaternionExt.Add( accumDeltaRot, QuaternionExt.Scale(sourceOffsets[i] * rotToSource, normalizedWeight) ); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; accumWeights += normalizedWeight; } accumDeltaRot = QuaternionExt.NormalizeSafe(accumDeltaRot); if (accumWeights < 1f) { accumDeltaRot = Quaternion.Lerp(Quaternion.identity, accumDeltaRot, accumWeights); } Quaternion newRot = accumDeltaRot * drivenLRot; if (Vector3.Dot(axesMask, axesMask) < 3f) { newRot = Quaternion.Euler(AnimationRuntimeUtils.Select(drivenLRot.eulerAngles, newRot.eulerAngles, axesMask)); } var offset = drivenOffset.Get(stream); if (Vector3.Dot(offset, offset) > 0f) { newRot *= Quaternion.Euler(offset); } driven.SetLocalRotation(stream, Quaternion.Lerp(drivenLRot, newRot, w)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }
public void ProcessAnimation(AnimationStream stream) { float w = jobWeight.Get(stream); if (w > 0f) { AnimationStreamHandleUtility.ReadFloats(stream, sourceWeights, weightBuffer); float sumWeights = AnimationRuntimeUtils.Sum(weightBuffer); if (sumWeights < k_Epsilon) { return; } float weightScale = sumWeights > 1f ? 1f / sumWeights : 1f; Vector2 minMaxAngles = new Vector2(minLimit.Get(stream), maxLimit.Get(stream)); driven.GetGlobalTR(stream, out Vector3 currentWPos, out Quaternion currentWRot); Vector3 currentDir = currentWRot * aimAxis; Quaternion accumDeltaRot = QuaternionExt.zero; float accumWeights = 0f; for (int i = 0; i < sourceTransforms.Length; ++i) { var normalizedWeight = weightBuffer[i] * weightScale; if (normalizedWeight < k_Epsilon) { continue; } ReadOnlyTransformHandle sourceTransform = sourceTransforms[i]; var toDir = sourceTransform.GetPosition(stream) - currentWPos; if (toDir.sqrMagnitude < k_Epsilon) { continue; } var rotToSource = Quaternion.AngleAxis( Mathf.Clamp(Vector3.Angle(currentDir, toDir), minMaxAngles.x, minMaxAngles.y), Vector3.Cross(currentDir, toDir).normalized ); accumDeltaRot = QuaternionExt.Add( accumDeltaRot, QuaternionExt.Scale(sourceOffsets[i] * rotToSource, normalizedWeight) ); // Required to update handles with binding info. sourceTransforms[i] = sourceTransform; accumWeights += normalizedWeight; } accumDeltaRot = QuaternionExt.NormalizeSafe(accumDeltaRot); if (accumWeights < 1f) { accumDeltaRot = Quaternion.Lerp(Quaternion.identity, accumDeltaRot, accumWeights); } Quaternion newRot = accumDeltaRot * currentWRot; // Convert newRot to local space if (drivenParent.IsValid(stream)) { newRot = Quaternion.Inverse(drivenParent.GetRotation(stream)) * newRot; } Quaternion currentLRot = driven.GetLocalRotation(stream); if (Vector3.Dot(axesMask, axesMask) < 3f) { newRot = Quaternion.Euler(AnimationRuntimeUtils.Lerp(currentLRot.eulerAngles, newRot.eulerAngles, axesMask)); } var offset = drivenOffset.Get(stream); if (Vector3.Dot(offset, offset) > 0f) { newRot *= Quaternion.Euler(offset); } driven.SetLocalRotation(stream, Quaternion.Lerp(currentLRot, newRot, w)); } else { AnimationRuntimeUtils.PassThrough(stream, driven); } }