@relu-interactives/spatial-ecs 0.3.1 → 0.3.2

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.
@@ -1,4 +1,4 @@
1
- export { createAnimationComponent, createAudioComponent, createCameraComponent, createEntityTypeComponent, createEnvironmentComponent, createImageComponent, createImageTargetAnchorComponent, createImageTargetComponent, createInstanceSlotComponent, createInstancedMeshComponent, createLightComponent, createMaterialComponent, createMeshComponent, createMeshGeometryComponent, createModelComponent, createNameComponent, createObject3DRefComponent, createParentIdComponent, createPhysicsComponent, createPostprocessingComponent, createScriptComponent, createScriptObjectComponent, createSelectableComponent, createSelectionTransformStateComponent, createSpriteComponent, createTransformComponent, createVRTeleportAreaComponent, createVideoComponent, createXRInteractableComponent, createXRRigComponent, registerDefaultComponentFactories, registerDefaultFactories } from '../chunk-PCOZLCXS.js';
1
+ export { createAnimationComponent, createAudioComponent, createCameraComponent, createEntityTypeComponent, createEnvironmentComponent, createImageComponent, createImageTargetAnchorComponent, createImageTargetComponent, createInstanceSlotComponent, createInstancedMeshComponent, createLightComponent, createMaterialComponent, createMeshComponent, createMeshGeometryComponent, createModelComponent, createNameComponent, createObject3DRefComponent, createParentIdComponent, createPhysicsComponent, createPostprocessingComponent, createScriptComponent, createScriptObjectComponent, createSelectableComponent, createSelectionTransformStateComponent, createSpriteComponent, createTransformComponent, createVRTeleportAreaComponent, createVideoComponent, createXRInteractableComponent, createXRRigComponent, registerDefaultComponentFactories, registerDefaultFactories } from '../chunk-JWTRFJBL.js';
2
2
  import '../chunk-67WGASUJ.js';
3
3
  import '../chunk-U3MDYKPV.js';
4
4
  import '../chunk-OY7ZODZP.js';
@@ -485,4 +485,30 @@ declare class XRSessionSystem implements EcsSystem {
485
485
  getInputs(): XrInputState[];
486
486
  }
487
487
 
488
- 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, VideoSystem as V, type XrCapabilities as X, type XrInputState as a, AudioSystem as b, MeshGeometrySystem as c, type ModuleLoader as d, PostprocessingSyncSystem as e, ScriptBehaviourSystem as f, ScriptObjectSystem as g, type SelectionContext as h, XRInputSystem as i, XRInteractionSystem as j, XRLocomotionSystem as k, XRSessionSystem as l, type XrHandedness as m, type XrInputKind as n, readXrCapabilities as r };
488
+ declare class VRTeleportAreaSystem implements EcsSystem {
489
+ private readonly signatures;
490
+ update(world: World): void;
491
+ }
492
+
493
+ declare class XRControllerVisualSystem implements EcsSystem {
494
+ private readonly controllerModelFactory;
495
+ private readonly handModelFactory;
496
+ private readonly group;
497
+ private built;
498
+ private attachedTo;
499
+ /** Index → whether we've already attached visuals for that slot. */
500
+ private readonly ready;
501
+ /** How many controller slots to wire. Two covers every current headset. */
502
+ private readonly slots;
503
+ constructor(slots?: number);
504
+ update(world: World): void;
505
+ /**
506
+ * Parent the visuals to the XR rig when there is one, so locomotion moves the
507
+ * hands with the player. Falls back to the scene root.
508
+ */
509
+ private ensureAttached;
510
+ private createRay;
511
+ dispose(): void;
512
+ }
513
+
514
+ 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, AudioSystem as b, MeshGeometrySystem as c, type ModuleLoader as d, PostprocessingSyncSystem as e, ScriptBehaviourSystem as f, ScriptObjectSystem as g, type SelectionContext as h, VideoSystem as i, XRControllerVisualSystem as j, XRInputSystem as k, XRInteractionSystem as l, XRLocomotionSystem as m, XRSessionSystem as n, type XrHandedness as o, type XrInputKind as p, readXrCapabilities as r };
@@ -485,4 +485,30 @@ declare class XRSessionSystem implements EcsSystem {
485
485
  getInputs(): XrInputState[];
486
486
  }
