Skip to content

Commit 533ab8a

Browse files
authored
Merge pull request #14345 from donmccurdy/animation-optimize-optout
AnimationMixer: Move validate/optimization call, allow opt-out.
2 parents 30bfaa8 + 65deb93 commit 533ab8a

File tree

7 files changed

+82
-11
lines changed

7 files changed

+82
-11
lines changed

docs/api/animation/AnimationClip.html

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ <h3>[property:Number duration]</h3>
4646
array via [page:.resetDuration resetDuration].
4747
</p>
4848

49+
<h3>[property:Boolean isOptimized]</h3>
50+
<p>
51+
Whether the clip has been optimized with .optimize().
52+
</p>
53+
54+
<h3>[property:Boolean isValidated]</h3>
55+
<p>
56+
Whether the clip has been validated with .validate().
57+
</p>
58+
4959
<h3>[property:String name]</h3>
5060
<p>
5161
A name for this clip. A certain clip can be searched via [page:.findByName findByName].
@@ -69,7 +79,8 @@ <h2>Methods</h2>
6979
<h3>[method:AnimationClip optimize]()</h3>
7080
<p>
7181
Optimizes each track by removing equivalent sequential keys (which are common in morph target
72-
sequences).
82+
sequences). Called automatically by [page:AnimationMixer]'s clipAction() method. Calling this
83+
method will set [page:.isValidated isValidated] to true, and additional calls will do nothing.
7384
</p>
7485

7586
<h3>[method:null resetDuration]()</h3>
@@ -83,6 +94,13 @@ <h3>[method:AnimationClip trim]()</h3>
8394
Trims all tracks to the clip's duration.
8495
</p>
8596

97+
<h3>[method:AnimationClip validate]()</h3>
98+
<p>
99+
Performs minimal validation on each track in the clip. Called automatically by
100+
[page:AnimationMixer]'s clipAction() method. Calling this method will set
101+
[page:.isValidated isValidated] to true, and additional calls will do nothing.
102+
</p>
103+
86104

87105
<h2>Static Methods</h2>
88106

docs/api/animation/AnimationMixer.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ <h3>[method:AnimationAction clipAction]([param:AnimationClip clip], [param:Objec
5555
from the mixer's default root. The first parameter can be either an [page:AnimationClip] object
5656
or the name of an AnimationClip.<br /><br />
5757

58+
Automatically calls .validate() and .optimize() on the clip.<br /><br />
59+
5860
If an action fitting these parameters doesn't yet exist, it will be created by this method.<br /><br />
5961

6062
Note: Calling this method several times with the same parameters returns always the same clip

docs/api/animation/KeyframeTrack.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ <h3>[method:null InterpolantFactoryMethodSmooth]( [link:https://developer.mozill
204204

205205
<h3>[method:null optimize]()</h3>
206206
<p>
207-
Removes equivalent sequential keys, which are common in morph target sequences. Called
208-
automatically by the constructor.
207+
Removes equivalent sequential keys, which are common in morph target sequences. Calling this
208+
method will set [page:.isOptimized isOptimized] to true, and additional calls will do nothing.
209209
</p>
210210

211211
<h3>[method:null scale]()</h3>
@@ -236,7 +236,7 @@ <h3>[method:null trim]( [param:Number startTimeInSeconds], [param:Number endTime
236236

237237
<h3>[method:null validate]()</h3>
238238
<p>
239-
Performs minimal validation on the tracks. Called automatically by the constructor.<br /><br />
239+
Performs minimal validation on the tracks.<br /><br />
240240
This method logs errors to the console, if a track is empty, if the [page:.valueSize value size] is not valid, if an item
241241
in the [page:.times times] or [page:.values values] array is not a valid number or if the items in the *times* array are out of order.
242242
</p>

src/animation/AnimationClip.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ function AnimationClip( name, duration, tracks ) {
1919
this.tracks = tracks;
2020
this.duration = ( duration !== undefined ) ? duration : - 1;
2121

22+
this.isValidated = false;
23+
this.isOptimized = false;
24+
2225
this.uuid = _Math.generateUUID();
2326

2427
// this means it should figure out its duration by scanning the tracks
@@ -28,8 +31,6 @@ function AnimationClip( name, duration, tracks ) {
2831

2932
}
3033

31-
this.optimize();
32-
3334
}
3435

3536
Object.assign( AnimationClip, {
@@ -341,14 +342,34 @@ Object.assign( AnimationClip.prototype, {
341342

342343
},
343344

345+
validate: function () {
346+
347+
if ( this.isValidated ) return this;
348+
349+
for ( var i = 0; i < this.tracks.length; i ++ ) {
350+
351+
this.tracks[ i ].validate();
352+
353+
}
354+
355+
this.isValidated = true;
356+
357+
return this;
358+
359+
},
360+
344361
optimize: function () {
345362

363+
if ( this.isOptimized ) return this;
364+
346365
for ( var i = 0; i < this.tracks.length; i ++ ) {
347366

348367
this.tracks[ i ].optimize();
349368

350369
}
351370

371+
this.isOptimized = true;
372+
352373
return this;
353374

354375
}

src/animation/AnimationMixer.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,9 @@ AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototy
555555
// clip must be known when specified via string
556556
if ( clipObject === null ) return null;
557557

558+
clipObject.validate();
559+
clipObject.optimize();
560+
558561
// allocate all resources required to run it
559562
var newAction = new AnimationAction( this, clipObject, optionalRoot );
560563

src/animation/KeyframeTrack.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ function KeyframeTrack( name, times, values, interpolation ) {
3636

3737
this.setInterpolation( interpolation || this.DefaultInterpolation );
3838

39-
this.validate();
40-
this.optimize();
41-
4239
}
4340

4441
// Static methods:

test/unit/src/animation/AnimationClip.tests.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
/* global QUnit */
55

66
import { AnimationClip } from '../../../../src/animation/AnimationClip';
7+
import { NumberKeyframeTrack } from '../../../../src/animation/tracks/NumberKeyframeTrack';
78

89
export default QUnit.module( 'Animation', () => {
910

@@ -66,9 +67,38 @@ export default QUnit.module( 'Animation', () => {
6667

6768
} );
6869

69-
QUnit.todo( "optimize", ( assert ) => {
70+
QUnit.test( 'optimize', ( assert ) => {
7071

71-
assert.ok( false, "everything's gonna be alright" );
72+
var track = new NumberKeyframeTrack( '.material.opacity', [ 0, 1, 2, 3, 4 ], [ 0, 0, 0, 0, 1 ] );
73+
var clip = new AnimationClip( 'fadeIn', 4, [ track ] );
74+
75+
assert.equal( clip.tracks[0].values.length, 5 );
76+
77+
clip.isOptimized = true;
78+
clip.optimize();
79+
80+
assert.equal( clip.tracks[0].values.length, 5 );
81+
82+
clip.isOptimized = false;
83+
clip.optimize();
84+
85+
assert.equal( clip.tracks[0].values.length, 3 );
86+
87+
} );
88+
89+
QUnit.test( 'validate', ( assert ) => {
90+
91+
var track = new NumberKeyframeTrack( '.material.opacity', [ 0, 1 ], [ 0, NaN ] );
92+
var clip = new AnimationClip( 'fadeIn', 1, [ track ] );
93+
94+
track.validate = () => { throw new Error('Validation should not be called.') };
95+
clip.isValidated = true;
96+
clip.validate();
97+
98+
delete track.validate;
99+
clip.isValidated = false;
100+
clip.validate();
101+
assert.ok( clip.isValidated );
72102

73103
} );
74104

0 commit comments

Comments
 (0)