@@ -50,24 +50,33 @@
|
|
50
50
|
return this._animatorController;
|
51
51
|
}
|
52
52
|
|
53
|
+
|
54
|
+
get parametersAreDirty() { return this._parametersAreDirty; }
|
55
|
+
get isDirty() { return this._isDirty; }
|
56
|
+
private _parametersAreDirty: boolean = false;
|
57
|
+
private _isDirty: boolean = false;
|
58
|
+
|
53
59
|
// NOTE: the uppercase events have been deprecated because UnityEvent methods are all exported with lowercase first letter
|
54
60
|
|
55
61
|
/**@deprecated use play */
|
56
62
|
Play(name: string | number, layer: number = -1, normalizedTime: number = Number.NEGATIVE_INFINITY, transitionDurationInSec: number = 0) { this.play(name, layer, normalizedTime, transitionDurationInSec); }
|
57
63
|
play(name: string | number, layer: number = -1, normalizedTime: number = Number.NEGATIVE_INFINITY, transitionDurationInSec: number = 0) {
|
58
64
|
this.runtimeAnimatorController?.play(name, layer, normalizedTime, transitionDurationInSec);
|
65
|
+
this._isDirty = true;
|
59
66
|
}
|
60
67
|
|
61
68
|
/**@deprecated use reset */
|
62
69
|
Reset() { this.reset(); }
|
63
70
|
reset() {
|
64
71
|
this._animatorController?.reset();
|
72
|
+
this._isDirty = true;
|
65
73
|
}
|
66
74
|
|
67
75
|
/**@deprecated use setBool */
|
68
76
|
SetBool(name: string | number, val: boolean) { this.setBool(name, val); }
|
69
77
|
setBool(name: string | number, value: boolean) {
|
70
78
|
this.runtimeAnimatorController?.setBool(name, value);
|
79
|
+
this._parametersAreDirty = true;
|
71
80
|
}
|
72
81
|
|
73
82
|
/**@deprecated use getBool */
|
@@ -80,6 +89,7 @@
|
|
80
89
|
SetFloat(name: string | number, val: number) { this.setFloat(name, val); }
|
81
90
|
setFloat(name: string | number, val: number) {
|
82
91
|
this.runtimeAnimatorController?.setFloat(name, val);
|
92
|
+
this._parametersAreDirty = true;
|
83
93
|
}
|
84
94
|
|
85
95
|
/**@deprecated use getFloat */
|
@@ -92,6 +102,7 @@
|
|
92
102
|
SetInteger(name: string | number, val: number) { this.setInteger(name, val); }
|
93
103
|
setInteger(name: string | number, val: number) {
|
94
104
|
this.runtimeAnimatorController?.setInteger(name, val);
|
105
|
+
this._parametersAreDirty = true;
|
95
106
|
}
|
96
107
|
|
97
108
|
/**@deprecated use getInteger */
|
@@ -103,20 +114,20 @@
|
|
103
114
|
/**@deprecated use setTrigger */
|
104
115
|
SetTrigger(name: string | number) { this.setTrigger(name); }
|
105
116
|
setTrigger(name: string | number) {
|
106
|
-
if (debug) console.log("SetTrigger", name);
|
107
117
|
this.runtimeAnimatorController?.setTrigger(name);
|
118
|
+
this._parametersAreDirty = true;
|
108
119
|
}
|
109
120
|
|
110
121
|
/**@deprecated use resetTrigger */
|
111
122
|
ResetTrigger(name: string | number) { this.resetTrigger(name); }
|
112
123
|
resetTrigger(name: string | number) {
|
113
124
|
this.runtimeAnimatorController?.resetTrigger(name);
|
125
|
+
this._parametersAreDirty = true;
|
114
126
|
}
|
115
127
|
|
116
128
|
/**@deprecated use getTrigger */
|
117
129
|
GetTrigger(name: string | number) { this.getTrigger(name); }
|
118
130
|
getTrigger(name: string | number) {
|
119
|
-
if (debug) console.log("GetTrigger", name);
|
120
131
|
this.runtimeAnimatorController?.getTrigger(name);
|
121
132
|
}
|
122
133
|
|
@@ -187,6 +198,9 @@
|
|
187
198
|
}
|
188
199
|
|
189
200
|
onBeforeRender() {
|
201
|
+
this._isDirty = false;
|
202
|
+
this._parametersAreDirty = false;
|
203
|
+
|
190
204
|
const isAnimatedExternally = getObjectAnimated(this.gameObject);
|
191
205
|
if (isAnimatedExternally) return;
|
192
206
|
|
@@ -96,22 +96,25 @@
|
|
96
96
|
// TODO: do we want to rename this event?
|
97
97
|
this.addEventListener("ready", this.onReady);
|
98
98
|
|
99
|
-
this.attachShadow({mode: 'open'});
|
99
|
+
this.attachShadow({ mode: 'open' });
|
100
100
|
const template = document.createElement('template');
|
101
|
-
template.innerHTML =
|
102
|
-
`<style>
|
101
|
+
template.innerHTML = `<style>
|
103
102
|
:host {
|
104
|
-
position:
|
103
|
+
position: absolute;
|
105
104
|
display: block;
|
106
|
-
width: max(600px,
|
107
|
-
height: max(300px,
|
105
|
+
width: max(600px, 100%);
|
106
|
+
height: max(300px, 100%);
|
108
107
|
}
|
109
108
|
@media (max-width: 600px) {
|
110
109
|
:host {
|
111
|
-
width:
|
112
|
-
height: 100vh;
|
110
|
+
width: 100%;
|
113
111
|
}
|
114
112
|
}
|
113
|
+
@media (max-height: 300px) {
|
114
|
+
:host {
|
115
|
+
height: 100%;
|
116
|
+
}
|
117
|
+
}
|
115
118
|
:host canvas {
|
116
119
|
position: absolute;
|
117
120
|
user-select: none;
|
@@ -197,6 +197,7 @@
|
|
197
197
|
}
|
198
198
|
|
199
199
|
stop() {
|
200
|
+
this._isStopping = true;
|
200
201
|
for (const track of this._audioTracks) track.stop();
|
201
202
|
const pauseChanged = this._isPaused == true;
|
202
203
|
const wasPlaying = this._isPlaying;
|
@@ -214,6 +215,7 @@
|
|
214
215
|
if (this._internalUpdateRoutine)
|
215
216
|
this.stopCoroutine(this._internalUpdateRoutine);
|
216
217
|
this._internalUpdateRoutine = null;
|
218
|
+
this._isStopping = false;
|
217
219
|
}
|
218
220
|
|
219
221
|
evaluate() {
|
@@ -266,6 +268,8 @@
|
|
266
268
|
private _isPlaying: boolean = false;
|
267
269
|
private _internalUpdateRoutine: any;
|
268
270
|
private _isPaused: boolean = false;
|
271
|
+
/** internal, true during the time stop() is being processed */
|
272
|
+
private _isStopping: boolean = false;
|
269
273
|
private _time: number = 0;
|
270
274
|
private _duration: number = 0;
|
271
275
|
private _weight: number = 1;
|
@@ -341,8 +345,13 @@
|
|
341
345
|
}
|
342
346
|
}
|
343
347
|
|
344
|
-
|
345
|
-
|
348
|
+
// When timeline reaches the end "stop()" is called which is evaluating with time 0
|
349
|
+
// We don't want to re-evaluate the animation then in case the timeline is blended with the Animator
|
350
|
+
// e.g then the timeline animation at time 0 is 100% applied on top of the animator animation
|
351
|
+
if (!this._isStopping) {
|
352
|
+
for (const handler of this._animationTracks) {
|
353
|
+
handler.evaluate(time);
|
354
|
+
}
|
346
355
|
}
|
347
356
|
for (const handler of this._audioTracks) {
|
348
357
|
handler.evaluate(time);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { TypeStore } from "./../engine_typestore.js"
|
2
|
-
|
2
|
+
|
3
3
|
// Import types
|
4
4
|
import { __Ignore } from "../../engine-components/codegen/components.js";
|
5
5
|
import { ActionBuilder } from "../../engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js";
|
@@ -217,7 +217,7 @@
|
|
217
217
|
import { XRGrabRendering } from "../../engine-components/webxr/WebXRGrabRendering.js";
|
218
218
|
import { XRRig } from "../../engine-components/webxr/WebXRRig.js";
|
219
219
|
import { XRState } from "../../engine-components/XRFlag.js";
|
220
|
-
|
220
|
+
|
221
221
|
// Register types
|
222
222
|
TypeStore.add("__Ignore", __Ignore);
|
223
223
|
TypeStore.add("ActionBuilder", ActionBuilder);
|
@@ -287,13 +287,7 @@
|
|
287
287
|
evaluate(time: number) {
|
288
288
|
if (this.track.muted) return;
|
289
289
|
if (!this.mixer) return;
|
290
|
-
|
291
|
-
// consider the case where we want to blend into an Animator (e.g. last clip is faded out)
|
292
|
-
// and currently evaluate is being called when the director is stopped which happens for example
|
293
|
-
// if Wrap mode is set to None. I think it makes sense to NOT evaluate anymore when stopping (not sure why we did it in the first place)
|
294
|
-
// I won't change the root behaviour on the other tracks for now to avoid side-effects
|
295
|
-
if (!this.director.isPlaying) return;
|
296
|
-
|
290
|
+
|
297
291
|
this.bind();
|
298
292
|
|
299
293
|
// if (this._animator && this.director.isPlaying && this.director.weight > 0) this._animator.enabled = false;
|
@@ -142,6 +142,8 @@
|
|
142
142
|
if (!hasProLicense()) name += "-MadeWithNeedle";
|
143
143
|
name += "-" + getFormattedDate(); // seems iOS caches the file in some cases, this ensures we always have a fresh file
|
144
144
|
|
145
|
+
if (!this.link) this.link = ensureQuicklookLinkIsCreated(this.context);
|
146
|
+
|
145
147
|
// ability to specify a custom USDZ file to be used instead of a dynamic one
|
146
148
|
if (this.customUsdzFile) {
|
147
149
|
if(debug) console.log("Exporting custom usdz", this.customUsdzFile)
|