@@ -9,15 +9,62 @@ import { VectorKeyframeTrack } from './tracks/VectorKeyframeTrack.js';
9
9
import { generateUUID } from '../math/MathUtils.js' ;
10
10
import { NormalAnimationBlendMode } from '../constants.js' ;
11
11
12
+ /**
13
+ * A reusable set of keyframe tracks which represent an animation.
14
+ */
12
15
class AnimationClip {
13
16
17
+ /**
18
+ * Constructs a new animation clip.
19
+ *
20
+ * Note: Instead of instantiating an AnimationClip directly with the constructor, you can
21
+ * use the static interface of this class for creating clips. In most cases though, animation clips
22
+ * will automatically be created by loaders when importing animated 3D assets.
23
+ *
24
+ * @param {string } [name=''] - The clip's name.
25
+ * @param {number } [duration=-1] - The clip's duration in seconds. If a negative value is passed,
26
+ * the duration will be calculated from the passed keyframes.
27
+ * @param {Array<KeyframeTrack> } tracks - An array of keyframe tracks.
28
+ * @param {(NormalAnimationBlendMode|AdditiveAnimationBlendMode) } [blendMode=NormalAnimationBlendMode] - Defines how the animation
29
+ * is blended/combined when two or more animations are simultaneously played.
30
+ */
14
31
constructor ( name = '' , duration = - 1 , tracks = [ ] , blendMode = NormalAnimationBlendMode ) {
15
32
33
+ /**
34
+ * The clip's name.
35
+ *
36
+ * @type {string }
37
+ */
16
38
this . name = name ;
39
+
40
+ /**
41
+ * An array of keyframe tracks.
42
+ *
43
+ * @type {Array<KeyframeTrack> }
44
+ */
17
45
this . tracks = tracks ;
46
+
47
+ /**
48
+ * The clip's duration in seconds.
49
+ *
50
+ * @type {number }
51
+ */
18
52
this . duration = duration ;
53
+
54
+ /**
55
+ * Defines how the animation is blended/combined when two or more animations
56
+ * are simultaneously played.
57
+ *
58
+ * @type {(NormalAnimationBlendMode|AdditiveAnimationBlendMode) }
59
+ */
19
60
this . blendMode = blendMode ;
20
61
62
+ /**
63
+ * The UUID of the animation clip.
64
+ *
65
+ * @type {string }
66
+ * @readonly
67
+ */
21
68
this . uuid = generateUUID ( ) ;
22
69
23
70
// this means it should figure out its duration by scanning the tracks
@@ -29,7 +76,13 @@ class AnimationClip {
29
76
30
77
}
31
78
32
-
79
+ /**
80
+ * Factory method for creating an animation clip from the given JSON.
81
+ *
82
+ * @static
83
+ * @param {Object } json - The serialized animation clip.
84
+ * @return {AnimationClip } The new animation clip.
85
+ */
33
86
static parse ( json ) {
34
87
35
88
const tracks = [ ] ,
@@ -49,6 +102,13 @@ class AnimationClip {
49
102
50
103
}
51
104
105
+ /**
106
+ * Serializes the given animation clip into JSON.
107
+ *
108
+ * @static
109
+ * @param {AnimationClip } clip - The animation clip to serialize.
110
+ * @return {Object } The JSON object.
111
+ */
52
112
static toJSON ( clip ) {
53
113
54
114
const tracks = [ ] ,
@@ -74,6 +134,20 @@ class AnimationClip {
74
134
75
135
}
76
136
137
+ /**
138
+ * Returns a new animation clip from the passed morph targets array of a
139
+ * geometry, taking a name and the number of frames per second.
140
+ *
141
+ * Note: The fps parameter is required, but the animation speed can be
142
+ * overridden via {@link AnimationAction#setDuration}.
143
+ *
144
+ * @static
145
+ * @param {string } name - The name of the animation clip.
146
+ * @param {Array<Object> } morphTargetSequence - A sequence of morph targets.
147
+ * @param {number } fps - The Frames-Per-Second value.
148
+ * @param {boolean } noLoop - Whether the clip should be no loop or not.
149
+ * @return {AnimationClip } The new animation clip.
150
+ */
77
151
static CreateFromMorphTargetSequence ( name , morphTargetSequence , fps , noLoop ) {
78
152
79
153
const numMorphTargets = morphTargetSequence . length ;
@@ -116,6 +190,16 @@ class AnimationClip {
116
190
117
191
}
118
192
193
+ /**
194
+ * Searches for an animation clip by name, taking as its first parameter
195
+ * either an array of clips, or a mesh or geometry that contains an
196
+ * array named "animations" property.
197
+ *
198
+ * @static
199
+ * @param {(Array<AnimationClip>|Object3D) } objectOrClipArray - The array or object to search through.
200
+ * @param {string } name - The name to search for.
201
+ * @return {?AnimationClip } The found animation clip. Returns `null` if no clip has been found.
202
+ */
119
203
static findByName ( objectOrClipArray , name ) {
120
204
121
205
let clipArray = objectOrClipArray ;
@@ -141,6 +225,19 @@ class AnimationClip {
141
225
142
226
}
143
227
228
+ /**
229
+ * Returns an array of new AnimationClips created from the morph target
230
+ * sequences of a geometry, trying to sort morph target names into
231
+ * animation-group-based patterns like "Walk_001, Walk_002, Run_001, Run_002...".
232
+ *
233
+ * See {@link MD2Loader#parse} as an example for how the method should be used.
234
+ *
235
+ * @static
236
+ * @param {Array<Object> } morphTargets - A sequence of morph targets.
237
+ * @param {number } fps - The Frames-Per-Second value.
238
+ * @param {boolean } noLoop - Whether the clip should be no loop or not.
239
+ * @return {Array<AnimationClip> } An array of new animation clips.
240
+ */
144
241
static CreateClipsFromMorphTargetSequences ( morphTargets , fps , noLoop ) {
145
242
146
243
const animationToMorphTargets = { } ;
@@ -186,7 +283,14 @@ class AnimationClip {
186
283
187
284
}
188
285
189
- // parse the animation.hierarchy format
286
+ /**
287
+ * Parses the `animation.hierarchy` format and returns a new animation clip.
288
+ *
289
+ * @static
290
+ * @param {Object } animation - A serialized animation clip as JSON.
291
+ * @param {Array<Bones> } bones - An array of bones.
292
+ * @return {AnimationClip } The new animation clip.
293
+ */
190
294
static parseAnimation ( animation , bones ) {
191
295
192
296
if ( ! animation ) {
@@ -314,6 +418,11 @@ class AnimationClip {
314
418
315
419
}
316
420
421
+ /**
422
+ * Sets the duration of this clip to the duration of its longest keyframe track.
423
+ *
424
+ * @return {AnimationClip } A reference to this animation clip.
425
+ */
317
426
resetDuration ( ) {
318
427
319
428
const tracks = this . tracks ;
@@ -333,6 +442,11 @@ class AnimationClip {
333
442
334
443
}
335
444
445
+ /**
446
+ * Trims all tracks to the clip's duration.
447
+ *
448
+ * @return {AnimationClip } A reference to this animation clip.
449
+ */
336
450
trim ( ) {
337
451
338
452
for ( let i = 0 ; i < this . tracks . length ; i ++ ) {
@@ -345,6 +459,12 @@ class AnimationClip {
345
459
346
460
}
347
461
462
+ /**
463
+ * Performs minimal validation on each track in the clip. Returns `true` if all
464
+ * tracks are valid.
465
+ *
466
+ * @return {boolean } Whether the clip's keyframes are valid or not.
467
+ */
348
468
validate ( ) {
349
469
350
470
let valid = true ;
@@ -359,6 +479,12 @@ class AnimationClip {
359
479
360
480
}
361
481
482
+ /**
483
+ * Optimizes each track by removing equivalent sequential keys (which are
484
+ * common in morph target sequences).
485
+ *
486
+ * @return {AnimationClip } A reference to this animation clip.
487
+ */
362
488
optimize ( ) {
363
489
364
490
for ( let i = 0 ; i < this . tracks . length ; i ++ ) {
@@ -371,6 +497,11 @@ class AnimationClip {
371
497
372
498
}
373
499
500
+ /**
501
+ * Returns a new animation clip with copied values from this instance.
502
+ *
503
+ * @return {AnimationClip } A clone of this instance.
504
+ */
374
505
clone ( ) {
375
506
376
507
const tracks = [ ] ;
@@ -385,6 +516,11 @@ class AnimationClip {
385
516
386
517
}
387
518
519
+ /**
520
+ * Serializes this animation clip into JSON.
521
+ *
522
+ * @return {Object } The JSON object.
523
+ */
388
524
toJSON ( ) {
389
525
390
526
return this . constructor . toJSON ( this ) ;
0 commit comments