@needle-tools/engine 5.1.0-alpha.2 → 5.1.0-alpha.4
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 +74 -1
- package/SKILL.md +4 -1
- package/components.needle.json +1 -1
- package/dist/needle-engine.bundle-AjVIot3d.min.js +1733 -0
- package/dist/{needle-engine.bundle-dit3f1l5.js → needle-engine.bundle-B7cqsI4c.js} +12199 -11704
- package/dist/needle-engine.bundle-DQCuBTVp.umd.cjs +1733 -0
- package/dist/needle-engine.d.ts +879 -226
- package/dist/needle-engine.js +584 -582
- 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/debug/debug_spatial_console.d.ts +2 -0
- package/lib/engine/debug/debug_spatial_console.js +10 -7
- package/lib/engine/debug/debug_spatial_console.js.map +1 -1
- package/lib/engine/engine_addressables.d.ts +2 -0
- package/lib/engine/engine_addressables.js +6 -3
- package/lib/engine/engine_addressables.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 +3 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_disposable.d.ts +172 -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 +13 -3
- 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 +7 -4
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_networking.d.ts +51 -37
- package/lib/engine/engine_networking.js +132 -82
- package/lib/engine/engine_networking.js.map +1 -1
- package/lib/engine/engine_networking.transport.websocket.d.ts +15 -0
- package/lib/engine/engine_networking.transport.websocket.js +38 -0
- package/lib/engine/engine_networking.transport.websocket.js.map +1 -0
- package/lib/engine/engine_networking_blob.js +1 -1
- package/lib/engine/engine_networking_blob.js.map +1 -1
- package/lib/engine/engine_networking_instantiate.js +2 -2
- package/lib/engine/engine_networking_instantiate.js.map +1 -1
- package/lib/engine/engine_networking_types.d.ts +39 -1
- package/lib/engine/engine_networking_types.js +7 -0
- package/lib/engine/engine_networking_types.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.d.ts +2 -0
- package/lib/engine/engine_scenedata.js +4 -2
- package/lib/engine/engine_scenedata.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.d.ts +10 -16
- package/lib/engine/engine_serialization_builtin_serializer.js +56 -46
- 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 +19 -11
- 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 +4 -119
- package/lib/engine-components/AnimatorController.js +35 -233
- 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 +72 -9
- package/lib/engine-components/Component.js +114 -10
- 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/ReflectionProbe.js +2 -0
- package/lib/engine-components/ReflectionProbe.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/postprocessing/VolumeParameter.d.ts +2 -0
- package/lib/engine-components/postprocessing/VolumeParameter.js +4 -1
- package/lib/engine-components/postprocessing/VolumeParameter.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.d.ts +16 -6
- package/lib/engine-components/timeline/PlayableDirector.js +70 -62
- 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/license.js +5 -2
- package/plugins/common/worker.js +9 -4
- package/plugins/vite/asap.js +17 -8
- package/plugins/vite/dependencies.js +29 -10
- 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/debug/debug_spatial_console.ts +10 -7
- package/src/engine/engine_addressables.ts +6 -3
- package/src/engine/engine_audio.ts +184 -0
- package/src/engine/engine_components.ts +1 -1
- package/src/engine/engine_context.ts +4 -3
- package/src/engine/engine_disposable.ts +214 -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 +13 -3
- 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 +7 -4
- package/src/engine/engine_networking.transport.websocket.ts +45 -0
- package/src/engine/engine_networking.ts +161 -137
- package/src/engine/engine_networking_blob.ts +1 -1
- package/src/engine/engine_networking_instantiate.ts +2 -2
- package/src/engine/engine_networking_types.ts +41 -1
- package/src/engine/engine_physics_rapier.ts +82 -27
- package/src/engine/engine_scenedata.ts +5 -3
- package/src/engine/engine_serialization_builtin_serializer.ts +64 -52
- package/src/engine/engine_serialization_core.ts +9 -0
- package/src/engine/engine_types.ts +24 -15
- 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 +23 -292
- package/src/engine-components/AudioSource.ts +130 -79
- package/src/engine-components/Collider.ts +66 -18
- package/src/engine-components/Component.ts +118 -20
- 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/ReflectionProbe.ts +2 -0
- 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/postprocessing/VolumeParameter.ts +4 -1
- package/src/engine-components/timeline/PlayableDirector.ts +67 -65
- package/src/engine-components/timeline/SignalAsset.ts +4 -1
- package/src/engine-components/timeline/TimelineBuilder.ts +564 -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-B-5Q2CpC.min.js +0 -1732
- package/dist/needle-engine.bundle-qZfVf_v-.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
|
@@ -204,12 +204,19 @@ export class Rigidbody extends Behaviour implements IRigidbody {
|
|
|
204
204
|
|
|
205
205
|
get isRigidbody() { return true; }
|
|
206
206
|
|
|
207
|
-
/** When true the mass
|
|
207
|
+
/** When true the mass is automatically computed from the attached colliders using `mass = density × volume`.
|
|
208
|
+
* Each collider's {@link Collider.density} determines how heavy it contributes to the total mass.
|
|
209
|
+
* Disable to set mass explicitly via the `mass` property.
|
|
210
|
+
*/
|
|
208
211
|
@validate()
|
|
209
212
|
autoMass: boolean = true;
|
|
210
213
|
|
|
211
|
-
/**
|
|
212
|
-
*
|
|
214
|
+
/** The mass of the rigidbody in kg (when `autoMass` is disabled).
|
|
215
|
+
* When `autoMass` is enabled, reading this returns the computed mass from `density × volume` of all attached colliders.
|
|
216
|
+
* Setting this property automatically disables `autoMass`.
|
|
217
|
+
*
|
|
218
|
+
* **Prefer using {@link Collider.density}** with `autoMass` enabled instead — density scales
|
|
219
|
+
* naturally with collider size, while explicit mass stays fixed regardless of shape changes.
|
|
213
220
|
*/
|
|
214
221
|
@serializable()
|
|
215
222
|
set mass(value: number) {
|
|
@@ -403,9 +410,16 @@ export class Rigidbody extends Behaviour implements IRigidbody {
|
|
|
403
410
|
this.context.physics.engine?.removeBody(this);
|
|
404
411
|
}
|
|
405
412
|
|
|
406
|
-
onValidate() {
|
|
413
|
+
onValidate(property?: string) {
|
|
407
414
|
this._propertiesChanged = true;
|
|
415
|
+
if (property === "autoMass" && !this.autoMass) {
|
|
416
|
+
if (isDevEnvironment() && !Rigidbody._didWarnAutoMass) {
|
|
417
|
+
Rigidbody._didWarnAutoMass = true;
|
|
418
|
+
console.warn("[Rigidbody] autoMass disabled — consider using Collider.density instead of setting mass explicitly. Density scales naturally with collider size.");
|
|
419
|
+
}
|
|
420
|
+
}
|
|
408
421
|
}
|
|
422
|
+
private static _didWarnAutoMass = false;
|
|
409
423
|
|
|
410
424
|
// need to do this right before updating physics to prevent rendered object glitching through physical bodies
|
|
411
425
|
* beforePhysics() {
|
|
@@ -249,10 +249,10 @@ export class SeeThrough extends Behaviour {
|
|
|
249
249
|
}
|
|
250
250
|
|
|
251
251
|
const materials = renderer.sharedMaterials;// : this.rendererMaterials.get(renderer);
|
|
252
|
-
if (!materials) return;
|
|
252
|
+
if (!materials?.length) return;
|
|
253
253
|
|
|
254
254
|
const block = MaterialPropertyBlock.get(renderer.gameObject);
|
|
255
|
-
const currentOpacity = (block.getOverride("opacity")?.value ?? materials[0]
|
|
255
|
+
const currentOpacity = (block.getOverride("opacity")?.value ?? materials[0]?.opacity ?? 1);
|
|
256
256
|
|
|
257
257
|
let newAlpha = Mathf.lerp(currentOpacity, targetAlpha, duration <= 0 ? 1 : this.context.time.deltaTime / duration);;
|
|
258
258
|
if (newAlpha >= 0.99) newAlpha = 1;
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
* @module Built-in Components
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
|
+
export { AnimatorControllerBuilder, type ConditionMode, type StateOptions, type TransitionOptions } from "./AnimatorController.builder.js";
|
|
37
38
|
export * from "./codegen/components.js";
|
|
38
|
-
export { AnimatorControllerBuilder, type ConditionMode, type StateOptions, type TransitionOptions } from "./AnimatorController.js";
|
|
39
39
|
export { Collider } from "./Collider.js"; // export abstract type
|
|
40
40
|
export { Behaviour, Component, GameObject } from "./Component.js";
|
|
41
41
|
|
|
@@ -6,18 +6,10 @@ export { Animation } from "../Animation.js";
|
|
|
6
6
|
export { Keyframe } from "../AnimationCurve.js";
|
|
7
7
|
export { AnimationCurve } from "../AnimationCurve.js";
|
|
8
8
|
export { Animator } from "../Animator.js";
|
|
9
|
-
export { AnimatorControllerBuilder } from "../AnimatorController.js";
|
|
9
|
+
export { AnimatorControllerBuilder } from "../AnimatorController.builder.js";
|
|
10
10
|
export { AnimatorController } from "../AnimatorController.js";
|
|
11
11
|
export { AudioListener } from "../AudioListener.js";
|
|
12
12
|
export { AudioSource } from "../AudioSource.js";
|
|
13
|
-
export { Avatar_POI } from "../avatar/Avatar_Brain_LookAt.js";
|
|
14
|
-
export { Avatar_Brain_LookAt } from "../avatar/Avatar_Brain_LookAt.js";
|
|
15
|
-
export { Avatar_MouthShapes } from "../avatar/Avatar_MouthShapes.js";
|
|
16
|
-
export { Avatar_MustacheShake } from "../avatar/Avatar_MustacheShake.js";
|
|
17
|
-
export { AvatarBlink_Simple } from "../avatar/AvatarBlink_Simple.js";
|
|
18
|
-
export { AvatarEyeLook_Rotation } from "../avatar/AvatarEyeLook_Rotation.js";
|
|
19
|
-
export { AvatarModel } from "../AvatarLoader.js";
|
|
20
|
-
export { AvatarLoader } from "../AvatarLoader.js";
|
|
21
13
|
export { AxesHelper } from "../AxesHelper.js";
|
|
22
14
|
export { BasicIKConstraint } from "../BasicIKConstraint.js";
|
|
23
15
|
export { BoxHelperComponent } from "../BoxHelperComponent.js";
|
|
@@ -168,10 +160,12 @@ export { PlayableDirector } from "../timeline/PlayableDirector.js";
|
|
|
168
160
|
export { SignalAsset } from "../timeline/SignalAsset.js";
|
|
169
161
|
export { SignalReceiverEvent } from "../timeline/SignalAsset.js";
|
|
170
162
|
export { SignalReceiver } from "../timeline/SignalAsset.js";
|
|
163
|
+
export { TimelineBuilder } from "../timeline/TimelineBuilder.js";
|
|
171
164
|
export { AnimationTrackHandler } from "../timeline/TimelineTracks.js";
|
|
172
165
|
export { AudioTrackHandler } from "../timeline/TimelineTracks.js";
|
|
173
166
|
export { MarkerTrackHandler } from "../timeline/TimelineTracks.js";
|
|
174
167
|
export { SignalTrackHandler } from "../timeline/TimelineTracks.js";
|
|
168
|
+
export { ActivationTrackHandler } from "../timeline/TimelineTracks.js";
|
|
175
169
|
export { ControlTrackHandler } from "../timeline/TimelineTracks.js";
|
|
176
170
|
export { TransformGizmo } from "../TransformGizmo.js";
|
|
177
171
|
export { BaseUIComponent } from "../ui/BaseUIComponent.js";
|
|
@@ -4,7 +4,6 @@ import { isDevEnvironment } from '../../engine/debug/index.js';
|
|
|
4
4
|
import { FrameEvent } from '../../engine/engine_context.js';
|
|
5
5
|
import { isLocalNetwork } from '../../engine/engine_networking_utils.js';
|
|
6
6
|
import { serializable } from '../../engine/engine_serialization.js';
|
|
7
|
-
import type { GuidsMap } from '../../engine/engine_types.js';
|
|
8
7
|
import { deepClone, delay, getParam } from '../../engine/engine_utils.js';
|
|
9
8
|
import { Animator } from '../Animator.js';
|
|
10
9
|
import { AudioListener } from '../AudioListener.js';
|
|
@@ -115,7 +114,15 @@ export class PlayableDirector extends Behaviour {
|
|
|
115
114
|
* The timeline asset containing tracks, clips, and markers that this director will play.
|
|
116
115
|
* Assign a timeline asset exported from Unity or Blender to enable playback.
|
|
117
116
|
*/
|
|
118
|
-
|
|
117
|
+
@serializable()
|
|
118
|
+
get playableAsset(): Models.TimelineAssetModel | undefined { return this._playableAsset; }
|
|
119
|
+
set playableAsset(value: Models.TimelineAssetModel | undefined) {
|
|
120
|
+
if (this._playableAsset !== value) {
|
|
121
|
+
this._playableAsset = value;
|
|
122
|
+
this._needsGraphRebuild = true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
private _playableAsset?: Models.TimelineAssetModel;
|
|
119
126
|
|
|
120
127
|
/**
|
|
121
128
|
* When true, the timeline starts playing automatically when the component awakens.
|
|
@@ -123,7 +130,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
123
130
|
* @default false
|
|
124
131
|
*/
|
|
125
132
|
@serializable()
|
|
126
|
-
playOnAwake
|
|
133
|
+
playOnAwake: boolean = false;
|
|
127
134
|
|
|
128
135
|
/**
|
|
129
136
|
* Determines how the timeline behaves when it reaches the end of its duration.
|
|
@@ -207,14 +214,10 @@ export class PlayableDirector extends Behaviour {
|
|
|
207
214
|
onEnable() {
|
|
208
215
|
if (debug) console.log("[Timeline] OnEnable", this.name, this.playOnAwake);
|
|
209
216
|
|
|
210
|
-
for (const
|
|
211
|
-
track
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
track.onEnable?.();
|
|
215
|
-
}
|
|
216
|
-
for (const track of this._animationTracks) {
|
|
217
|
-
track.onEnable?.();
|
|
217
|
+
for (const tracks of this._allTracks) {
|
|
218
|
+
for (const track of tracks) {
|
|
219
|
+
track.onEnable?.();
|
|
220
|
+
}
|
|
218
221
|
}
|
|
219
222
|
if (this.playOnAwake) {
|
|
220
223
|
this.play();
|
|
@@ -265,6 +268,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
265
268
|
this.resolveBindings();
|
|
266
269
|
this.updateTimelineDuration();
|
|
267
270
|
this.setupAndCreateTrackHandlers();
|
|
271
|
+
this._needsGraphRebuild = false;
|
|
268
272
|
}
|
|
269
273
|
|
|
270
274
|
/**
|
|
@@ -273,6 +277,8 @@ export class PlayableDirector extends Behaviour {
|
|
|
273
277
|
*/
|
|
274
278
|
async play() {
|
|
275
279
|
if (!this.isValid()) return;
|
|
280
|
+
// Ensure graph is built (handles the case where playableAsset is assigned after awake)
|
|
281
|
+
if (this._needsGraphRebuild) this.rebuildGraph();
|
|
276
282
|
const pauseChanged = this._isPaused == true;
|
|
277
283
|
this._isPaused = false;
|
|
278
284
|
if (this._isPlaying) return;
|
|
@@ -290,8 +296,13 @@ export class PlayableDirector extends Behaviour {
|
|
|
290
296
|
await Promise.all(promises);
|
|
291
297
|
if (!this._isPlaying) return;
|
|
292
298
|
}
|
|
293
|
-
|
|
299
|
+
let ticks = 0;
|
|
300
|
+
while (this._audioTracks.length > 0 && this._isPlaying && !AudioSource.userInteractionRegistered && this.waitForAudio) {
|
|
301
|
+
if (ticks++ <= 0) {
|
|
302
|
+
if (isDevEnvironment() || debug) console.warn(`[Timeline] Waiting for user interaction to play audio... (timeline '${this.name}' will start as soon as user interacts with the page). To start the timeline immediately without waiting for user interaction, set 'waitForAudio' to false on the PlayableDirector component.`);
|
|
303
|
+
}
|
|
294
304
|
await delay(200);
|
|
305
|
+
}
|
|
295
306
|
}
|
|
296
307
|
this.invokeStateChangedMethodsOnTracks();
|
|
297
308
|
// Update timeline in LateUpdate to give other scripts time to react to the updated state
|
|
@@ -343,6 +354,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
343
354
|
* Evaluate the timeline at the current time. This is useful when you want to manually update the timeline e.g. when the timeline is paused and you set `time` to a new value.
|
|
344
355
|
*/
|
|
345
356
|
evaluate() {
|
|
357
|
+
if (this._needsGraphRebuild) this.rebuildGraph();
|
|
346
358
|
this.internalEvaluate(true);
|
|
347
359
|
}
|
|
348
360
|
|
|
@@ -391,6 +403,20 @@ export class PlayableDirector extends Behaviour {
|
|
|
391
403
|
return this._markerTracks;
|
|
392
404
|
}
|
|
393
405
|
|
|
406
|
+
/**
|
|
407
|
+
* @returns all activation tracks of the timeline
|
|
408
|
+
*/
|
|
409
|
+
get activationTracks(): Tracks.ActivationTrackHandler[] {
|
|
410
|
+
return this._activationTracks;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* @returns all tracks of the timeline
|
|
415
|
+
*/
|
|
416
|
+
get tracks(): ReadonlyArray<Tracks.TrackHandler> {
|
|
417
|
+
return this._allTracks.flat();
|
|
418
|
+
}
|
|
419
|
+
|
|
394
420
|
/**
|
|
395
421
|
* Iterates over all markers of the timeline, optionally filtering by type
|
|
396
422
|
*
|
|
@@ -412,19 +438,17 @@ export class PlayableDirector extends Behaviour {
|
|
|
412
438
|
}
|
|
413
439
|
|
|
414
440
|
|
|
415
|
-
private _guidsMap?: GuidsMap;
|
|
416
|
-
/** @internal */
|
|
417
|
-
resolveGuids(map: GuidsMap) {
|
|
418
|
-
this._guidsMap = map;
|
|
419
|
-
}
|
|
420
441
|
|
|
421
442
|
// INTERNALS
|
|
422
443
|
|
|
444
|
+
private _needsGraphRebuild: boolean = false;
|
|
423
445
|
private _isPlaying: boolean = false;
|
|
424
446
|
private _internalUpdateRoutine: any;
|
|
425
447
|
private _isPaused: boolean = false;
|
|
426
448
|
/** internal, true during the time stop() is being processed */
|
|
427
449
|
private _isStopping: boolean = false;
|
|
450
|
+
/** @internal Whether the current evaluate() was triggered by user code (not the internal update loop or stop/pause). */
|
|
451
|
+
_isUserEvaluation: boolean = false;
|
|
428
452
|
private _time: number = 0;
|
|
429
453
|
private _duration: number = 0;
|
|
430
454
|
private _weight: number = 1;
|
|
@@ -433,6 +457,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
433
457
|
private readonly _signalTracks: Array<Tracks.SignalTrackHandler> = [];
|
|
434
458
|
private readonly _markerTracks: Array<Tracks.MarkerTrackHandler> = [];
|
|
435
459
|
private readonly _controlTracks: Array<Tracks.ControlTrackHandler> = [];
|
|
460
|
+
private readonly _activationTracks: Array<Tracks.ActivationTrackHandler> = [];
|
|
436
461
|
private readonly _customTracks: Array<Tracks.TrackHandler> = [];
|
|
437
462
|
|
|
438
463
|
private readonly _tracksArray: Array<Array<Tracks.TrackHandler>> = [];
|
|
@@ -443,6 +468,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
443
468
|
this._tracksArray.push(this._signalTracks);
|
|
444
469
|
this._tracksArray.push(this._markerTracks);
|
|
445
470
|
this._tracksArray.push(this._controlTracks);
|
|
471
|
+
this._tracksArray.push(this._activationTracks);
|
|
446
472
|
this._tracksArray.push(this._customTracks);
|
|
447
473
|
return this._tracksArray;
|
|
448
474
|
}
|
|
@@ -503,60 +529,32 @@ export class PlayableDirector extends Behaviour {
|
|
|
503
529
|
|
|
504
530
|
const time = this._time;
|
|
505
531
|
|
|
506
|
-
|
|
507
|
-
if (track.muted) continue;
|
|
508
|
-
switch (track.type) {
|
|
509
|
-
case Models.TrackType.Activation:
|
|
510
|
-
// when the timeline is being disabled or stopped
|
|
511
|
-
// then we want to leave objects active state as they were
|
|
512
|
-
// see NE-3241
|
|
513
|
-
// TODO: support all "post-playback-state" settings an activation track has, this is just "Leave as is"
|
|
514
|
-
if (!called_by_user && !this._isPlaying) continue;
|
|
515
|
-
|
|
516
|
-
for (let i = 0; i < track.outputs.length; i++) {
|
|
517
|
-
const binding = track.outputs[i];
|
|
518
|
-
if (typeof binding === "object") {
|
|
519
|
-
let isActive: boolean = false;
|
|
520
|
-
if (track.clips) {
|
|
521
|
-
for (const clip of track.clips) {
|
|
522
|
-
if (clip.start <= time && time <= clip.end) {
|
|
523
|
-
isActive = true;
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
const obj = binding as Object3D;
|
|
528
|
-
if (obj.visible !== undefined) {
|
|
529
|
-
if (obj.visible !== isActive) {
|
|
530
|
-
obj.visible = isActive;
|
|
531
|
-
if (debug)
|
|
532
|
-
console.warn(this.name, "set ActivationTrack-" + i, obj.name, isActive, time);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
break;
|
|
538
|
-
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
532
|
+
this._isUserEvaluation = called_by_user;
|
|
542
533
|
for (const track of this._allTracks) {
|
|
543
534
|
for (const handler of track) {
|
|
544
535
|
// When timeline reaches the end "stop()" is called which is evaluating with time 0
|
|
545
536
|
// We don't want to re-evaluate the animation then in case the timeline is blended with the Animator
|
|
546
537
|
// e.g then the timeline animation at time 0 is 100% applied on top of the animator animation
|
|
547
|
-
|
|
548
538
|
if (this._isStopping && handler instanceof Tracks.AnimationTrackHandler) {
|
|
549
539
|
continue;
|
|
550
540
|
}
|
|
551
541
|
handler.evaluate(time);
|
|
552
542
|
}
|
|
553
543
|
}
|
|
544
|
+
this._isUserEvaluation = false;
|
|
554
545
|
}
|
|
555
546
|
|
|
556
547
|
private resolveBindings() {
|
|
557
548
|
if (!this._clonedPlayableAsset) {
|
|
558
549
|
this._clonedPlayableAsset = true;
|
|
559
|
-
|
|
550
|
+
// Deep clone so each director owns its own copy of the asset data.
|
|
551
|
+
// Needed because NEEDLE_persistent_assets returns the same shared object for all references —
|
|
552
|
+
// without this, resolving guid strings below would mutate shared data.
|
|
553
|
+
// On instantiated clones this is skipped (_clonedPlayableAsset is copied as true)
|
|
554
|
+
// because the instantiate resolve system already created an independent copy.
|
|
555
|
+
this.playableAsset = deepClone(this.playableAsset, (_obj, _key, val) => {
|
|
556
|
+
return !(val?.isObject3D === true);
|
|
557
|
+
});
|
|
560
558
|
}
|
|
561
559
|
|
|
562
560
|
if (!this.playableAsset || !this.playableAsset.tracks) return;
|
|
@@ -569,15 +567,13 @@ export class PlayableDirector extends Behaviour {
|
|
|
569
567
|
|
|
570
568
|
for (const track of this.playableAsset.tracks) {
|
|
571
569
|
for (let i = track.outputs.length - 1; i >= 0; i--) {
|
|
572
|
-
|
|
570
|
+
const binding = track.outputs[i];
|
|
573
571
|
if (typeof binding === "string") {
|
|
574
|
-
if (this._guidsMap && this._guidsMap[binding])
|
|
575
|
-
binding = this._guidsMap[binding];
|
|
576
572
|
const obj = GameObject.findByGuid(binding, root);
|
|
577
573
|
if (obj === null || typeof obj !== "object") {
|
|
578
574
|
// if the binding is missing remove it to avoid unnecessary loops
|
|
579
575
|
track.outputs.splice(i, 1);
|
|
580
|
-
console.warn(
|
|
576
|
+
console.warn(`[Timeline] Failed to resolve binding on track '${track.name}' of type '${track.type}' in director '${this.name}' with timeline asset '${this.playableAsset.name}' ('${binding}' not found in scene)`);
|
|
581
577
|
}
|
|
582
578
|
else {
|
|
583
579
|
if (debug)
|
|
@@ -592,21 +588,20 @@ export class PlayableDirector extends Behaviour {
|
|
|
592
588
|
continue;
|
|
593
589
|
}
|
|
594
590
|
// if the binding is missing remove it to avoid unnecessary loops
|
|
595
|
-
if (track.type !== Models.TrackType.Audio && track.type !== Models.TrackType.Control && track.type !== Models.TrackType.Marker && track.type !== Models.TrackType.Signal)
|
|
596
|
-
console.warn(
|
|
591
|
+
if (track.type !== Models.TrackType.Audio && track.type !== Models.TrackType.Control && track.type !== Models.TrackType.Marker && track.type !== Models.TrackType.Signal) {
|
|
592
|
+
console.warn(`[Timeline] Missing binding on track '${track.name}' of type '${track.type}' in director '${this.name}' with timeline asset '${this.playableAsset.name}' (null binding)`);
|
|
593
|
+
}
|
|
597
594
|
}
|
|
598
595
|
}
|
|
599
596
|
if (track.type === Models.TrackType.Control) {
|
|
600
597
|
if (track.clips) {
|
|
601
598
|
for (let i = 0; i < track.clips.length; i++) {
|
|
602
599
|
const clip = track.clips[i];
|
|
603
|
-
|
|
600
|
+
const binding = clip.asset.sourceObject;
|
|
604
601
|
if (typeof binding === "string") {
|
|
605
|
-
if (this._guidsMap && this._guidsMap[binding])
|
|
606
|
-
binding = this._guidsMap[binding];
|
|
607
602
|
const obj = GameObject.findByGuid(binding, root);
|
|
608
603
|
if (obj === null || typeof obj !== "object") {
|
|
609
|
-
console.warn(
|
|
604
|
+
console.warn(`[Timeline] Failed to resolve sourceObject binding on track '${track.name}' of type '${track.type}' in director '${this.name}' with timeline asset '${this.playableAsset.name}' ('${binding}' not found in scene)`);
|
|
610
605
|
}
|
|
611
606
|
else {
|
|
612
607
|
if (debug)
|
|
@@ -649,6 +644,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
649
644
|
this._animationTracks.length = 0;
|
|
650
645
|
this._audioTracks.length = 0;
|
|
651
646
|
this._signalTracks.length = 0;
|
|
647
|
+
this._activationTracks.length = 0;
|
|
652
648
|
|
|
653
649
|
if (!this.playableAsset) return;
|
|
654
650
|
let audioListener: AudioListener | null = GameObject.findObjectOfType(AudioListener, this.context);
|
|
@@ -810,6 +806,12 @@ export class PlayableDirector extends Behaviour {
|
|
|
810
806
|
handler.resolveSourceObjects(this.context);
|
|
811
807
|
this._controlTracks.push(handler);
|
|
812
808
|
}
|
|
809
|
+
else if (track.type === Models.TrackType.Activation) {
|
|
810
|
+
const handler = new Tracks.ActivationTrackHandler();
|
|
811
|
+
handler.director = this;
|
|
812
|
+
handler.track = track;
|
|
813
|
+
this._activationTracks.push(handler);
|
|
814
|
+
}
|
|
813
815
|
}
|
|
814
816
|
}
|
|
815
817
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { serializable } from "../../engine/engine_serialization_decorator.js";
|
|
2
|
+
import { ISignalReceiver } from "../../engine/engine_types.js";
|
|
2
3
|
import { getParam } from "../../engine/engine_utils.js";
|
|
3
4
|
import { Behaviour } from "../Component.js";
|
|
4
5
|
import { EventList } from "../EventList.js";
|
|
@@ -33,7 +34,9 @@ export class SignalReceiverEvent {
|
|
|
33
34
|
* @category Animation and Sequencing
|
|
34
35
|
* @group Components
|
|
35
36
|
*/
|
|
36
|
-
export class SignalReceiver extends Behaviour {
|
|
37
|
+
export class SignalReceiver extends Behaviour implements ISignalReceiver {
|
|
38
|
+
|
|
39
|
+
readonly isSignalReceiver = true;
|
|
37
40
|
|
|
38
41
|
private static receivers: { [key: string]: SignalReceiver[] } = {};
|
|
39
42
|
|