123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- /**
- * @author mikael emtinger / http://gomo.se/
- * @author mrdoob / http://mrdoob.com/
- * @author alteredq / http://alteredqualia.com/
- * @author khang duong
- * @author erik kitson
- */
- THREE.KeyFrameAnimation = function ( data ) {
- this.root = data.node;
- this.data = THREE.AnimationHandler.init( data );
- this.hierarchy = THREE.AnimationHandler.parse( this.root );
- this.currentTime = 0;
- this.timeScale = 0.001;
- this.isPlaying = false;
- this.isPaused = true;
- this.loop = true;
- // initialize to first keyframes
- for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
- var keys = this.data.hierarchy[ h ].keys,
- sids = this.data.hierarchy[ h ].sids,
- obj = this.hierarchy[ h ];
- if ( keys.length && sids ) {
- for ( var s = 0; s < sids.length; s ++ ) {
- var sid = sids[ s ],
- next = this.getNextKeyWith( sid, h, 0 );
- if ( next ) {
- next.apply( sid );
- }
- }
- obj.matrixAutoUpdate = false;
- this.data.hierarchy[ h ].node.updateMatrix();
- obj.matrixWorldNeedsUpdate = true;
- }
- }
- };
- THREE.KeyFrameAnimation.prototype = {
- constructor: THREE.KeyFrameAnimation,
- play: function ( startTime ) {
- this.currentTime = startTime !== undefined ? startTime : 0;
- if ( this.isPlaying === false ) {
- this.isPlaying = true;
- // reset key cache
- var h, hl = this.hierarchy.length,
- object,
- node;
- for ( h = 0; h < hl; h ++ ) {
- object = this.hierarchy[ h ];
- node = this.data.hierarchy[ h ];
- if ( node.animationCache === undefined ) {
- node.animationCache = {};
- node.animationCache.prevKey = null;
- node.animationCache.nextKey = null;
- node.animationCache.originalMatrix = object.matrix;
- }
- var keys = this.data.hierarchy[ h ].keys;
- if ( keys.length > 1 ) {
- node.animationCache.prevKey = keys[ 0 ];
- node.animationCache.nextKey = keys[ 1 ];
- this.startTime = Math.min( keys[ 0 ].time, this.startTime );
- this.endTime = Math.max( keys[ keys.length - 1 ].time, this.endTime );
- }
- }
- this.update( 0 );
- }
- this.isPaused = false;
- },
- stop: function () {
- this.isPlaying = false;
- this.isPaused = false;
- // reset JIT matrix and remove cache
- for ( var h = 0; h < this.data.hierarchy.length; h ++ ) {
- var obj = this.hierarchy[ h ];
- var node = this.data.hierarchy[ h ];
- if ( node.animationCache !== undefined ) {
- var original = node.animationCache.originalMatrix;
- original.copy( obj.matrix );
- obj.matrix = original;
- delete node.animationCache;
- }
- }
- },
- update: function ( delta ) {
- if ( this.isPlaying === false ) return;
- this.currentTime += delta * this.timeScale;
- //
- var duration = this.data.length;
- if ( this.loop === true && this.currentTime > duration ) {
- this.currentTime %= duration;
- }
- this.currentTime = Math.min( this.currentTime, duration );
- for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
- var object = this.hierarchy[ h ];
- var node = this.data.hierarchy[ h ];
- var keys = node.keys,
- animationCache = node.animationCache;
- if ( keys.length ) {
- var prevKey = animationCache.prevKey;
- var nextKey = animationCache.nextKey;
- if ( nextKey.time <= this.currentTime ) {
- while ( nextKey.time < this.currentTime && nextKey.index > prevKey.index ) {
- prevKey = nextKey;
- nextKey = keys[ prevKey.index + 1 ];
- }
- animationCache.prevKey = prevKey;
- animationCache.nextKey = nextKey;
- }
- if ( nextKey.time >= this.currentTime ) {
- prevKey.interpolate( nextKey, this.currentTime );
- } else {
- prevKey.interpolate( nextKey, nextKey.time );
- }
- this.data.hierarchy[ h ].node.updateMatrix();
- object.matrixWorldNeedsUpdate = true;
- }
- }
- },
- getNextKeyWith: function ( sid, h, key ) {
- var keys = this.data.hierarchy[ h ].keys;
- key = key % keys.length;
- for ( ; key < keys.length; key ++ ) {
- if ( keys[ key ].hasTarget( sid ) ) {
- return keys[ key ];
- }
- }
- return keys[ 0 ];
- },
- getPrevKeyWith: function ( sid, h, key ) {
- var keys = this.data.hierarchy[ h ].keys;
- key = key >= 0 ? key : key + keys.length;
- for ( ; key >= 0; key -- ) {
- if ( keys[ key ].hasTarget( sid ) ) {
- return keys[ key ];
- }
- }
- return keys[ keys.length - 1 ];
- }
- };
|