Pārlūkot izejas kodu

Tree-shaking: AnimationUtils (#24337)

Patrick Schroen 3 gadi atpakaļ
vecāks
revīzija
88ee281526

+ 1 - 1
src/Three.js

@@ -85,7 +85,7 @@ export { BooleanKeyframeTrack } from './animation/tracks/BooleanKeyframeTrack.js
 export { PropertyMixer } from './animation/PropertyMixer.js';
 export { PropertyBinding } from './animation/PropertyBinding.js';
 export { KeyframeTrack } from './animation/KeyframeTrack.js';
-export { AnimationUtils } from './animation/AnimationUtils.js';
+export * as AnimationUtils from './animation/AnimationUtils.js';
 export { AnimationObjectGroup } from './animation/AnimationObjectGroup.js';
 export { AnimationMixer } from './animation/AnimationMixer.js';
 export { AnimationClip } from './animation/AnimationClip.js';

+ 1 - 1
src/animation/AnimationClip.js

@@ -1,4 +1,4 @@
-import { AnimationUtils } from './AnimationUtils.js';
+import * as AnimationUtils from './AnimationUtils.js';
 import { KeyframeTrack } from './KeyframeTrack.js';
 import { BooleanKeyframeTrack } from './tracks/BooleanKeyframeTrack.js';
 import { ColorKeyframeTrack } from './tracks/ColorKeyframeTrack.js';

+ 204 - 199
src/animation/AnimationUtils.js

@@ -1,343 +1,339 @@
 import { Quaternion } from '../math/Quaternion.js';
 import { AdditiveAnimationBlendMode } from '../constants.js';
 
-const AnimationUtils = {
+// same as Array.prototype.slice, but also works on typed arrays
+function arraySlice( array, from, to ) {
 
-	// same as Array.prototype.slice, but also works on typed arrays
-	arraySlice: function ( array, from, to ) {
+	if ( isTypedArray( array ) ) {
 
-		if ( AnimationUtils.isTypedArray( array ) ) {
+		// in ios9 array.subarray(from, undefined) will return empty array
+		// but array.subarray(from) or array.subarray(from, len) is correct
+		return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );
 
-			// in ios9 array.subarray(from, undefined) will return empty array
-			// but array.subarray(from) or array.subarray(from, len) is correct
-			return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );
-
-		}
+	}
 
-		return array.slice( from, to );
+	return array.slice( from, to );
 
-	},
+}
 
