@relu-interactives/spatial-ecs 0.3.2 → 0.3.5

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.
Files changed (37) hide show
  1. package/dist/{XRRig-Cu-EyliG.d.cts → XRRig-2686IqLQ.d.cts} +5 -5
  2. package/dist/{XRRig-CAmf04NX.d.ts → XRRig-D2QURXl1.d.ts} +5 -5
  3. package/dist/{chunk-67WGASUJ.js → chunk-2LVFGVWI.js} +3 -3
  4. package/dist/{chunk-67WGASUJ.js.map → chunk-2LVFGVWI.js.map} +1 -1
  5. package/dist/{chunk-JWTRFJBL.js → chunk-4BZYK3JP.js} +4 -4
  6. package/dist/{chunk-JWTRFJBL.js.map → chunk-4BZYK3JP.js.map} +1 -1
  7. package/dist/{chunk-U3MDYKPV.js → chunk-6QC2PJLD.js} +4 -3
  8. package/dist/chunk-6QC2PJLD.js.map +1 -0
  9. package/dist/{chunk-SALBG747.js → chunk-G53MZVKQ.js} +333 -25
  10. package/dist/chunk-G53MZVKQ.js.map +1 -0
  11. package/dist/components/index.cjs +2 -1
  12. package/dist/components/index.cjs.map +1 -1
  13. package/dist/components/index.d.cts +2 -2
  14. package/dist/components/index.d.ts +2 -2
  15. package/dist/components/index.js +1 -1
  16. package/dist/factories/index.cjs +2 -1
  17. package/dist/factories/index.cjs.map +1 -1
  18. package/dist/factories/index.d.cts +1 -1
  19. package/dist/factories/index.d.ts +1 -1
  20. package/dist/factories/index.js +3 -3
  21. package/dist/{index-CRmfSYdj.d.ts → index-B-CViRMx.d.ts} +57 -10
  22. package/dist/{index-w1oqWl_M.d.ts → index-BtKOaHfY.d.ts} +1 -1
  23. package/dist/{index-Bc0YCz1A.d.cts → index-BvCmmuJ0.d.cts} +57 -10
  24. package/dist/{index-CUFd71ri.d.cts → index-Xu238jLn.d.cts} +1 -1
  25. package/dist/index.cjs +337 -21
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +50 -6
  28. package/dist/index.d.ts +50 -6
  29. package/dist/index.js +8 -8
  30. package/dist/systems/index.cjs +318 -21
  31. package/dist/systems/index.cjs.map +1 -1
  32. package/dist/systems/index.d.cts +1 -1
  33. package/dist/systems/index.d.ts +1 -1
  34. package/dist/systems/index.js +3 -3
  35. package/package.json +1 -1
  36. package/dist/chunk-SALBG747.js.map +0 -1
  37. package/dist/chunk-U3MDYKPV.js.map +0 -1
@@ -2082,7 +2082,8 @@ var _VRTeleportAreaComponent = class _VRTeleportAreaComponent extends Component
2082
2082
  constructor(options) {
2083
2083
  super();
2084
2084
  this.enabled = options?.enabled ?? true;
2085
- this.shape = options?.shape ?? "plane";
2085
+ const shape = options?.shape;
2086
+ this.shape = shape === "cylinder" ? "circle" : options?.shape ?? "plane";
2086
2087
  this.width = options?.width ?? 10;
2087
2088
  this.depth = options?.depth ?? 10;
2088
2089
  }
@@ -4903,6 +4904,15 @@ function buildComponentValueMaps(snapshot) {
4903
4904
  snapshot.components,
4904
4905
  "ScriptObjectComponent"
4905
4906
  ),
4907
+ xrRigValues: readByComponent(snapshot.components, "XRRigComponent"),
4908
+ vrTeleportAreaValues: readByComponent(
4909
+ snapshot.components,
4910
+ "VRTeleportAreaComponent"
4911
+ ),
4912
+ xrInteractableValues: readByComponent(
4913
+ snapshot.components,
4914
+ "XRInteractableComponent"
4915
+ ),
4906
4916
  instancedMeshValues: readByComponent(snapshot.components, "InstancedMeshComponent"),
