Jelajahi Sumber

AnimationUtils: Add AnimationUtils.subclip(), clip.clone(), and track.clone().

Don McCurdy 7 tahun lalu
induk
melakukan
69bf0671fe

+ 4 - 0
docs/api/en/animation/AnimationUtils.html

@@ -48,6 +48,10 @@
 		Sorts the array previously returned by [page:AnimationUtils.getKeyframeOrder getKeyframeOrder].
 		</p>
 
+		<h3>[method:AnimationClip subclip]( [param:AnimationClip clip], [param:String name], [param:Number startFrame], [param:Number endFrame], [param:Number fps] )</h3>
+		<div>
+		Creates a new clip, containing only the segment of the original clip between the given frames.
+		</div>
 
 		<h2>Source</h2>
 

+ 31 - 4
src/animation/AnimationClip.js

@@ -409,14 +409,42 @@ Object.assign( AnimationClip.prototype, {
 
 	},
 
-	trim: function () {
+	trim: function ( startTime, endTime ) {
 
-		for ( var i = 0; i < this.tracks.length; i ++ ) {
+		if ( startTime === undefined ) startTime = 0;
+		if ( endTime === undefined ) endTime = this.duration;
+
+		var tracks = [];
+
+		for ( var i = 0; i < this.tracks.length; ++ i ) {
+
+			var track = this.tracks[ i ];
+
+			var hasKeyframe = false;
+
+			// omit tracks without frames between new start/end times
+			for ( var j = 0; j < track.times.length; ++ j ) {
+
+				if ( startTime <= track.times[ j ] && endTime > track.times [ j ] ) {
+
+					hasKeyframe = true;
 
-			this.tracks[ i ].trim( 0, this.duration );
+					break;
+
+				}
+
+			}
+
+			if ( ! hasKeyframe ) continue;
+
+			this.tracks[ i ].trim( startTime, endTime );
+
+			tracks.push( this.tracks[ i ] );
 
 		}
 
+		this.tracks = tracks;
+
 		return this;
 
 	},
@@ -447,7 +475,6 @@ Object.assign( AnimationClip.prototype, {
 
 	},
 
-
 	clone: function () {
 
 		var tracks = [];

+ 73 - 0
src/animation/AnimationUtils.js

@@ -158,6 +158,79 @@ var AnimationUtils = {
 
 		}
 
+	},
+
+	subclip: function ( sourceClip, name, startFrame, endFrame, fps ) {
+
+		fps = fps || 30;
+
+		var clip = sourceClip.clone();
+
+		clip.name = name;
+
+		var tracks = [];
+
+		for ( var i = 0; i < clip.tracks.length; ++ i ) {
+
+			var track = clip.tracks[ i ];
+			var valueSize = track.getValueSize();
+
+			var times = [];
+			var values = [];
+
+			for ( var j = 0; j < track.times.length; ++ j ) {
+
+				var frame = track.times[ j ] * fps;
+
+				if ( frame < startFrame || frame >= endFrame ) continue;
+
+				times.push( track.times[ j ] );
+
+				for ( var k = 0; k < valueSize; ++ k ) {
+
+					values.push( track.values[ j * valueSize + k ] );
+
+				}
+
+			}
+
+			if ( times.length === 0 ) continue;
+
+			track.times = AnimationUtils.convertArray( times, track.times.constructor );
+			track.values = AnimationUtils.convertArray( values, track.values.constructor );
+
+			tracks.push( track );
+
+		}
+
+		clip.tracks = tracks;
+
+		// find minimum .times value across all tracks in the trimmed clip
+
+		var minStartTime = Infinity;
+
+		for ( var i = 0; i < clip.tracks.length; ++ i ) {
+
+			if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) {
+
+				minStartTime = clip.tracks[ i ].times[ 0 ];
+
+			}
+
+		}
+
+		// shift all tracks such that clip begins at t=0
+
+		for ( var i = 0; i < clip.tracks.length; ++ i ) {
+
+			clip.tracks[ i ].shift( -1 * minStartTime );
+
+		}
+
+		clip.resetDuration();
+
+		return clip;
+
 	}
 
 };

+ 3 - 0
src/animation/KeyframeTrack.js

@@ -347,6 +347,9 @@ Object.assign( KeyframeTrack.prototype, {
 	// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
 	optimize: function () {
 
+		// TODO: Opt-out of optimization?
+		return this;
+
 		var times = this.times,
 			values = this.values,
 			stride = this.getValueSize(),