summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs')
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs93
1 files changed, 93 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs
new file mode 100644
index 0000000..ae190e3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs
@@ -0,0 +1,93 @@
+using System.Collections.Generic;
+using UnityEngine.Animations;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ // Does a post processing of the weights on an animation track to properly normalize
+ // the mixer weights so that blending does not bring default poses and subtracks, layers and
+ // layer graphs blend correctly
+ class AnimationOutputWeightProcessor : ITimelineEvaluateCallback
+ {
+ struct WeightInfo
+ {
+ public Playable mixer;
+ public Playable parentMixer;
+ public int port;
+ }
+
+ AnimationPlayableOutput m_Output;
+ AnimationMotionXToDeltaPlayable m_MotionXPlayable;
+ readonly List<WeightInfo> m_Mixers = new List<WeightInfo>();
+
+ public AnimationOutputWeightProcessor(AnimationPlayableOutput output)
+ {
+ m_Output = output;
+ output.SetWeight(0);
+ FindMixers();
+ }
+
+ void FindMixers()
+ {
+ var playable = m_Output.GetSourcePlayable();
+ var outputPort = m_Output.GetSourceOutputPort();
+
+ m_Mixers.Clear();
+ // only write the final output in playmode. it should always be 1 in editor because we blend to the defaults
+ FindMixers(playable, outputPort, playable.GetInput(outputPort));
+ }
+
+ // Recursively accumulates mixers.
+ void FindMixers(Playable parent, int port, Playable node)
+ {
+ if (!node.IsValid())
+ return;
+
+ var type = node.GetPlayableType();
+ if (type == typeof(AnimationMixerPlayable) || type == typeof(AnimationLayerMixerPlayable))
+ {
+ // use post fix traversal so children come before parents
+ int subCount = node.GetInputCount();
+ for (int j = 0; j < subCount; j++)
+ {
+ FindMixers(node, j, node.GetInput(j));
+ }
+
+ // if we encounter a layer mixer, we assume there is nesting occuring
+ // and we modulate the weight instead of overwriting it.
+ var weightInfo = new WeightInfo
+ {
+ parentMixer = parent,
+ mixer = node,
+ port = port,
+ };
+ m_Mixers.Add(weightInfo);
+ }
+ else
+ {
+ var count = node.GetInputCount();
+ for (var i = 0; i < count; i++)
+ {
+ FindMixers(parent, port, node.GetInput(i));
+ }
+ }
+ }
+
+ public void Evaluate()
+ {
+ float weight = 1;
+ m_Output.SetWeight(1);
+ for (int i = 0; i < m_Mixers.Count; i++)
+ {
+ var mixInfo = m_Mixers[i];
+ weight = WeightUtility.NormalizeMixer(mixInfo.mixer);
+ mixInfo.parentMixer.SetInputWeight(mixInfo.port, weight);
+ }
+
+ // only write the final weight in player/playmode. In editor, we are blending to the appropriate defaults
+ // the last mixer in the list is the final blend, since the list is composed post-order.
+ if (Application.isPlaying)
+ m_Output.SetWeight(weight);
+ }
+ }
+}