4907
4917
  instanceSlotValues: readByComponent(snapshot.components, "InstanceSlotComponent"),
4908
4918
  prefabNodeValues: readByComponent(snapshot.components, "PrefabNode"),
@@ -5028,6 +5038,67 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
5028
5038
  soc.data = remapEntityRefsInScriptData(data, idMap);
5029
5039
  }
5030
5040
  }
5041
+ {
5042
+ const sourceXrRig = asRecord3(values.xrRigValues.get(sourceEntityId));
5043
+ const rig = world.getComponent(targetEntityId, XRRigComponent);
5044
+ if (sourceXrRig && rig) {
5045
+ if (typeof sourceXrRig.locomotion === "string") {
5046
+ rig.locomotion = sourceXrRig.locomotion;
5047
+ }
5048
+ if (typeof sourceXrRig.moveSpeed === "number") {
5049
+ rig.moveSpeed = sourceXrRig.moveSpeed;
5050
+ }
5051
+ if (typeof sourceXrRig.snapTurn === "boolean") {
5052
+ rig.snapTurn = sourceXrRig.snapTurn;
5053
+ }
5054
+ if (typeof sourceXrRig.snapTurnDegrees === "number") {
5055
+ rig.snapTurnDegrees = sourceXrRig.snapTurnDegrees;
5056
+ }
5057
+ if (typeof sourceXrRig.fallbackEyeHeight === "number") {
5058
+ rig.fallbackEyeHeight = sourceXrRig.fallbackEyeHeight;
5059
+ }
5060
+ }
5061
+ }
5062
+ {
5063
+ const sourceArea = asRecord3(values.vrTeleportAreaValues.get(sourceEntityId));
5064
+ const area = world.getComponent(targetEntityId, VRTeleportAreaComponent);
5065
+ if (sourceArea && area) {
5066
+ if (typeof sourceArea.enabled === "boolean") {
5067
+ area.enabled = sourceArea.enabled;
5068
+ }
5069
+ if (typeof sourceArea.shape === "string") {
5070
+ area.shape = sourceArea.shape === "cylinder" ? "circle" : sourceArea.shape;
5071
+ }
5072
+ if (typeof sourceArea.width === "number") area.width = sourceArea.width;
5073
+ if (typeof sourceArea.depth === "number") area.depth = sourceArea.depth;
5074
+ }
5075
+ }
5076
+ {
5077
+ const sourceInteractable = asRecord3(
5078
+ values.xrInteractableValues.get(sourceEntityId)
5079
+ );
5080
+ const interactable = world.getComponent(
5081
+ targetEntityId,
5082
+ XRInteractableComponent
5083
+ );
5084
+ if (sourceInteractable && interactable) {
5085
+ if (typeof sourceInteractable.enabled === "boolean") {
5086
+ interactable.enabled = sourceInteractable.enabled;
5087
+ }
5088
+ if (typeof sourceInteractable.grabbable === "boolean") {
5089
+ interactable.grabbable = sourceInteractable.grabbable;
5090
+ }
5091
+ if (typeof sourceInteractable.pointable === "boolean") {
5092
+ interactable.pointable = sourceInteractable.pointable;
5093
+ }
5094
+ if (typeof sourceInteractable.grabMode === "string") {
5095
+ interactable.grabMode = sourceInteractable.grabMode;
5096
+ }
5097
+ if (typeof sourceInteractable.highlightOnHover === "boolean") {
5098
+ interactable.highlightOnHover = sourceInteractable.highlightOnHover;
5099
+ }
5100
+ }
5101
+ }
5031
5102
  {
5032
5103
  const imComponent = world.getComponent(targetEntityId, InstancedMeshComponent);
5033
5104
  if (imComponent && imComponent.instanceEntityIds.length > 0) {
@@ -7824,6 +7895,32 @@ var _XRInteractionSystem = class _XRInteractionSystem {
7824
7895
  };
7825
7896
  __name(_XRInteractionSystem, "XRInteractionSystem");
7826
7897
  var XRInteractionSystem = _XRInteractionSystem;
7898
+ var ARC_GRAVITY = 9.8;
7899
+ var ARC_SPEED = 7;
7900
+ var ARC_STEPS = 24;
7901
+ var ARC_MAX_TIME = 2;
7902
+ function sampleTeleportArc(origin, direction, out = [], options) {
7903
+ const speed = options?.speed ?? ARC_SPEED;
7904
+ const gravity = options?.gravity ?? ARC_GRAVITY;
7905
+ const steps = Math.max(2, options?.steps ?? ARC_STEPS);
7906
+ const maxTime = options?.maxTime ?? ARC_MAX_TIME;
7907
+ out.length = 0;
7908
+ const velocity = direction.clone().normalize().multiplyScalar(speed);
7909
+ for (let i = 0; i < steps; i += 1) {
7910
+ const t = i / (steps - 1) * maxTime;
7911
+ out.push(
7912
+ new THREE14__namespace.Vector3(
7913
+ origin.x + velocity.x * t,
7914
+ origin.y + velocity.y * t - 0.5 * gravity * t * t,
7915
+ origin.z + velocity.z * t
7916
+ )
7917
+ );
7918
+ }
7919
+ return out;
7920
+ }
7921
+ __name(sampleTeleportArc, "sampleTeleportArc");
7922
+
7923
+ // core/systems/XRLocomotionSystem.ts
7827
7924
  var UP = new THREE14__namespace.Vector3(0, 1, 0);
7828
7925
  var AXIS_DEADZONE = 0.5;
7829
7926
  var _XRLocomotionSystem = class _XRLocomotionSystem {
@@ -7831,13 +7928,26 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
7831
7928
  this.raycaster = new THREE14__namespace.Raycaster();
7832
7929
  /** Per-source latch so one stick push yields exactly one snap turn. */
7833
7930
  this.turnLatched = /* @__PURE__ */ new WeakSet();
7834
- /** Where the pointer currently lands, for the consumer to draw a marker. */
7835
- this.teleportPoint = null;
7931
+ /** Reused arc buffer — aiming runs every frame. */
7932
+ this.arcPoints = [];
7933
+ /** Curve up to the landing point, for the visual system. Empty when not aiming. */
7934
+ this.aimCurve = [];
7935
+ this.landingPoint = null;
7936
+ /** True once we've tried to self-heal camera parenting for this session. */
7937
+ this.parentingChecked = false;
7836
7938
  this.inputSystem = inputSystem;
7837
7939
  }
7838
7940
  update(world, deltaTime) {
7839
- this.teleportPoint = null;
7840
- if (!world.isXrPresenting()) return;
7941
+ this.aimCurve = [];
7942
+ this.landingPoint = null;
7943
+ if (!world.isXrPresenting()) {
7944
+ this.parentingChecked = false;
7945
+ return;
7946
+ }
7947
+ if (!this.parentingChecked) {
7948
+ this.parentingChecked = true;
7949
+ this.ensureCameraUnderRig(world);
7950
+ }
7841
7951
  const rigEntityId = world.query(XRRigComponent, TransformComponent)[0];
7842
7952
  if (typeof rigEntityId !== "number") return;
7843
7953
  const rig = world.getComponent(rigEntityId, XRRigComponent);
@@ -7854,9 +7964,37 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
7854
7964
  this.applySmoothMove(world, rig, rigTransform, inputs, deltaTime);
7855
7965
  }
7856
7966
  }
7967
+ /**
7968
+ * Guarantee the render camera is a CHILD of the rig.
7969
+ *
7970
+ * Locomotion moves the rig, and three composes the head pose against
7971
+ * `camera.parent` — so if the camera sits at the scene root instead, moving
7972
+ * the rig does nothing at all and the player is frozen in place. Scenes
7973
+ * authored before the rig existed (or with the camera re-parented by hand)
7974
+ * would otherwise silently fail to move, which is exactly the symptom that is
7975
+ * hardest to diagnose from inside a headset. Repairing it via `ParentId` lets
7976
+ * `ObjectManagementSystem` reconcile the scene graph normally.
7977
+ */
7978
+ ensureCameraUnderRig(world) {
7979
+ const rigEntityId = world.query(XRRigComponent)[0];
7980
+ if (typeof rigEntityId !== "number") return;
7981
+ const activeCamera = world.getCamera();
7982
+ for (const entityId of world.query(CameraComponent, Object3DRef)) {
7983
+ if (world.getComponent(entityId, Object3DRef)?.object !== activeCamera) {
7984
+ continue;
7985
+ }
7986
+ const parent = world.getComponent(entityId, ParentId);
7987
+ if (parent) {
7988
+ if (parent.value !== rigEntityId) parent.value = rigEntityId;
7989
+ } else {
7990
+ world.addComponent(entityId, new ParentId(rigEntityId));
7991
+ }
7992
+ return;
7993
+ }
7994
+ }
7857
7995
  /**
7858
7996
  * Snap turning, not smooth turning — rotating the view continuously is the
7859
- * single biggest cause of VR nausea, so the comfort-safe option is the one
7997
+ * single biggest cause of VR nausea, so the comfort-safe option is what's
7860
7998
  * wired to the stick.
7861
7999
  */
7862
8000
  applySnapTurn(rig, transform, inputs) {
@@ -7870,8 +8008,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
7870
8008
  }
7871
8009
  if (this.turnLatched.has(source)) continue;
7872
8010
  this.turnLatched.add(source);
7873
- const step = THREE14__namespace.MathUtils.degToRad(rig.snapTurnDegrees);
7874
- transform.rotation.y -= Math.sign(x) * step;
8011
+ transform.rotation.y -= Math.sign(x) * THREE14__namespace.MathUtils.degToRad(rig.snapTurnDegrees);
7875
8012
  }
