|
@@ -9,104 +9,28 @@ import { VectorKeyframeTrack } from './tracks/VectorKeyframeTrack.js';
|
|
|
import { MathUtils } from '../math/MathUtils.js';
|
|
|
import { NormalAnimationBlendMode } from '../constants.js';
|
|
|
|
|
|
-function AnimationClip( name, duration = - 1, tracks, blendMode = NormalAnimationBlendMode ) {
|
|
|
+class AnimationClip {
|
|
|
|
|
|
- this.name = name;
|
|
|
- this.tracks = tracks;
|
|
|
- this.duration = duration;
|
|
|
- this.blendMode = blendMode;
|
|
|
+ constructor( name, duration = - 1, tracks, blendMode = NormalAnimationBlendMode ) {
|
|
|
|
|
|
- this.uuid = MathUtils.generateUUID();
|
|
|
-
|
|
|
- // this means it should figure out its duration by scanning the tracks
|
|
|
- if ( this.duration < 0 ) {
|
|
|
-
|
|
|
- this.resetDuration();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-function getTrackTypeForValueTypeName( typeName ) {
|
|
|
-
|
|
|
- switch ( typeName.toLowerCase() ) {
|
|
|
-
|
|
|
- case 'scalar':
|
|
|
- case 'double':
|
|
|
- case 'float':
|
|
|
- case 'number':
|
|
|
- case 'integer':
|
|
|
-
|
|
|
- return NumberKeyframeTrack;
|
|
|
-
|
|
|
- case 'vector':
|
|
|
- case 'vector2':
|
|
|
- case 'vector3':
|
|
|
- case 'vector4':
|
|
|
-
|
|
|
- return VectorKeyframeTrack;
|
|
|
-
|
|
|
- case 'color':
|
|
|
-
|
|
|
- return ColorKeyframeTrack;
|
|
|
-
|
|
|
- case 'quaternion':
|
|
|
-
|
|
|
- return QuaternionKeyframeTrack;
|
|
|
-
|
|
|
- case 'bool':
|
|
|
- case 'boolean':
|
|
|
-
|
|
|
- return BooleanKeyframeTrack;
|
|
|
-
|
|
|
- case 'string':
|
|
|
-
|
|
|
- return StringKeyframeTrack;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName );
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-function parseKeyframeTrack( json ) {
|
|
|
-
|
|
|
- if ( json.type === undefined ) {
|
|
|
-
|
|
|
- throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- const trackType = getTrackTypeForValueTypeName( json.type );
|
|
|
-
|
|
|
- if ( json.times === undefined ) {
|
|
|
-
|
|
|
- const times = [], values = [];
|
|
|
-
|
|
|
- AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
|
|
|
-
|
|
|
- json.times = times;
|
|
|
- json.values = values;
|
|
|
+ this.name = name;
|
|
|
+ this.tracks = tracks;
|
|
|
+ this.duration = duration;
|
|
|
+ this.blendMode = blendMode;
|
|
|
|
|
|
- }
|
|
|
+ this.uuid = MathUtils.generateUUID();
|
|
|
|
|
|
- // derived classes can define a static parse method
|
|
|
- if ( trackType.parse !== undefined ) {
|
|
|
+ // this means it should figure out its duration by scanning the tracks
|
|
|
+ if ( this.duration < 0 ) {
|
|
|
|
|
|
- return trackType.parse( json );
|
|
|
+ this.resetDuration();
|
|
|
|
|
|
- } else {
|
|
|
-
|
|
|
- // by default, we assume a constructor compatible with the base
|
|
|
- return new trackType( json.name, json.times, json.values, json.interpolation );
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
-}
|
|
|
-
|
|
|
-Object.assign( AnimationClip, {
|
|
|
|
|
|
- parse: function ( json ) {
|
|
|
+ static parse( json ) {
|
|
|
|
|
|
const tracks = [],
|
|
|
jsonTracks = json.tracks,
|
|
@@ -118,14 +42,14 @@ Object.assign( AnimationClip, {
|
|
|
|
|
|
}
|
|
|
|
|
|
- const clip = new AnimationClip( json.name, json.duration, tracks, json.blendMode );
|
|
|
+ const clip = new this( json.name, json.duration, tracks, json.blendMode );
|
|
|
clip.uuid = json.uuid;
|
|
|
|
|
|
return clip;
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
- toJSON: function ( clip ) {
|
|
|
+ static toJSON( clip ) {
|
|
|
|
|
|
const tracks = [],
|
|
|
clipTracks = clip.tracks;
|
|
@@ -148,9 +72,9 @@ Object.assign( AnimationClip, {
|
|
|
|
|
|
return json;
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
- CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) {
|
|
|
+ static CreateFromMorphTargetSequence( name, morphTargetSequence, fps, noLoop ) {
|
|
|
|
|
|
const numMorphTargets = morphTargetSequence.length;
|
|
|
const tracks = [];
|
|
@@ -188,11 +112,11 @@ Object.assign( AnimationClip, {
|
|
|
|
|
|
}
|
|
|
|
|
|
- return new AnimationClip( name, - 1, tracks );
|
|
|
+ return new this( name, - 1, tracks );
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
- findByName: function ( objectOrClipArray, name ) {
|
|
|
+ static findByName( objectOrClipArray, name ) {
|
|
|
|
|
|
let clipArray = objectOrClipArray;
|
|
|
|
|
@@ -215,9 +139,9 @@ Object.assign( AnimationClip, {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
- CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) {
|
|
|
+ static CreateClipsFromMorphTargetSequences( morphTargets, fps, noLoop ) {
|
|
|
|
|
|
const animationToMorphTargets = {};
|
|
|
|
|
@@ -254,16 +178,16 @@ Object.assign( AnimationClip, {
|
|
|
|
|
|
for ( const name in animationToMorphTargets ) {
|
|
|
|
|
|
- clips.push( AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );
|
|
|
+ clips.push( this.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
return clips;
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
// parse the animation.hierarchy format
|
|
|
- parseAnimation: function ( animation, bones ) {
|
|
|
+ static parseAnimation( animation, bones ) {
|
|
|
|
|
|
if ( ! animation ) {
|
|
|
|
|
@@ -384,17 +308,13 @@ Object.assign( AnimationClip, {
|
|
|
|
|
|
}
|
|
|
|
|
|
- const clip = new AnimationClip( clipName, duration, tracks, blendMode );
|
|
|
+ const clip = new this( clipName, duration, tracks, blendMode );
|
|
|
|
|
|
return clip;
|
|
|
|
|
|
}
|
|
|
|
|
|
-} );
|
|
|
-
|
|
|
-Object.assign( AnimationClip.prototype, {
|
|
|
-
|
|
|
- resetDuration: function () {
|
|
|
+ resetDuration() {
|
|
|
|
|
|
const tracks = this.tracks;
|
|
|
let duration = 0;
|
|
@@ -411,9 +331,9 @@ Object.assign( AnimationClip.prototype, {
|
|
|
|
|
|
return this;
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
- trim: function () {
|
|
|
+ trim() {
|
|
|
|
|
|
for ( let i = 0; i < this.tracks.length; i ++ ) {
|
|
|
|
|
@@ -423,9 +343,9 @@ Object.assign( AnimationClip.prototype, {
|
|
|
|
|
|
return this;
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
- validate: function () {
|
|
|
+ validate() {
|
|
|
|
|
|
let valid = true;
|
|
|
|
|
@@ -437,9 +357,9 @@ Object.assign( AnimationClip.prototype, {
|
|
|
|
|
|
return valid;
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
- optimize: function () {
|
|
|
+ optimize() {
|
|
|
|
|
|
for ( let i = 0; i < this.tracks.length; i ++ ) {
|
|
|
|
|
@@ -449,9 +369,9 @@ Object.assign( AnimationClip.prototype, {
|
|
|
|
|
|
return this;
|
|
|
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
- clone: function () {
|
|
|
+ clone() {
|
|
|
|
|
|
const tracks = [];
|
|
|
|
|
@@ -461,7 +381,7 @@ Object.assign( AnimationClip.prototype, {
|
|
|
|
|
|
}
|
|
|
|
|
|
- return new AnimationClip( this.name, this.duration, tracks, this.blendMode );
|
|
|
+ return new this.constructor( this.name, this.duration, tracks, this.blendMode );
|
|
|
|
|
|
},
|
|
|
|
|
@@ -471,7 +391,83 @@ Object.assign( AnimationClip.prototype, {
|
|
|
|
|
|
}
|
|
|
|
|
|
-} );
|
|
|
+}
|
|
|
+
|
|
|
+function getTrackTypeForValueTypeName( typeName ) {
|
|
|
+
|
|
|
+ switch ( typeName.toLowerCase() ) {
|
|
|
+
|
|
|
+ case 'scalar':
|
|
|
+ case 'double':
|
|
|
+ case 'float':
|
|
|
+ case 'number':
|
|
|
+ case 'integer':
|
|
|
+
|
|
|
+ return NumberKeyframeTrack;
|
|
|
+
|
|
|
+ case 'vector':
|
|
|
+ case 'vector2':
|
|
|
+ case 'vector3':
|
|
|
+ case 'vector4':
|
|
|
+
|
|
|
+ return VectorKeyframeTrack;
|
|
|
+
|
|
|
+ case 'color':
|
|
|
+
|
|
|
+ return ColorKeyframeTrack;
|
|
|
+
|
|
|
+ case 'quaternion':
|
|
|
+
|
|
|
+ return QuaternionKeyframeTrack;
|
|
|
+
|
|
|
+ case 'bool':
|
|
|
+ case 'boolean':
|
|
|
+
|
|
|
+ return BooleanKeyframeTrack;
|
|
|
+
|
|
|
+ case 'string':
|
|
|
+
|
|
|
+ return StringKeyframeTrack;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+function parseKeyframeTrack( json ) {
|
|
|
+
|
|
|
+ if ( json.type === undefined ) {
|
|
|
+
|
|
|
+ throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ const trackType = getTrackTypeForValueTypeName( json.type );
|
|
|
+
|
|
|
+ if ( json.times === undefined ) {
|
|
|
+
|
|
|
+ const times = [], values = [];
|
|
|
+
|
|
|
+ AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
|
|
|
+
|
|
|
+ json.times = times;
|
|
|
+ json.values = values;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // derived classes can define a static parse method
|
|
|
+ if ( trackType.parse !== undefined ) {
|
|
|
+
|
|
|
+ return trackType.parse( json );
|
|
|
+
|
|
|
+ } else {
|
|
|
|
|
|
+ // by default, we assume a constructor compatible with the base
|
|
|
+ return new trackType( json.name, json.times, json.values, json.interpolation );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
|
|
|
export { AnimationClip };
|