@needle-tools/engine 5.1.0-canary.deec6e4 → 5.1.0-canary.e7c2511
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/CHANGELOG.md +18 -0
- package/components.needle.json +1 -1
- package/dist/{needle-engine.bundle-CvtELXh0.js → needle-engine.bundle-D-eWNCu1.js} +15969 -15550
- package/dist/needle-engine.bundle-D3ZUII8o.min.js +1733 -0
- package/dist/needle-engine.bundle-_rOpvUGL.umd.cjs +1733 -0
- package/dist/needle-engine.d.ts +746 -156
- package/dist/needle-engine.js +529 -529
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/api.d.ts +5 -0
- package/lib/engine/api.js +4 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/codegen/register_types.js +2 -10
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_audio.d.ts +68 -0
- package/lib/engine/engine_audio.js +172 -0
- package/lib/engine/engine_audio.js.map +1 -1
- package/lib/engine/engine_components.js +1 -1
- package/lib/engine/engine_components.js.map +1 -1
- package/lib/engine/engine_context.d.ts +1 -1
- package/lib/engine/engine_context.js +2 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_disposable.d.ts +171 -0
- package/lib/engine/engine_disposable.js +136 -0
- package/lib/engine/engine_disposable.js.map +1 -0
- package/lib/engine/engine_gameobject.d.ts +1 -10
- package/lib/engine/engine_gameobject.js +22 -120
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_gltf_builtin_components.js +7 -69
- package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
- package/lib/engine/engine_init.js +6 -6
- package/lib/engine/engine_init.js.map +1 -1
- package/lib/engine/engine_input.d.ts +1 -1
- package/lib/engine/engine_input.js +1 -1
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_instantiate_resolve.d.ts +42 -0
- package/lib/engine/engine_instantiate_resolve.js +372 -0
- package/lib/engine/engine_instantiate_resolve.js.map +1 -0
- package/lib/engine/engine_license.js +1 -1
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_mainloop_utils.js +5 -2
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_networking.js +3 -1
- package/lib/engine/engine_networking.js.map +1 -1
- package/lib/engine/engine_networking_blob.js +1 -1
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +11 -3
- package/lib/engine/engine_physics_rapier.js +88 -25
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_scenedata.js +2 -2
- package/lib/engine/engine_scenedata.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.js +28 -5
- package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
- package/lib/engine/engine_serialization_core.d.ts +1 -0
- package/lib/engine/engine_serialization_core.js +7 -0
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_types.d.ts +17 -9
- package/lib/engine/engine_types.js +1 -1
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_util_decorator.js +7 -2
- package/lib/engine/engine_util_decorator.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +1 -1
- package/lib/engine/engine_utils.js +19 -5
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
- package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine/webcomponents/needle-engine.d.ts +10 -4
- package/lib/engine/webcomponents/needle-engine.js +1 -1
- package/lib/engine/webcomponents/needle-engine.js.map +1 -1
- package/lib/engine/xr/NeedleXRSession.d.ts +3 -2
- package/lib/engine/xr/NeedleXRSession.js +50 -14
- package/lib/engine/xr/NeedleXRSession.js.map +1 -1
- package/lib/engine/xr/events.d.ts +1 -1
- package/lib/engine/xr/events.js.map +1 -1
- package/lib/engine-components/Animation.js +17 -16
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/Animator.d.ts +6 -0
- package/lib/engine-components/Animator.js +17 -12
- package/lib/engine-components/Animator.js.map +1 -1
- package/lib/engine-components/AnimatorController.builder.d.ts +113 -0
- package/lib/engine-components/AnimatorController.builder.js +195 -0
- package/lib/engine-components/AnimatorController.builder.js.map +1 -0
- package/lib/engine-components/AnimatorController.d.ts +2 -119
- package/lib/engine-components/AnimatorController.js +31 -232
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/AudioSource.d.ts +19 -3
- package/lib/engine-components/AudioSource.js +121 -68
- package/lib/engine-components/AudioSource.js.map +1 -1
- package/lib/engine-components/Collider.d.ts +18 -9
- package/lib/engine-components/Collider.js +61 -14
- package/lib/engine-components/Collider.js.map +1 -1
- package/lib/engine-components/Component.d.ts +58 -6
- package/lib/engine-components/Component.js +77 -0
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/DragControls.d.ts +7 -0
- package/lib/engine-components/DragControls.js +19 -7
- package/lib/engine-components/DragControls.js.map +1 -1
- package/lib/engine-components/EventList.d.ts +31 -9
- package/lib/engine-components/EventList.js +37 -76
- package/lib/engine-components/EventList.js.map +1 -1
- package/lib/engine-components/Joints.d.ts +4 -2
- package/lib/engine-components/Joints.js +19 -3
- package/lib/engine-components/Joints.js.map +1 -1
- package/lib/engine-components/Light.js +9 -1
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/Networking.d.ts +1 -1
- package/lib/engine-components/Networking.js +1 -1
- package/lib/engine-components/OrbitControls.js +16 -11
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/RigidBody.d.ts +12 -4
- package/lib/engine-components/RigidBody.js +18 -4
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SeeThrough.js +2 -2
- package/lib/engine-components/SeeThrough.js.map +1 -1
- package/lib/engine-components/api.d.ts +1 -1
- package/lib/engine-components/api.js +1 -1
- package/lib/engine-components/api.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +3 -9
- package/lib/engine-components/codegen/components.js +3 -9
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +16 -6
- package/lib/engine-components/timeline/PlayableDirector.js +63 -61
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
- package/lib/engine-components/timeline/SignalAsset.js +1 -0
- package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
- package/lib/engine-components/timeline/TimelineBuilder.d.ts +247 -0
- package/lib/engine-components/timeline/TimelineBuilder.js +400 -0
- package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
- package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
- package/lib/engine-components/timeline/TimelineModels.js +3 -0
- package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +23 -0
- package/lib/engine-components/timeline/TimelineTracks.js +71 -13
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/timeline/index.d.ts +2 -1
- package/lib/engine-components/timeline/index.js +2 -0
- package/lib/engine-components/timeline/index.js.map +1 -1
- package/lib/engine-components/ui/Canvas.d.ts +1 -1
- package/lib/engine-components/ui/Canvas.js +2 -8
- package/lib/engine-components/ui/Canvas.js.map +1 -1
- package/lib/engine-components/ui/Text.d.ts +1 -0
- package/lib/engine-components/ui/Text.js +10 -7
- package/lib/engine-components/ui/Text.js.map +1 -1
- package/lib/engine-components/web/CursorFollow.js +21 -12
- package/lib/engine-components/web/CursorFollow.js.map +1 -1
- package/lib/engine-components/webxr/WebXRImageTracking.js +4 -0
- package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
- package/package.json +2 -83
- package/plugins/common/worker.js +9 -4
- package/plugins/vite/asap.js +17 -8
- package/plugins/vite/dependencies.js +29 -0
- package/plugins/vite/dependency-watcher.js +2 -2
- package/plugins/vite/editor-connection.js +3 -3
- package/plugins/vite/local-files-core.js +3 -3
- package/plugins/vite/local-files-utils.d.ts +3 -1
- package/plugins/vite/local-files-utils.js +29 -5
- package/plugins/vite/reload.js +1 -1
- package/plugins/vite/server.js +2 -1
- package/src/engine/api.ts +7 -0
- package/src/engine/codegen/register_types.ts +2 -10
- package/src/engine/engine_audio.ts +184 -0
- package/src/engine/engine_components.ts +1 -1
- package/src/engine/engine_context.ts +3 -3
- package/src/engine/engine_disposable.ts +213 -0
- package/src/engine/engine_gameobject.ts +54 -159
- package/src/engine/engine_gltf_builtin_components.ts +7 -76
- package/src/engine/engine_init.ts +6 -6
- package/src/engine/engine_input.ts +1 -1
- package/src/engine/engine_instantiate_resolve.ts +407 -0
- package/src/engine/engine_license.ts +1 -1
- package/src/engine/engine_mainloop_utils.ts +5 -2
- package/src/engine/engine_networking.ts +3 -1
- package/src/engine/engine_networking_blob.ts +1 -1
- package/src/engine/engine_physics_rapier.ts +82 -27
- package/src/engine/engine_scenedata.ts +3 -3
- package/src/engine/engine_serialization_builtin_serializer.ts +32 -9
- package/src/engine/engine_serialization_core.ts +9 -0
- package/src/engine/engine_types.ts +22 -13
- package/src/engine/engine_util_decorator.ts +7 -2
- package/src/engine/engine_utils.ts +16 -5
- package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
- package/src/engine/webcomponents/needle menu/needle-menu.ts +1 -1
- package/src/engine/webcomponents/needle-engine.ts +10 -4
- package/src/engine/xr/NeedleXRSession.ts +48 -13
- package/src/engine/xr/events.ts +1 -1
- package/src/engine-components/Animation.ts +19 -16
- package/src/engine-components/Animator.ts +18 -11
- package/src/engine-components/AnimatorController.builder.ts +261 -0
- package/src/engine-components/AnimatorController.ts +19 -291
- package/src/engine-components/AudioSource.ts +130 -79
- package/src/engine-components/Collider.ts +66 -18
- package/src/engine-components/Component.ts +79 -9
- package/src/engine-components/DragControls.ts +18 -11
- package/src/engine-components/EventList.ts +45 -83
- package/src/engine-components/Joints.ts +20 -4
- package/src/engine-components/Light.ts +10 -2
- package/src/engine-components/Networking.ts +1 -1
- package/src/engine-components/OrbitControls.ts +18 -9
- package/src/engine-components/RigidBody.ts +18 -4
- package/src/engine-components/SeeThrough.ts +2 -2
- package/src/engine-components/api.ts +1 -1
- package/src/engine-components/codegen/components.ts +3 -9
- package/src/engine-components/timeline/PlayableDirector.ts +61 -64
- package/src/engine-components/timeline/SignalAsset.ts +4 -1
- package/src/engine-components/timeline/TimelineBuilder.ts +565 -0
- package/src/engine-components/timeline/TimelineModels.ts +5 -1
- package/src/engine-components/timeline/TimelineTracks.ts +74 -13
- package/src/engine-components/timeline/index.ts +2 -1
- package/src/engine-components/ui/Canvas.ts +2 -8
- package/src/engine-components/ui/Text.ts +12 -8
- package/src/engine-components/web/CursorFollow.ts +21 -13
- package/src/engine-components/webxr/WebXRImageTracking.ts +2 -0
- package/dist/needle-engine.bundle-1s2gOoKZ.min.js +0 -1732
- package/dist/needle-engine.bundle-j4nGJXCs.umd.cjs +0 -1732
- package/lib/engine-components/AvatarLoader.d.ts +0 -80
- package/lib/engine-components/AvatarLoader.js +0 -232
- package/lib/engine-components/AvatarLoader.js.map +0 -1
- package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
- package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
- package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
- package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
- package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
- package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
- package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
- package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
- package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
- package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
- package/src/engine-components/AvatarLoader.ts +0 -264
- package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
- package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
- package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
- package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
- package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
|
@@ -4,6 +4,7 @@ import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../eng
|
|
|
4
4
|
import { Behaviour, Component, GameObject } from "../engine-components/Component.js";
|
|
5
5
|
import { CallInfo, EventList } from "../engine-components/EventList.js";
|
|
6
6
|
import { AssetReference } from "./engine_addressables.js";
|
|
7
|
+
import { AudioClip } from "./engine_audio.js";
|
|
7
8
|
import { debugExtension } from "./engine_default_parameters.js";
|
|
8
9
|
import { SerializationContext, TypeSerializer } from "./engine_serialization_core.js";
|
|
9
10
|
import { RenderTexture } from "./engine_texture.js";
|
|
@@ -11,7 +12,7 @@ import { IComponent } from "./engine_types.js";
|
|
|
11
12
|
import { resolveUrl } from "./engine_utils.js";
|
|
12
13
|
import { RGBAColor } from "./js-extensions/index.js";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
// #region Color
|
|
15
16
|
class ColorSerializer extends TypeSerializer {
|
|
16
17
|
constructor() {
|
|
17
18
|
super([Color, RGBAColor], "ColorSerializer")
|
|
@@ -35,6 +36,8 @@ class ColorSerializer extends TypeSerializer {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
// #region Euler
|
|
40
|
+
|
|
38
41
|
class EulerSerializer extends TypeSerializer {
|
|
39
42
|
constructor() {
|
|
40
43
|
super([Euler], "EulerSerializer");
|
|
@@ -58,6 +61,8 @@ declare type ObjectData = {
|
|
|
58
61
|
node?: number;
|
|
59
62
|
guid?: string;
|
|
60
63
|
}
|
|
64
|
+
|
|
65
|
+
// #region ObjectSerializer
|
|
61
66
|
class ObjectSerializer extends TypeSerializer {
|
|
62
67
|
constructor() {
|
|
63
68
|
super(Object3D, "ObjectSerializer");
|
|
@@ -119,7 +124,7 @@ class ObjectSerializer extends TypeSerializer {
|
|
|
119
124
|
}
|
|
120
125
|
if (!res) {
|
|
121
126
|
if (isDevEnvironment() || debugExtension)
|
|
122
|
-
console.warn(
|
|
127
|
+
console.warn(`Could not resolve object reference \"${context.path}\" (guid: ${data.guid}). The referenced object may have been deleted — check if the reference is still valid in your scene.`);
|
|
123
128
|
data["could_not_resolve"] = true;
|
|
124
129
|
}
|
|
125
130
|
else {
|
|
@@ -137,7 +142,7 @@ class ObjectSerializer extends TypeSerializer {
|
|
|
137
142
|
}
|
|
138
143
|
}
|
|
139
144
|
|
|
140
|
-
|
|
145
|
+
// #region ComponentSerializer
|
|
141
146
|
class ComponentSerializer extends TypeSerializer {
|
|
142
147
|
|
|
143
148
|
constructor() {
|
|
@@ -226,6 +231,7 @@ declare type EventListCall = {
|
|
|
226
231
|
|
|
227
232
|
const $eventListDebugInfo = Symbol("eventListDebugInfo");
|
|
228
233
|
|
|
234
|
+
// #region EventListSerializer
|
|
229
235
|
class EventListSerializer extends TypeSerializer {
|
|
230
236
|
constructor() {
|
|
231
237
|
super([EventList]);
|
|
@@ -328,11 +334,6 @@ class EventListSerializer extends TypeSerializer {
|
|
|
328
334
|
if (debugExtension)
|
|
329
335
|
console.log(evt);
|
|
330
336
|
|
|
331
|
-
const eventListOwner = context.target;
|
|
332
|
-
if (eventListOwner !== undefined && context.path !== undefined) {
|
|
333
|
-
evt.setEventTarget(context.path, eventListOwner);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
337
|
return evt;
|
|
337
338
|
}
|
|
338
339
|
return undefined;
|
|
@@ -371,6 +372,7 @@ class EventListSerializer extends TypeSerializer {
|
|
|
371
372
|
*/
|
|
372
373
|
const cloneOriginalMap = new WeakMap<Texture, Texture>();
|
|
373
374
|
|
|
375
|
+
// #region RenderTextureSerializer
|
|
374
376
|
export class RenderTextureSerializer extends TypeSerializer {
|
|
375
377
|
constructor() {
|
|
376
378
|
super([RenderTexture, WebGLRenderTarget]);
|
|
@@ -412,7 +414,7 @@ export class RenderTextureSerializer extends TypeSerializer {
|
|
|
412
414
|
}
|
|
413
415
|
}
|
|
414
416
|
|
|
415
|
-
|
|
417
|
+
// #region UriSerializer
|
|
416
418
|
export class UriSerializer extends TypeSerializer {
|
|
417
419
|
constructor() {
|
|
418
420
|
super([URL]);
|
|
@@ -430,7 +432,27 @@ export class UriSerializer extends TypeSerializer {
|
|
|
430
432
|
}
|
|
431
433
|
}
|
|
432
434
|
|
|
435
|
+
// #region AudioClipSerializer
|
|
436
|
+
class AudioClipSerializer extends TypeSerializer {
|
|
437
|
+
constructor() {
|
|
438
|
+
super([AudioClip]);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
onSerialize(_data: AudioClip, _context: SerializationContext) {
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
onDeserialize(data: string, context: SerializationContext) {
|
|
446
|
+
if (typeof data === "string" && data.length > 0) {
|
|
447
|
+
const url = resolveUrl(context.gltfId, data);
|
|
448
|
+
if (url) return new AudioClip(url);
|
|
449
|
+
}
|
|
450
|
+
return undefined;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
433
454
|
|
|
455
|
+
// #region Init serializer
|
|
434
456
|
// Module-level references used by EventListSerializer internally
|
|
435
457
|
export let colorSerializer: ColorSerializer;
|
|
436
458
|
export let objectSerializer: ObjectSerializer;
|
|
@@ -460,4 +482,5 @@ export function initBuiltinSerializers() {
|
|
|
460
482
|
eventListSerializer = new EventListSerializer();
|
|
461
483
|
new RenderTextureSerializer();
|
|
462
484
|
new UriSerializer();
|
|
485
|
+
new AudioClipSerializer();
|
|
463
486
|
}
|
|
@@ -207,6 +207,15 @@ export interface ISerializable {
|
|
|
207
207
|
onAfterDeserialize?(data: any, context: SerializationContext): void;
|
|
208
208
|
};
|
|
209
209
|
|
|
210
|
+
export function isSerializable(obj: any): obj is ISerializable {
|
|
211
|
+
return obj && typeof obj === "object" && (
|
|
212
|
+
typeof obj.$serializedTypes === "object" ||
|
|
213
|
+
typeof obj.onBeforeDeserialize === "function" ||
|
|
214
|
+
typeof obj.onBeforeDeserializeMember === "function" ||
|
|
215
|
+
typeof obj.onAfterDeserializeMember === "function" ||
|
|
216
|
+
typeof obj.onAfterDeserialize === "function"
|
|
217
|
+
)
|
|
218
|
+
}
|
|
210
219
|
|
|
211
220
|
export function serializeObject(obj: ISerializable, context: SerializationContext): object | null {
|
|
212
221
|
const types = obj.$serializedTypes;
|
|
@@ -5,7 +5,6 @@ import { type GLTF as THREE_GLTF } from "three/examples/jsm/loaders/GLTFLoader.j
|
|
|
5
5
|
|
|
6
6
|
import type { Camera as CameraComponent } from "../engine-components/api.js";
|
|
7
7
|
import type { Context } from "./engine_context.js";
|
|
8
|
-
import { InstantiateContext } from "./engine_gameobject.js";
|
|
9
8
|
import { CollisionDetectionMode, type PhysicsMaterial, RigidbodyConstraints } from "./engine_physics.types.js";
|
|
10
9
|
import { CircularBuffer } from "./engine_utils.js";
|
|
11
10
|
import type { NeedleXRSession } from "./engine_xr.js";
|
|
@@ -201,8 +200,6 @@ export interface IComponent extends IHasGuid {
|
|
|
201
200
|
__internalDisable(isAddingOrRemovingFromScene?: boolean);
|
|
202
201
|
/** @internal */
|
|
203
202
|
__internalDestroy();
|
|
204
|
-
/** @internal */
|
|
205
|
-
resolveGuids?(guidsMap: GuidsMap): void;
|
|
206
203
|
|
|
207
204
|
/** experimental, called when the script is registered for the first time, this is called even if the component is not enabled. */
|
|
208
205
|
registering?();
|
|
@@ -240,14 +237,14 @@ export interface IComponent extends IHasGuid {
|
|
|
240
237
|
}
|
|
241
238
|
|
|
242
239
|
export function isComponent(obj: any): obj is IComponent {
|
|
243
|
-
return obj && obj.isComponent;
|
|
240
|
+
return obj && typeof obj === "object" && obj.isComponent;
|
|
244
241
|
}
|
|
245
242
|
|
|
246
243
|
export type ICamera = CameraComponent;
|
|
247
244
|
|
|
248
245
|
export type IAnimationComponent = Pick<IComponent, "gameObject"> & {
|
|
249
246
|
isAnimationComponent: boolean;
|
|
250
|
-
addClip?(clip: AnimationClip);
|
|
247
|
+
addClip?(clip: AnimationClip): void;
|
|
251
248
|
}
|
|
252
249
|
|
|
253
250
|
/** Interface for a camera controller component that can be attached to a camera to control it */
|
|
@@ -274,7 +271,10 @@ export declare interface IRenderer extends IComponent {
|
|
|
274
271
|
|
|
275
272
|
export declare interface IEventList {
|
|
276
273
|
readonly isEventList: true;
|
|
277
|
-
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export declare interface ISignalReceiver {
|
|
277
|
+
readonly isSignalReceiver: true;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
// export declare interface IPhysicsComponent extends IComponent {
|
|
@@ -302,12 +302,18 @@ export declare interface ICollider extends IComponent {
|
|
|
302
302
|
* Default: [0]
|
|
303
303
|
*/
|
|
304
304
|
membership?: number[];
|
|
305
|
-
/** The collider filter indicates what groups the collider can interact with (e.g. group 3 and 4)
|
|
306
|
-
* An `undefined` array indicates that the collider can interact with all groups
|
|
307
|
-
* Note: Make sure to call updateProperties after having changed this property
|
|
305
|
+
/** The collider filter indicates what groups the collider can interact with (e.g. group 3 and 4)
|
|
306
|
+
* An `undefined` array indicates that the collider can interact with all groups
|
|
307
|
+
* Note: Make sure to call updateProperties after having changed this property
|
|
308
308
|
* Default: undefined
|
|
309
309
|
*/
|
|
310
310
|
filter?: number[];
|
|
311
|
+
/** The density of the collider used for automatic mass calculation.
|
|
312
|
+
* When the attached Rigidbody has `autoMass` enabled, the mass is computed as `density × volume`.
|
|
313
|
+
* Note: Make sure to call updateProperties after having changed this property
|
|
314
|
+
* Default: undefined (uses physics engine default of 1.0)
|
|
315
|
+
*/
|
|
316
|
+
density?: number;
|
|
311
317
|
}
|
|
312
318
|
|
|
313
319
|
export declare interface ISphereCollider extends ICollider {
|
|
@@ -475,8 +481,10 @@ export interface IPhysicsEngine {
|
|
|
475
481
|
postStep();
|
|
476
482
|
/** Indicates whether the physics engine is currently updating */
|
|
477
483
|
get isUpdating(): boolean;
|
|
478
|
-
/**
|
|
479
|
-
|
|
484
|
+
/** Tears down the physics world and frees all resources. The world will be re-created on next use. */
|
|
485
|
+
dispose(): void;
|
|
486
|
+
/** @deprecated Use {@link dispose} instead. */
|
|
487
|
+
clearCaches(): void;
|
|
480
488
|
|
|
481
489
|
/** Enables or disables the physics engine */
|
|
482
490
|
enabled: boolean;
|
|
@@ -738,8 +746,9 @@ export interface IPhysicsEngine {
|
|
|
738
746
|
getBody(obj: ICollider | IRigidbody): null | any;
|
|
739
747
|
|
|
740
748
|
// Joints
|
|
741
|
-
addFixedJoint(body1: IRigidbody, body2: IRigidbody);
|
|
742
|
-
addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: Vec3, axis: Vec3);
|
|
749
|
+
addFixedJoint(body1: IRigidbody, body2: IRigidbody): Promise<any> | any;
|
|
750
|
+
addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: Vec3, axis: Vec3): Promise<any> | any;
|
|
751
|
+
removeJoint(joint: any): void;
|
|
743
752
|
|
|
744
753
|
/** Enable to render collider shapes */
|
|
745
754
|
debugRenderColliders: boolean;
|
|
@@ -79,8 +79,12 @@ function createPropertyWrapper(target: IComponent | any, _propertyKey: string |
|
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
//
|
|
83
|
-
|
|
82
|
+
// Only install the getter/setter once per instance.
|
|
83
|
+
// processStart may call __internalAwake again for components that were inactive
|
|
84
|
+
// during processNewScripts — the base Component.__internalAwake has a __didAwake guard
|
|
85
|
+
// but this decorator wrapper runs before reaching it, so we need our own idempotency check.
|
|
86
|
+
const desc = Object.getOwnPropertyDescriptor(this, propertyKey);
|
|
87
|
+
if (!desc || !desc.get) {
|
|
84
88
|
|
|
85
89
|
// make sure the field is initialized in a hidden property
|
|
86
90
|
this[$prop] = this[propertyKey];
|
|
@@ -99,6 +103,7 @@ function createPropertyWrapper(target: IComponent | any, _propertyKey: string |
|
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
Object.defineProperty(this, propertyKey, {
|
|
106
|
+
configurable: true,
|
|
102
107
|
set: function (v) {
|
|
103
108
|
if (this[$isAssigningProperties] === true) {
|
|
104
109
|
this[$prop] = v;
|
|
@@ -279,24 +279,35 @@ declare type deepClonePredicate = (owner: any, propertyName: string, current: an
|
|
|
279
279
|
* return true;
|
|
280
280
|
* });
|
|
281
281
|
* */
|
|
282
|
-
export function deepClone(obj: any, predicate?: deepClonePredicate): any {
|
|
282
|
+
export function deepClone(obj: any, predicate?: deepClonePredicate, _visited?: WeakSet<object>): any {
|
|
283
283
|
if (obj !== null && obj !== undefined && typeof obj === "object") {
|
|
284
|
+
if (!_visited) _visited = new WeakSet();
|
|
285
|
+
if (_visited.has(obj)) return obj;
|
|
286
|
+
_visited.add(obj);
|
|
287
|
+
|
|
284
288
|
let clone;
|
|
285
289
|
if (Array.isArray(obj)) clone = [];
|
|
286
290
|
else {
|
|
287
|
-
clone = Object.create(obj);
|
|
288
|
-
|
|
291
|
+
clone = Object.create(Object.getPrototypeOf(obj));
|
|
292
|
+
// Copy own properties, skipping getter-only properties that can't be set
|
|
293
|
+
const descriptors = Object.getOwnPropertyDescriptors(obj);
|
|
294
|
+
for (const key in descriptors) {
|
|
295
|
+
const desc = descriptors[key];
|
|
296
|
+
if (desc.set || desc.writable !== false) {
|
|
297
|
+
try { clone[key] = obj[key]; }
|
|
298
|
+
catch { /* skip read-only properties */ }
|
|
299
|
+
}
|
|
300
|
+
}
|
|
289
301
|
}
|
|
290
302
|
for (const key of Object.keys(obj)) {
|
|
291
303
|
const val = obj[key];
|
|
292
304
|
if (predicate && !predicate(obj, key, val)) {
|
|
293
|
-
// console.log("SKIP", val);
|
|
294
305
|
clone[key] = val;
|
|
295
306
|
}
|
|
296
307
|
else if (val?.clone !== undefined && typeof val.clone === "function")
|
|
297
308
|
clone[key] = val.clone();
|
|
298
309
|
else
|
|
299
|
-
clone[key] = deepClone(val, predicate);
|
|
310
|
+
clone[key] = deepClone(val, predicate, _visited);
|
|
300
311
|
}
|
|
301
312
|
return clone;
|
|
302
313
|
}
|
|
@@ -35,7 +35,7 @@ export class GenerateMeshBVHWorker extends WorkerBase {
|
|
|
35
35
|
|
|
36
36
|
worker.onerror = e => {
|
|
37
37
|
|
|
38
|
-
reject(new Error(`[GenerateMeshBVHWorker] ${e.message || "
|
|
38
|
+
reject(new Error(`[GenerateMeshBVHWorker] ${e.message || "Could not load worker."}`));
|
|
39
39
|
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { showBalloonMessage } from "../../debug/debug.js";
|
|
2
|
-
import { HTMLElementBase } from "../../engine_ssr.js";
|
|
3
2
|
import type { Context } from "../../engine_context.js";
|
|
4
3
|
import { hasCommercialLicense, onLicenseCheckResultChanged, Telemetry } from "../../engine_license.js";
|
|
5
4
|
import { isLocalNetwork } from "../../engine_networking_utils.js";
|
|
5
|
+
import { HTMLElementBase } from "../../engine_ssr.js";
|
|
6
6
|
import { DeviceUtilities, getParam } from "../../engine_utils.js";
|
|
7
7
|
import { onXRSessionStart, XRSessionEventArgs } from "../../xr/events.js";
|
|
8
8
|
import { ButtonsFactory } from "../buttons.js";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
|
|
2
|
-
import { HTMLElementBase } from "../engine_ssr.js";
|
|
3
2
|
import { PUBLIC_KEY, VERSION } from "../engine_constants.js";
|
|
4
3
|
import { ContextEvent, ContextRegistry } from "../engine_context_registry.js";
|
|
5
4
|
import { hasCommercialLicense } from "../engine_license.js";
|
|
6
5
|
import { onStart } from "../engine_lifecycle_api.js";
|
|
7
6
|
import { setDracoDecoderPath, setDracoDecoderType, setKtx2TranscoderPath } from "../engine_loaders.gltf.js";
|
|
8
7
|
import { Context, ContextCreateArgs } from "../engine_setup.js";
|
|
8
|
+
import { HTMLElementBase } from "../engine_ssr.js";
|
|
9
9
|
import { nameToThreeTonemapping } from "../engine_tonemapping.js";
|
|
10
10
|
import { type INeedleEngineComponent, type LoadedModel } from "../engine_types.js";
|
|
11
11
|
import type { addAttributeChangeCallback } from "../engine_utils.js";
|
|
@@ -42,11 +42,17 @@ export interface NeedleEngineAttributes {
|
|
|
42
42
|
'hash': string;
|
|
43
43
|
/** Set to automatically add OrbitControls to the loaded scene. */
|
|
44
44
|
'camera-controls': string;
|
|
45
|
-
/** Override the default
|
|
45
|
+
/** Override the default Draco decoder/decompressor path. Can be a URL or a local path to a directory containing the Draco decoder files.
|
|
46
|
+
* @default "https://www.gstatic.com/draco/versioned/decoders/1.5.7/"
|
|
47
|
+
* @example <needle-engine dracoDecoderPath="./decoders/draco/"></needle-engine>
|
|
48
|
+
*/
|
|
46
49
|
'dracoDecoderPath': string;
|
|
47
|
-
/** Override the default
|
|
50
|
+
/** Override the default Draco decoder type. */
|
|
48
51
|
'dracoDecoderType': 'wasm' | 'js';
|
|
49
|
-
/** Override the default KTX2 transcoder/decoder path.
|
|
52
|
+
/** Override the default KTX2 transcoder/decoder path. Can be a URL or a local path to a directory containing the KTX2 transcoder files.
|
|
53
|
+
* @default "https://cdn.needle.tools/static/three/0.179.1/basis2/"
|
|
54
|
+
* @example <needle-engine ktx2DecoderPath="./decoders/ktx2/"></needle-engine>
|
|
55
|
+
*/
|
|
50
56
|
'ktx2DecoderPath': string;
|
|
51
57
|
/** Prevent context from being disposed when element is removed from DOM. */
|
|
52
58
|
'keep-alive': 'true' | 'false';
|
|
@@ -840,15 +840,16 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
840
840
|
get viewerPose(): XRViewerPose | undefined { return this._viewerPose; }
|
|
841
841
|
|
|
842
842
|
|
|
843
|
-
/** @returns `true` if any image is currently being tracked */
|
|
844
|
-
/** returns true if images are currently being tracked */
|
|
843
|
+
/** @returns `true` if any image is currently being tracked or emulated */
|
|
845
844
|
get isTrackingImages() {
|
|
846
845
|
if (this.frame && "getImageTrackingResults" in this.frame && typeof this.frame.getImageTrackingResults === "function") {
|
|
847
846
|
try {
|
|
848
847
|
const trackingResult = this.frame.getImageTrackingResults();
|
|
849
848
|
for (const result of trackingResult) {
|
|
850
849
|
const state = result.trackingState;
|
|
851
|
-
if (state === "tracked")
|
|
850
|
+
if (state === "tracked" || state === "emulated") {
|
|
851
|
+
return true;
|
|
852
|
+
}
|
|
852
853
|
}
|
|
853
854
|
}
|
|
854
855
|
catch {
|
|
@@ -1053,6 +1054,8 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1053
1054
|
private readonly _xr_update_scripts: INeedleXRSessionEventReceiver[] = [];
|
|
1054
1055
|
/** scripts that are in the scene but inactive (e.g. disabled parent gameObject) */
|
|
1055
1056
|
private readonly _inactive_scripts: INeedleXRSessionEventReceiver[] = [];
|
|
1057
|
+
/** tracks scripts that have received onEnterXR — prevents spurious onLeaveXR calls */
|
|
1058
|
+
private readonly _scripts_in_xr = new Set<INeedleXRSessionEventReceiver>();
|
|
1056
1059
|
private readonly _controllerAdded: ControllerChangedEvt[];
|
|
1057
1060
|
private readonly _controllerRemoved: ControllerChangedEvt[];
|
|
1058
1061
|
private readonly _originalCameraWorldPosition?: Vector3 | null;
|
|
@@ -1163,7 +1166,18 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1163
1166
|
// we set the session on the webxr manager at the end because we want to receive inputsource events first
|
|
1164
1167
|
// e.g. in case there's a bug in the threejs codebase
|
|
1165
1168
|
this.context.xr = this;
|
|
1166
|
-
this.context.renderer.xr.setSession(this.session).then(this.onRendererSessionSet)
|
|
1169
|
+
this.context.renderer.xr.setSession(this.session).then(this.onRendererSessionSet)
|
|
1170
|
+
.catch(err => {
|
|
1171
|
+
// Workaround for WebXR emulators on localhost: the polyfilled XRSession fails the
|
|
1172
|
+
// native XRWebGLBinding constructor's instanceof check. Retry with layers disabled.
|
|
1173
|
+
// See https://github.com/meta-quest/immersive-web-emulator/issues/80
|
|
1174
|
+
if (isDevEnvironment() && err instanceof TypeError && typeof XRWebGLBinding !== "undefined") {
|
|
1175
|
+
console.error(`XRWebGLBinding failed (${err.message}).\nSee https://github.com/meta-quest/immersive-web-emulator/issues/80`);
|
|
1176
|
+
}
|
|
1177
|
+
else {
|
|
1178
|
+
console.error("renderer.xr.setSession failed:", err);
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1167
1181
|
// disable three.js renderer controller autoUpdate (added in ac67b31e3548386f8a93e23a4176554c92bbd0d9)
|
|
1168
1182
|
if ("controllerAutoUpdate" in this.context.renderer.xr) {
|
|
1169
1183
|
console.debug("Disabling three.js controllerAutoUpdate");
|
|
@@ -1331,8 +1345,10 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1331
1345
|
// even if they might already be destroyed e.g. by the WebXR component (it destroys the default controller scripts)
|
|
1332
1346
|
// they should still receive this callback to be properly cleaned up
|
|
1333
1347
|
for (const listener of this._xr_scripts) {
|
|
1348
|
+
this._scripts_in_xr.delete(listener);
|
|
1334
1349
|
listener?.onLeaveXR?.({ xr: this });
|
|
1335
1350
|
}
|
|
1351
|
+
this._scripts_in_xr.clear();
|
|
1336
1352
|
|
|
1337
1353
|
this.sync?.onExitXR(this);
|
|
1338
1354
|
|
|
@@ -1399,10 +1415,17 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1399
1415
|
}
|
|
1400
1416
|
|
|
1401
1417
|
// make sure the camera is parented to the active rig
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1418
|
+
// Note: applyCustomForward() inserts _cameraRenderParent between rig and camera,
|
|
1419
|
+
// so the hierarchy is: rig → _cameraRenderParent → camera. We check the effective parent.
|
|
1420
|
+
if (this.rig) {
|
|
1421
|
+
const cameraObject = this._mainCamera?.gameObject ?? this.context.mainCamera;
|
|
1422
|
+
if (cameraObject) {
|
|
1423
|
+
const effectiveParent = cameraObject.parent === this._cameraRenderParent
|
|
1424
|
+
? this._cameraRenderParent.parent
|
|
1425
|
+
: cameraObject.parent;
|
|
1426
|
+
if (effectiveParent !== this.rig.gameObject) {
|
|
1427
|
+
this.rig.gameObject.add(cameraObject);
|
|
1428
|
+
}
|
|
1406
1429
|
}
|
|
1407
1430
|
}
|
|
1408
1431
|
|
|
@@ -1534,8 +1557,12 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1534
1557
|
}
|
|
1535
1558
|
|
|
1536
1559
|
//performance.mark('NeedleXRSession update scripts start');
|
|
1537
|
-
//
|
|
1538
|
-
|
|
1560
|
+
// check all XR scripts for destroyed or inactive state
|
|
1561
|
+
// this must cover _xr_scripts (not just _xr_update_scripts) so that scripts
|
|
1562
|
+
// without onUpdateXR are also detected as inactive when removed from the scene
|
|
1563
|
+
// iterate backwards since markInactive/removeScript modifies the array
|
|
1564
|
+
for (let i = this._xr_scripts.length - 1; i >= 0; i--) {
|
|
1565
|
+
const script = this._xr_scripts[i];
|
|
1539
1566
|
if (script.destroyed === true) {
|
|
1540
1567
|
this._script_to_remove.push(script);
|
|
1541
1568
|
continue;
|
|
@@ -1544,6 +1571,10 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1544
1571
|
this.markInactive(script);
|
|
1545
1572
|
continue;
|
|
1546
1573
|
}
|
|
1574
|
+
}
|
|
1575
|
+
// invoke update on scripts that have onUpdateXR
|
|
1576
|
+
for (const script of this._xr_update_scripts) {
|
|
1577
|
+
if (script.destroyed || script.activeAndEnabled === false) continue;
|
|
1547
1578
|
if (script.onUpdateXR) script.onUpdateXR(args);
|
|
1548
1579
|
}
|
|
1549
1580
|
//performance.mark('NeedleXRSession update scripts end');
|
|
@@ -1666,9 +1697,11 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1666
1697
|
const script = this._inactive_scripts[i];
|
|
1667
1698
|
if (script.activeAndEnabled) {
|
|
1668
1699
|
this._inactive_scripts.splice(i, 1);
|
|
1669
|
-
|
|
1670
|
-
this.
|
|
1671
|
-
|
|
1700
|
+
// addScript returns false if already re-added (e.g. via new_scripts_xr processing)
|
|
1701
|
+
if (this.addScript(script)) {
|
|
1702
|
+
this.invokeCallback_EnterXR(script);
|
|
1703
|
+
for (const ctrl of this.controllers) this.invokeCallback_ControllerAdded(script, ctrl);
|
|
1704
|
+
}
|
|
1672
1705
|
}
|
|
1673
1706
|
}
|
|
1674
1707
|
}
|
|
@@ -1689,6 +1722,7 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1689
1722
|
}
|
|
1690
1723
|
|
|
1691
1724
|
private invokeCallback_EnterXR(script: INeedleXRSessionEventReceiver) {
|
|
1725
|
+
this._scripts_in_xr.add(script);
|
|
1692
1726
|
if (script.onEnterXR) {
|
|
1693
1727
|
script.onEnterXR({ xr: this });
|
|
1694
1728
|
}
|
|
@@ -1704,6 +1738,7 @@ export class NeedleXRSession implements INeedleXRSession {
|
|
|
1704
1738
|
}
|
|
1705
1739
|
}
|
|
1706
1740
|
private invokeCallback_LeaveXR(script: INeedleXRSessionEventReceiver) {
|
|
1741
|
+
if (!this._scripts_in_xr.delete(script)) return;
|
|
1707
1742
|
if (script.onLeaveXR && !script.destroyed) {
|
|
1708
1743
|
script.onLeaveXR({ xr: this });
|
|
1709
1744
|
}
|
package/src/engine/xr/events.ts
CHANGED
|
@@ -447,25 +447,13 @@ export class Animation extends Behaviour implements IAnimationComponent {
|
|
|
447
447
|
|
|
448
448
|
private internalOnPlay(action: AnimationAction, options: PlayOptions): Promise<AnimationAction> {
|
|
449
449
|
var existing = this.actions.find(a => a === action);
|
|
450
|
-
if (existing === action && existing.isRunning() && existing.time < existing.getClip().duration) {
|
|
451
|
-
const handle = this.tryFindHandle(action);
|
|
452
|
-
if (existing.paused) {
|
|
453
|
-
existing.paused = false;
|
|
454
|
-
}
|
|
455
|
-
if (handle) return handle.waitForFinish();
|
|
456
|
-
}
|
|
457
450
|
|
|
458
|
-
//
|
|
459
|
-
|
|
460
|
-
if (options.clampWhenFinished === undefined) options.clampWhenFinished = this.clampWhenFinished;
|
|
461
|
-
if (options.minMaxOffsetNormalized === undefined && this.randomStartTime) options.minMaxOffsetNormalized = this.minMaxOffsetNormalized;
|
|
462
|
-
if (options.minMaxSpeed === undefined) options.minMaxSpeed = this.minMaxSpeed;
|
|
463
|
-
|
|
464
|
-
// Reset currently running animations
|
|
451
|
+
// Stop other animations before the early-return check so exclusive always applies,
|
|
452
|
+
// even when the target animation is already running.
|
|
465
453
|
const stopOther = options?.exclusive ?? true;
|
|
466
454
|
if (stopOther) {
|
|
467
455
|
for (const act of this.actions) {
|
|
468
|
-
if (act
|
|
456
|
+
if (act !== action) {
|
|
469
457
|
if (options.fadeDuration) {
|
|
470
458
|
act.fadeOut(options.fadeDuration);
|
|
471
459
|
}
|
|
@@ -475,6 +463,20 @@ export class Animation extends Behaviour implements IAnimationComponent {
|
|
|
475
463
|
}
|
|
476
464
|
}
|
|
477
465
|
}
|
|
466
|
+
|
|
467
|
+
if (existing === action && existing.isRunning() && existing.time < existing.getClip().duration) {
|
|
468
|
+
const handle = this.tryFindHandle(action);
|
|
469
|
+
if (existing.paused) {
|
|
470
|
+
existing.paused = false;
|
|
471
|
+
}
|
|
472
|
+
if (handle) return handle.waitForFinish();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Assign defaults
|
|
476
|
+
if (options.loop === undefined) options.loop = this.loop;
|
|
477
|
+
if (options.clampWhenFinished === undefined) options.clampWhenFinished = this.clampWhenFinished;
|
|
478
|
+
if (options.minMaxOffsetNormalized === undefined && this.randomStartTime) options.minMaxOffsetNormalized = this.minMaxOffsetNormalized;
|
|
479
|
+
if (options.minMaxSpeed === undefined) options.minMaxSpeed = this.minMaxSpeed;
|
|
478
480
|
if (options?.fadeDuration) {
|
|
479
481
|
action.fadeIn(options.fadeDuration);
|
|
480
482
|
}
|
|
@@ -515,10 +517,11 @@ export class Animation extends Behaviour implements IAnimationComponent {
|
|
|
515
517
|
|
|
516
518
|
action.paused = false;
|
|
517
519
|
action.play();
|
|
520
|
+
if (debug) console.log("[Animation] Now Playing", action.getClip().name, action)
|
|
521
|
+
|
|
518
522
|
|
|
519
523
|
window.requestAnimationFrame(() => AnimationUtils.testIfRootCanAnimate(action));
|
|
520
524
|
|
|
521
|
-
if (debug) console.log("PLAY", action.getClip().name, action)
|
|
522
525
|
const handle = new AnimationHandle(action, this.mixer!, options, _ => {
|
|
523
526
|
this._handles.splice(this._handles.indexOf(handle), 1);
|
|
524
527
|
});
|
|
@@ -89,6 +89,15 @@ export class Animator extends Behaviour implements IAnimationComponent {
|
|
|
89
89
|
return true;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* The current animator mixer, used for low-level control of animations. Owned by the AnimatorController
|
|
94
|
+
* @returns The current AnimationMixer, or null if no controller is assigned
|
|
95
|
+
* @see AnimatorController.mixer
|
|
96
|
+
*/
|
|
97
|
+
get mixer() {
|
|
98
|
+
return this._animatorController?.mixer || null;
|
|
99
|
+
}
|
|
100
|
+
|
|
92
101
|
/**
|
|
93
102
|
* When enabled, animation will affect the root transform position and rotation
|
|
94
103
|
*/
|
|
@@ -401,17 +410,15 @@ export class Animator extends Behaviour implements IAnimationComponent {
|
|
|
401
410
|
initializeRuntimeAnimatorController(force: boolean = false) {
|
|
402
411
|
const shouldRun = (force || this.runtimeAnimatorController !== this._initializeWithRuntimeAnimatorController);
|
|
403
412
|
if (this.runtimeAnimatorController && shouldRun) {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
else console.warn("Could not clone animator controller", this.runtimeAnimatorController);
|
|
413
|
+
// Create a fresh controller from the (possibly remapped) model.
|
|
414
|
+
// The constructor deep-clones the model, preserving Object3D refs that
|
|
415
|
+
// the resolve system has already remapped to cloned objects.
|
|
416
|
+
const controller = new AnimatorController(this.runtimeAnimatorController.model);
|
|
417
|
+
this.runtimeAnimatorController = controller;
|
|
418
|
+
this._initializeWithRuntimeAnimatorController = controller;
|
|
419
|
+
controller.bind(this);
|
|
420
|
+
controller.setSpeed(this._speed);
|
|
421
|
+
controller.normalizedStartOffset = this._normalizedStartOffset;
|
|
415
422
|
}
|
|
416
423
|
}
|
|
417
424
|
|