7876
8013
  }
7877
8014
  applySmoothMove(world, rig, transform, inputs, deltaTime) {
@@ -7896,16 +8033,41 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
7896
8033
  const targets = this.collectTeleportTargets(world);
7897
8034
  if (targets.length === 0) return;
7898
8035
  for (const input of inputs) {
7899
- this.raycaster.set(input.rayOrigin, input.rayDirection);
7900
- const hit = this.raycaster.intersectObjects(targets, true)[0];
8036
+ if (!input.select && !input.selectEnd) continue;
8037
+ const points = sampleTeleportArc(
8038
+ input.rayOrigin,
8039
+ input.rayDirection,
8040
+ this.arcPoints
8041
+ );
8042
+ const hit = this.raycastArc(points, targets);
7901
8043
  if (!hit) continue;
7902
- this.teleportPoint = hit.point.clone();
8044
+ this.landingPoint = hit.point;
8045
+ this.aimCurve = points.slice(0, hit.segmentIndex + 1).concat(hit.point);
7903
8046
  if (input.selectEnd) {
7904
8047
  transform.position.x = hit.point.x;
7905
8048
  transform.position.y = hit.point.y;
7906
8049
  transform.position.z = hit.point.z;
8050
+ this.aimCurve = [];
8051
+ this.landingPoint = null;
8052
+ }
8053
+ }
8054
+ }
8055
+ /** Walk the arc segment-by-segment, returning the first surface hit. */
8056
+ raycastArc(points, targets) {
8057
+ for (let i = 1; i < points.length; i += 1) {
8058
+ const from = points[i - 1];
8059
+ const to = points[i];
8060
+ const delta = new THREE14__namespace.Vector3().subVectors(to, from);
8061
+ const distance = delta.length();
8062
+ if (distance < 1e-6) continue;
8063
+ this.raycaster.set(from, delta.divideScalar(distance));
8064
+ this.raycaster.far = distance;
8065
+ const hit = this.raycaster.intersectObjects(targets, true)[0];
8066
+ if (hit) {
8067
+ return { point: hit.point.clone(), segmentIndex: i - 1 };
7907
8068
  }
7908
8069
  }
8070
+ return null;
7909
8071
  }
