@relu-interactives/spatial-ecs 0.4.4 → 0.5.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/dist/{System-ln4Q7Eot.d.cts → System-V_mv07le.d.cts} +2 -2
- package/dist/{System-ln4Q7Eot.d.ts → System-V_mv07le.d.ts} +2 -2
- package/dist/{XRHandPose-CxPv-LBo.d.cts → XRHandPose-CQTLGxFC.d.cts} +218 -2
- package/dist/{XRHandPose-BImIa4ZS.d.ts → XRHandPose-CU3vNFuS.d.ts} +218 -2
- package/dist/{chunk-4AK4I3QF.js → chunk-BUEKOSR5.js} +102 -3
- package/dist/chunk-BUEKOSR5.js.map +1 -0
- package/dist/{chunk-SGADE55G.js → chunk-RXBLOO5B.js} +249 -90
- package/dist/chunk-RXBLOO5B.js.map +1 -0
- package/dist/{chunk-4DWZK4X4.js → chunk-WJD2VKEH.js} +3 -3
- package/dist/chunk-WJD2VKEH.js.map +1 -0
- package/dist/{chunk-OY2OONRR.js → chunk-Z6ZMR3CS.js} +1374 -30
- package/dist/chunk-Z6ZMR3CS.js.map +1 -0
- package/dist/components/index.cjs +99 -0
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +3 -3
- package/dist/components/index.d.ts +3 -3
- package/dist/components/index.js +1 -1
- package/dist/docs/guide/mixed-reality.md +137 -3
- package/dist/docs/guide/spatial-ui.md +165 -0
- package/dist/docs/guide/vr-and-hand-poses.md +29 -0
- package/dist/docs/guide/world-api.md +1 -1
- package/dist/factories/index.cjs +372 -114
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +13 -3
- package/dist/factories/index.d.ts +13 -3
- package/dist/factories/index.js +3 -3
- package/dist/{index-CuGqxuk-.d.ts → index-C3ik3sA1.d.ts} +16 -3
- package/dist/{index-B2oHfqkj.d.ts → index-CppKDxbu.d.ts} +187 -3
- package/dist/{index-CQsHUez3.d.cts → index-Dlr-7-4m.d.cts} +16 -3
- package/dist/{index-7YCk4cmQ.d.cts → index-I2IsocYW.d.cts} +187 -3
- package/dist/index.cjs +1977 -366
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -9
- package/dist/index.d.ts +42 -9
- package/dist/index.js +10 -8
- package/dist/index.js.map +1 -1
- package/dist/systems/index.cjs +1465 -25
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +2 -2
- package/dist/systems/index.d.ts +2 -2
- package/dist/systems/index.js +3 -3
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/worldSnapshotUtils.d.cts +1 -1
- package/dist/worldSnapshotUtils.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-4AK4I3QF.js.map +0 -1
- package/dist/chunk-4DWZK4X4.js.map +0 -1
- package/dist/chunk-OY2OONRR.js.map +0 -1
- package/dist/chunk-SGADE55G.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { k as EcsSystem, l as World, r as EntityId } from './System-
|
|
1
|
+
import { k as EcsSystem, l as World, I as InputSystem, r as EntityId } from './System-V_mv07le.cjs';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { m as XrHandJoints, r as XrHandShape } from './handPose-DlcTtqgx.cjs';
|
|
4
4
|
|
|
@@ -426,6 +426,7 @@ declare class XRInteractionSystem implements EcsSystem {
|
|
|
426
426
|
private readonly grabs;
|
|
427
427
|
private hoveredEntityId;
|
|
428
428
|
/** Per-hand hover, with the hit distance so the ray can stop at the surface. */
|
|
429
|
+
private readonly busyContributors;
|
|
429
430
|
private readonly hovers;
|
|
430
431
|
/** Monotonic seconds, accumulated from deltaTime for velocity sampling. */
|
|
431
432
|
private elapsed;
|
|
@@ -529,6 +530,14 @@ declare class XRInteractionSystem implements EcsSystem {
|
|
|
529
530
|
* grabbed and teleported.
|
|
530
531
|
*/
|
|
531
532
|
isSourceBusy(world: World, input: XrInputState): boolean;
|
|
533
|
+
/** OR-ed into isSourceBusy; see the comment there. */
|
|
534
|
+
registerBusyContributor(contributor: (world: World, input: XrInputState) => boolean): void;
|
|
535
|
+
/** Hover for a specific input source (handedness-free — Vision Pro's
|
|
536
|
+
* transient pointers all report handedness "none"). */
|
|
537
|
+
getHoverForInput(input: XrInputState): {
|
|
538
|
+
entityId: number;
|
|
539
|
+
distance: number;
|
|
540
|
+
} | null;
|
|
532
541
|
/** True when THIS hand is holding something. */
|
|
533
542
|
isGrabbingWith(handedness: XrInputState["handedness"]): boolean;
|
|
534
543
|
/**
|
|
@@ -651,6 +660,25 @@ declare class XRSessionSystem implements EcsSystem {
|
|
|
651
660
|
private session;
|
|
652
661
|
constructor(inputSystem?: XRInputSystem);
|
|
653
662
|
update(world: World): void;
|
|
663
|
+
/**
|
|
664
|
+
* Stop three's depth-occlusion pass from writing COLOR.
|
|
665
|
+
*
|
|
666
|
+
* With depth sensing granted, three draws a full-screen, head-locked mesh
|
|
667
|
+
* every frame whose fragment shader assigns ONLY `gl_FragDepth` — that is
|
|
668
|
+
* the whole occlusion mechanism — but its material never sets
|
|
669
|
+
* `colorWrite: false`, so the colour output is UNDEFINED per GLSL. Desktop
|
|
670
|
+
* drivers happen to zero it, which is why this ships unnoticed; Quest's
|
|
671
|
+
* mobile GPU frequently leaves the last-computed temporary in the register —
|
|
672
|
+
* the sampled DEPTH value — so the pass paints the depth camera's view over
|
|
673
|
+
* the screen as faint head-locked contour bands. On device that reads as "a
|
|
674
|
+
* large wireframe dome that follows my head".
|
|
675
|
+
*
|
|
676
|
+
* The mesh is created lazily inside three's render, so this is re-checked
|
|
677
|
+
* every frame rather than hooked once; the write is idempotent and the
|
|
678
|
+
* check is two property reads. Depth-only is the mesh's entire purpose —
|
|
679
|
+
* occlusion is unaffected.
|
|
680
|
+
*/
|
|
681
|
+
private muteDepthOcclusionColor;
|
|
654
682
|
private handleSessionStart;
|
|
655
683
|
/**
|
|
656
684
|
* Apply the rig's authored tracking origin, and compensate when the device
|
|
@@ -690,12 +718,26 @@ declare class XREnvironmentSystem implements EcsSystem {
|
|
|
690
718
|
/** Keyed by the XRPlane/XRMesh object itself — the runtime's own identity. */
|
|
691
719
|
private readonly planes;
|
|
692
720
|
private readonly meshes;
|
|
721
|
+
/**
|
|
722
|
+
* Surfaces observed but not yet SPAWNED — their gate is still proving the
|
|
723
|
+
* pose is world-anchored. Creating from an unflagged head-glued pose (seen
|
|
724
|
+
* on-device after a suspend/resume regenerated the scan identities) plants
|
|
725
|
+
* a rotated ghost copy of the room wherever the head happens to be, which
|
|
726
|
+
* the apply-gate then freezes there — wrong forever. So admission itself
|
|
727
|
+
* is gated: a few frames of world-anchored behavior first.
|
|
728
|
+
*/
|
|
729
|
+
private readonly pendingPlanes;
|
|
730
|
+
private readonly pendingMeshes;
|
|
693
731
|
private presenting;
|
|
694
732
|
private debugVisible;
|
|
695
733
|
/** Seconds presenting, used to decide the room has genuinely nothing in it. */
|
|
696
734
|
private elapsed;
|
|
697
735
|
/** `initiateRoomCapture` may be called only ONCE per session. */
|
|
698
736
|
private roomCaptureRequested;
|
|
737
|
+
/** This frame's inverse viewer matrix, or null when unavailable. */
|
|
738
|
+
private viewerInverse;
|
|
739
|
+
private readonly tmpViewerMatrix;
|
|
740
|
+
private readonly tmpViewPos;
|
|
699
741
|
update(world: World, deltaTime?: number): void;
|
|
700
742
|
/**
|
|
701
743
|
* Ask the runtime to scan the room when it turns out we have no room.
|
|
@@ -718,9 +760,47 @@ declare class XREnvironmentSystem implements EcsSystem {
|
|
|
718
760
|
planes: number;
|
|
719
761
|
meshes: number;
|
|
720
762
|
};
|
|
763
|
+
/**
|
|
764
|
+
* A census of every surface currently spawned: what it is, where it sits and
|
|
765
|
+
* roughly how big it is. Built for the template's post-session readout, so a
|
|
766
|
+
* mystery shape on the headset can be looked up by its label instead of
|
|
767
|
+
* guessed at — a small-radius entry at head height IS the mystery shape, and
|
|
768
|
+
* a clean list means whatever was seen did not come from this system.
|
|
769
|
+
*/
|
|
770
|
+
getDebugSnapshot(world: World): {
|
|
771
|
+
kind: "plane" | "mesh";
|
|
772
|
+
label: string | null;
|
|
773
|
+
position: {
|
|
774
|
+
x: number;
|
|
775
|
+
y: number;
|
|
776
|
+
z: number;
|
|
777
|
+
};
|
|
778
|
+
radius: number;
|
|
779
|
+
/** Tracking currently lost — pose frozen at the last known place. */
|
|
780
|
+
emulated: boolean;
|
|
781
|
+
}[];
|
|
782
|
+
/** Create the no-scan floor once; it lives in the ordinary plane map. */
|
|
783
|
+
private ensureSyntheticFloor;
|
|
784
|
+
/** Real scene data exists (or arrived) — the stand-in must go. */
|
|
785
|
+
private removeSyntheticFloor;
|
|
721
786
|
private findRig;
|
|
722
787
|
private syncPlanes;
|
|
723
788
|
private syncMeshes;
|
|
789
|
+
/**
|
|
790
|
+
* Admission control for a NOT-yet-spawned surface. With a viewer pose
|
|
791
|
+
* available, the surface must behave world-anchored for a few frames before
|
|
792
|
+
* an entity is created for it; without one (older runtimes, tests) it is
|
|
793
|
+
* admitted immediately — the gate can't classify anyway. Returns the
|
|
794
|
+
* warmed-up gate (carried into the entry so its motion history survives),
|
|
795
|
+
* or null while the surface must keep waiting.
|
|
796
|
+
*/
|
|
797
|
+
private admit;
|
|
798
|
+
/**
|
|
799
|
+
* Run a surface's pose through its head-glue gate: position in reference
|
|
800
|
+
* space vs position relative to the viewer. Without a viewer pose the gate
|
|
801
|
+
* passes everything, degrading to the flag-only behavior.
|
|
802
|
+
*/
|
|
803
|
+
private gateAllows;
|
|
724
804
|
private createPlaneEntity;
|
|
725
805
|
private applyPlaneCollider;
|
|
726
806
|
private createMeshEntity;
|
|
@@ -734,6 +814,106 @@ declare class XREnvironmentSystem implements EcsSystem {
|
|
|
734
814
|
dispose(world: World): void;
|
|
735
815
|
}
|
|
736
816
|
|
|
817
|
+
declare class UIInteractionSystem implements EcsSystem {
|
|
818
|
+
private readonly interaction;
|
|
819
|
+
private readonly inputSystem;
|
|
820
|
+
private readonly xrPresses;
|
|
821
|
+
private mousePress;
|
|
822
|
+
private mouseHover;
|
|
823
|
+
/** entityId → seconds of pressed-tint left to display. */
|
|
824
|
+
private readonly tintFloors;
|
|
825
|
+
private readonly tinted;
|
|
826
|
+
private readonly raycaster;
|
|
827
|
+
/**
|
|
828
|
+
* @param interaction The XR interaction system, or null in a world with no
|
|
829
|
+
* XR (flat 3D experiences) — the mouse path still works via
|
|
830
|
+
* `options.inputSystem`.
|
|
831
|
+
*/
|
|
832
|
+
constructor(interaction: XRInteractionSystem | null, options?: {
|
|
833
|
+
inputSystem?: InputSystem;
|
|
834
|
+
});
|
|
835
|
+
update(world: World, deltaTime?: number): void;
|
|
836
|
+
private updateXr;
|
|
837
|
+
private updateMouse;
|
|
838
|
+
private raycastMouse;
|
|
839
|
+
private widgetKind;
|
|
840
|
+
private fire;
|
|
841
|
+
private dragSlider;
|
|
842
|
+
private dragSliderMouse;
|
|
843
|
+
private applySliderPoint;
|
|
844
|
+
private widgetObject;
|
|
845
|
+
private rayHitsWidget;
|
|
846
|
+
private rayPointOnWidget;
|
|
847
|
+
/**
|
|
848
|
+
* Dispatch to the widget's Behaviours, then BUBBLE up the parent chain so a
|
|
849
|
+
* panel script hears its children. Bubbling (not a world broadcast) keeps
|
|
850
|
+
* two spawned copies of the same menu prefab independent.
|
|
851
|
+
*/
|
|
852
|
+
private dispatchBubbling;
|
|
853
|
+
private actionIdOf;
|
|
854
|
+
private beginPressTint;
|
|
855
|
+
private endPressTint;
|
|
856
|
+
private updateTints;
|
|
857
|
+
private setTint;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Renders spatial-UI widgets: panels, text, buttons, toggles and sliders.
|
|
862
|
+
*
|
|
863
|
+
* Lives in `World.setup`'s DEFAULT system list (like `VRTeleportAreaSystem`)
|
|
864
|
+
* so the editor and every runtime render UI with no consumer wiring. Each
|
|
865
|
+
* widget's face is ONE canvas-textured quad, rebuilt only when its style
|
|
866
|
+
* SIGNATURE changes — a canvas redraw plus GPU upload costs 1–3 ms, fine per
|
|
867
|
+
* edit and catastrophic per frame. Interaction state (hover/pressed) never
|
|
868
|
+
* touches the canvas: `UIInteractionSystem` tints the material instead.
|
|
869
|
+
*
|
|
870
|
+
* Toggle knobs and slider knob/fill are separate GEOMETRY positioned from the
|
|
871
|
+
* value each frame, so dragging a slider redraws nothing.
|
|
872
|
+
*
|
|
873
|
+
* Widget SIZE is authored on the component in metres, never via transform
|
|
874
|
+
* scale — the texture is rasterised for the authored size, so scale would
|
|
875
|
+
* stretch texels into blur (and folding live scale into the signature would
|
|
876
|
+
* rebuild every frame during a two-hand scale gesture).
|
|
877
|
+
*/
|
|
878
|
+
/** Structural canvas type so tests can inject a stub with no DOM. */
|
|
879
|
+
type UiCanvasLike = {
|
|
880
|
+
width: number;
|
|
881
|
+
height: number;
|
|
882
|
+
getContext(kind: "2d"): CanvasRenderingContext2D | null;
|
|
883
|
+
};
|
|
884
|
+
declare class UIPanelSystem implements EcsSystem {
|
|
885
|
+
private readonly entries;
|
|
886
|
+
private readonly createCanvas;
|
|
887
|
+
constructor(options?: {
|
|
888
|
+
createCanvas?: () => UiCanvasLike;
|
|
889
|
+
});
|
|
890
|
+
update(world: World, deltaTime?: number): void;
|
|
891
|
+
/** All GPU/canvas resources; call on world teardown. */
|
|
892
|
+
dispose(): void;
|
|
893
|
+
private syncPanel;
|
|
894
|
+
private syncText;
|
|
895
|
+
private syncButton;
|
|
896
|
+
private syncToggle;
|
|
897
|
+
private syncSlider;
|
|
898
|
+
private rebuildIfChanged;
|
|
899
|
+
private configureTexture;
|
|
900
|
+
private makeQuad;
|
|
901
|
+
/** A filled disc (or arc segment, for the fill's rounded cap). */
|
|
902
|
+
private makeDisc;
|
|
903
|
+
private addPart;
|
|
904
|
+
/** Remove + dispose knob/fill/cap so a sync pass rebuilds them fresh. */
|
|
905
|
+
private disposeMovingParts;
|
|
906
|
+
/**
|
|
907
|
+
* Billboard: yaw the ENTITY TRANSFORM toward the camera. Writing the
|
|
908
|
+
* Object3D directly would be overwritten by `TransformSyncSystem` (which
|
|
909
|
+
* runs after this system, before render) — the same reason locomotion
|
|
910
|
+
* writes the rig transform. Skipped in the editor so the gizmo and the
|
|
911
|
+
* authored rotation stay in charge while authoring.
|
|
912
|
+
*/
|
|
913
|
+
private applyFollow;
|
|
914
|
+
private destroyEntry;
|
|
915
|
+
}
|
|
916
|
+
|
|
737
917
|
/**
|
|
738
918
|
* Answers "where does this ray meet the real world?".
|
|
739
919
|
*
|
|
@@ -787,8 +967,12 @@ declare class XRAnchorSystem implements EcsSystem {
|
|
|
787
967
|
private readonly anchors;
|
|
788
968
|
/** In-flight creations, so one entity is not anchored twice. */
|
|
789
969
|
private readonly pending;
|
|
970
|
+
/** Per-anchor head-glue gates — see XREnvironmentSystem's TrackedEntry. */
|
|
971
|
+
private readonly gates;
|
|
790
972
|
private presenting;
|
|
791
|
-
|
|
973
|
+
private readonly tmpViewerMatrix;
|
|
974
|
+
private readonly tmpViewPos;
|
|
975
|
+
update(world: World, deltaTime?: number): void;
|
|
792
976
|
/** Whether this entity's pose is currently being driven by an anchor. */
|
|
793
977
|
isAnchored(entityId: EntityId): boolean;
|
|
794
978
|
private requestAnchor;
|
|
@@ -979,4 +1163,4 @@ declare class XRHoverVisualSystem implements EcsSystem {
|
|
|
979
1163
|
dispose(): void;
|
|
980
1164
|
}
|
|
981
1165
|
|
|
982
|
-
export { AnimationSystem as A, CameraSyncSystem as C, EnvironmentSyncSystem as E, InstancedMeshSystem as I, LightSyncSystem as L, MaterialSyncSystem as M, NO_XR_CAPABILITIES as N, ObjectVisibilitySystem as O, PhysicsSyncSystem as P, SCRIPT_OBJECT_ROOT_FLAG as S, VRTeleportAreaSystem as V, type XrCapabilities as X, type XrInputState as a, type XrHandPoseEventDetail as b, AudioSystem as c, MeshGeometrySystem as d, type ModuleLoader as e, PostprocessingSyncSystem as f, ScriptBehaviourSystem as g, ScriptObjectSystem as h, type SelectionContext as i,
|
|
1166
|
+
export { AnimationSystem as A, type XrInputKind as B, CameraSyncSystem as C, readXrCapabilities as D, EnvironmentSyncSystem as E, InstancedMeshSystem as I, LightSyncSystem as L, MaterialSyncSystem as M, NO_XR_CAPABILITIES as N, ObjectVisibilitySystem as O, PhysicsSyncSystem as P, SCRIPT_OBJECT_ROOT_FLAG as S, UIInteractionSystem as U, VRTeleportAreaSystem as V, type XrCapabilities as X, type XrInputState as a, type XrHandPoseEventDetail as b, AudioSystem as c, MeshGeometrySystem as d, type ModuleLoader as e, PostprocessingSyncSystem as f, ScriptBehaviourSystem as g, ScriptObjectSystem as h, type SelectionContext as i, UIPanelSystem as j, type UiCanvasLike as k, VideoSystem as l, XRAnchorSystem as m, XRControllerVisualSystem as n, XREnvironmentSystem as o, XRHandPoseSystem as p, XRHitTestSystem as q, XRHoverVisualSystem as r, XRInputSystem as s, XRInteractionSystem as t, XRLocomotionSystem as u, XRSessionSystem as v, XRTeleportVisualSystem as w, XR_HOVER_SHELL_FLAG as x, type XrHandedness as y, type XrHitResult as z };
|