コード例 #1
0
 public void BuildBlendTree(FastList <AnimationOperation> blendStack)
 {
     // Note! The tree has to be flattened and given as a stack!
     blendStack.Add(AnimationOperation.NewPush(anim1Evaluator, TimeSpan.FromTicks((long)(currentTime * Animation1.Duration.Ticks))));
     blendStack.Add(AnimationOperation.NewPush(anim2Evaluator, TimeSpan.FromTicks((long)(currentTime * Animation2.Duration.Ticks))));
     blendStack.Add(AnimationOperation.NewBlend(CoreAnimationOperation.Blend, BlendLerp));
 }
コード例 #2
0
        /// <summary>
        /// BuildBlendTree is called every frame from the animation system when the <see cref="AnimationComponent"/> needs to be evaluated
        /// It overrides the default behavior of the <see cref="AnimationComponent"/> by setting a custom blend tree
        /// </summary>
        /// <param name="blendStack">The stack of animation operations to be blended</param>
        public void BuildBlendTree(FastList <AnimationOperation> blendStack)
        {
            switch (state)
            {
            case AnimationState.Walking:
            {
                // Note! The tree is laid out as a stack and has to be flattened before returning it to the animation system!
                blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp1,
                                                          TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp1.Duration.Ticks))));
                blendStack.Add(AnimationOperation.NewPush(animEvaluatorWalkLerp2,
                                                          TimeSpan.FromTicks((long)(currentTime * animationClipWalkLerp2.Duration.Ticks))));
                blendStack.Add(AnimationOperation.NewBlend(CoreAnimationOperation.Blend, walkLerpFactor));
            }
            break;

            case AnimationState.Jumping:
            {
                blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpStart,
                                                          TimeSpan.FromTicks((long)(currentTime * AnimationJumpStart.Duration.Ticks))));
            }
            break;

            case AnimationState.Airborne:
            {
                blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpMid,
                                                          TimeSpan.FromTicks((long)(currentTime * AnimationJumpMid.Duration.Ticks))));
            }
            break;

            case AnimationState.Landing:
            {
                blendStack.Add(AnimationOperation.NewPush(animEvaluatorJumpEnd,
                                                          TimeSpan.FromTicks((long)(currentTime * AnimationJumpEnd.Duration.Ticks))));
            }
            break;

            case AnimationState.Punching:
            {
                blendStack.Add(AnimationOperation.NewPush(animEvaluatorPunch,
                                                          TimeSpan.FromTicks((long)(currentTime * AnimationPunch.Duration.Ticks))));
            }
            break;
            }
        }
コード例 #3
0
            private AnimationClip SubtractAnimations(AnimationClip baseAnimation, AnimationClip sourceAnimation)
            {
                if (baseAnimation == null)
                {
                    throw new ArgumentNullException("baseAnimation");
                }
                if (sourceAnimation == null)
                {
                    throw new ArgumentNullException("sourceAnimation");
                }

                var animationBlender = new AnimationBlender();

                var baseEvaluator   = animationBlender.CreateEvaluator(baseAnimation);
                var sourceEvaluator = animationBlender.CreateEvaluator(sourceAnimation);

                // Create a result animation with same channels
                var resultAnimation = new AnimationClip();

                foreach (var channel in sourceAnimation.Channels)
                {
                    // Create new instance of curve
                    var newCurve = (AnimationCurve)Activator.CreateInstance(typeof(AnimationCurve <>).MakeGenericType(channel.Value.ElementType));

                    // Quaternion curve are linear, others are cubic
                    if (newCurve.ElementType != typeof(Quaternion))
                    {
                        newCurve.InterpolationType = AnimationCurveInterpolationType.Cubic;
                    }

                    resultAnimation.AddCurve(channel.Key, newCurve);
                }

                var resultEvaluator = animationBlender.CreateEvaluator(resultAnimation);

                var animationOperations = new FastList <AnimationOperation>();

                // Perform animation blending for each frame and upload results in a new animation
                // Note that it does a simple per-frame sampling, so animation discontinuities will be lost.
                // TODO: Framerate is hardcoded at 30 FPS.
                var frameTime = TimeSpan.FromSeconds(1.0f / 30.0f);

                for (var time = TimeSpan.Zero; time < sourceAnimation.Duration + frameTime; time += frameTime)
                {
                    // Last frame, round it to end of animation
                    if (time > sourceAnimation.Duration)
                    {
                        time = sourceAnimation.Duration;
                    }

                    TimeSpan baseTime;
                    switch (Parameters.Mode)
                    {
                    case AdditiveAnimationBaseMode.FirstFrame:
                        baseTime = TimeSpan.Zero;
                        break;

                    case AdditiveAnimationBaseMode.Animation:
                        baseTime = TimeSpan.FromTicks(time.Ticks % baseAnimation.Duration.Ticks);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }

                    // Generates result = source - base
                    animationOperations.Clear();
                    animationOperations.Add(AnimationOperation.NewPush(sourceEvaluator, time));
                    animationOperations.Add(AnimationOperation.NewPush(baseEvaluator, baseTime));
                    animationOperations.Add(AnimationOperation.NewBlend(CoreAnimationOperation.Subtract, 1.0f));
                    animationOperations.Add(AnimationOperation.NewPop(resultEvaluator, time));

                    // Compute
                    AnimationClipResult animationClipResult = null;
                    animationBlender.Compute(animationOperations, ref animationClipResult);
                }

                resultAnimation.Duration   = sourceAnimation.Duration;
                resultAnimation.RepeatMode = sourceAnimation.RepeatMode;

                return(resultAnimation);
            }