7910
8072
  collectTeleportTargets(world) {
7911
8073
  const objects = [];
@@ -7918,12 +8080,13 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
7918
8080
  }
7919
8081
  return objects;
7920
8082
  }
7921
- /**
7922
- * Where the teleport pointer currently lands this frame, or null.
7923
- * Consumers use this to render an aim marker.
7924
- */
7925
- getTeleportPoint() {
7926
- return this.teleportPoint;
8083
+ /** Arc points up to the landing spot this frame; empty when not aiming. */
8084
+ getAimCurve() {
8085
+ return this.aimCurve;
8086
+ }
8087
+ /** Where the arc currently lands, or null when not aiming at a valid area. */
8088
+ getLandingPoint() {
8089
+ return this.landingPoint;
7927
8090
  }
7928
8091
  };
7929
8092
  __name(_XRLocomotionSystem, "XRLocomotionSystem");
@@ -8046,7 +8209,7 @@ var _XRSessionSystem = class _XRSessionSystem {
8046
8209
  __name(_XRSessionSystem, "XRSessionSystem");
8047
8210
  var XRSessionSystem = _XRSessionSystem;
8048
8211
  function buildGeometry2(area) {
8049
- if (area.shape === "cylinder") {
8212
+ if (area.shape === "circle") {
8050
8213
  const radius = Math.max(5e-3, area.width / 2);
8051
8214
  return new THREE14__namespace.CircleGeometry(radius, 48);
8052
8215
  }
@@ -8085,7 +8248,7 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
8085
8248
  __name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
8086
8249
  var VRTeleportAreaSystem = _VRTeleportAreaSystem;
8087
8250
  var _XRControllerVisualSystem = class _XRControllerVisualSystem {
8088
- constructor(slots = 2) {
8251
+ constructor(options) {
8089
8252
  this.controllerModelFactory = new XRControllerModelFactory_js.XRControllerModelFactory();
8090
8253
  this.handModelFactory = new XRHandModelFactory_js.XRHandModelFactory();
8091
8254
  this.group = new THREE14__namespace.Group();
@@ -8093,7 +8256,9 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
8093
8256
  this.attachedTo = null;
8094
8257
  /** Index → whether we've already attached visuals for that slot. */
8095
8258
  this.ready = /* @__PURE__ */ new Set();
8096
- this.slots = slots;
8259
+ this.rays = [];
8260
+ this.slots = options?.slots ?? 2;
8261
+ this.interactionSystem = options?.interactionSystem ?? null;
8097
8262
  this.group.name = "XRControllerVisuals";
8098
8263
  this.group.userData.ecsPreviewHidden = true;
8099
8264
  }
@@ -8101,6 +8266,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
8101
8266
  const renderer = world.getRenderer();
8102
8267
  if (!renderer.xr?.enabled) return;
8103
8268
  this.ensureAttached(world);
8269
+ this.updateRayVisibility();
8104
8270
  if (this.built) return;
8105
8271
  for (let index = 0; index < this.slots; index += 1) {
8106
8272
  if (this.ready.has(index)) continue;
@@ -8108,7 +8274,9 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
8108
8274
  const grip = renderer.xr.getControllerGrip(index);
8109
8275
  const hand = renderer.xr.getHand(index);
8110
8276
  if (!controller || !grip || !hand) continue;
8111
- controller.add(this.createRay());
8277
+ const ray = this.createRay();
8278
+ this.rays.push(ray);
8279
+ controller.add(ray);
8112
8280
  this.group.add(controller);
8113
8281
  grip.add(this.controllerModelFactory.createControllerModel(grip));
8114
8282
  this.group.add(grip);
@@ -8120,6 +8288,17 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
8120
8288
  this.built = true;
8121
8289
  }
8122
8290
  }
8291
+ /**
8292
+ * Show the aim ray only when it is meaningful: hovering something
8293
+ * interactive, or mid-grab. A permanently-drawn ray is visual noise, and it
8294
+ * implies everything is clickable when most of the scene is not. Teleport
8295
+ * aiming has its own arc, so the straight ray stays hidden for that.
8296
+ */
8297
+ updateRayVisibility() {
8298
+ if (!this.interactionSystem) return;
8299
+ const active = this.interactionSystem.getHoveredEntityId() !== null || this.interactionSystem.isGrabbing();
8300
+ for (const ray of this.rays) ray.visible = active;
8301
+ }
8123
8302
  /**
8124
8303
  * Parent the visuals to the XR rig when there is one, so locomotion moves the
8125
8304
  * hands with the player. Falls back to the scene root.
@@ -8145,6 +8324,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
8145
8324
  const line = new THREE14__namespace.Line(geometry, material);
8146
8325
  line.name = "XRPointerRay";
8147
8326
  line.renderOrder = 999;
8327
+ line.visible = this.interactionSystem === null;
8148
8328
  return line;
8149
8329
  }
8150
8330
  dispose() {
@@ -8160,6 +8340,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
8160
8340
  }
8161
8341
  });
8162
8342
  this.group.clear();
8343
+ this.rays.length = 0;
8163
8344
  this.ready.clear();
8164
8345
  this.built = false;
8165
8346
  this.attachedTo = null;
@@ -8167,6 +8348,121 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
8167
8348
  };
8168
8349
  __name(_XRControllerVisualSystem, "XRControllerVisualSystem");
8169
8350
  var XRControllerVisualSystem = _XRControllerVisualSystem;
8351
+ var MARKER_RADIUS = 0.28;
8352
+ var ACCENT = new THREE14__namespace.Color("#4da3ff");
8353
+ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
8354
+ constructor(locomotionSystem) {
8355
+ this.group = new THREE14__namespace.Group();
8356
+ this.arcGeometry = new THREE14__namespace.BufferGeometry();
8357
+ this.marker = new THREE14__namespace.Group();
8358
+ this.attached = false;
8359
+ this.locomotionSystem = locomotionSystem;
8360
+ this.group.name = "XRTeleportVisuals";
8361
+ this.group.userData.ecsPreviewHidden = true;
8362
+ const arcMaterial = new THREE14__namespace.LineBasicMaterial({
8363
+ vertexColors: true,
8364
+ transparent: true,
8365
+ depthTest: false
8366
+ });
8367
+ this.arc = new THREE14__namespace.Line(this.arcGeometry, arcMaterial);
8368
+ this.arc.frustumCulled = false;
8369
+ this.arc.renderOrder = 998;
8370
+ this.group.add(this.arc);
8371
+ this.marker.add(this.createRing(), this.createDot());
8372
+ this.marker.renderOrder = 999;
8373
+ this.group.add(this.marker);
8374
+ this.setVisible(false);
8375
+ }
8376
+ update(world) {
8377
+ if (!this.attached) {
8378
+ world.getScene().add(this.group);
8379
+ this.attached = true;
8380
+ }
8381
+ const curve = this.locomotionSystem.getAimCurve();
8382
+ const landing = this.locomotionSystem.getLandingPoint();
8383
+ if (!landing || curve.length < 2) {
8384
+ this.setVisible(false);
8385
+ return;
8386
+ }
8387
+ this.updateArcGeometry(curve);
8388
+ this.marker.position.copy(landing);
8389
+ this.marker.position.y += 0.01;
8390
+ this.setVisible(true);
8391
+ }
8392
+ updateArcGeometry(curve) {
8393
+ const count = curve.length;
8394
+ const positions = new Float32Array(count * 3);
8395
+ const colors = new Float32Array(count * 3);
8396
+ for (let i = 0; i < count; i += 1) {
8397
+ const point = curve[i];
8398
+ positions[i * 3] = point.x;
8399
+ positions[i * 3 + 1] = point.y;
8400
+ positions[i * 3 + 2] = point.z;
8401
+ const t = count > 1 ? i / (count - 1) : 0;
8402
+ const fade = 1 - t * 0.75;
8403
+ colors[i * 3] = ACCENT.r * fade;
8404
+ colors[i * 3 + 1] = ACCENT.g * fade;
8405
+ colors[i * 3 + 2] = ACCENT.b * fade;
8406
+ }
8407
+ this.arcGeometry.setAttribute(
8408
+ "position",
8409
+ new THREE14__namespace.BufferAttribute(positions, 3)
8410
+ );
8411
+ this.arcGeometry.setAttribute("color", new THREE14__namespace.BufferAttribute(colors, 3));
8412
+ this.arcGeometry.computeBoundingSphere();
8413
+ }
8414
+ createRing() {
8415
+ const geometry = new THREE14__namespace.RingGeometry(
8416
+ MARKER_RADIUS * 0.72,
8417
+ MARKER_RADIUS,
8418
+ 48
8419
+ );
8420
+ geometry.rotateX(-Math.PI / 2);
8421
+ return new THREE14__namespace.Mesh(
8422
+ geometry,
8423
+ new THREE14__namespace.MeshBasicMaterial({
8424
+ color: ACCENT,
8425
+ transparent: true,
8426
+ opacity: 0.9,
8427
+ side: THREE14__namespace.DoubleSide,
8428
+ depthTest: false
8429
+ })
8430
+ );
8431
+ }
8432
+ createDot() {
8433
+ const geometry = new THREE14__namespace.CircleGeometry(MARKER_RADIUS * 0.16, 24);
8434
+ geometry.rotateX(-Math.PI / 2);
8435
+ return new THREE14__namespace.Mesh(
8436
+ geometry,
8437
+ new THREE14__namespace.MeshBasicMaterial({
8438
+ color: ACCENT,
8439
+ transparent: true,
8440
+ opacity: 0.55,
8441
+ side: THREE14__namespace.DoubleSide,
8442
+ depthTest: false
8443
+ })
8444
+ );
8445
+ }
8446
+ setVisible(visible) {
8447
+ this.group.visible = visible;
8448
+ }
8449
+ dispose() {
8450
+ this.group.removeFromParent();
8451
+ this.group.traverse((child) => {
8452
+ const mesh = child;
8453
+ mesh.geometry?.dispose?.();
8454
+ const material = mesh.material;
8455
+ if (Array.isArray(material)) {
8456
+ for (const entry of material) entry.dispose?.();
8457
+ } else {
8458
+ material?.dispose?.();
8459
+ }
8460
+ });
8461
+ this.attached = false;
8462
+ }
8463
+ };
8464
+ __name(_XRTeleportVisualSystem, "XRTeleportVisualSystem");
8465
+ var XRTeleportVisualSystem = _XRTeleportVisualSystem;
8170
8466
 
8171
8467
  exports.AnimationSystem = AnimationSystem;
8172
8468
  exports.AudioSystem = AudioSystem;
@@ -8194,5 +8490,6 @@ exports.XRInputSystem = XRInputSystem;
8194
8490
  exports.XRInteractionSystem = XRInteractionSystem;
8195
8491
  exports.XRLocomotionSystem = XRLocomotionSystem;
8196
8492
  exports.XRSessionSystem = XRSessionSystem;
8493
+ exports.XRTeleportVisualSystem = XRTeleportVisualSystem;
8197
8494
  //# sourceMappingURL=index.cjs.map
8198
8495
  //# sourceMappingURL=index.cjs.map