title: ThreeJS - how to set current time in Animation
body: <p>I'm using skinning / skeletal animation in ThreeJS. I have an animation, and I want to be able to move backward and forward through it, and jump to different locations within it, rather than the usual looping behaviour.</p>
  
  <p>The animation is created like this, as in the example:</p>
  
  <pre><code>var animation = new THREE.Animation( mesh, geometry.animation.name );
  </code></pre>
  
  <p>I have tried updating the animation with negative deltas, as well as setting animation.currentTime directly:</p>
  
  <pre><code>animation.currentTime = animationLocation;
  </code></pre>
  
  <p>These appear to work only if I move forward in time, but if I go backward the animation breaks and I get an error:</p>
  
  <pre><code>THREE.Animation.update: Warning! Scale out of bounds: ... on bone ... 
  </code></pre>
  
  <p>One thing that does actually work without error is to call <code>stop()</code> and then <code>play()</code> with a new start time:</p>
  
  <pre><code>animation.stop();
  animation.play( true, animationLocation );
  </code></pre>
  
  <p>...however when I look at what these functions are actually doing, they involve many many function calls, looping, resetting transforms etc. This seems like a horrible way to do it, even if it works as a hack. </p>
  
  <p>It may be that this functionality does not exist yet, in which case I'll try to dig in and create a function that does a minimal amount of work, but I'm hoping there is another way that I haven't found. </p>
  
  <p>Can anyone help with this?</p>
  
  <p>[UPDATE]</p>
  
  <p>As an update on my progress, I'll post the best solution I have at this time...</p>
  
  <p>I pulled out the contents of the <code>stop()</code> and <code>play()</code> functions, and stripped out everything I could, making some assumptions about certain values having already been set by 'play()'. </p>
  
  <p>This still seems like it is probably not the best way to do it, but it is doing a bit less work than by just calling <code>stop()</code> then <code>play()</code>.</p>
  
  <p>This is what I was able to get it down to:</p>
  
  <pre><code>THREE.Animation.prototype.gotoTime = function( time ) {
  
      //clamp to duration of the animation:
      time = THREE.Math.clamp( time, 0, this.length );
  
      this.currentTime = time;
  
      // reset key cache
      var h, hl = this.hierarchy.length,
          object;
  
      for ( h = 0; h &lt; hl; h ++ ) {
  
          object = this.hierarchy[ h ];
  
          var prevKey = object.animationCache.prevKey;
          var nextKey = object.animationCache.nextKey;
  
          prevKey.pos = this.data.hierarchy[ h ].keys[ 0 ];
          prevKey.rot = this.data.hierarchy[ h ].keys[ 0 ];
          prevKey.scl = this.data.hierarchy[ h ].keys[ 0 ];
  
          nextKey.pos = this.getNextKeyWith( "pos", h, 1 );
          nextKey.rot = this.getNextKeyWith( "rot", h, 1 );
          nextKey.scl = this.getNextKeyWith( "scl", h, 1 );
  
      }
  
      //isPlaying must be true for update to work due to "early out"
      //so remember the current play state:
      var wasPlaying = this.isPlaying;
      this.isPlaying = true; 
  
      //update with a delta time of zero:
      this.update( 0 );
  
      //reset the play state:
      this.isPlaying = wasPlaying;
  
  }
  </code></pre>
  
  <p>The main limitation of the function in terms of usefulness is that you can't interpolate from one arbitrary time to another. You can basically just scrub around in the animation.</p>