Set animation's time to 0

Jan 12, 2010 at 1:00 PM

Hello,

When I stop an animation using StopAnimation() before the end of the animation and then
I play the animation again using PlayAnimation() I've noticed that the time of the animation is the same as before the stop animation

I've tried to used SeekAnimation(0) to set the time of the animation to 0 but it doesn't seem to work.

What can I do ?

Thank you !

Coordinator
Jan 14, 2010 at 11:44 PM

Hi.

I tried implementing SeekAnimation(0) in the animation sample, and it appears to work correctly.
However, you are correct, stopping and playing the animation again certainly *doesn't* work. Background animation caching being too smart for it's own good.. :-(

Note: AnimationInstance is a handle (structure) to the actual playing animation. So it's quite possible for an animation to be finished / invalid handle. SeekAnimation, for instance, will return false if the handle isn't valid. (It's built this way to prevent garbage build up).

I'm not sure why seek would be failing...

Jan 31, 2010 at 4:52 PM

Hi.

It seems I forget to give you some informations.
I reproduct my initial problem in tutorial :

just replace Model Animation.cs by this :

 

 

using System;
using System.Text;
using System.Collections.Generic;



using Xen;
using Xen.Camera;
using Xen.Graphics;
using Xen.Ex.Graphics;
using Xen.Ex.Graphics2D;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;


/*
 * This sample extends from Tutorial_10 (ModelInstance)
 * This sample demonstrates:
 * 
 * Playing an animation with an AnimationController
 * 
 */
namespace Tutorials.Tutorial_11
{
	class Actor : IDraw, IContentOwner
	{
		private ModelInstance model;

		//NEW CODE
		//An animation controller animates a model instance
		private AnimationController animationController;
		//This structure is a handle to an animation
                private AnimationInstance animation;

                public AnimationInstance Animation
                {
                    get { return animation; }
                    set { animation = value; }
                }

		//NEW CODE
		public Actor(ContentRegister content)
		{

			model = new ModelInstance();

			//create the animation controller.
			animationController = model.GetAnimationController();


			content.Add(this);

                        PlayAnimation1();
		}

        public void PlayAnimation1()
        {
            int animationIndex = animationController.AnimationIndex("Walk");

            animation.StopAnimation();

            //begin playing the animation, looping
            animation = animationController.PlayLoopingAnimation(animationIndex);
        }

        public void PlayAnimation2()
        {
            int animationIndex = animationController.AnimationIndex("Wave");

            animation.StopAnimation();

            //begin playing the animation, looping
            animation = animationController.PlayAnimation(animationIndex);
        }


		//everything else from here on is identical...

		public void Draw(DrawState state)
		{
			//ModelInstances automatically setup the default material shaders
			//Custom shaders can be used with model.SetShaderOverride(...)
			model.Draw(state);
		}

		public bool CullTest(ICuller culler)
		{
			return model.CullTest(culler);
		}


		public void LoadContent(ContentRegister content, DrawState state, ContentManager manager)
		{
			//load the model data into the model instance
			model.ModelData = manager.Load<Xen.Ex.Graphics.Content.ModelData>(@"tiny_4anim");
		}

		public void UnloadContent(ContentRegister content, DrawState state)
		{
		}
	}

	[DisplayName(Name = "Tutorial 11: Model Animation")]
	public class Tutorial : Application
	{
		//screen draw target
		private DrawTargetScreen drawToScreen;

		protected override void Initialise()
		{
			Camera3D camera = new Camera3D();
			camera.LookAt(new Vector3(0, 0, 4), new Vector3(3, 4, 4), new Vector3(0, 0, 1));

			//create the draw target.
			drawToScreen = new DrawTargetScreen(this, camera);
			drawToScreen.ClearBuffer.ClearColour = Color.CornflowerBlue;

			//NEW CODE
			//create the actor instance
            actor = new Actor(Content);
			drawToScreen.Add(actor);
		}

		protected override void Draw(DrawState state)
		{
			drawToScreen.Draw(state);
		}

		protected override void Update(UpdateState state)
		{
			if (state.PlayerInput[PlayerIndex.One].InputState.Buttons.Back.OnPressed)
				this.Shutdown();


            if (state.KeyboardState.KeyState.O.OnPressed)
            {
                actor.PlayAnimation2();
            }

            if (actor.Animation.AnimationName == "Wave" && actor.Animation.Time > actor.Animation.AnimationDuration - 0.02f)
                actor.PlayAnimation1();

           // if (actor.Animation.AnimationName == "Wave" && actor.Animation.AnimationFinished)
             //   actor.PlayAnimation1();
		}

        Actor actor;
	}
}

When you will press 'O' it will work only the first time.

 

if you use the second commented option it will work each time but there 1 frame without animation between the both animation.

Thank you for your help and for Xen.

 

Jan 31, 2010 at 10:20 PM

I remember reading somewhere that "animation calculation is spawned in a per-frame Update task, and then used in the following draw call."

Is it possible that your asking the animation to draw, but that it be won't be drawn till the next frame because the bone animation calculation is offloading to the threading which won't return right away?

Coordinator
Feb 1, 2010 at 1:09 AM

Thanks for the sample. I'll take a look tomorrow. There were some issues I fixed up just recently, but this could be different. As mentioned, there is a lot of sync code to keep the animation tasks working correctly. It's quite possible something isn't quite right.

Feb 12, 2010 at 6:21 PM

Still no idea ? I've tried a lot of turnaround to avoid this glitch but nothing else seems to work...

Thank you ;)

 

 

Coordinator
Apr 5, 2010 at 5:55 PM

Sorry I just realised I completely forgot to update you on this bug.

I did figure it out eventually, but I totally forgot to tell you the solution! Argh. Anyway, I'm putting out an update very soon that has the fix in it. Long story short, the cached animation instances were not resetting some thread buffering values.

Basically meant adding:

this.frameTimeBuffer = 0;
this.frameTimerBuffer = 0;
this.durationBuffer = 0;

to the end of the AnimationStreamControl.Initalise method.
Sorry!

Apr 21, 2010 at 6:35 PM

Thank you !

In fact I had found a weird fix but now I ll use your solution !