487
487
 
488
- 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, VideoSystem as V, type XrCapabilities as X, type XrInputState as a, AudioSystem as b, MeshGeometrySystem as c, type ModuleLoader as d, PostprocessingSyncSystem as e, ScriptBehaviourSystem as f, ScriptObjectSystem as g, type SelectionContext as h, XRInputSystem as i, XRInteractionSystem as j, XRLocomotionSystem as k, XRSessionSystem as l, type XrHandedness as m, type XrInputKind as n, readXrCapabilities as r };
488
+ declare class VRTeleportAreaSystem implements EcsSystem {
489
+ private readonly signatures;
490
+ update(world: World): void;
491
+ }
492
+
493
+ declare class XRControllerVisualSystem implements EcsSystem {
494
+ private readonly controllerModelFactory;
495
+ private readonly handModelFactory;
496
+ private readonly group;
497
+ private built;
498
+ private attachedTo;
499
+ /** Index → whether we've already attached visuals for that slot. */
500
+ private readonly ready;
501
+ /** How many controller slots to wire. Two covers every current headset. */
502
+ private readonly slots;
503
+ constructor(slots?: number);
504
+ update(world: World): void;
505
+ /**
506
+ * Parent the visuals to the XR rig when there is one, so locomotion moves the
507
+ * hands with the player. Falls back to the scene root.
508
+ */
509
+ private ensureAttached;
510
+ private createRay;
511
+ dispose(): void;
512
+ }
513
+
514
+ 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, AudioSystem as b, MeshGeometrySystem as c, type ModuleLoader as d, PostprocessingSyncSystem as e, ScriptBehaviourSystem as f, ScriptObjectSystem as g, type SelectionContext as h, VideoSystem as i, XRControllerVisualSystem as j, XRInputSystem as k, XRInteractionSystem as l, XRLocomotionSystem as m, XRSessionSystem as n, type XrHandedness as o, type XrInputKind as p, readXrCapabilities as r };
package/dist/index.cjs CHANGED
@@ -19,6 +19,8 @@ var OutputPass_js = require('three/examples/jsm/postprocessing/OutputPass.js');
19
19
  var HueSaturationShader_js = require('three/examples/jsm/shaders/HueSaturationShader.js');
20
20
  var SepiaShader_js = require('three/examples/jsm/shaders/SepiaShader.js');
21
21
  var VignetteShader_js = require('three/examples/jsm/shaders/VignetteShader.js');
22
+ var XRControllerModelFactory_js = require('three/examples/jsm/webxr/XRControllerModelFactory.js');
23
+ var XRHandModelFactory_js = require('three/examples/jsm/webxr/XRHandModelFactory.js');
22
24
 
