@needle-tools/engine 4.14.0-next.b2e3b1a → 4.14.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/CHANGELOG.md +1 -1
- package/components.needle.json +1 -1
- package/dist/{needle-engine.bundle-BC1QDiuv.umd.cjs → needle-engine.bundle-COL2Bar3.umd.cjs} +125 -125
- package/dist/{needle-engine.bundle-Bhgt3W8p.min.js → needle-engine.bundle-NolzHLqO.min.js} +127 -127
- package/dist/{needle-engine.bundle-CeQXs7Hh.js → needle-engine.bundle-Z_gAD7Kg.js} +4924 -4963
- package/dist/needle-engine.d.ts +132 -65
- package/dist/needle-engine.js +2 -2
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/api.d.ts +202 -17
- package/lib/engine/api.js +270 -17
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_components.d.ts +1 -1
- package/lib/engine/engine_components.js +3 -7
- package/lib/engine/engine_components.js.map +1 -1
- package/lib/engine/engine_context.d.ts +0 -12
- package/lib/engine/engine_context.js +0 -29
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_gltf_builtin_components.js +1 -16
- package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.d.ts +92 -13
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js +92 -32
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js.map +1 -1
- package/package.json +2 -2
- package/src/engine/api.ts +370 -18
- package/src/engine/engine_components.ts +3 -7
- package/src/engine/engine_context.ts +2 -28
- package/src/engine/engine_gltf_builtin_components.ts +1 -17
- package/src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +110 -53
|
@@ -13,7 +13,7 @@ import { AudioSource } from "../../../../AudioSource.js";
|
|
|
13
13
|
import { Behaviour, GameObject } from "../../../../Component.js";
|
|
14
14
|
import { Rigidbody } from "../../../../RigidBody.js";
|
|
15
15
|
import type { IPointerClickHandler, PointerEventData } from "../../../../ui/PointerEvents.js";
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
import { makeNameSafeForUSD,USDDocument, USDObject, USDZExporterContext } from "../../ThreeUSDZExporter.js";
|
|
18
18
|
import { AnimationExtension, RegisteredAnimationInfo, type UsdzAnimation } from "../Animation.js";
|
|
19
19
|
import { AudioExtension } from "./AudioExtension.js";
|
|
@@ -22,32 +22,32 @@ import { ActionBuilder, ActionModel, BehaviorModel, EmphasizeActionMotionType,Gr
|
|
|
22
22
|
|
|
23
23
|
const debug = getParam("debugusdzbehaviours");
|
|
24
24
|
|
|
25
|
-
function ensureRaycaster(obj: GameObject) {
|
|
26
|
-
if (!obj) return;
|
|
27
|
-
if (!obj.getComponentInParent(Raycaster)) {
|
|
28
|
-
if (isDevEnvironment())
|
|
29
|
-
console.debug("Raycaster on \"" + obj.name + "\" was automatically added, because no raycaster was found in the parent hierarchy.")
|
|
30
|
-
obj.addComponent(ObjectRaycaster);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
25
|
/**
|
|
35
|
-
*
|
|
26
|
+
* Moves an object to the target object's transform when clicked.
|
|
27
|
+
* Works in the browser and in USDZ/QuickLook (Everywhere Actions).
|
|
28
|
+
*
|
|
29
|
+
* @see {@link SetActiveOnClick}to toggle visibility of objects when clicked
|
|
30
|
+
* @see {@link PlayAnimationOnClick} to play animations when clicked
|
|
31
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
36
32
|
* @summary Moves an object to a target transform upon click
|
|
37
33
|
* @category Everywhere Actions
|
|
38
34
|
* @group Components
|
|
39
35
|
*/
|
|
40
36
|
export class ChangeTransformOnClick extends Behaviour implements IPointerClickHandler, UsdzBehaviour {
|
|
41
37
|
|
|
38
|
+
/** The object to move. */
|
|
42
39
|
@serializable(Object3D)
|
|
43
40
|
object?: Object3D;
|
|
44
41
|
|
|
42
|
+
/** The target object whose transform to move to. */
|
|
45
43
|
@serializable(Object3D)
|
|
46
44
|
target?: Object3D;
|
|
47
45
|
|
|
46
|
+
/** The duration of the movement animation in seconds. */
|
|
48
47
|
@serializable()
|
|
49
48
|
duration: number = 1;
|
|
50
49
|
|
|
50
|
+
/** If true, the motion is relative to the object's current transform instead of moving to the target's absolute position. */
|
|
51
51
|
@serializable()
|
|
52
52
|
relativeMotion: boolean = false;
|
|
53
53
|
|
|
@@ -57,10 +57,6 @@ export class ChangeTransformOnClick extends Behaviour implements IPointerClickHa
|
|
|
57
57
|
private targetRot = new Quaternion();
|
|
58
58
|
private targetScale = new Vector3();
|
|
59
59
|
|
|
60
|
-
start(): void {
|
|
61
|
-
ensureRaycaster(this.gameObject);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
60
|
onPointerEnter() {
|
|
65
61
|
this.context.input.setCursor("pointer");
|
|
66
62
|
}
|
|
@@ -189,7 +185,15 @@ export class ChangeTransformOnClick extends Behaviour implements IPointerClickHa
|
|
|
189
185
|
}
|
|
190
186
|
|
|
191
187
|
/**
|
|
192
|
-
*
|
|
188
|
+
* Switches the material of objects in the scene when clicked.
|
|
189
|
+
* Works in the browser and in USDZ/QuickLook (Everywhere Actions).
|
|
190
|
+
*
|
|
191
|
+
* Finds all objects in the scene that use `materialToSwitch` and replaces it with `variantMaterial`.
|
|
192
|
+
* Multiple `ChangeMaterialOnClick` components using the same `materialToSwitch` can be combined to create a material selection UI.
|
|
193
|
+
*
|
|
194
|
+
* @see {@link SetActiveOnClick} to toggle visibility of objects when clicked
|
|
195
|
+
* @see {@link PlayAnimationOnClick} to play animations when clicked
|
|
196
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
193
197
|
* @summary Changes the material of objects when clicked
|
|
194
198
|
* @category Everywhere Actions
|
|
195
199
|
* @group Components
|
|
@@ -218,7 +222,6 @@ export class ChangeMaterialOnClick extends Behaviour implements IPointerClickHan
|
|
|
218
222
|
start(): void {
|
|
219
223
|
// initialize the object list
|
|
220
224
|
this._objectsWithThisMaterial = this.objectsWithThisMaterial;
|
|
221
|
-
ensureRaycaster(this.gameObject);
|
|
222
225
|
if (isDevEnvironment() && this._objectsWithThisMaterial.length <= 0) {
|
|
223
226
|
console.warn("ChangeMaterialOnClick: No objects found with material \"" + this.materialToSwitch?.name + "\"");
|
|
224
227
|
}
|
|
@@ -345,7 +348,7 @@ export class ChangeMaterialOnClick extends Behaviour implements IPointerClickHan
|
|
|
345
348
|
);
|
|
346
349
|
ChangeMaterialOnClick._parallelStartHiddenActions.push(...myVariants);
|
|
347
350
|
if (!ChangeMaterialOnClick._startHiddenBehaviour) {
|
|
348
|
-
ChangeMaterialOnClick._startHiddenBehaviour =
|
|
351
|
+
ChangeMaterialOnClick._startHiddenBehaviour =
|
|
349
352
|
new BehaviorModel("StartHidden_" + this.selfModel.name,
|
|
350
353
|
TriggerBuilder.sceneStartTrigger(),
|
|
351
354
|
ActionBuilder.fadeAction(ChangeMaterialOnClick._parallelStartHiddenActions, fadeDuration, false));
|
|
@@ -381,29 +384,37 @@ export class ChangeMaterialOnClick extends Behaviour implements IPointerClickHan
|
|
|
381
384
|
}
|
|
382
385
|
|
|
383
386
|
/**
|
|
384
|
-
*
|
|
387
|
+
* Shows or hides a target object when this object is clicked.
|
|
388
|
+
* Works in the browser and in USDZ/QuickLook (Everywhere Actions).
|
|
389
|
+
*
|
|
390
|
+
* Optionally hides itself after being clicked (`hideSelf`), or toggles the target's visibility on each click (`toggleOnClick`).
|
|
391
|
+
*
|
|
392
|
+
* @see {@link HideOnStart}to hide an object when the scene starts
|
|
393
|
+
* @see {@link PlayAnimationOnClick} to play animations when clicked
|
|
394
|
+
* @see {@link ChangeMaterialOnClick} to change material when clicked
|
|
395
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
385
396
|
* @summary Sets the active state of an object when clicked
|
|
386
397
|
* @category Everywhere Actions
|
|
387
398
|
* @group Components
|
|
388
399
|
*/
|
|
389
400
|
export class SetActiveOnClick extends Behaviour implements IPointerClickHandler, UsdzBehaviour {
|
|
390
401
|
|
|
402
|
+
/** The target object to show or hide. */
|
|
391
403
|
@serializable(Object3D)
|
|
392
404
|
target?: Object3D;
|
|
393
405
|
|
|
406
|
+
/** If true, the target's visibility will be toggled on each click. When enabled, `hideSelf` and `targetState` are ignored. */
|
|
394
407
|
@serializable()
|
|
395
408
|
toggleOnClick: boolean = false;
|
|
396
409
|
|
|
410
|
+
/** The visibility state to apply to the target when clicked. Only used when `toggleOnClick` is false. */
|
|
397
411
|
@serializable()
|
|
398
412
|
targetState: boolean = true;
|
|
399
413
|
|
|
414
|
+
/** If true, this object will hide itself after being clicked. Only used when `toggleOnClick` is false. */
|
|
400
415
|
@serializable()
|
|
401
416
|
hideSelf: boolean = true;
|
|
402
417
|
|
|
403
|
-
start(): void {
|
|
404
|
-
ensureRaycaster(this.gameObject);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
418
|
onPointerEnter() {
|
|
408
419
|
this.context.input.setCursor("pointer");
|
|
409
420
|
}
|
|
@@ -416,7 +427,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
416
427
|
|
|
417
428
|
if (!this.toggleOnClick && this.hideSelf)
|
|
418
429
|
this.gameObject.visible = false;
|
|
419
|
-
|
|
430
|
+
|
|
420
431
|
if (this.target)
|
|
421
432
|
this.target.visible = this.toggleOnClick ? !this.target.visible : this.targetState;
|
|
422
433
|
}
|
|
@@ -442,7 +453,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
442
453
|
|
|
443
454
|
beforeCreateDocument() {
|
|
444
455
|
if (!this.target) return;
|
|
445
|
-
|
|
456
|
+
|
|
446
457
|
// need to cache on the object itself, because otherwise different actions would override each other's visibility state
|
|
447
458
|
// TODO would probably be better to have this somewhere on the exporter, not on this component
|
|
448
459
|
if (this.gameObject[SetActiveOnClick.wasVisible] === undefined)
|
|
@@ -503,7 +514,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
503
514
|
// It's much easier to reason about nested actions when we're not duplicating tons of hierarchy...
|
|
504
515
|
// We can probably only do a shallow clone when the tapped object has geometry of its own, otherwise
|
|
505
516
|
// we end up with nothing to tap on.
|
|
506
|
-
|
|
517
|
+
|
|
507
518
|
// Option A: we deep clone ourselves. This makes hierarchical cases and nested behaviours really complex.
|
|
508
519
|
// We do this currently when the object doesn't have any geometry.
|
|
509
520
|
if (!this.selfModelClone.geometry) {
|
|
@@ -522,11 +533,11 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
522
533
|
clone.name += "_toggle" + (SetActiveOnClick.clonedToggleIndex++);
|
|
523
534
|
originalModel.add(clone);
|
|
524
535
|
this.gameObject[SetActiveOnClick.toggleClone] = clone;
|
|
525
|
-
|
|
536
|
+
|
|
526
537
|
console.warn("USDZExport: Toggle " + this.gameObject.name + " doesn't have geometry. It will be deep cloned and nested behaviours will likely not work.");
|
|
527
538
|
}
|
|
528
539
|
const clonedSelfModel = this.gameObject[SetActiveOnClick.toggleClone];
|
|
529
|
-
|
|
540
|
+
|
|
530
541
|
if (!this.gameObject[SetActiveOnClick.reverseToggleClone]) {
|
|
531
542
|
const clone = this.selfModelClone.clone();
|
|
532
543
|
clone.setMatrix(new Matrix4());
|
|
@@ -578,7 +589,7 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
578
589
|
TriggerBuilder.tapTrigger(selfModel),
|
|
579
590
|
ActionBuilder.parallel(...toggleSequence)
|
|
580
591
|
));
|
|
581
|
-
|
|
592
|
+
|
|
582
593
|
const reverseSequence: ActionModel[] = [];
|
|
583
594
|
reverseSequence.push(ActionBuilder.fadeAction(this.toggleModel, 0, false));
|
|
584
595
|
reverseSequence.push(ActionBuilder.fadeAction(selfModel, 0, true));
|
|
@@ -621,7 +632,13 @@ export class SetActiveOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
621
632
|
}
|
|
622
633
|
|
|
623
634
|
/**
|
|
624
|
-
* Hides the object
|
|
635
|
+
* Hides the object when the scene starts.
|
|
636
|
+
* Works in the browser and in USDZ/QuickLook (Everywhere Actions).
|
|
637
|
+
*
|
|
638
|
+
* Useful for setting up objects that should initially be hidden and shown later via a {@link SetActiveOnClick} component.
|
|
639
|
+
*
|
|
640
|
+
* @see {@link SetActiveOnClick} to show or hide objects on click
|
|
641
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
625
642
|
* @summary Hides the object on scene start
|
|
626
643
|
* @category Everywhere Actions
|
|
627
644
|
* @group Components
|
|
@@ -663,26 +680,36 @@ export class HideOnStart extends Behaviour implements UsdzBehaviour {
|
|
|
663
680
|
}
|
|
664
681
|
|
|
665
682
|
private wasVisible: boolean = false;
|
|
666
|
-
|
|
683
|
+
|
|
667
684
|
beforeCreateDocument() {
|
|
668
685
|
this.wasVisible = GameObject.isActiveSelf(this.gameObject);
|
|
669
686
|
}
|
|
670
687
|
}
|
|
671
688
|
|
|
672
689
|
/**
|
|
673
|
-
*
|
|
690
|
+
* Applies an emphasis animation to a target object when this object is clicked.
|
|
691
|
+
* Works in USDZ/QuickLook (Everywhere Actions).
|
|
692
|
+
*
|
|
693
|
+
* The emphasis effect can be a bounce, jiggle, or other motion type defined by `motionType`.
|
|
694
|
+
*
|
|
695
|
+
* @see {@link PlayAnimationOnClick} to play animations when clicked
|
|
696
|
+
* @see {@link SetActiveOnClick} to toggle visibility when clicked
|
|
697
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
674
698
|
* @summary Emphasizes the target object when clicked
|
|
675
699
|
* @category Everywhere Actions
|
|
676
700
|
* @group Components
|
|
677
701
|
*/
|
|
678
702
|
export class EmphasizeOnClick extends Behaviour implements UsdzBehaviour {
|
|
679
703
|
|
|
704
|
+
/** The target object to emphasize. */
|
|
680
705
|
@serializable()
|
|
681
706
|
target?: Object3D;
|
|
682
707
|
|
|
708
|
+
/** The duration of the emphasis animation in seconds. */
|
|
683
709
|
@serializable()
|
|
684
710
|
duration: number = 0.5;
|
|
685
711
|
|
|
712
|
+
/** The type of motion to use for the emphasis effect (e.g. `"bounce"`, `"jiggle"`). */
|
|
686
713
|
@serializable()
|
|
687
714
|
motionType: EmphasizeActionMotionType = "bounce";
|
|
688
715
|
|
|
@@ -704,29 +731,37 @@ export class EmphasizeOnClick extends Behaviour implements UsdzBehaviour {
|
|
|
704
731
|
}
|
|
705
732
|
|
|
706
733
|
/**
|
|
707
|
-
* Plays an audio clip when clicked.
|
|
734
|
+
* Plays an audio clip when this object is clicked.
|
|
735
|
+
* Works in the browser and in USDZ/QuickLook (Everywhere Actions).
|
|
736
|
+
*
|
|
737
|
+
* Assign a `target` {@link AudioSource} to use its spatial audio settings, or assign a `clip` URL directly.
|
|
738
|
+
* If no `target` is assigned, an {@link AudioSource} will be created automatically on this object.
|
|
739
|
+
*
|
|
740
|
+
* @see {@link AudioSource}for spatial audio settings
|
|
741
|
+
* @see {@link PlayAnimationOnClick} to play animations when clicked
|
|
742
|
+
* @see {@link SetActiveOnClick} to toggle visibility when clicked
|
|
743
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
708
744
|
* @summary Plays an audio clip when clicked
|
|
709
745
|
* @category Everywhere Actions
|
|
710
746
|
* @group Components
|
|
711
747
|
*/
|
|
712
748
|
export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler, UsdzBehaviour {
|
|
713
749
|
|
|
750
|
+
/** The {@link AudioSource} to use for playback. If not set, one will be created automatically on this object. */
|
|
714
751
|
@serializable(AudioSource)
|
|
715
752
|
target?: AudioSource;
|
|
716
753
|
|
|
754
|
+
/** URL of the audio clip to play. If not set, the clip assigned to `target` is used. */
|
|
717
755
|
@serializable(URL)
|
|
718
756
|
clip: string = "";
|
|
719
757
|
|
|
758
|
+
/** If true, clicking again while the audio is playing will stop it. */
|
|
720
759
|
@serializable()
|
|
721
760
|
toggleOnClick: boolean = false;
|
|
722
761
|
|
|
723
762
|
// Not exposed, but used for implicit playback of PlayOnAwake audio sources
|
|
724
763
|
trigger: "tap" | "start" = "tap";
|
|
725
764
|
|
|
726
|
-
start(): void {
|
|
727
|
-
ensureRaycaster(this.gameObject);
|
|
728
|
-
}
|
|
729
|
-
|
|
730
765
|
ensureAudioSource() {
|
|
731
766
|
if (!this.target) {
|
|
732
767
|
const newAudioSource = this.gameObject.addComponent(AudioSource);
|
|
@@ -781,7 +816,7 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
781
816
|
const clipName = AudioExtension.getName(clipUrl);
|
|
782
817
|
const volume = this.target ? this.target.volume : 1;
|
|
783
818
|
const auralMode = this.target && this.target.spatialBlend == 0 ? "nonSpatial" : "spatial";
|
|
784
|
-
|
|
819
|
+
|
|
785
820
|
// This checks if any child is clickable – if yes, the tap trigger is added; if not, we omit it.
|
|
786
821
|
let anyChildHasGeometry = false;
|
|
787
822
|
this.gameObject.traverse(c => {
|
|
@@ -790,7 +825,7 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
790
825
|
// Workaround: seems iOS often simply doesn't play audio on scene start when this is NOT present.
|
|
791
826
|
// unclear why, but having a useless tap action (nothing to tap on) "fixes" it.
|
|
792
827
|
anyChildHasGeometry = true;
|
|
793
|
-
|
|
828
|
+
|
|
794
829
|
const audioClip = ext.addAudioClip(clipUrl);
|
|
795
830
|
// const stopAction: IBehaviorElement = ActionBuilder.playAudioAction(playbackTarget, audioClip, "stop", volume, auralMode);
|
|
796
831
|
let playAction: IBehaviorElement = ActionBuilder.playAudioAction(playbackTarget, audioClip, "play", volume, auralMode);
|
|
@@ -831,16 +866,30 @@ export class PlayAudioOnClick extends Behaviour implements IPointerClickHandler,
|
|
|
831
866
|
}
|
|
832
867
|
|
|
833
868
|
/**
|
|
834
|
-
* Plays an animation when clicked.
|
|
869
|
+
* Plays an animation state when this object is clicked.
|
|
870
|
+
* Works in the browser and in USDZ/QuickLook (Everywhere Actions).
|
|
871
|
+
*
|
|
872
|
+
* Assign an {@link Animator} and a `stateName` to play a specific animation state,
|
|
873
|
+
* or assign an {@link Animation} component to play a legacy animation clip.
|
|
874
|
+
*
|
|
875
|
+
* For USDZ export, the component follows animator state transitions automatically, including looping states.
|
|
876
|
+
*
|
|
877
|
+
* @see {@link Animator}for playing animator state machine animations
|
|
878
|
+
* @see {@link Animation} for playing legacy animation clips
|
|
879
|
+
* @see {@link PlayAudioOnClick} to play audio when clicked
|
|
880
|
+
* @see {@link SetActiveOnClick} to toggle visibility when clicked
|
|
881
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
835
882
|
* @summary Plays an animation when clicked
|
|
836
883
|
* @category Everywhere Actions
|
|
837
884
|
* @group Components
|
|
838
885
|
*/
|
|
839
886
|
export class PlayAnimationOnClick extends Behaviour implements IPointerClickHandler, UsdzBehaviour, UsdzAnimation {
|
|
840
887
|
|
|
888
|
+
/** The {@link Animator} component whose state to play when clicked. */
|
|
841
889
|
@serializable(Animator)
|
|
842
890
|
animator?: Animator;
|
|
843
891
|
|
|
892
|
+
/** The name of the animation state to play. Required when using an {@link Animator}. */
|
|
844
893
|
@serializable()
|
|
845
894
|
stateName?: string;
|
|
846
895
|
|
|
@@ -852,10 +901,6 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
852
901
|
|
|
853
902
|
private get target() { return this.animator?.gameObject || this.animation?.gameObject }
|
|
854
903
|
|
|
855
|
-
start(): void {
|
|
856
|
-
ensureRaycaster(this.gameObject);
|
|
857
|
-
}
|
|
858
|
-
|
|
859
904
|
|
|
860
905
|
onPointerEnter() {
|
|
861
906
|
this.context.input.setCursor("pointer");
|
|
@@ -905,9 +950,9 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
905
950
|
afterCreateDocument(ext: BehaviorExtension, context: USDZExporterContext) {
|
|
906
951
|
if ((this.animationSequence === undefined && this.animationLoopAfterSequence === undefined) || !this.stateAnimationModel) return;
|
|
907
952
|
if (!this.target) return;
|
|
908
|
-
|
|
953
|
+
|
|
909
954
|
const document = context.document;
|
|
910
|
-
|
|
955
|
+
|
|
911
956
|
// check if the AnimationExtension has been attached and what data it has for the current object
|
|
912
957
|
const animationExt = context.extensions.find(ext => ext instanceof AnimationExtension) as AnimationExtension;
|
|
913
958
|
if (!animationExt) return;
|
|
@@ -921,7 +966,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
921
966
|
if (requiresExclusivePlayback) {
|
|
922
967
|
if (isDevEnvironment())
|
|
923
968
|
console.warn("Setting exclusive playback for " + this.target.name + "@" + this.stateName + " because it has " + animationExt.getClipCount(this.target) + " animations. This works around QuickLook bug FB13410767.");
|
|
924
|
-
|
|
969
|
+
|
|
925
970
|
PlayAnimationOnClick.rootsWithExclusivePlayback.add(this.target);
|
|
926
971
|
}
|
|
927
972
|
|
|
@@ -941,7 +986,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
941
986
|
this.trigger == "tap" ? TriggerBuilder.tapTrigger(this.selfModel) : TriggerBuilder.sceneStartTrigger(),
|
|
942
987
|
sequence
|
|
943
988
|
);
|
|
944
|
-
|
|
989
|
+
|
|
945
990
|
// See comment above for why exclusive playback is currently required when playing multiple animations on the same root.
|
|
946
991
|
if (requiresExclusivePlayback)
|
|
947
992
|
playAnimationOnTap.makeExclusive(true);
|
|
@@ -1010,14 +1055,14 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
1010
1055
|
let animationLoopAfterSequence: Array<RegisteredAnimationInfo> = [];
|
|
1011
1056
|
|
|
1012
1057
|
if (animation) {
|
|
1013
|
-
const anim = ext.registerAnimation(target, animation.clip);
|
|
1058
|
+
const anim = ext.registerAnimation(target, animation.clip);
|
|
1014
1059
|
if (anim) {
|
|
1015
1060
|
if (animation.loop)
|
|
1016
1061
|
animationLoopAfterSequence.push(anim);
|
|
1017
1062
|
else
|
|
1018
1063
|
animationSequence.push(anim);
|
|
1019
1064
|
}
|
|
1020
|
-
|
|
1065
|
+
|
|
1021
1066
|
let randomTimeOffset = 0;
|
|
1022
1067
|
if (animation.minMaxOffsetNormalized) {
|
|
1023
1068
|
const from = animation.minMaxOffsetNormalized.x;
|
|
@@ -1111,7 +1156,7 @@ export class PlayAnimationOnClick extends Behaviour implements IPointerClickHand
|
|
|
1111
1156
|
if (lastClip) {
|
|
1112
1157
|
let clipCopy: AnimationClip | undefined;
|
|
1113
1158
|
if (ext.holdClipMap.has(lastClip)) {
|
|
1114
|
-
clipCopy = ext.holdClipMap.get(lastClip);
|
|
1159
|
+
clipCopy = ext.holdClipMap.get(lastClip);
|
|
1115
1160
|
}
|
|
1116
1161
|
else {
|
|
1117
1162
|
// We're creating a "hold" clip here; exactly 1 second long, and inteprolates exactly on the duration of the clip
|
|
@@ -1241,17 +1286,24 @@ export class PreliminaryTrigger extends Behaviour {
|
|
|
1241
1286
|
}
|
|
1242
1287
|
|
|
1243
1288
|
/**
|
|
1244
|
-
*
|
|
1289
|
+
* Action to show or hide an object.
|
|
1290
|
+
* Use together with a {@link TapGestureTrigger} to show or hide objects when tapped or clicked.
|
|
1291
|
+
*
|
|
1292
|
+
* @see {@link TapGestureTrigger} to trigger actions on tap/click
|
|
1293
|
+
* @see {@link SetActiveOnClick} for a combined trigger and action component
|
|
1294
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
1245
1295
|
* @summary Hides or shows the object when clicked
|
|
1246
1296
|
* @category Everywhere Actions
|
|
1247
1297
|
* @group Components
|
|
1248
1298
|
*/
|
|
1249
1299
|
export class VisibilityAction extends PreliminaryAction {
|
|
1250
1300
|
|
|
1301
|
+
/** The type of visibility action to apply. */
|
|
1251
1302
|
//@type int
|
|
1252
1303
|
@serializable()
|
|
1253
1304
|
type: VisibilityActionType = VisibilityActionType.Hide;
|
|
1254
1305
|
|
|
1306
|
+
/** The duration of the fade animation in seconds. */
|
|
1255
1307
|
@serializable()
|
|
1256
1308
|
duration: number = 1;
|
|
1257
1309
|
|
|
@@ -1268,7 +1320,12 @@ export class VisibilityAction extends PreliminaryAction {
|
|
|
1268
1320
|
}
|
|
1269
1321
|
|
|
1270
1322
|
/**
|
|
1271
|
-
* Triggers
|
|
1323
|
+
* Triggers a {@link PreliminaryAction} (such as {@link VisibilityAction}) when the object is tapped or clicked.
|
|
1324
|
+
* Works in the browser and in USDZ/QuickLook (Everywhere Actions).
|
|
1325
|
+
*
|
|
1326
|
+
* @see {@link VisibilityAction} for controlling object visibility on tap
|
|
1327
|
+
* @see {@link SetActiveOnClick} for a combined trigger and action component
|
|
1328
|
+
* @see [Everywhere Actions](https://engine.needle.tools/docs/everywhere-actions)
|
|
1272
1329
|
* @summary Triggers an action when the object is tapped/clicked
|
|
1273
1330
|
* @category Everywhere Actions
|
|
1274
1331
|
* @group Components
|