Skip to content

Commit 245dc45

Browse files
authored
Tests: Add unit test for custom interpolant. (#33480)
1 parent bbc428c commit 245dc45

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { Interpolant } from '../../../../../src/math/Interpolant.js';
2+
3+
export default QUnit.module( 'Maths', () => {
4+
5+
QUnit.module( 'Interpolants', () => {
6+
7+
QUnit.module( 'CustomInterpolant', () => {
8+
9+
// A custom cubic spline interpolant mimicking `GLTFCubicSplineInterpolant`
10+
// from `GLTFLoader`. The keyframe layout for CUBICSPLINE animations is:
11+
// [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
12+
13+
class CubicSplineInterpolant extends Interpolant {
14+
15+
constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
16+
17+
super( parameterPositions, sampleValues, sampleSize, resultBuffer );
18+
19+
}
20+
21+
copySampleValue_( index ) {
22+
23+
const result = this.resultBuffer,
24+
values = this.sampleValues,
25+
valueSize = this.valueSize,
26+
offset = index * valueSize * 3 + valueSize;
27+
28+
for ( let i = 0; i !== valueSize; i ++ ) {
29+
30+
result[ i ] = values[ offset + i ];
31+
32+
}
33+
34+
return result;
35+
36+
}
37+
38+
interpolate_( i1, t0, t, t1 ) {
39+
40+
const result = this.resultBuffer;
41+
const values = this.sampleValues;
42+
const stride = this.valueSize;
43+
44+
const stride2 = stride * 2;
45+
const stride3 = stride * 3;
46+
47+
const td = t1 - t0;
48+
49+
const p = ( t - t0 ) / td;
50+
const pp = p * p;
51+
const ppp = pp * p;
52+
53+
const offset1 = i1 * stride3;
54+
const offset0 = offset1 - stride3;
55+
56+
const s2 = - 2 * ppp + 3 * pp;
57+
const s3 = ppp - pp;
58+
const s0 = 1 - s2;
59+
const s1 = s3 - pp + p;
60+
61+
for ( let i = 0; i !== stride; i ++ ) {
62+
63+
const p0 = values[ offset0 + i + stride ];
64+
const m0 = values[ offset0 + i + stride2 ] * td;
65+
const p1 = values[ offset1 + i + stride ];
66+
const m1 = values[ offset1 + i ] * td;
67+
68+
result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
69+
70+
}
71+
72+
return result;
73+
74+
}
75+
76+
}
77+
78+
// INHERITANCE
79+
QUnit.test( 'Extending', ( assert ) => {
80+
81+
// parameterPositions, sampleValues, sampleSize, resultBuffer
82+
const object = new CubicSplineInterpolant( [ 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], 1, [] );
83+
assert.strictEqual(
84+
object instanceof Interpolant, true,
85+
'CubicSplineInterpolant extends from Interpolant'
86+
);
87+
88+
} );
89+
90+
// PUBLIC
91+
QUnit.test( 'evaluate', ( assert ) => {
92+
93+
// Two keyframes at t = 0 and t = 1, valueSize = 1.
94+
// Layout: [ in_0, v_0, out_0, in_1, v_1, out_1 ]
95+
// Vertex values 0 -> 1 with non-zero tangents to exercise all spline terms.
96+
const positions = [ 0, 1 ];
97+
const values = [ 0, 0, 1, - 1, 1, 0 ];
98+
const interpolant = new CubicSplineInterpolant( positions, values, 1, [ 0 ] );
99+
100+
assert.deepEqual( interpolant.evaluate( 0 ), [ 0 ], 'evaluate at first keyframe' );
101+
assert.deepEqual( interpolant.evaluate( 1 ), [ 1 ], 'evaluate at last keyframe' );
102+
103+
// At t = 0.5 with td = 1, p = 0.5 → s0 = 0.5, s1 = 0.125, s2 = 0.5, s3 = -0.125
104+
// result = 0.5 * 0 + 0.125 * 1 + 0.5 * 1 + ( -0.125 ) * ( -1 ) = 0.75
105+
assert.deepEqual( interpolant.evaluate( 0.5 ), [ 0.75 ], 'evaluate inside interval' );
106+
107+
// Out-of-range queries clamp to the boundary spline vertex.
108+
assert.deepEqual( interpolant.evaluate( - 1 ), [ 0 ], 'evaluate before first keyframe' );
109+
assert.deepEqual( interpolant.evaluate( 2 ), [ 1 ], 'evaluate after last keyframe' );
110+
111+
} );
112+
113+
} );
114+
115+
} );
116+
117+
} );

test/unit/three.source.unit.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ import './src/math/Vector4.tests.js';
208208

209209
//src/math/interpolants
210210
import './src/math/interpolants/CubicInterpolant.tests.js';
211+
import './src/math/interpolants/CustomInterpolant.tests.js';
211212
import './src/math/interpolants/DiscreteInterpolant.tests.js';
212213
import './src/math/interpolants/LinearInterpolant.tests.js';
213214
import './src/math/interpolants/QuaternionLinearInterpolant.tests.js';

0 commit comments

Comments
 (0)