23
25
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
24
26
  function _interopNamespace(e) {
@@ -3890,11 +3892,19 @@ function createTeleportArea({
3890
3892
  depthWrite: false
3891
3893
  });
3892
3894
  const object = new THREE38__namespace.Mesh(geometry, material);
3893
- object.rotation.x = -Math.PI / 2;
3894
3895
  const entityId = createBaseEntity(world, object, {
3895
3896
  label: payload.name ?? "Teleport Area",
3896
3897
  entityType: "teleportArea",
3897
- transformInput: payload.transform
3898
+ // The flat-on-the-ground rotation must live in the ECS TRANSFORM, not on
3899
+ // the Object3D: createBaseEntity applies the transform over the object, and
3900
+ // TransformSyncSystem re-applies it every frame — so a rotation set
3901
+ // directly on the mesh is overwritten immediately and the area stands up
3902
+ // like a wall. Same convention as the `plane` primitive.
3903
+ transformInput: {
3904
+ position: payload.transform?.position,
3905
+ rotation: payload.transform?.rotation ?? { x: -Math.PI / 2, y: 0, z: 0 },
3906
+ scale: payload.transform?.scale
3907
+ }
3898
3908
  });
3899
3909
  world.addComponent(
3900
3910
  entityId,
@@ -10647,6 +10657,128 @@ var _XRSessionSystem = class _XRSessionSystem {
10647
10657
  };
10648
10658
  __name(_XRSessionSystem, "XRSessionSystem");
10649
10659
  var XRSessionSystem = _XRSessionSystem;
10660
+ function buildGeometry2(area) {
10661
+ if (area.shape === "cylinder") {
10662
+ const radius = Math.max(5e-3, area.width / 2);
10663
+ return new THREE38__namespace.CircleGeometry(radius, 48);
10664
+ }
10665
+ return new THREE38__namespace.PlaneGeometry(
10666
+ Math.max(0.01, area.width),
10667
+ Math.max(0.01, area.depth)
10668
+ );
10669
+ }
10670
+ __name(buildGeometry2, "buildGeometry");
10671
+ function signatureOf(area) {
10672
+ return `${area.shape}:${area.width}:${area.depth}`;
10673
+ }
10674
+ __name(signatureOf, "signatureOf");
10675
+ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
10676
+ constructor() {
10677
+ this.signatures = /* @__PURE__ */ new Map();
10678
+ }
10679
+ update(world) {
10680
+ const entityIds = world.query(VRTeleportAreaComponent, Object3DRef);
10681
+ const alive = new Set(entityIds);
10682
+ for (const tracked of this.signatures.keys()) {
10683
+ if (!alive.has(tracked)) this.signatures.delete(tracked);
10684
+ }
10685
+ for (const entityId of entityIds) {
10686
+ const area = world.getComponent(entityId, VRTeleportAreaComponent);
10687
+ const object = world.getComponent(entityId, Object3DRef)?.object;
10688
+ if (!area || !(object instanceof THREE38__namespace.Mesh)) continue;
10689
+ const signature = signatureOf(area);
10690
+ if (this.signatures.get(entityId) === signature) continue;
10691
+ this.signatures.set(entityId, signature);
10692
+ object.geometry?.dispose?.();
10693
+ object.geometry = buildGeometry2(area);
10694
+ }
10695
+ }
10696
+ };
10697
+ __name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
10698
+ var VRTeleportAreaSystem = _VRTeleportAreaSystem;
10699
+ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
10700
+ constructor(slots = 2) {
10701
+ this.controllerModelFactory = new XRControllerModelFactory_js.XRControllerModelFactory();
10702
+ this.handModelFactory = new XRHandModelFactory_js.XRHandModelFactory();
10703
+ this.group = new THREE38__namespace.Group();
10704
+ this.built = false;
10705
+ this.attachedTo = null;
10706
+ /** Index → whether we've already attached visuals for that slot. */
10707
+ this.ready = /* @__PURE__ */ new Set();
10708
+ this.slots = slots;
10709
+ this.group.name = "XRControllerVisuals";
10710
+ this.group.userData.ecsPreviewHidden = true;
10711
+ }
10712
+ update(world) {
10713
+ const renderer = world.getRenderer();
10714
+ if (!renderer.xr?.enabled) return;
10715
+ this.ensureAttached(world);
10716
+ if (this.built) return;
10717
+ for (let index = 0; index < this.slots; index += 1) {
10718
+ if (this.ready.has(index)) continue;
10719
+ const controller = renderer.xr.getController(index);
10720
+ const grip = renderer.xr.getControllerGrip(index);
10721
+ const hand = renderer.xr.getHand(index);
10722
+ if (!controller || !grip || !hand) continue;
10723
+ controller.add(this.createRay());
10724
+ this.group.add(controller);
10725
+ grip.add(this.controllerModelFactory.createControllerModel(grip));
10726
+ this.group.add(grip);
10727
+ hand.add(this.handModelFactory.createHandModel(hand, "mesh"));
10728
+ this.group.add(hand);
10729
+ this.ready.add(index);
10730
+ }
10731
+ if (this.ready.size >= this.slots) {
10732
+ this.built = true;
10733
+ }
10734
+ }
10735
+ /**
10736
+ * Parent the visuals to the XR rig when there is one, so locomotion moves the
10737
+ * hands with the player. Falls back to the scene root.
10738
+ */
10739
+ ensureAttached(world) {
10740
+ const camera = world.getCamera();
10741
+ const target = camera.parent ?? world.getScene();
10742
+ if (this.attachedTo === target) return;
10743
+ target.add(this.group);
10744
+ this.attachedTo = target;
10745
+ }
10746
+ createRay() {
10747
+ const geometry = new THREE38__namespace.BufferGeometry().setFromPoints([
10748
+ new THREE38__namespace.Vector3(0, 0, 0),
10749
+ new THREE38__namespace.Vector3(0, 0, -5)
10750
+ ]);
10751
+ const material = new THREE38__namespace.LineBasicMaterial({
10752
+ color: "#4da3ff",
10753
+ transparent: true,
10754
+ opacity: 0.6,
10755
+ depthTest: false
10756
+ });
10757
+ const line = new THREE38__namespace.Line(geometry, material);
10758
+ line.name = "XRPointerRay";
10759
+ line.renderOrder = 999;
10760
+ return line;
10761
+ }
10762
+ dispose() {
10763
+ this.group.removeFromParent();
10764
+ this.group.traverse((child) => {
10765
+ const mesh = child;
10766
+ mesh.geometry?.dispose?.();
10767
+ const material = mesh.material;
10768
+ if (Array.isArray(material)) {
10769
+ for (const entry of material) entry.dispose?.();
10770
+ } else {
10771
+ material?.dispose?.();
10772
+ }
10773
+ });
10774
+ this.group.clear();
10775
+ this.ready.clear();
10776
+ this.built = false;
10777
+ this.attachedTo = null;
10778
+ }
10779
+ };
10780
+ __name(_XRControllerVisualSystem, "XRControllerVisualSystem");
10781
+ var XRControllerVisualSystem = _XRControllerVisualSystem;
10650
10782
 
