@babylonjs/addons 8.22.2 → 8.23.0
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/lottie/index.d.ts +1 -0
- package/lottie/index.js +3 -0
- package/lottie/index.js.map +1 -0
- package/lottie/lottie/animationParser.d.ts +47 -0
- package/lottie/lottie/animationParser.js +368 -0
- package/lottie/lottie/animationParser.js.map +1 -0
- package/lottie/lottie/parsedTypes.d.ts +140 -0
- package/lottie/lottie/parsedTypes.js +2 -0
- package/lottie/lottie/parsedTypes.js.map +1 -0
- package/lottie/lottie/rawTypes.d.ts +152 -0
- package/lottie/lottie/rawTypes.js +4 -0
- package/lottie/lottie/rawTypes.js.map +1 -0
- package/lottie/lottiePlayer.d.ts +92 -0
- package/lottie/lottiePlayer.js +101 -0
- package/lottie/lottiePlayer.js.map +1 -0
- package/lottie/maths/bezier.d.ts +44 -0
- package/lottie/maths/bezier.js +53 -0
- package/lottie/maths/bezier.js.map +1 -0
- package/lottie/maths/boundingBox.d.ts +28 -0
- package/lottie/maths/boundingBox.js +155 -0
- package/lottie/maths/boundingBox.js.map +1 -0
- package/lottie/maths/matrix.d.ts +91 -0
- package/lottie/maths/matrix.js +174 -0
- package/lottie/maths/matrix.js.map +1 -0
- package/lottie/rendering/animationController.d.ts +72 -0
- package/lottie/rendering/animationController.js +210 -0
- package/lottie/rendering/animationController.js.map +1 -0
- package/lottie/rendering/controlNode.d.ts +32 -0
- package/lottie/rendering/controlNode.js +39 -0
- package/lottie/rendering/controlNode.js.map +1 -0
- package/lottie/rendering/node.d.ts +97 -0
- package/lottie/rendering/node.js +331 -0
- package/lottie/rendering/node.js.map +1 -0
- package/lottie/rendering/renderingManager.d.ts +45 -0
- package/lottie/rendering/renderingManager.js +61 -0
- package/lottie/rendering/renderingManager.js.map +1 -0
- package/lottie/sprites/spriteNode.d.ts +32 -0
- package/lottie/sprites/spriteNode.js +52 -0
- package/lottie/sprites/spriteNode.js.map +1 -0
- package/lottie/sprites/spritePacker.d.ts +101 -0
- package/lottie/sprites/spritePacker.js +237 -0
- package/lottie/sprites/spritePacker.js.map +1 -0
- package/lottie/worker.d.ts +1 -0
- package/lottie/worker.js +39 -0
- package/lottie/worker.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { ThinMatrix } from "../maths/matrix.js";
|
|
2
|
+
/**
|
|
3
|
+
* Represents a node in the scenegraph that contains the animation information from a lottie animation layer or group.
|
|
4
|
+
*/
|
|
5
|
+
export class Node {
|
|
6
|
+
/**
|
|
7
|
+
* Gets the id of this node.
|
|
8
|
+
* @returns The unique identifier of this node.
|
|
9
|
+
*/
|
|
10
|
+
get id() {
|
|
11
|
+
return this._id;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Gets the childer of this node.
|
|
15
|
+
* @returns An array of child nodes.
|
|
16
|
+
*/
|
|
17
|
+
get children() {
|
|
18
|
+
return this._children;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Gets whether this node is a shape.
|
|
22
|
+
* @returns True if this node is a shape, false otherwise.
|
|
23
|
+
*/
|
|
24
|
+
get isShape() {
|
|
25
|
+
return this._isShape;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets the world matrix of this node.
|
|
29
|
+
* @returns The world matrix.
|
|
30
|
+
*/
|
|
31
|
+
get worldMatrix() {
|
|
32
|
+
return this._worldMatrix;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gets whether this node is animated.
|
|
36
|
+
* @returns True if this node has animations, false otherwise.
|
|
37
|
+
*/
|
|
38
|
+
get isAnimated() {
|
|
39
|
+
return this._isAnimated;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Gets the opacity of this node.
|
|
43
|
+
* If the node is not visible, the opacity will be 0.
|
|
44
|
+
* @returns The opacity of the node, from 0 to 1.
|
|
45
|
+
*/
|
|
46
|
+
get opacity() {
|
|
47
|
+
if (!this._isVisible) {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
return this._opacity.currentValue / 100.0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Gets the initial scale of this node.
|
|
54
|
+
* @returns The initial scale.
|
|
55
|
+
*/
|
|
56
|
+
get startScale() {
|
|
57
|
+
return this._scale.startValue;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Gets the parent node of this node.
|
|
61
|
+
* @returns The parent node, or undefined if this is a root node.
|
|
62
|
+
*/
|
|
63
|
+
get parent() {
|
|
64
|
+
return this._parent;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sets the node visibility.
|
|
68
|
+
* @param value The new visibility value.
|
|
69
|
+
*/
|
|
70
|
+
set isVisible(value) {
|
|
71
|
+
if (this._isVisible === value) {
|
|
72
|
+
return; // No change in visibility
|
|
73
|
+
}
|
|
74
|
+
this._isVisible = value;
|
|
75
|
+
// Propage to children
|
|
76
|
+
for (let i = 0; i < this._children.length; i++) {
|
|
77
|
+
this._children[i].isVisible = value;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Constructs a new node.
|
|
82
|
+
* @param id Unique identifier for the node.
|
|
83
|
+
* @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.
|
|
84
|
+
* @param position Position of the node in the scene.
|
|
85
|
+
* @param rotation Rotation of the node in degrees.
|
|
86
|
+
* @param scale Scale of the node in the scene.
|
|
87
|
+
* @param opacity Opacity of the node, from 0 to 1.
|
|
88
|
+
* @param parent Parent node in the scenegraph.
|
|
89
|
+
*/
|
|
90
|
+
constructor(id, ignoreOpacityAnimations, position, rotation, scale, opacity, parent) {
|
|
91
|
+
this._isVisible = false;
|
|
92
|
+
this._isAnimated = false;
|
|
93
|
+
this._animationsFunctions = [];
|
|
94
|
+
this._isControl = false;
|
|
95
|
+
this._isShape = false;
|
|
96
|
+
this._isVisible = false;
|
|
97
|
+
this._id = id;
|
|
98
|
+
this._ignoreOpacityAnimations = ignoreOpacityAnimations;
|
|
99
|
+
this._position = position || { startValue: { x: 0, y: 0 }, currentValue: { x: 0, y: 0 }, currentKeyframeIndex: 0 };
|
|
100
|
+
this._rotation = rotation || { startValue: 0, currentValue: 0, currentKeyframeIndex: 0 };
|
|
101
|
+
this._scale = scale || { startValue: { x: 1, y: 1 }, currentValue: { x: 1, y: 1 }, currentKeyframeIndex: 0 };
|
|
102
|
+
this._localMatrix = new ThinMatrix();
|
|
103
|
+
this._globalMatrix = new ThinMatrix();
|
|
104
|
+
// Store the matrix at least once
|
|
105
|
+
this._localMatrix.compose(this._scale.currentValue, this._rotation.currentValue, this._position.currentValue);
|
|
106
|
+
this._opacity = opacity || { startValue: 100, currentValue: 100, currentKeyframeIndex: 0 };
|
|
107
|
+
// Animated ?
|
|
108
|
+
if (this._position.keyframes !== undefined && this._position.keyframes.length > 0) {
|
|
109
|
+
this._isAnimated = true;
|
|
110
|
+
this._animationsFunctions.push((frame) => {
|
|
111
|
+
return this._updatePosition(frame);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (this._rotation.keyframes !== undefined && this._rotation.keyframes.length > 0) {
|
|
115
|
+
this._isAnimated = true;
|
|
116
|
+
this._animationsFunctions.push((frame) => {
|
|
117
|
+
return this._updateRotation(frame);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (this._scale.keyframes !== undefined && this._scale.keyframes.length > 0) {
|
|
121
|
+
this._isAnimated = true;
|
|
122
|
+
this._animationsFunctions.push((frame) => {
|
|
123
|
+
return this._updateScale(frame);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// Parenting
|
|
127
|
+
this._children = [];
|
|
128
|
+
if (parent) {
|
|
129
|
+
this._worldMatrix = this._globalMatrix;
|
|
130
|
+
if (parent.isAnimated || !parent.parent || this.isAnimated || parent._isControl) {
|
|
131
|
+
this._parent = parent;
|
|
132
|
+
parent._children.push(this);
|
|
133
|
+
this._localMatrix.multiplyToRef(parent._worldMatrix, this._globalMatrix);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// We can merge them
|
|
137
|
+
this._localMatrix.multiplyToRef(parent._localMatrix, this._localMatrix);
|
|
138
|
+
// New parent
|
|
139
|
+
this._parent = parent.parent;
|
|
140
|
+
this._localMatrix.multiplyToRef(this._parent._worldMatrix, this._globalMatrix);
|
|
141
|
+
parent.parent._children.push(this);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
this._worldMatrix = this._localMatrix;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Resets the node's properties to their initial values.
|
|
150
|
+
*/
|
|
151
|
+
reset() {
|
|
152
|
+
// Vectors need to be copied to avoid modifying the original start values
|
|
153
|
+
this._position.currentValue = { x: this._position.startValue.x, y: this._position.startValue.y };
|
|
154
|
+
if (this._position.keyframes) {
|
|
155
|
+
this._position.currentKeyframeIndex = 0;
|
|
156
|
+
}
|
|
157
|
+
this._rotation.currentValue = this._rotation.startValue;
|
|
158
|
+
if (this._rotation.keyframes) {
|
|
159
|
+
this._rotation.currentKeyframeIndex = 0;
|
|
160
|
+
}
|
|
161
|
+
this._scale.currentValue = { x: this._scale.startValue.x, y: this._scale.startValue.y };
|
|
162
|
+
if (this._scale.keyframes) {
|
|
163
|
+
this._scale.currentKeyframeIndex = 0;
|
|
164
|
+
}
|
|
165
|
+
this._opacity.currentValue = this._opacity.startValue;
|
|
166
|
+
if (this._opacity.keyframes) {
|
|
167
|
+
this._opacity.currentKeyframeIndex = 0;
|
|
168
|
+
}
|
|
169
|
+
for (let i = 0; i < this._children.length; i++) {
|
|
170
|
+
this._children[i].reset();
|
|
171
|
+
}
|
|
172
|
+
// On reset update the scenegraph so all matrices are reset to their initial values
|
|
173
|
+
if (this._parent === undefined) {
|
|
174
|
+
this.update(0, false, true);
|
|
175
|
+
}
|
|
176
|
+
this._isVisible = false;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Updates the node's properties based on the current frame of the animation.
|
|
180
|
+
* @param frame Frame number we are playing in the animation.
|
|
181
|
+
* @param isParentUpdated Whether the parent node has been updated.
|
|
182
|
+
* @param isReset Whether the node is being reset.
|
|
183
|
+
* @returns True if the node was updated, false otherwise.
|
|
184
|
+
*/
|
|
185
|
+
update(frame, isParentUpdated = false, isReset = false) {
|
|
186
|
+
let isUpdated = false || isReset;
|
|
187
|
+
if (this.isAnimated) {
|
|
188
|
+
for (let i = 0; i < this._animationsFunctions.length; i++) {
|
|
189
|
+
isUpdated = this._animationsFunctions[i](frame) || isUpdated;
|
|
190
|
+
}
|
|
191
|
+
if (isUpdated) {
|
|
192
|
+
this._localMatrix.compose(this._scale.currentValue, this._rotation.currentValue, this._position.currentValue);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (this._parent) {
|
|
196
|
+
if (isParentUpdated || isUpdated) {
|
|
197
|
+
this._localMatrix.multiplyToRef(this._parent._worldMatrix, this._globalMatrix);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (!this._ignoreOpacityAnimations) {
|
|
201
|
+
this._updateOpacity(frame);
|
|
202
|
+
}
|
|
203
|
+
for (let i = 0; i < this._children.length; i++) {
|
|
204
|
+
this._children[i].update(frame, isUpdated || isParentUpdated);
|
|
205
|
+
}
|
|
206
|
+
return isUpdated || isParentUpdated;
|
|
207
|
+
}
|
|
208
|
+
_updatePosition(frame) {
|
|
209
|
+
const keyframes = this._position.keyframes;
|
|
210
|
+
if (frame < keyframes[0].time) {
|
|
211
|
+
return false; // Animation not started yet
|
|
212
|
+
}
|
|
213
|
+
if (frame > keyframes[keyframes.length - 1].time) {
|
|
214
|
+
this._position.currentValue = keyframes[keyframes.length - 1].value;
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
// Find the right keyframe we are currently in
|
|
218
|
+
let currentFrameIndex = -1;
|
|
219
|
+
for (let i = this._position.currentKeyframeIndex; i < keyframes.length - 1; i++) {
|
|
220
|
+
if (frame >= keyframes[i].time && frame < keyframes[i + 1].time) {
|
|
221
|
+
currentFrameIndex = i;
|
|
222
|
+
this._position.currentKeyframeIndex = currentFrameIndex;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (currentFrameIndex === -1) {
|
|
227
|
+
return false; // No valid keyframe found for the current animation frame
|
|
228
|
+
}
|
|
229
|
+
const currentVector2Keyframe = keyframes[currentFrameIndex];
|
|
230
|
+
const nextVector2Keyframe = keyframes[currentFrameIndex + 1];
|
|
231
|
+
// Animate the position
|
|
232
|
+
const gradient = (frame - currentVector2Keyframe.time) / (nextVector2Keyframe.time - currentVector2Keyframe.time);
|
|
233
|
+
const easeGradientFactor = currentVector2Keyframe.easeFunction1.interpolate(gradient);
|
|
234
|
+
this._position.currentValue.x = currentVector2Keyframe.value.x + easeGradientFactor * (nextVector2Keyframe.value.x - currentVector2Keyframe.value.x);
|
|
235
|
+
const easeGradientFactor2 = currentVector2Keyframe.easeFunction2.interpolate(gradient);
|
|
236
|
+
this._position.currentValue.y = currentVector2Keyframe.value.y + easeGradientFactor2 * (nextVector2Keyframe.value.y - currentVector2Keyframe.value.y);
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
_updateRotation(frame) {
|
|
240
|
+
const keyframes = this._rotation.keyframes;
|
|
241
|
+
if (frame < keyframes[0].time) {
|
|
242
|
+
return false; // Animation not started yet
|
|
243
|
+
}
|
|
244
|
+
if (frame > keyframes[keyframes.length - 1].time) {
|
|
245
|
+
this._rotation.currentValue = keyframes[keyframes.length - 1].value;
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
// Find the right keyframe we are currently in
|
|
249
|
+
let currentFrameIndex = -1;
|
|
250
|
+
for (let i = this._rotation.currentKeyframeIndex; i < keyframes.length - 1; i++) {
|
|
251
|
+
if (frame >= keyframes[i].time && frame < keyframes[i + 1].time) {
|
|
252
|
+
currentFrameIndex = i;
|
|
253
|
+
this._rotation.currentKeyframeIndex = currentFrameIndex;
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (currentFrameIndex === -1) {
|
|
258
|
+
return false; // No valid keyframe found for the current animation frame
|
|
259
|
+
}
|
|
260
|
+
const currentScalarKeyframe = keyframes[currentFrameIndex];
|
|
261
|
+
const nextScalarKeyframe = keyframes[currentFrameIndex + 1];
|
|
262
|
+
// Animate the position
|
|
263
|
+
const gradient = (frame - currentScalarKeyframe.time) / (nextScalarKeyframe.time - currentScalarKeyframe.time);
|
|
264
|
+
const easeGradientFactor = currentScalarKeyframe.easeFunction.interpolate(gradient);
|
|
265
|
+
this._rotation.currentValue = -(currentScalarKeyframe.value + easeGradientFactor * (nextScalarKeyframe.value - currentScalarKeyframe.value));
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
_updateScale(frame) {
|
|
269
|
+
const keyframes = this._scale.keyframes;
|
|
270
|
+
if (frame < keyframes[0].time) {
|
|
271
|
+
return false; // Animation not started yet
|
|
272
|
+
}
|
|
273
|
+
if (frame > keyframes[keyframes.length - 1].time) {
|
|
274
|
+
this._scale.currentValue = keyframes[keyframes.length - 1].value;
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
// Find the right keyframe we are currently in
|
|
278
|
+
let currentFrameIndex = -1;
|
|
279
|
+
for (let i = this._scale.currentKeyframeIndex; i < keyframes.length - 1; i++) {
|
|
280
|
+
if (frame >= keyframes[i].time && frame < keyframes[i + 1].time) {
|
|
281
|
+
currentFrameIndex = i;
|
|
282
|
+
this._scale.currentKeyframeIndex = currentFrameIndex;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (currentFrameIndex === -1) {
|
|
287
|
+
return false; // No valid keyframe found for the current animation frame
|
|
288
|
+
}
|
|
289
|
+
const currentVector2Keyframe = keyframes[currentFrameIndex];
|
|
290
|
+
const nextVector2Keyframe = keyframes[currentFrameIndex + 1];
|
|
291
|
+
// Animate the scale
|
|
292
|
+
const gradient = (frame - currentVector2Keyframe.time) / (nextVector2Keyframe.time - currentVector2Keyframe.time);
|
|
293
|
+
const easeGradientFactor = currentVector2Keyframe.easeFunction1.interpolate(gradient);
|
|
294
|
+
this._scale.currentValue.x = currentVector2Keyframe.value.x + easeGradientFactor * (nextVector2Keyframe.value.x - currentVector2Keyframe.value.x);
|
|
295
|
+
const easeGradientFactor2 = currentVector2Keyframe.easeFunction2.interpolate(gradient);
|
|
296
|
+
this._scale.currentValue.y = currentVector2Keyframe.value.y + easeGradientFactor2 * (nextVector2Keyframe.value.y - currentVector2Keyframe.value.y);
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
_updateOpacity(frame) {
|
|
300
|
+
if (this._opacity.keyframes === undefined || this._opacity.keyframes.length === 0) {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
if (frame < this._opacity.keyframes[0].time) {
|
|
304
|
+
return false; // Animation not started yet
|
|
305
|
+
}
|
|
306
|
+
if (frame > this._opacity.keyframes[this._opacity.keyframes.length - 1].time) {
|
|
307
|
+
this._opacity.currentValue = this._opacity.keyframes[this._opacity.keyframes.length - 1].value;
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
// Find the right keyframe we are currently in
|
|
311
|
+
let currentFrameIndex = -1;
|
|
312
|
+
for (let i = this._opacity.currentKeyframeIndex; i < this._opacity.keyframes.length - 1; i++) {
|
|
313
|
+
if (frame >= this._opacity.keyframes[i].time && frame < this._opacity.keyframes[i + 1].time) {
|
|
314
|
+
currentFrameIndex = i;
|
|
315
|
+
this._opacity.currentKeyframeIndex = currentFrameIndex;
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
if (currentFrameIndex === -1) {
|
|
320
|
+
return false; // No valid keyframe found for the current animation frame
|
|
321
|
+
}
|
|
322
|
+
const currentScalarKeyframe = this._opacity.keyframes[currentFrameIndex];
|
|
323
|
+
const nextScalarKeyframe = this._opacity.keyframes[currentFrameIndex + 1];
|
|
324
|
+
// Animate the opacity
|
|
325
|
+
const gradient = (frame - currentScalarKeyframe.time) / (nextScalarKeyframe.time - currentScalarKeyframe.time);
|
|
326
|
+
const easeGradientFactor = currentScalarKeyframe.easeFunction.interpolate(gradient);
|
|
327
|
+
this._opacity.currentValue = currentScalarKeyframe.value + easeGradientFactor * (nextScalarKeyframe.value - currentScalarKeyframe.value);
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../../../../dev/addons/src/lottie/rendering/node.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IVector2Like } from \"core/Maths/math.like\";\r\n\r\nimport type { ScalarProperty, Vector2Property } from \"../lottie/parsedTypes\";\r\n\r\nimport { ThinMatrix } from \"../maths/matrix\";\r\n\r\n/**\r\n * Represents a node in the scenegraph that contains the animation information from a lottie animation layer or group.\r\n */\r\nexport class Node {\r\n private readonly _id: string;\r\n private readonly _ignoreOpacityAnimations: boolean;\r\n private readonly _position: Vector2Property;\r\n private readonly _rotation: ScalarProperty;\r\n private readonly _scale: Vector2Property;\r\n private _worldMatrix: ThinMatrix;\r\n private _localMatrix: ThinMatrix;\r\n private _globalMatrix: ThinMatrix;\r\n\r\n private readonly _opacity: ScalarProperty;\r\n\r\n private readonly _parent: Node | undefined;\r\n private readonly _children: Node[];\r\n\r\n private _isVisible = false;\r\n\r\n private _isAnimated = false;\r\n\r\n private _animationsFunctions: ((frame: number) => boolean)[] = [];\r\n\r\n protected _isControl = false;\r\n protected _isShape = false;\r\n\r\n /**\r\n * Gets the id of this node.\r\n * @returns The unique identifier of this node.\r\n */\r\n public get id(): string {\r\n return this._id;\r\n }\r\n\r\n /**\r\n * Gets the childer of this node.\r\n * @returns An array of child nodes.\r\n */\r\n public get children(): Node[] {\r\n return this._children;\r\n }\r\n\r\n /**\r\n * Gets whether this node is a shape.\r\n * @returns True if this node is a shape, false otherwise.\r\n */\r\n public get isShape(): boolean {\r\n return this._isShape;\r\n }\r\n\r\n /**\r\n * Gets the world matrix of this node.\r\n * @returns The world matrix.\r\n */\r\n public get worldMatrix(): ThinMatrix {\r\n return this._worldMatrix;\r\n }\r\n\r\n /**\r\n * Gets whether this node is animated.\r\n * @returns True if this node has animations, false otherwise.\r\n */\r\n public get isAnimated(): boolean {\r\n return this._isAnimated;\r\n }\r\n\r\n /**\r\n * Gets the opacity of this node.\r\n * If the node is not visible, the opacity will be 0.\r\n * @returns The opacity of the node, from 0 to 1.\r\n */\r\n public get opacity(): number {\r\n if (!this._isVisible) {\r\n return 0;\r\n }\r\n\r\n return this._opacity.currentValue / 100.0;\r\n }\r\n\r\n /**\r\n * Gets the initial scale of this node.\r\n * @returns The initial scale.\r\n */\r\n public get startScale(): IVector2Like {\r\n return this._scale.startValue;\r\n }\r\n\r\n /**\r\n * Gets the parent node of this node.\r\n * @returns The parent node, or undefined if this is a root node.\r\n */\r\n public get parent(): Node | undefined {\r\n return this._parent;\r\n }\r\n\r\n /**\r\n * Sets the node visibility.\r\n * @param value The new visibility value.\r\n */\r\n public set isVisible(value: boolean) {\r\n if (this._isVisible === value) {\r\n return; // No change in visibility\r\n }\r\n this._isVisible = value;\r\n // Propage to children\r\n for (let i = 0; i < this._children.length; i++) {\r\n this._children[i].isVisible = value;\r\n }\r\n }\r\n\r\n /**\r\n * Constructs a new node.\r\n * @param id Unique identifier for the node.\r\n * @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.\r\n * @param position Position of the node in the scene.\r\n * @param rotation Rotation of the node in degrees.\r\n * @param scale Scale of the node in the scene.\r\n * @param opacity Opacity of the node, from 0 to 1.\r\n * @param parent Parent node in the scenegraph.\r\n */\r\n public constructor(\r\n id: string,\r\n ignoreOpacityAnimations: boolean,\r\n position?: Vector2Property,\r\n rotation?: ScalarProperty,\r\n scale?: Vector2Property,\r\n opacity?: ScalarProperty,\r\n parent?: Node\r\n ) {\r\n this._isVisible = false;\r\n\r\n this._id = id;\r\n this._ignoreOpacityAnimations = ignoreOpacityAnimations;\r\n\r\n this._position = position || { startValue: { x: 0, y: 0 }, currentValue: { x: 0, y: 0 }, currentKeyframeIndex: 0 };\r\n this._rotation = rotation || { startValue: 0, currentValue: 0, currentKeyframeIndex: 0 };\r\n this._scale = scale || { startValue: { x: 1, y: 1 }, currentValue: { x: 1, y: 1 }, currentKeyframeIndex: 0 };\r\n this._localMatrix = new ThinMatrix();\r\n this._globalMatrix = new ThinMatrix();\r\n\r\n // Store the matrix at least once\r\n this._localMatrix.compose(this._scale.currentValue, this._rotation.currentValue, this._position.currentValue);\r\n\r\n this._opacity = opacity || { startValue: 100, currentValue: 100, currentKeyframeIndex: 0 };\r\n\r\n // Animated ?\r\n if (this._position.keyframes !== undefined && this._position.keyframes.length > 0) {\r\n this._isAnimated = true;\r\n this._animationsFunctions.push((frame) => {\r\n return this._updatePosition(frame);\r\n });\r\n }\r\n\r\n if (this._rotation.keyframes !== undefined && this._rotation.keyframes.length > 0) {\r\n this._isAnimated = true;\r\n this._animationsFunctions.push((frame) => {\r\n return this._updateRotation(frame);\r\n });\r\n }\r\n\r\n if (this._scale.keyframes !== undefined && this._scale.keyframes.length > 0) {\r\n this._isAnimated = true;\r\n this._animationsFunctions.push((frame) => {\r\n return this._updateScale(frame);\r\n });\r\n }\r\n\r\n // Parenting\r\n this._children = [];\r\n if (parent) {\r\n this._worldMatrix = this._globalMatrix;\r\n\r\n if (parent.isAnimated || !parent.parent || this.isAnimated || parent._isControl) {\r\n this._parent = parent;\r\n parent._children.push(this);\r\n this._localMatrix.multiplyToRef(parent._worldMatrix, this._globalMatrix);\r\n } else {\r\n // We can merge them\r\n this._localMatrix.multiplyToRef(parent._localMatrix, this._localMatrix);\r\n\r\n // New parent\r\n this._parent = parent.parent;\r\n this._localMatrix.multiplyToRef(this._parent._worldMatrix, this._globalMatrix);\r\n parent.parent._children.push(this);\r\n }\r\n } else {\r\n this._worldMatrix = this._localMatrix;\r\n }\r\n }\r\n\r\n /**\r\n * Resets the node's properties to their initial values.\r\n */\r\n public reset(): void {\r\n // Vectors need to be copied to avoid modifying the original start values\r\n this._position.currentValue = { x: this._position.startValue.x, y: this._position.startValue.y };\r\n if (this._position.keyframes) {\r\n this._position.currentKeyframeIndex = 0;\r\n }\r\n\r\n this._rotation.currentValue = this._rotation.startValue;\r\n if (this._rotation.keyframes) {\r\n this._rotation.currentKeyframeIndex = 0;\r\n }\r\n\r\n this._scale.currentValue = { x: this._scale.startValue.x, y: this._scale.startValue.y };\r\n if (this._scale.keyframes) {\r\n this._scale.currentKeyframeIndex = 0;\r\n }\r\n\r\n this._opacity.currentValue = this._opacity.startValue;\r\n if (this._opacity.keyframes) {\r\n this._opacity.currentKeyframeIndex = 0;\r\n }\r\n\r\n for (let i = 0; i < this._children.length; i++) {\r\n this._children[i].reset();\r\n }\r\n\r\n // On reset update the scenegraph so all matrices are reset to their initial values\r\n if (this._parent === undefined) {\r\n this.update(0, false, true);\r\n }\r\n\r\n this._isVisible = false;\r\n }\r\n\r\n /**\r\n * Updates the node's properties based on the current frame of the animation.\r\n * @param frame Frame number we are playing in the animation.\r\n * @param isParentUpdated Whether the parent node has been updated.\r\n * @param isReset Whether the node is being reset.\r\n * @returns True if the node was updated, false otherwise.\r\n */\r\n public update(frame: number, isParentUpdated = false, isReset = false): boolean {\r\n let isUpdated = false || isReset;\r\n\r\n if (this.isAnimated) {\r\n for (let i = 0; i < this._animationsFunctions.length; i++) {\r\n isUpdated = this._animationsFunctions[i](frame) || isUpdated;\r\n }\r\n\r\n if (isUpdated) {\r\n this._localMatrix.compose(this._scale.currentValue, this._rotation.currentValue, this._position.currentValue);\r\n }\r\n }\r\n\r\n if (this._parent) {\r\n if (isParentUpdated || isUpdated) {\r\n this._localMatrix.multiplyToRef(this._parent._worldMatrix, this._globalMatrix);\r\n }\r\n }\r\n\r\n if (!this._ignoreOpacityAnimations) {\r\n this._updateOpacity(frame);\r\n }\r\n\r\n for (let i = 0; i < this._children.length; i++) {\r\n this._children[i].update(frame, isUpdated || isParentUpdated);\r\n }\r\n\r\n return isUpdated || isParentUpdated;\r\n }\r\n\r\n private _updatePosition(frame: number): boolean {\r\n const keyframes = this._position.keyframes!;\r\n\r\n if (frame < keyframes[0].time) {\r\n return false; // Animation not started yet\r\n }\r\n\r\n if (frame > keyframes[keyframes.length - 1].time) {\r\n this._position.currentValue = keyframes[keyframes.length - 1].value;\r\n return true;\r\n }\r\n\r\n // Find the right keyframe we are currently in\r\n let currentFrameIndex = -1;\r\n for (let i = this._position.currentKeyframeIndex; i < keyframes.length - 1; i++) {\r\n if (frame >= keyframes[i].time && frame < keyframes[i + 1].time) {\r\n currentFrameIndex = i;\r\n this._position.currentKeyframeIndex = currentFrameIndex;\r\n break;\r\n }\r\n }\r\n\r\n if (currentFrameIndex === -1) {\r\n return false; // No valid keyframe found for the current animation frame\r\n }\r\n\r\n const currentVector2Keyframe = keyframes[currentFrameIndex];\r\n const nextVector2Keyframe = keyframes[currentFrameIndex + 1];\r\n\r\n // Animate the position\r\n const gradient = (frame - currentVector2Keyframe.time) / (nextVector2Keyframe.time - currentVector2Keyframe.time);\r\n\r\n const easeGradientFactor = currentVector2Keyframe.easeFunction1.interpolate(gradient);\r\n this._position.currentValue.x = currentVector2Keyframe.value.x + easeGradientFactor * (nextVector2Keyframe.value.x - currentVector2Keyframe.value.x);\r\n\r\n const easeGradientFactor2 = currentVector2Keyframe.easeFunction2.interpolate(gradient);\r\n this._position.currentValue.y = currentVector2Keyframe.value.y + easeGradientFactor2 * (nextVector2Keyframe.value.y - currentVector2Keyframe.value.y);\r\n\r\n return true;\r\n }\r\n\r\n private _updateRotation(frame: number): boolean {\r\n const keyframes = this._rotation.keyframes!;\r\n\r\n if (frame < keyframes[0].time) {\r\n return false; // Animation not started yet\r\n }\r\n\r\n if (frame > keyframes[keyframes.length - 1].time) {\r\n this._rotation.currentValue = keyframes[keyframes.length - 1].value;\r\n return true;\r\n }\r\n\r\n // Find the right keyframe we are currently in\r\n let currentFrameIndex = -1;\r\n for (let i = this._rotation.currentKeyframeIndex; i < keyframes.length - 1; i++) {\r\n if (frame >= keyframes[i].time && frame < keyframes[i + 1].time) {\r\n currentFrameIndex = i;\r\n this._rotation.currentKeyframeIndex = currentFrameIndex;\r\n break;\r\n }\r\n }\r\n\r\n if (currentFrameIndex === -1) {\r\n return false; // No valid keyframe found for the current animation frame\r\n }\r\n\r\n const currentScalarKeyframe = keyframes[currentFrameIndex];\r\n const nextScalarKeyframe = keyframes[currentFrameIndex + 1];\r\n\r\n // Animate the position\r\n const gradient = (frame - currentScalarKeyframe.time) / (nextScalarKeyframe.time - currentScalarKeyframe.time);\r\n\r\n const easeGradientFactor = currentScalarKeyframe.easeFunction.interpolate(gradient);\r\n this._rotation.currentValue = -(currentScalarKeyframe.value + easeGradientFactor * (nextScalarKeyframe.value - currentScalarKeyframe.value));\r\n\r\n return true;\r\n }\r\n\r\n private _updateScale(frame: number): boolean {\r\n const keyframes = this._scale.keyframes!;\r\n\r\n if (frame < keyframes[0].time) {\r\n return false; // Animation not started yet\r\n }\r\n\r\n if (frame > keyframes[keyframes.length - 1].time) {\r\n this._scale.currentValue = keyframes[keyframes.length - 1].value;\r\n return true;\r\n }\r\n\r\n // Find the right keyframe we are currently in\r\n let currentFrameIndex = -1;\r\n for (let i = this._scale.currentKeyframeIndex; i < keyframes.length - 1; i++) {\r\n if (frame >= keyframes[i].time && frame < keyframes[i + 1].time) {\r\n currentFrameIndex = i;\r\n this._scale.currentKeyframeIndex = currentFrameIndex;\r\n break;\r\n }\r\n }\r\n\r\n if (currentFrameIndex === -1) {\r\n return false; // No valid keyframe found for the current animation frame\r\n }\r\n\r\n const currentVector2Keyframe = keyframes[currentFrameIndex];\r\n const nextVector2Keyframe = keyframes[currentFrameIndex + 1];\r\n\r\n // Animate the scale\r\n const gradient = (frame - currentVector2Keyframe.time) / (nextVector2Keyframe.time - currentVector2Keyframe.time);\r\n\r\n const easeGradientFactor = currentVector2Keyframe.easeFunction1.interpolate(gradient);\r\n this._scale.currentValue.x = currentVector2Keyframe.value.x + easeGradientFactor * (nextVector2Keyframe.value.x - currentVector2Keyframe.value.x);\r\n\r\n const easeGradientFactor2 = currentVector2Keyframe.easeFunction2.interpolate(gradient);\r\n this._scale.currentValue.y = currentVector2Keyframe.value.y + easeGradientFactor2 * (nextVector2Keyframe.value.y - currentVector2Keyframe.value.y);\r\n\r\n return true;\r\n }\r\n\r\n private _updateOpacity(frame: number): boolean {\r\n if (this._opacity.keyframes === undefined || this._opacity.keyframes.length === 0) {\r\n return false;\r\n }\r\n\r\n if (frame < this._opacity.keyframes[0].time) {\r\n return false; // Animation not started yet\r\n }\r\n\r\n if (frame > this._opacity.keyframes[this._opacity.keyframes.length - 1].time) {\r\n this._opacity.currentValue = this._opacity.keyframes[this._opacity.keyframes.length - 1].value;\r\n return true;\r\n }\r\n\r\n // Find the right keyframe we are currently in\r\n let currentFrameIndex = -1;\r\n for (let i = this._opacity.currentKeyframeIndex; i < this._opacity.keyframes.length - 1; i++) {\r\n if (frame >= this._opacity.keyframes[i].time && frame < this._opacity.keyframes[i + 1].time) {\r\n currentFrameIndex = i;\r\n this._opacity.currentKeyframeIndex = currentFrameIndex;\r\n break;\r\n }\r\n }\r\n\r\n if (currentFrameIndex === -1) {\r\n return false; // No valid keyframe found for the current animation frame\r\n }\r\n\r\n const currentScalarKeyframe = this._opacity.keyframes[currentFrameIndex];\r\n const nextScalarKeyframe = this._opacity.keyframes[currentFrameIndex + 1];\r\n\r\n // Animate the opacity\r\n const gradient = (frame - currentScalarKeyframe.time) / (nextScalarKeyframe.time - currentScalarKeyframe.time);\r\n\r\n const easeGradientFactor = currentScalarKeyframe.easeFunction.interpolate(gradient);\r\n this._opacity.currentValue = currentScalarKeyframe.value + easeGradientFactor * (nextScalarKeyframe.value - currentScalarKeyframe.value);\r\n\r\n return true;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import "@babylonjs/core/Engines/Extensions/engine.dynamicBuffer.js";
|
|
2
|
+
import "@babylonjs/core/Shaders/sprites.vertex.js";
|
|
3
|
+
import "@babylonjs/core/Shaders/sprites.fragment.js";
|
|
4
|
+
import type { ThinEngine } from "@babylonjs/core/Engines/thinEngine.js";
|
|
5
|
+
import type { ThinTexture } from "@babylonjs/core/Materials/Textures/thinTexture.js";
|
|
6
|
+
import type { ThinSprite } from "@babylonjs/core/Sprites/thinSprite.js";
|
|
7
|
+
import type { ThinMatrix } from "../maths/matrix.js";
|
|
8
|
+
import type { AnimationConfiguration } from "../lottiePlayer.js";
|
|
9
|
+
/**
|
|
10
|
+
* Represents all the sprites from the animation and manages their rendering.
|
|
11
|
+
*/
|
|
12
|
+
export declare class RenderingManager {
|
|
13
|
+
private readonly _engine;
|
|
14
|
+
private readonly _spritesRenderer;
|
|
15
|
+
private readonly _spritesTexture;
|
|
16
|
+
private _sprites;
|
|
17
|
+
private readonly _configuration;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new instance of the RenderingManager.
|
|
20
|
+
* @param engine ThinEngine instance used for rendering.
|
|
21
|
+
* @param spriteTexture The texture atlas containing the sprites.
|
|
22
|
+
* @param configuration Configuration options for the rendering manager.
|
|
23
|
+
*/
|
|
24
|
+
constructor(engine: ThinEngine, spriteTexture: ThinTexture, configuration: AnimationConfiguration);
|
|
25
|
+
/**
|
|
26
|
+
* Adds a sprite to the rendering manager.
|
|
27
|
+
* @param sprite Sprite to add to the rendering manager.
|
|
28
|
+
*/
|
|
29
|
+
addSprite(sprite: ThinSprite): void;
|
|
30
|
+
/**
|
|
31
|
+
* Prepares the rendering manager for rendering.
|
|
32
|
+
*/
|
|
33
|
+
ready(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Renders all the sprites in the rendering manager.
|
|
36
|
+
* @param worldMatrix World matrix to apply to the sprites.
|
|
37
|
+
* @param projectionMatrix Projection matrix to apply to the sprites.
|
|
38
|
+
*/
|
|
39
|
+
render(worldMatrix: ThinMatrix, projectionMatrix: ThinMatrix): void;
|
|
40
|
+
/**
|
|
41
|
+
* Disposes the rendering manager and its resources.
|
|
42
|
+
*/
|
|
43
|
+
dispose(): void;
|
|
44
|
+
private _customSpriteUpdate;
|
|
45
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import "@babylonjs/core/Engines/Extensions/engine.dynamicBuffer.js";
|
|
2
|
+
import "@babylonjs/core/Shaders/sprites.vertex.js";
|
|
3
|
+
import "@babylonjs/core/Shaders/sprites.fragment.js";
|
|
4
|
+
import { SpriteRenderer } from "@babylonjs/core/Sprites/spriteRenderer.js";
|
|
5
|
+
/**
|
|
6
|
+
* Represents all the sprites from the animation and manages their rendering.
|
|
7
|
+
*/
|
|
8
|
+
export class RenderingManager {
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new instance of the RenderingManager.
|
|
11
|
+
* @param engine ThinEngine instance used for rendering.
|
|
12
|
+
* @param spriteTexture The texture atlas containing the sprites.
|
|
13
|
+
* @param configuration Configuration options for the rendering manager.
|
|
14
|
+
*/
|
|
15
|
+
constructor(engine, spriteTexture, configuration) {
|
|
16
|
+
this._customSpriteUpdate = () => {
|
|
17
|
+
// All the work is done upfront within the sprite render
|
|
18
|
+
// so that we do not need babylon to update back the information
|
|
19
|
+
};
|
|
20
|
+
this._engine = engine;
|
|
21
|
+
this._spritesTexture = spriteTexture;
|
|
22
|
+
this._sprites = [];
|
|
23
|
+
this._configuration = configuration;
|
|
24
|
+
this._spritesRenderer = new SpriteRenderer(this._engine, this._configuration.spritesCapacity, 0);
|
|
25
|
+
this._spritesRenderer.disableDepthWrite = true;
|
|
26
|
+
this._spritesRenderer.autoResetAlpha = false;
|
|
27
|
+
this._spritesRenderer.fogEnabled = false;
|
|
28
|
+
this._spritesRenderer.texture = this._spritesTexture;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Adds a sprite to the rendering manager.
|
|
32
|
+
* @param sprite Sprite to add to the rendering manager.
|
|
33
|
+
*/
|
|
34
|
+
addSprite(sprite) {
|
|
35
|
+
this._sprites.push(sprite);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Prepares the rendering manager for rendering.
|
|
39
|
+
*/
|
|
40
|
+
ready() {
|
|
41
|
+
this._sprites = this._sprites.reverse();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Renders all the sprites in the rendering manager.
|
|
45
|
+
* @param worldMatrix World matrix to apply to the sprites.
|
|
46
|
+
* @param projectionMatrix Projection matrix to apply to the sprites.
|
|
47
|
+
*/
|
|
48
|
+
render(worldMatrix, projectionMatrix) {
|
|
49
|
+
this._engine.clear(this._configuration.backgroundColor, true, false, false);
|
|
50
|
+
this._spritesRenderer.render(this._sprites, 0, worldMatrix, projectionMatrix, this._customSpriteUpdate);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Disposes the rendering manager and its resources.
|
|
54
|
+
*/
|
|
55
|
+
dispose() {
|
|
56
|
+
this._sprites.length = 0;
|
|
57
|
+
this._spritesRenderer.texture = null; // Prevent disposal of the shared texture atlas.
|
|
58
|
+
this._spritesRenderer.dispose();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=renderingManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderingManager.js","sourceRoot":"","sources":["../../../../../dev/addons/src/lottie/rendering/renderingManager.ts"],"names":[],"mappings":"AAAA,oEAAsD;AACtD,mDAAqC;AACrC,qDAAuC;AAKvC,OAAO,EAAE,cAAc,EAAE,kDAAoC;AAM7D;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAOzB;;;;;OAKG;IACH,YAAmB,MAAkB,EAAE,aAA0B,EAAE,aAAqC;QA+ChG,wBAAmB,GAAG,GAAS,EAAE;YACrC,wDAAwD;YACxD,gEAAgE;QACpE,CAAC,CAAC;QAjDE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,eAAe,GAAG,aAAa,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;QAEpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QACjG,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC/C,IAAI,CAAC,gBAAgB,CAAC,cAAc,GAAG,KAAK,CAAC;QAC7C,IAAI,CAAC,gBAAgB,CAAC,UAAU,GAAG,KAAK,CAAC;QACzC,IAAI,CAAC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC;IACzD,CAAC;IAED;;;OAGG;IACI,SAAS,CAAC,MAAkB;QAC/B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACI,KAAK;QACR,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC5C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,WAAuB,EAAE,gBAA4B;QAC/D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5E,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC5G,CAAC;IAED;;OAEG;IACI,OAAO;QACV,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,gDAAgD;QACtF,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;IACpC,CAAC;CAMJ","sourcesContent":["import \"core/Engines/Extensions/engine.dynamicBuffer\";\r\nimport \"core/Shaders/sprites.vertex\";\r\nimport \"core/Shaders/sprites.fragment\";\r\n\r\nimport type { ThinEngine } from \"core/Engines/thinEngine\";\r\nimport type { ThinTexture } from \"core/Materials/Textures/thinTexture\";\r\nimport type { ThinSprite } from \"core/Sprites/thinSprite\";\r\nimport { SpriteRenderer } from \"core/Sprites/spriteRenderer\";\r\n\r\nimport type { ThinMatrix } from \"../maths/matrix\";\r\n\r\nimport type { AnimationConfiguration } from \"../lottiePlayer\";\r\n\r\n/**\r\n * Represents all the sprites from the animation and manages their rendering.\r\n */\r\nexport class RenderingManager {\r\n private readonly _engine: ThinEngine;\r\n private readonly _spritesRenderer: SpriteRenderer;\r\n private readonly _spritesTexture: ThinTexture;\r\n private _sprites: ThinSprite[];\r\n private readonly _configuration: AnimationConfiguration;\r\n\r\n /**\r\n * Creates a new instance of the RenderingManager.\r\n * @param engine ThinEngine instance used for rendering.\r\n * @param spriteTexture The texture atlas containing the sprites.\r\n * @param configuration Configuration options for the rendering manager.\r\n */\r\n public constructor(engine: ThinEngine, spriteTexture: ThinTexture, configuration: AnimationConfiguration) {\r\n this._engine = engine;\r\n this._spritesTexture = spriteTexture;\r\n this._sprites = [];\r\n this._configuration = configuration;\r\n\r\n this._spritesRenderer = new SpriteRenderer(this._engine, this._configuration.spritesCapacity, 0);\r\n this._spritesRenderer.disableDepthWrite = true;\r\n this._spritesRenderer.autoResetAlpha = false;\r\n this._spritesRenderer.fogEnabled = false;\r\n this._spritesRenderer.texture = this._spritesTexture;\r\n }\r\n\r\n /**\r\n * Adds a sprite to the rendering manager.\r\n * @param sprite Sprite to add to the rendering manager.\r\n */\r\n public addSprite(sprite: ThinSprite): void {\r\n this._sprites.push(sprite);\r\n }\r\n\r\n /**\r\n * Prepares the rendering manager for rendering.\r\n */\r\n public ready(): void {\r\n this._sprites = this._sprites.reverse();\r\n }\r\n\r\n /**\r\n * Renders all the sprites in the rendering manager.\r\n * @param worldMatrix World matrix to apply to the sprites.\r\n * @param projectionMatrix Projection matrix to apply to the sprites.\r\n */\r\n public render(worldMatrix: ThinMatrix, projectionMatrix: ThinMatrix): void {\r\n this._engine.clear(this._configuration.backgroundColor, true, false, false);\r\n this._spritesRenderer.render(this._sprites, 0, worldMatrix, projectionMatrix, this._customSpriteUpdate);\r\n }\r\n\r\n /**\r\n * Disposes the rendering manager and its resources.\r\n */\r\n public dispose(): void {\r\n this._sprites.length = 0;\r\n this._spritesRenderer.texture = null; // Prevent disposal of the shared texture atlas.\r\n this._spritesRenderer.dispose();\r\n }\r\n\r\n private _customSpriteUpdate = (): void => {\r\n // All the work is done upfront within the sprite render\r\n // so that we do not need babylon to update back the information\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ThinSprite } from "@babylonjs/core/Sprites/thinSprite.js";
|
|
2
|
+
import type { ScalarProperty, Vector2Property } from "../lottie/parsedTypes.js";
|
|
3
|
+
import { Node } from "../rendering/node.js";
|
|
4
|
+
/**
|
|
5
|
+
* Represents a sprite in the scene graph.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SpriteNode extends Node {
|
|
8
|
+
private _sprite;
|
|
9
|
+
private _originalWidth;
|
|
10
|
+
private _originalHeight;
|
|
11
|
+
private _firstTime;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new SpriteNode instance.
|
|
14
|
+
* @param id Unique identifier for the sprite node.
|
|
15
|
+
* @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.
|
|
16
|
+
* @param sprite The sprite associated with this node.
|
|
17
|
+
* @param position The position of the sprite in the scene.
|
|
18
|
+
* @param rotation The rotation of the sprite in degrees.
|
|
19
|
+
* @param scale The scale of the sprite in the scene.
|
|
20
|
+
* @param opacity The opacity of the sprite.
|
|
21
|
+
* @param parent The parent node in the scene graph.
|
|
22
|
+
*/
|
|
23
|
+
constructor(id: string, ignoreOpacityAnimations: boolean, sprite: ThinSprite, position?: Vector2Property, rotation?: ScalarProperty, scale?: Vector2Property, opacity?: ScalarProperty, parent?: Node);
|
|
24
|
+
/**
|
|
25
|
+
* Updates the node's properties based on the current frame of the animation.
|
|
26
|
+
* @param frame Frame number we are playing in the animation.
|
|
27
|
+
* @param isParentUpdated Whether the parent node has been updated.
|
|
28
|
+
* @param isReset Whether the node is being reset.
|
|
29
|
+
* @returns True if the node was updated, false otherwise.
|
|
30
|
+
*/
|
|
31
|
+
update(frame: number, isParentUpdated?: boolean, isReset?: boolean): boolean;
|
|
32
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Node } from "../rendering/node.js";
|
|
2
|
+
/**
|
|
3
|
+
* Temporary scale vector used during sprite updates for matrix decomposition.
|
|
4
|
+
*/
|
|
5
|
+
const TempScale = { x: 1, y: 1 };
|
|
6
|
+
/**
|
|
7
|
+
* Represents a sprite in the scene graph.
|
|
8
|
+
*/
|
|
9
|
+
export class SpriteNode extends Node {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new SpriteNode instance.
|
|
12
|
+
* @param id Unique identifier for the sprite node.
|
|
13
|
+
* @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.
|
|
14
|
+
* @param sprite The sprite associated with this node.
|
|
15
|
+
* @param position The position of the sprite in the scene.
|
|
16
|
+
* @param rotation The rotation of the sprite in degrees.
|
|
17
|
+
* @param scale The scale of the sprite in the scene.
|
|
18
|
+
* @param opacity The opacity of the sprite.
|
|
19
|
+
* @param parent The parent node in the scene graph.
|
|
20
|
+
*/
|
|
21
|
+
constructor(id, ignoreOpacityAnimations, sprite, position, rotation, scale, opacity, parent) {
|
|
22
|
+
super(id, ignoreOpacityAnimations, position, rotation, scale, opacity, parent);
|
|
23
|
+
this._firstTime = true;
|
|
24
|
+
this._sprite = sprite;
|
|
25
|
+
this._originalWidth = sprite.width;
|
|
26
|
+
this._originalHeight = sprite.height;
|
|
27
|
+
this._isShape = true;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Updates the node's properties based on the current frame of the animation.
|
|
31
|
+
* @param frame Frame number we are playing in the animation.
|
|
32
|
+
* @param isParentUpdated Whether the parent node has been updated.
|
|
33
|
+
* @param isReset Whether the node is being reset.
|
|
34
|
+
* @returns True if the node was updated, false otherwise.
|
|
35
|
+
*/
|
|
36
|
+
update(frame, isParentUpdated = false, isReset = false) {
|
|
37
|
+
const isDirty = super.update(frame, isParentUpdated, isReset) || this._firstTime;
|
|
38
|
+
this._firstTime = false;
|
|
39
|
+
if (isDirty) {
|
|
40
|
+
const rotation = this.worldMatrix.decompose(TempScale, this._sprite.position);
|
|
41
|
+
// Apply scaling to the original sprite dimensions
|
|
42
|
+
this._sprite.width = this._originalWidth * TempScale.x;
|
|
43
|
+
this._sprite.height = this._originalHeight * TempScale.y;
|
|
44
|
+
// Rotation
|
|
45
|
+
this._sprite.angle = rotation;
|
|
46
|
+
}
|
|
47
|
+
// Opacity
|
|
48
|
+
this._sprite.color.a = this.opacity;
|
|
49
|
+
return isDirty;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=spriteNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spriteNode.js","sourceRoot":"","sources":["../../../../../dev/addons/src/lottie/sprites/spriteNode.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC;;GAEG;AACH,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAEjC;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,IAAI;IAOhC;;;;;;;;;;OAUG;IACH,YACI,EAAU,EACV,uBAAgC,EAChC,MAAkB,EAClB,QAA0B,EAC1B,QAAyB,EACzB,KAAuB,EACvB,OAAwB,EACxB,MAAa;QAEb,KAAK,CAAC,EAAE,EAAE,uBAAuB,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAvB3E,eAAU,GAAG,IAAI,CAAC;QAyBtB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;QAErC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACa,MAAM,CAAC,KAAa,EAAE,eAAe,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK;QAC1E,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC;QACjF,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAExB,IAAI,OAAO,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAE9E,kDAAkD;YAClD,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC,CAAC;YACvD,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC;YAEzD,WAAW;YACX,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;QAClC,CAAC;QAED,UAAU;QACV,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;QAEpC,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ","sourcesContent":["import type { ThinSprite } from \"core/Sprites/thinSprite\";\r\n\r\nimport type { ScalarProperty, Vector2Property } from \"../lottie/parsedTypes\";\r\n\r\nimport { Node } from \"../rendering/node\";\r\n\r\n/**\r\n * Temporary scale vector used during sprite updates for matrix decomposition.\r\n */\r\nconst TempScale = { x: 1, y: 1 };\r\n\r\n/**\r\n * Represents a sprite in the scene graph.\r\n */\r\nexport class SpriteNode extends Node {\r\n private _sprite: ThinSprite;\r\n private _originalWidth: number;\r\n private _originalHeight: number;\r\n\r\n private _firstTime = true;\r\n\r\n /**\r\n * Creates a new SpriteNode instance.\r\n * @param id Unique identifier for the sprite node.\r\n * @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.\r\n * @param sprite The sprite associated with this node.\r\n * @param position The position of the sprite in the scene.\r\n * @param rotation The rotation of the sprite in degrees.\r\n * @param scale The scale of the sprite in the scene.\r\n * @param opacity The opacity of the sprite.\r\n * @param parent The parent node in the scene graph.\r\n */\r\n public constructor(\r\n id: string,\r\n ignoreOpacityAnimations: boolean,\r\n sprite: ThinSprite,\r\n position?: Vector2Property,\r\n rotation?: ScalarProperty,\r\n scale?: Vector2Property,\r\n opacity?: ScalarProperty,\r\n parent?: Node\r\n ) {\r\n super(id, ignoreOpacityAnimations, position, rotation, scale, opacity, parent);\r\n\r\n this._sprite = sprite;\r\n this._originalWidth = sprite.width;\r\n this._originalHeight = sprite.height;\r\n\r\n this._isShape = true;\r\n }\r\n\r\n /**\r\n * Updates the node's properties based on the current frame of the animation.\r\n * @param frame Frame number we are playing in the animation.\r\n * @param isParentUpdated Whether the parent node has been updated.\r\n * @param isReset Whether the node is being reset.\r\n * @returns True if the node was updated, false otherwise.\r\n */\r\n public override update(frame: number, isParentUpdated = false, isReset = false): boolean {\r\n const isDirty = super.update(frame, isParentUpdated, isReset) || this._firstTime;\r\n this._firstTime = false;\r\n\r\n if (isDirty) {\r\n const rotation = this.worldMatrix.decompose(TempScale, this._sprite.position);\r\n\r\n // Apply scaling to the original sprite dimensions\r\n this._sprite.width = this._originalWidth * TempScale.x;\r\n this._sprite.height = this._originalHeight * TempScale.y;\r\n\r\n // Rotation\r\n this._sprite.angle = rotation;\r\n }\r\n\r\n // Opacity\r\n this._sprite.color.a = this.opacity;\r\n\r\n return isDirty;\r\n }\r\n}\r\n"]}
|