-	// converts an array to a specific type
-	convertArray: function ( array, type, forceClone ) {
+// converts an array to a specific type
+function convertArray( array, type, forceClone ) {
 
-		if ( ! array || // let 'undefined' and 'null' pass
-			! forceClone && array.constructor === type ) return array;
+	if ( ! array || // let 'undefined' and 'null' pass
+		! forceClone && array.constructor === type ) return array;
 
-		if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {
+	if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {
 
-			return new type( array ); // create typed array
+		return new type( array ); // create typed array
 
-		}
-
-		return Array.prototype.slice.call( array ); // create Array
+	}
 
-	},
+	return Array.prototype.slice.call( array ); // create Array
 
-	isTypedArray: function ( object ) {
+}
 
-		return ArrayBuffer.isView( object ) &&
-			! ( object instanceof DataView );
+function isTypedArray( object ) {
 
-	},
+	return ArrayBuffer.isView( object ) &&
+		! ( object instanceof DataView );
 
-	// returns an array by which times and values can be sorted
-	getKeyframeOrder: function ( times ) {
+}
 
-		function compareTime( i, j ) {
+// returns an array by which times and values can be sorted
+function getKeyframeOrder( times ) {
 
-			return times[ i ] - times[ j ];
+	function compareTime( i, j ) {
 
-		}
+		return times[ i ] - times[ j ];
 
-		const n = times.length;
-		const result = new Array( n );
-		for ( let i = 0; i !== n; ++ i ) result[ i ] = i;
+	}
 
-		result.sort( compareTime );
+	const n = times.length;
+	const result = new Array( n );
+	for ( let i = 0; i !== n; ++ i ) result[ i ] = i;
 
-		return result;
+	result.sort( compareTime );
 
-	},
+	return result;
 
-	// uses the array previously returned by 'getKeyframeOrder' to sort data
-	sortedArray: function ( values, stride, order ) {
+}
 
-		const nValues = values.length;
-		const result = new values.constructor( nValues );
+// uses the array previously returned by 'getKeyframeOrder' to sort data
+function sortedArray( values, stride, order ) {
 
-		for ( let i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {
+	const nValues = values.length;
+	const result = new values.constructor( nValues );
 
-			const srcOffset = order[ i ] * stride;
+	for ( let i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {
 
-			for ( let j = 0; j !== stride; ++ j ) {
+		const srcOffset = order[ i ] * stride;
 
-				result[ dstOffset ++ ] = values[ srcOffset + j ];
+		for ( let j = 0; j !== stride; ++ j ) {
 
-			}
+			result[ dstOffset ++ ] = values[ srcOffset + j ];
 
 		}
 
-		return result;
+	}
 
-	},
+	return result;
 
-	// function for parsing AOS keyframe formats
-	flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) {
+}
 
-		let i = 1, key = jsonKeys[ 0 ];
+// function for parsing AOS keyframe formats
+function flattenJSON( jsonKeys, times, values, valuePropertyName ) {
 
-		while ( key !== undefined && key[ valuePropertyName ] === undefined ) {
+	let i = 1, key = jsonKeys[ 0 ];
 
-			key = jsonKeys[ i ++ ];
+	while ( key !== undefined && key[ valuePropertyName ] === undefined ) {
 
-		}
+		key = jsonKeys[ i ++ ];
 
-		if ( key === undefined ) return; // no data
+	}
 
-		let value = key[ valuePropertyName ];
-		if ( value === undefined ) return; // no data
+	if ( key === undefined ) return; // no data
 
-		if ( Array.isArray( value ) ) {
+	let value = key[ valuePropertyName ];
+	if ( value === undefined ) return; // no data
 
-			do {
+	if ( Array.isArray( value ) ) {
 
-				value = key[ valuePropertyName ];
+		do {
 
-				if ( value !== undefined ) {
+			value = key[ valuePropertyName ];
 
-					times.push( key.time );
-					values.push.apply( values, value ); // push all elements
+			if ( value !== undefined ) {
 
-				}
+				times.push( key.time );
+				values.push.apply( values, value ); // push all elements
 
-				key = jsonKeys[ i ++ ];
+			}
 
-			} while ( key !== undefined );
+			key = jsonKeys[ i ++ ];
 
-		} else if ( value.toArray !== undefined ) {
+		} while ( key !== undefined );
 
-			// ...assume THREE.Math-ish
+	} else if ( value.toArray !== undefined ) {
 
-			do {
+		// ...assume THREE.Math-ish
 
-				value = key[ valuePropertyName ];
+		do {
 
-				if ( value !== undefined ) {
+			value = key[ valuePropertyName ];
 
-					times.push( key.time );
-					value.toArray( values, values.length );
+			if ( value !== undefined ) {
 
-				}
+				times.push( key.time );
+				value.toArray( values, values.length );
 
-				key = jsonKeys[ i ++ ];
+			}
 
-			} while ( key !== undefined );
+			key = jsonKeys[ i ++ ];
 
-		} else {
+		} while ( key !== undefined );
 
-			// otherwise push as-is
+	} else {
 
-			do {
+		// otherwise push as-is
 
-				value = key[ valuePropertyName ];
+		do {
 
-				if ( value !== undefined ) {
+			value = key[ valuePropertyName ];
 
-					times.push( key.time );
-					values.push( value );
+			if ( value !== undefined ) {
 
-				}
+				times.push( key.time );
+				values.push( value );
 
-				key = jsonKeys[ i ++ ];
+			}
 
-			} while ( key !== undefined );
+			key = jsonKeys[ i ++ ];
 
-		}
+		} while ( key !== undefined );
 
-	},
+	}
 
-	subclip: function ( sourceClip, name, startFrame, endFrame, fps = 30 ) {
+}
 
-		const clip = sourceClip.clone();
+function subclip( sourceClip, name, startFrame, endFrame, fps = 30 ) {
 
-		clip.name = name;
+	const clip = sourceClip.clone();
 
-		const tracks = [];
+	clip.name = name;
 
-		for ( let i = 0; i < clip.tracks.length; ++ i ) {
+	const tracks = [];
 
-			const track = clip.tracks[ i ];
-			const valueSize = track.getValueSize();
+	for ( let i = 0; i < clip.tracks.length; ++ i ) {
 
-			const times = [];
-			const values = [];
+		const track = clip.tracks[ i ];
+		const valueSize = track.getValueSize();
 
-			for ( let j = 0; j < track.times.length; ++ j ) {
+		const times = [];
+		const values = [];
 
-				const frame = track.times[ j ] * fps;
+		for ( let j = 0; j < track.times.length; ++ j ) {
 
-				if ( frame < startFrame || frame >= endFrame ) continue;
+			const frame = track.times[ j ] * fps;
 
-				times.push( track.times[ j ] );
+			if ( frame < startFrame || frame >= endFrame ) continue;
 
-				for ( let k = 0; k < valueSize; ++ k ) {
+			times.push( track.times[ j ] );
 
-					values.push( track.values[ j * valueSize + k ] );
+			for ( let 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 );
+		if ( times.length === 0 ) continue;
 
-			tracks.push( track );
+		track.times = convertArray( times, track.times.constructor );
+		track.values = convertArray( values, track.values.constructor );
 
-		}
+		tracks.push( track );
 
-		clip.tracks = tracks;
+	}
 
-		// find minimum .times value across all tracks in the trimmed clip
+	clip.tracks = tracks;
 
-		let minStartTime = Infinity;
+	// find minimum .times value across all tracks in the trimmed clip
 
-		for ( let i = 0; i < clip.tracks.length; ++ i ) {
+	let minStartTime = Infinity;
 
-			if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) {
+	for ( let i = 0; i < clip.tracks.length; ++ i ) {
 
-				minStartTime = clip.tracks[ i ].times[ 0 ];
+		if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) {
 
-			}
+			minStartTime = clip.tracks[ i ].times[ 0 ];
 
 		}
 
-		// shift all tracks such that clip begins at t=0
+	}
 
-		for ( let i = 0; i < clip.tracks.length; ++ i ) {
+	// shift all tracks such that clip begins at t=0
 
-			clip.tracks[ i ].shift( - 1 * minStartTime );
+	for ( let i = 0; i < clip.tracks.length; ++ i ) {
 
-		}
+		clip.tracks[ i ].shift( - 1 * minStartTime );
 
-		clip.resetDuration();
+	}
 
-		return clip;
+	clip.resetDuration();
 
-	},
+	return clip;
 
-	makeClipAdditive: function ( targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30 ) {
+}
 
-		if ( fps <= 0 ) fps = 30;
+function makeClipAdditive( targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30 ) {
 
-		const numTracks = referenceClip.tracks.length;
-		const referenceTime = referenceFrame / fps;
+	if ( fps <= 0 ) fps = 30;
 
-		// Make each track's values relative to the values at the reference frame
-		for ( let i = 0; i < numTracks; ++ i ) {
+	const numTracks = referenceClip.tracks.length;
+	const referenceTime = referenceFrame / fps;
 
-			const referenceTrack = referenceClip.tracks[ i ];
-			const referenceTrackType = referenceTrack.ValueTypeName;
+	// Make each track's values relative to the values at the reference frame
+	for ( let i = 0; i < numTracks; ++ i ) {
 
-			// Skip this track if it's non-numeric
-			if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) continue;
+		const referenceTrack = referenceClip.tracks[ i ];
+		const referenceTrackType = referenceTrack.ValueTypeName;
 
-			// Find the track in the target clip whose name and type matches the reference track
-			const targetTrack = targetClip.tracks.find( function ( track ) {
+		// Skip this track if it's non-numeric
+		if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) continue;
 
-				return track.name === referenceTrack.name
-					&& track.ValueTypeName === referenceTrackType;
+		// Find the track in the target clip whose name and type matches the reference track
+		const targetTrack = targetClip.tracks.find( function ( track ) {
 
-			} );
+			return track.name === referenceTrack.name
+				&& track.ValueTypeName === referenceTrackType;
 
-			if ( targetTrack === undefined ) continue;
+		} );
 
-			let referenceOffset = 0;
-			const referenceValueSize = referenceTrack.getValueSize();
+		if ( targetTrack === undefined ) continue;
 
-			if ( referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
+		let referenceOffset = 0;
+		const referenceValueSize = referenceTrack.getValueSize();
 
-				referenceOffset = referenceValueSize / 3;
+		if ( referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
 
-			}
+			referenceOffset = referenceValueSize / 3;
 
-			let targetOffset = 0;
-			const targetValueSize = targetTrack.getValueSize();
+		}
 
-			if ( targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
+		let targetOffset = 0;
+		const targetValueSize = targetTrack.getValueSize();
 
-				targetOffset = targetValueSize / 3;
+		if ( targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
 
-			}
+			targetOffset = targetValueSize / 3;
 
-			const lastIndex = referenceTrack.times.length - 1;
-			let referenceValue;
+		}
 
-			// Find the value to subtract out of the track
-			if ( referenceTime <= referenceTrack.times[ 0 ] ) {
+		const lastIndex = referenceTrack.times.length - 1;
+		let referenceValue;
 
-				// Reference frame is earlier than the first keyframe, so just use the first keyframe
-				const startIndex = referenceOffset;
-				const endIndex = referenceValueSize - referenceOffset;
-				referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex, endIndex );
+		// Find the value to subtract out of the track
+		if ( referenceTime <= referenceTrack.times[ 0 ] ) {
 
-			} else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) {
+			// Reference frame is earlier than the first keyframe, so just use the first keyframe
+			const startIndex = referenceOffset;
+			const endIndex = referenceValueSize - referenceOffset;
+			referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex );
 
-				// Reference frame is after the last keyframe, so just use the last keyframe
-				const startIndex = lastIndex * referenceValueSize + referenceOffset;
-				const endIndex = startIndex + referenceValueSize - referenceOffset;
-				referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex, endIndex );
+		} else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) {
 
-			} else {
+			// Reference frame is after the last keyframe, so just use the last keyframe
+			const startIndex = lastIndex * referenceValueSize + referenceOffset;
+			const endIndex = startIndex + referenceValueSize - referenceOffset;
+			referenceValue = arraySlice( referenceTrack.values, startIndex, endIndex );
 
-				// Interpolate to the reference value
-				const interpolant = referenceTrack.createInterpolant();
-				const startIndex = referenceOffset;
-				const endIndex = referenceValueSize - referenceOffset;
-				interpolant.evaluate( referenceTime );
-				referenceValue = AnimationUtils.arraySlice( interpolant.resultBuffer, startIndex, endIndex );
+		} else {
 
-			}
+			// Interpolate to the reference value
+			const interpolant = referenceTrack.createInterpolant();
+			const startIndex = referenceOffset;
+			const endIndex = referenceValueSize - referenceOffset;
+			interpolant.evaluate( referenceTime );
+			referenceValue = arraySlice( interpolant.resultBuffer, startIndex, endIndex );
 
-			// Conjugate the quaternion
-			if ( referenceTrackType === 'quaternion' ) {
+		}
 
-				const referenceQuat = new Quaternion().fromArray( referenceValue ).normalize().conjugate();
-				referenceQuat.toArray( referenceValue );
+		// Conjugate the quaternion
+		if ( referenceTrackType === 'quaternion' ) {
 
-			}
+			const referenceQuat = new Quaternion().fromArray( referenceValue ).normalize().conjugate();
+			referenceQuat.toArray( referenceValue );
 
-			// Subtract the reference value from all of the track values
+		}
 
-			const numTimes = targetTrack.times.length;
-			for ( let j = 0; j < numTimes; ++ j ) {
+		// Subtract the reference value from all of the track values
 
-				const valueStart = j * targetValueSize + targetOffset;
+		const numTimes = targetTrack.times.length;
+		for ( let j = 0; j < numTimes; ++ j ) {
 
-				if ( referenceTrackType === 'quaternion' ) {
+			const valueStart = j * targetValueSize + targetOffset;
 
-					// Multiply the conjugate for quaternion track types
-					Quaternion.multiplyQuaternionsFlat(
-						targetTrack.values,
-						valueStart,
-						referenceValue,
-						0,
-						targetTrack.values,
-						valueStart
-					);
+			if ( referenceTrackType === 'quaternion' ) {
 
-				} else {
+				// Multiply the conjugate for quaternion track types
+				Quaternion.multiplyQuaternionsFlat(
+					targetTrack.values,
+					valueStart,
+					referenceValue,
+					0,
+					targetTrack.values,
+					valueStart
+				);
 
-					const valueEnd = targetValueSize - targetOffset * 2;
+			} else {
 
-					// Subtract each value for all other numeric track types
-					for ( let k = 0; k < valueEnd; ++ k ) {
+				const valueEnd = targetValueSize - targetOffset * 2;
 
-						targetTrack.values[ valueStart + k ] -= referenceValue[ k ];
+				// Subtract each value for all other numeric track types
+				for ( let k = 0; k < valueEnd; ++ k ) {
 
-					}
+					targetTrack.values[ valueStart + k ] -= referenceValue[ k ];
 
 				}
 
@@ -345,12 +341,21 @@ const AnimationUtils = {
 
 		}
 
-		targetClip.blendMode = AdditiveAnimationBlendMode;
+	}
+
+	targetClip.blendMode = AdditiveAnimationBlendMode;
 
-		return targetClip;
+	return targetClip;
 
-	}
+}
 
+export {
+	arraySlice,
+	convertArray,
+	isTypedArray,
+	getKeyframeOrder,
+	sortedArray,
+	flattenJSON,
+	subclip,
+	makeClipAdditive
 };
-
-export { AnimationUtils };

+ 1 - 1
src/animation/KeyframeTrack.js

@@ -6,7 +6,7 @@ import {
 import { CubicInterpolant } from '../math/interpolants/CubicInterpolant.js';
 import { LinearInterpolant } from '../math/interpolants/LinearInterpolant.js';
 import { DiscreteInterpolant } from '../math/interpolants/DiscreteInterpolant.js';
-import { AnimationUtils } from './AnimationUtils.js';
+import * as AnimationUtils from './AnimationUtils.js';
 
 class KeyframeTrack {
 

+ 1 - 1
test/unit/src/animation/AnimationUtils.tests.js

@@ -1,6 +1,6 @@
 /* global QUnit */
 
-// import { AnimationUtils } from '../../../../src/animation/AnimationUtils.js';
+// import * as AnimationUtils from '../../../../src/animation/AnimationUtils.js';
 
 export default QUnit.module( 'Animation', () => {