10651
10783
  // core/World.ts
10652
10784
  var _World = class _World {
@@ -10992,6 +11124,7 @@ var _World = class _World {
10992
11124
  const postprocessingSyncSystem = this.featureFlags.supportPostprocessing ? new PostprocessingSyncSystem(this.renderer, this.scene, this.camera) : null;
10993
11125
  const lightSyncSystem = new LightSyncSystem();
10994
11126
  const materialSyncSystem = new MaterialSyncSystem();
11127
+ const vrTeleportAreaSystem = new VRTeleportAreaSystem();
10995
11128
  const physicsSyncSystem = new PhysicsSyncSystem({
10996
11129
  isEditor: isEditor ?? false
10997
11130
  });
@@ -11021,6 +11154,7 @@ var _World = class _World {
11021
11154
  }
11022
11155
  this.addSystems([
11023
11156
  ...coreSystems,
11157
+ vrTeleportAreaSystem,
11024
11158
  physicsSyncSystem,
11025
11159
  ...systems,
11026
11160
  objectVisibilitySystem,
@@ -12052,8 +12186,10 @@ exports.ScriptBehaviourSystem = ScriptBehaviourSystem;
12052
12186
  exports.ScriptObject = ScriptObject;
12053
12187
  exports.ScriptObjectSystem = ScriptObjectSystem;
12054
12188
  exports.TransformSyncSystem = TransformSyncSystem;
12189
+ exports.VRTeleportAreaSystem = VRTeleportAreaSystem;
12055
12190
  exports.VideoSystem = VideoSystem;
12056
12191
  exports.World = World;
12192
+ exports.XRControllerVisualSystem = XRControllerVisualSystem;
12057
12193
  exports.XRInputSystem = XRInputSystem;
12058
12194
  exports.XRInteractionSystem = XRInteractionSystem;
12059
12195
  exports.XRLocomotionSystem = XRLocomotionSystem;