@babylonjs/core 6.20.0 → 6.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Animations/animation.d.ts +51 -3
- package/Animations/animation.js +92 -106
- package/Animations/animation.js.map +1 -1
- package/Animations/animationGroup.d.ts +60 -8
- package/Animations/animationGroup.js +132 -29
- package/Animations/animationGroup.js.map +1 -1
- package/Engines/Extensions/engine.query.js +1 -1
- package/Engines/Extensions/engine.query.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.query.js +1 -1
- package/Engines/WebGPU/Extensions/engine.query.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.renderTarget.js +3 -2
- package/Engines/WebGPU/Extensions/engine.renderTarget.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.renderTargetCube.js +2 -0
- package/Engines/WebGPU/Extensions/engine.renderTargetCube.js.map +1 -1
- package/Engines/WebGPU/webgpuOcclusionQuery.d.ts +3 -1
- package/Engines/WebGPU/webgpuOcclusionQuery.js +18 -6
- package/Engines/WebGPU/webgpuOcclusionQuery.js.map +1 -1
- package/Engines/WebGPU/webgpuQuerySet.d.ts +1 -1
- package/Engines/WebGPU/webgpuQuerySet.js +2 -1
- package/Engines/WebGPU/webgpuQuerySet.js.map +1 -1
- package/Engines/renderTargetWrapper.d.ts +6 -1
- package/Engines/renderTargetWrapper.js +3 -1
- package/Engines/renderTargetWrapper.js.map +1 -1
- package/Engines/thinEngine.js +2 -2
- package/Engines/thinEngine.js.map +1 -1
- package/Engines/webgpuEngine.js +5 -3
- package/Engines/webgpuEngine.js.map +1 -1
- package/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.js +1 -0
- package/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.js.map +1 -1
- package/Materials/Node/nodeMaterial.d.ts +4 -0
- package/Materials/Node/nodeMaterial.js +30 -20
- package/Materials/Node/nodeMaterial.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateBlock.js +5 -2
- package/Meshes/Node/Blocks/Instances/instantiateBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.js +10 -6
- package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.js +10 -6
- package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.js +10 -6
- package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setColorsBlock.js +9 -6
- package/Meshes/Node/Blocks/Set/setColorsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setMaterialIDBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/setMaterialIDBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setNormalsBlock.js +9 -6
- package/Meshes/Node/Blocks/Set/setNormalsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setPositionsBlock.js +7 -4
- package/Meshes/Node/Blocks/Set/setPositionsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setTangentsBlock.js +9 -6
- package/Meshes/Node/Blocks/Set/setTangentsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setUVsBlock.js +9 -6
- package/Meshes/Node/Blocks/Set/setUVsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/boxBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/boxBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/capsuleBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/capsuleBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/cylinderBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/cylinderBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/discBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/discBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/gridBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/gridBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/icoSphereBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/icoSphereBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/meshBlock.js +4 -1
- package/Meshes/Node/Blocks/Sources/meshBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/planeBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/planeBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/sphereBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/sphereBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/torusBlock.js +3 -1
- package/Meshes/Node/Blocks/Sources/torusBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryCollectionBlock.js +1 -0
- package/Meshes/Node/Blocks/geometryCollectionBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryOptimizeBlock.js +1 -0
- package/Meshes/Node/Blocks/geometryOptimizeBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryTransformBlock.js +1 -0
- package/Meshes/Node/Blocks/geometryTransformBlock.js.map +1 -1
- package/Meshes/Node/Blocks/matrixComposeBlock.js +4 -1
- package/Meshes/Node/Blocks/matrixComposeBlock.js.map +1 -1
- package/Meshes/Node/Blocks/mergeGeometryBlock.js +1 -0
- package/Meshes/Node/Blocks/mergeGeometryBlock.js.map +1 -1
- package/Meshes/Node/nodeGeometryBlock.js +10 -6
- package/Meshes/Node/nodeGeometryBlock.js.map +1 -1
- package/Meshes/Node/nodeGeometryBuildState.d.ts +37 -3
- package/Meshes/Node/nodeGeometryBuildState.js +64 -6
- package/Meshes/Node/nodeGeometryBuildState.js.map +1 -1
- package/Shaders/ShadersInclude/pbrDebug.js +3 -0
- package/Shaders/ShadersInclude/pbrDebug.js.map +1 -1
- package/package.json +1 -1
|
@@ -11,6 +11,41 @@ import type { IAnimatable } from "./animatable.interface";
|
|
|
11
11
|
import { Size } from "../Maths/math.size";
|
|
12
12
|
import type { Animatable } from "./animatable";
|
|
13
13
|
import type { RuntimeAnimation } from "./runtimeAnimation";
|
|
14
|
+
/**
|
|
15
|
+
* Options to be used when creating an additive animation
|
|
16
|
+
*/
|
|
17
|
+
export interface IMakeAnimationAdditiveOptions {
|
|
18
|
+
/**
|
|
19
|
+
* The frame that the animation should be relative to (if not provided, 0 will be used)
|
|
20
|
+
*/
|
|
21
|
+
referenceFrame?: number;
|
|
22
|
+
/**
|
|
23
|
+
* The name of the animation range to convert to additive. If not provided, fromFrame / toFrame will be used
|
|
24
|
+
* If fromFrame / toFrame are not provided either, the whole animation will be converted to additive
|
|
25
|
+
*/
|
|
26
|
+
range?: string;
|
|
27
|
+
/**
|
|
28
|
+
* If true, the original animation will be cloned and converted to additive. If false, the original animation will be converted to additive (default is false)
|
|
29
|
+
*/
|
|
30
|
+
cloneOriginalAnimation?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The name of the cloned animation if cloneOriginalAnimation is true. If not provided, use the original animation name
|
|
33
|
+
*/
|
|
34
|
+
clonedAnimationName?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Together with toFrame, defines the range of the animation to convert to additive. Will only be used if range is not provided
|
|
37
|
+
* If range and fromFrame / toFrame are not provided, the whole animation will be converted to additive
|
|
38
|
+
*/
|
|
39
|
+
fromFrame?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Together with fromFrame, defines the range of the animation to convert to additive.
|
|
42
|
+
*/
|
|
43
|
+
toFrame?: number;
|
|
44
|
+
/**
|
|
45
|
+
* If true, the key frames will be clipped to the range specified by range or fromFrame / toFrame (default is false)
|
|
46
|
+
*/
|
|
47
|
+
clipKeys?: boolean;
|
|
48
|
+
}
|
|
14
49
|
/**
|
|
15
50
|
* @internal
|
|
16
51
|
*/
|
|
@@ -145,15 +180,22 @@ export declare class Animation {
|
|
|
145
180
|
*/
|
|
146
181
|
static CreateMergeAndStartAnimation(name: string, node: Node, targetProperty: string, framePerSecond: number, totalFrame: number, from: any, to: any, loopMode?: number, easingFunction?: EasingFunction, onAnimationEnd?: () => void): Nullable<Animatable>;
|
|
147
182
|
/**
|
|
148
|
-
* Convert the keyframes
|
|
183
|
+
* Convert the keyframes of an animation to be relative to a given reference frame.
|
|
149
184
|
* @param sourceAnimation defines the Animation containing keyframes to convert
|
|
150
|
-
* @param referenceFrame defines the frame that keyframes in the range will be relative to
|
|
185
|
+
* @param referenceFrame defines the frame that keyframes in the range will be relative to (default: 0)
|
|
151
186
|
* @param range defines the name of the AnimationRange belonging to the Animation to convert
|
|
152
187
|
* @param cloneOriginal defines whether or not to clone the animation and convert the clone or convert the original animation (default is false)
|
|
153
188
|
* @param clonedName defines the name of the resulting cloned Animation if cloneOriginal is true
|
|
154
189
|
* @returns a new Animation if cloneOriginal is true or the original Animation if cloneOriginal is false
|
|
155
190
|
*/
|
|
156
191
|
static MakeAnimationAdditive(sourceAnimation: Animation, referenceFrame?: number, range?: string, cloneOriginal?: boolean, clonedName?: string): Animation;
|
|
192
|
+
/**
|
|
193
|
+
* Convert the keyframes of an animation to be relative to a given reference frame.
|
|
194
|
+
* @param sourceAnimation defines the Animation containing keyframes to convert
|
|
195
|
+
* @param options defines the options to use when converting ey keyframes
|
|
196
|
+
* @returns a new Animation if options.cloneOriginalAnimation is true or the original Animation if options.cloneOriginalAnimation is false
|
|
197
|
+
*/
|
|
198
|
+
static MakeAnimationAdditive(sourceAnimation: Animation, options?: IMakeAnimationAdditiveOptions): Animation;
|
|
157
199
|
/**
|
|
158
200
|
* Transition property of an host to the target Value
|
|
159
201
|
* @param property The property to transition
|
|
@@ -386,7 +428,7 @@ export declare class Animation {
|
|
|
386
428
|
/**
|
|
387
429
|
* @internal Internal use only
|
|
388
430
|
*/
|
|
389
|
-
_interpolate(currentFrame: number, state: _IAnimationState): any;
|
|
431
|
+
_interpolate(currentFrame: number, state: _IAnimationState, searchClosestKeyOnly?: boolean): any;
|
|
390
432
|
/**
|
|
391
433
|
* Defines the function to use to interpolate matrices
|
|
392
434
|
* @param startValue defines the start matrix
|
|
@@ -407,6 +449,12 @@ export declare class Animation {
|
|
|
407
449
|
* @param dontClone Whether to clone the keys or not (default is false, so the array of keys is cloned)
|
|
408
450
|
*/
|
|
409
451
|
setKeys(values: Array<IAnimationKey>, dontClone?: boolean): void;
|
|
452
|
+
/**
|
|
453
|
+
* Creates a key for the frame passed as a parameter and adds it to the animation IF a key doesn't already exist for that frame
|
|
454
|
+
* @param frame Frame number
|
|
455
|
+
* @returns The key index if the key was added or the index of the pre existing key if the frame passed as parameter already has a corresponding key
|
|
456
|
+
*/
|
|
457
|
+
createKeyForFrame(frame: number): number;
|
|
410
458
|
/**
|
|
411
459
|
* Serializes the animation to an object
|
|
412
460
|
* @returns Serialized object
|
package/Animations/animation.js
CHANGED
|
@@ -15,6 +15,11 @@ import { WebRequest } from "../Misc/webRequest.js";
|
|
|
15
15
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
16
16
|
export class _IAnimationState {
|
|
17
17
|
}
|
|
18
|
+
const evaluateAnimationState = {
|
|
19
|
+
key: 0,
|
|
20
|
+
repeatCount: 0,
|
|
21
|
+
loopMode: 2 /*Animation.ANIMATIONLOOPMODE_CONSTANT*/,
|
|
22
|
+
};
|
|
18
23
|
/**
|
|
19
24
|
* Class used to store any kind of animation
|
|
20
25
|
*/
|
|
@@ -146,25 +151,30 @@ export class Animation {
|
|
|
146
151
|
node.animations.push(animation);
|
|
147
152
|
return node.getScene().beginAnimation(node, 0, totalFrame, animation.loopMode === 1, 1.0, onAnimationEnd);
|
|
148
153
|
}
|
|
149
|
-
/**
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
/** @internal */
|
|
155
|
+
static MakeAnimationAdditive(sourceAnimation, referenceFrameOrOptions, range, cloneOriginal = false, clonedName) {
|
|
156
|
+
var _a, _b;
|
|
157
|
+
let options;
|
|
158
|
+
if (typeof referenceFrameOrOptions === "object") {
|
|
159
|
+
options = referenceFrameOrOptions;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
options = {
|
|
163
|
+
referenceFrame: referenceFrameOrOptions !== null && referenceFrameOrOptions !== void 0 ? referenceFrameOrOptions : 0,
|
|
164
|
+
range: range,
|
|
165
|
+
cloneOriginalAnimation: cloneOriginal,
|
|
166
|
+
clonedAnimationName: clonedName,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
159
169
|
let animation = sourceAnimation;
|
|
160
|
-
if (
|
|
170
|
+
if (options.cloneOriginalAnimation) {
|
|
161
171
|
animation = sourceAnimation.clone();
|
|
162
|
-
animation.name =
|
|
172
|
+
animation.name = options.clonedAnimationName || animation.name;
|
|
163
173
|
}
|
|
164
174
|
if (!animation._keys.length) {
|
|
165
175
|
return animation;
|
|
166
176
|
}
|
|
167
|
-
referenceFrame = referenceFrame >= 0 ? referenceFrame : 0;
|
|
177
|
+
const referenceFrame = options.referenceFrame && options.referenceFrame >= 0 ? options.referenceFrame : 0;
|
|
168
178
|
let startIndex = 0;
|
|
169
179
|
const firstKey = animation._keys[0];
|
|
170
180
|
let endIndex = animation._keys.length - 1;
|
|
@@ -178,110 +188,45 @@ export class Animation {
|
|
|
178
188
|
keyQuaternion: TmpVectors.Quaternion[1],
|
|
179
189
|
keyScaling: TmpVectors.Vector3[3],
|
|
180
190
|
};
|
|
181
|
-
let referenceFound = false;
|
|
182
191
|
let from = firstKey.frame;
|
|
183
192
|
let to = lastKey.frame;
|
|
184
|
-
if (range) {
|
|
185
|
-
const rangeValue = animation.getRange(range);
|
|
193
|
+
if (options.range) {
|
|
194
|
+
const rangeValue = animation.getRange(options.range);
|
|
186
195
|
if (rangeValue) {
|
|
187
196
|
from = rangeValue.from;
|
|
188
197
|
to = rangeValue.to;
|
|
189
198
|
}
|
|
190
199
|
}
|
|
191
|
-
|
|
192
|
-
|
|
200
|
+
else {
|
|
201
|
+
from = (_a = options.fromFrame) !== null && _a !== void 0 ? _a : from;
|
|
202
|
+
to = (_b = options.toFrame) !== null && _b !== void 0 ? _b : to;
|
|
203
|
+
}
|
|
204
|
+
if (from !== firstKey.frame) {
|
|
205
|
+
startIndex = animation.createKeyForFrame(from);
|
|
206
|
+
}
|
|
207
|
+
if (to !== lastKey.frame) {
|
|
208
|
+
endIndex = animation.createKeyForFrame(to);
|
|
209
|
+
}
|
|
193
210
|
// There's only one key, so use it
|
|
194
211
|
if (animation._keys.length === 1) {
|
|
195
212
|
const value = animation._getKeyValue(animation._keys[0]);
|
|
196
213
|
valueStore.referenceValue = value.clone ? value.clone() : value;
|
|
197
|
-
referenceFound = true;
|
|
198
214
|
}
|
|
199
215
|
// Reference frame is before the first frame, so just use the first frame
|
|
200
216
|
else if (referenceFrame <= firstKey.frame) {
|
|
201
217
|
const value = animation._getKeyValue(firstKey.value);
|
|
202
218
|
valueStore.referenceValue = value.clone ? value.clone() : value;
|
|
203
|
-
referenceFound = true;
|
|
204
219
|
}
|
|
205
220
|
// Reference frame is after the last frame, so just use the last frame
|
|
206
221
|
else if (referenceFrame >= lastKey.frame) {
|
|
207
222
|
const value = animation._getKeyValue(lastKey.value);
|
|
208
223
|
valueStore.referenceValue = value.clone ? value.clone() : value;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const nextKey = animation._keys[index + 1];
|
|
216
|
-
// If reference frame wasn't found yet, check if we can interpolate to it
|
|
217
|
-
if (!referenceFound && referenceFrame >= currentKey.frame && referenceFrame <= nextKey.frame) {
|
|
218
|
-
let value;
|
|
219
|
-
if (referenceFrame === currentKey.frame) {
|
|
220
|
-
value = animation._getKeyValue(currentKey.value);
|
|
221
|
-
}
|
|
222
|
-
else if (referenceFrame === nextKey.frame) {
|
|
223
|
-
value = animation._getKeyValue(nextKey.value);
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
const animationState = {
|
|
227
|
-
key: index,
|
|
228
|
-
repeatCount: 0,
|
|
229
|
-
loopMode: this.ANIMATIONLOOPMODE_CONSTANT,
|
|
230
|
-
};
|
|
231
|
-
value = animation._interpolate(referenceFrame, animationState);
|
|
232
|
-
}
|
|
233
|
-
valueStore.referenceValue = value.clone ? value.clone() : value;
|
|
234
|
-
referenceFound = true;
|
|
235
|
-
}
|
|
236
|
-
// If from key wasn't found yet, check if we can interpolate to it
|
|
237
|
-
if (!fromKeyFound && from >= currentKey.frame && from <= nextKey.frame) {
|
|
238
|
-
if (from === currentKey.frame) {
|
|
239
|
-
startIndex = index;
|
|
240
|
-
}
|
|
241
|
-
else if (from === nextKey.frame) {
|
|
242
|
-
startIndex = index + 1;
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
const animationState = {
|
|
246
|
-
key: index,
|
|
247
|
-
repeatCount: 0,
|
|
248
|
-
loopMode: this.ANIMATIONLOOPMODE_CONSTANT,
|
|
249
|
-
};
|
|
250
|
-
const value = animation._interpolate(from, animationState);
|
|
251
|
-
const key = {
|
|
252
|
-
frame: from,
|
|
253
|
-
value: value.clone ? value.clone() : value,
|
|
254
|
-
};
|
|
255
|
-
animation._keys.splice(index + 1, 0, key);
|
|
256
|
-
startIndex = index + 1;
|
|
257
|
-
}
|
|
258
|
-
fromKeyFound = true;
|
|
259
|
-
}
|
|
260
|
-
// If to key wasn't found yet, check if we can interpolate to it
|
|
261
|
-
if (!toKeyFound && to >= currentKey.frame && to <= nextKey.frame) {
|
|
262
|
-
if (to === currentKey.frame) {
|
|
263
|
-
endIndex = index;
|
|
264
|
-
}
|
|
265
|
-
else if (to === nextKey.frame) {
|
|
266
|
-
endIndex = index + 1;
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
const animationState = {
|
|
270
|
-
key: index,
|
|
271
|
-
repeatCount: 0,
|
|
272
|
-
loopMode: this.ANIMATIONLOOPMODE_CONSTANT,
|
|
273
|
-
};
|
|
274
|
-
const value = animation._interpolate(to, animationState);
|
|
275
|
-
const key = {
|
|
276
|
-
frame: to,
|
|
277
|
-
value: value.clone ? value.clone() : value,
|
|
278
|
-
};
|
|
279
|
-
animation._keys.splice(index + 1, 0, key);
|
|
280
|
-
endIndex = index + 1;
|
|
281
|
-
}
|
|
282
|
-
toKeyFound = true;
|
|
283
|
-
}
|
|
284
|
-
index++;
|
|
224
|
+
}
|
|
225
|
+
// Interpolate the reference value from the animation
|
|
226
|
+
else {
|
|
227
|
+
evaluateAnimationState.key = 0;
|
|
228
|
+
const value = animation._interpolate(referenceFrame, evaluateAnimationState);
|
|
229
|
+
valueStore.referenceValue = value.clone ? value.clone() : value;
|
|
285
230
|
}
|
|
286
231
|
// Conjugate the quaternion
|
|
287
232
|
if (animation.dataType === Animation.ANIMATIONTYPE_QUATERNION) {
|
|
@@ -292,9 +237,26 @@ export class Animation {
|
|
|
292
237
|
valueStore.referenceValue.decompose(valueStore.referenceScaling, valueStore.referenceQuaternion, valueStore.referencePosition);
|
|
293
238
|
valueStore.referenceQuaternion.normalize().conjugateInPlace();
|
|
294
239
|
}
|
|
240
|
+
let startFrame = Number.MAX_VALUE;
|
|
241
|
+
const clippedKeys = options.clipKeys ? [] : null;
|
|
295
242
|
// Subtract the reference value from all of the key values
|
|
296
|
-
for (index = startIndex; index <= endIndex; index++) {
|
|
297
|
-
|
|
243
|
+
for (let index = startIndex; index <= endIndex; index++) {
|
|
244
|
+
let key = animation._keys[index];
|
|
245
|
+
if (clippedKeys) {
|
|
246
|
+
key = {
|
|
247
|
+
frame: key.frame,
|
|
248
|
+
value: key.value.clone ? key.value.clone() : key.value,
|
|
249
|
+
inTangent: key.inTangent,
|
|
250
|
+
outTangent: key.outTangent,
|
|
251
|
+
interpolation: key.interpolation,
|
|
252
|
+
lockedTangent: key.lockedTangent,
|
|
253
|
+
};
|
|
254
|
+
if (startFrame === Number.MAX_VALUE) {
|
|
255
|
+
startFrame = key.frame;
|
|
256
|
+
}
|
|
257
|
+
key.frame -= startFrame;
|
|
258
|
+
clippedKeys.push(key);
|
|
259
|
+
}
|
|
298
260
|
// If this key was duplicated to create a frame 0 key, skip it because its value has already been updated
|
|
299
261
|
if (index && animation.dataType !== Animation.ANIMATIONTYPE_FLOAT && key.value === firstKey.value) {
|
|
300
262
|
continue;
|
|
@@ -324,6 +286,9 @@ export class Animation {
|
|
|
324
286
|
key.value -= valueStore.referenceValue;
|
|
325
287
|
}
|
|
326
288
|
}
|
|
289
|
+
if (clippedKeys) {
|
|
290
|
+
animation.setKeys(clippedKeys, true);
|
|
291
|
+
}
|
|
327
292
|
return animation;
|
|
328
293
|
}
|
|
329
294
|
/**
|
|
@@ -720,16 +685,13 @@ export class Animation {
|
|
|
720
685
|
* @returns the animation value
|
|
721
686
|
*/
|
|
722
687
|
evaluate(currentFrame) {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
repeatCount: 0,
|
|
726
|
-
loopMode: Animation.ANIMATIONLOOPMODE_CONSTANT,
|
|
727
|
-
});
|
|
688
|
+
evaluateAnimationState.key = 0;
|
|
689
|
+
return this._interpolate(currentFrame, evaluateAnimationState);
|
|
728
690
|
}
|
|
729
691
|
/**
|
|
730
692
|
* @internal Internal use only
|
|
731
693
|
*/
|
|
732
|
-
_interpolate(currentFrame, state) {
|
|
694
|
+
_interpolate(currentFrame, state, searchClosestKeyOnly = false) {
|
|
733
695
|
if (state.loopMode === Animation.ANIMATIONLOOPMODE_CONSTANT && state.repeatCount > 0) {
|
|
734
696
|
return state.highLimitValue.clone ? state.highLimitValue.clone() : state.highLimitValue;
|
|
735
697
|
}
|
|
@@ -744,13 +706,16 @@ export class Animation {
|
|
|
744
706
|
}
|
|
745
707
|
state.key = key;
|
|
746
708
|
if (key < 0) {
|
|
747
|
-
return this._getKeyValue(keys[0].value);
|
|
709
|
+
return searchClosestKeyOnly ? undefined : this._getKeyValue(keys[0].value);
|
|
748
710
|
}
|
|
749
711
|
else if (key + 1 > keysLength - 1) {
|
|
750
|
-
return this._getKeyValue(keys[keysLength - 1].value);
|
|
712
|
+
return searchClosestKeyOnly ? undefined : this._getKeyValue(keys[keysLength - 1].value);
|
|
751
713
|
}
|
|
752
714
|
const startKey = keys[key];
|
|
753
715
|
const endKey = keys[key + 1];
|
|
716
|
+
if (searchClosestKeyOnly && (currentFrame === startKey.frame || currentFrame === endKey.frame)) {
|
|
717
|
+
return undefined;
|
|
718
|
+
}
|
|
754
719
|
const startValue = this._getKeyValue(startKey.value);
|
|
755
720
|
const endValue = this._getKeyValue(endKey.value);
|
|
756
721
|
if (startKey.interpolation === AnimationKeyInterpolation.STEP) {
|
|
@@ -946,6 +911,27 @@ export class Animation {
|
|
|
946
911
|
setKeys(values, dontClone = false) {
|
|
947
912
|
this._keys = !dontClone ? values.slice(0) : values;
|
|
948
913
|
}
|
|
914
|
+
/**
|
|
915
|
+
* Creates a key for the frame passed as a parameter and adds it to the animation IF a key doesn't already exist for that frame
|
|
916
|
+
* @param frame Frame number
|
|
917
|
+
* @returns The key index if the key was added or the index of the pre existing key if the frame passed as parameter already has a corresponding key
|
|
918
|
+
*/
|
|
919
|
+
createKeyForFrame(frame) {
|
|
920
|
+
// Find the key corresponding to frame
|
|
921
|
+
evaluateAnimationState.key = 0;
|
|
922
|
+
const value = this._interpolate(frame, evaluateAnimationState, true);
|
|
923
|
+
if (!value) {
|
|
924
|
+
// A key corresponding to this frame already exists
|
|
925
|
+
return evaluateAnimationState.key === frame ? evaluateAnimationState.key : evaluateAnimationState.key + 1;
|
|
926
|
+
}
|
|
927
|
+
// The frame is between two keys, so create a new key
|
|
928
|
+
const newKey = {
|
|
929
|
+
frame,
|
|
930
|
+
value: value.clone ? value.clone() : value,
|
|
931
|
+
};
|
|
932
|
+
this._keys.splice(evaluateAnimationState.key + 1, 0, newKey);
|
|
933
|
+
return evaluateAnimationState.key + 1;
|
|
934
|
+
}
|
|
949
935
|
/**
|
|
950
936
|
* Serializes the animation to an object
|
|
951
937
|
* @returns Serialized object
|