@relu-interactives/spatial-ecs 0.3.6 → 0.3.7
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/{chunk-WRJ2K3LZ.js → chunk-O6FJA4XW.js} +84 -16
- package/dist/chunk-O6FJA4XW.js.map +1 -0
- package/dist/{index-C5FrDt3z.d.cts → index-B9nwRDf9.d.cts} +22 -0
- package/dist/{index-BpbmZuOz.d.ts → index-_q9TVDI5.d.ts} +22 -0
- package/dist/index.cjs +82 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/systems/index.cjs +82 -14
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +1 -1
- package/dist/systems/index.d.ts +1 -1
- package/dist/systems/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-WRJ2K3LZ.js.map +0 -1
|
@@ -434,10 +434,22 @@ declare class XRLocomotionSystem implements EcsSystem {
|
|
|
434
434
|
/** Curve up to the landing point, for the visual system. Empty when not aiming. */
|
|
435
435
|
private aimCurve;
|
|
436
436
|
private landingPoint;
|
|
437
|
+
/** True when the current aim lands somewhere the player may actually stand. */
|
|
438
|
+
private aimValid;
|
|
439
|
+
/** Sources currently aiming via thumbstick (hysteresis, so it doesn't chatter). */
|
|
440
|
+
private readonly stickAiming;
|
|
437
441
|
/** True once we've tried to self-heal camera parenting for this session. */
|
|
438
442
|
private parentingChecked;
|
|
439
443
|
constructor(inputSystem: XRInputSystem);
|
|
440
444
|
update(world: World, deltaTime: number): void;
|
|
445
|
+
/**
|
|
446
|
+
* Name what is missing, once per session.
|
|
447
|
+
*
|
|
448
|
+
* Inside a headset there is no console and no inspector, so a scene that
|
|
449
|
+
* simply cannot move gives the author nothing to go on. These messages are
|
|
450
|
+
* visible over remote debugging and say exactly which entity to add.
|
|
451
|
+
*/
|
|
452
|
+
private warnOnIncompleteSetup;
|
|
441
453
|
/**
|
|
442
454
|
* Guarantee the render camera is a CHILD of the rig.
|
|
443
455
|
*
|
|
@@ -458,11 +470,21 @@ declare class XRLocomotionSystem implements EcsSystem {
|
|
|
458
470
|
private applySnapTurn;
|
|
459
471
|
private applySmoothMove;
|
|
460
472
|
private applyTeleport;
|
|
473
|
+
/**
|
|
474
|
+
* Thumbstick-forward aiming with hysteresis.
|
|
475
|
+
*
|
|
476
|
+
* Engaging at 0.6 and releasing at 0.3 stops a stick resting near the
|
|
477
|
+
* threshold from flickering the arc on and off — and the release edge is what
|
|
478
|
+
* commits the teleport, so chatter there would teleport the player randomly.
|
|
479
|
+
*/
|
|
480
|
+
private readStickAim;
|
|
461
481
|
/** Walk the arc segment-by-segment, returning the first surface hit. */
|
|
462
482
|
private raycastArc;
|
|
463
483
|
private collectTeleportTargets;
|
|
464
484
|
/** Arc points up to the landing spot this frame; empty when not aiming. */
|
|
465
485
|
getAimCurve(): THREE.Vector3[];
|
|
486
|
+
/** True when the aim lands on a valid teleport area. */
|
|
487
|
+
isAimValid(): boolean;
|
|
466
488
|
/** Where the arc currently lands, or null when not aiming at a valid area. */
|
|
467
489
|
getLandingPoint(): THREE.Vector3 | null;
|
|
468
490
|
}
|
|
@@ -434,10 +434,22 @@ declare class XRLocomotionSystem implements EcsSystem {
|
|
|
434
434
|
/** Curve up to the landing point, for the visual system. Empty when not aiming. */
|
|
435
435
|
private aimCurve;
|
|
436
436
|
private landingPoint;
|
|
437
|
+
/** True when the current aim lands somewhere the player may actually stand. */
|
|
438
|
+
private aimValid;
|
|
439
|
+
/** Sources currently aiming via thumbstick (hysteresis, so it doesn't chatter). */
|
|
440
|
+
private readonly stickAiming;
|
|
437
441
|
/** True once we've tried to self-heal camera parenting for this session. */
|
|
438
442
|
private parentingChecked;
|
|
439
443
|
constructor(inputSystem: XRInputSystem);
|
|
440
444
|
update(world: World, deltaTime: number): void;
|
|
445
|
+
/**
|
|
446
|
+
* Name what is missing, once per session.
|
|
447
|
+
*
|
|
448
|
+
* Inside a headset there is no console and no inspector, so a scene that
|
|
449
|
+
* simply cannot move gives the author nothing to go on. These messages are
|
|
450
|
+
* visible over remote debugging and say exactly which entity to add.
|
|
451
|
+
*/
|
|
452
|
+
private warnOnIncompleteSetup;
|
|
441
453
|
/**
|
|
442
454
|
* Guarantee the render camera is a CHILD of the rig.
|
|
443
455
|
*
|
|
@@ -458,11 +470,21 @@ declare class XRLocomotionSystem implements EcsSystem {
|
|
|
458
470
|
private applySnapTurn;
|
|
459
471
|
private applySmoothMove;
|
|
460
472
|
private applyTeleport;
|
|
473
|
+
/**
|
|
474
|
+
* Thumbstick-forward aiming with hysteresis.
|
|
475
|
+
*
|
|
476
|
+
* Engaging at 0.6 and releasing at 0.3 stops a stick resting near the
|
|
477
|
+
* threshold from flickering the arc on and off — and the release edge is what
|
|
478
|
+
* commits the teleport, so chatter there would teleport the player randomly.
|
|
479
|
+
*/
|
|
480
|
+
private readStickAim;
|
|
461
481
|
/** Walk the arc segment-by-segment, returning the first surface hit. */
|
|
462
482
|
private raycastArc;
|
|
463
483
|
private collectTeleportTargets;
|
|
464
484
|
/** Arc points up to the landing spot this frame; empty when not aiming. */
|
|
465
485
|
getAimCurve(): THREE.Vector3[];
|
|
486
|
+
/** True when the aim lands on a valid teleport area. */
|
|
487
|
+
isAimValid(): boolean;
|
|
466
488
|
/** Where the arc currently lands, or null when not aiming at a valid area. */
|
|
467
489
|
getLandingPoint(): THREE.Vector3 | null;
|
|
468
490
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -10697,6 +10697,10 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
10697
10697
|
/** Curve up to the landing point, for the visual system. Empty when not aiming. */
|
|
10698
10698
|
this.aimCurve = [];
|
|
10699
10699
|
this.landingPoint = null;
|
|
10700
|
+
/** True when the current aim lands somewhere the player may actually stand. */
|
|
10701
|
+
this.aimValid = false;
|
|
10702
|
+
/** Sources currently aiming via thumbstick (hysteresis, so it doesn't chatter). */
|
|
10703
|
+
this.stickAiming = /* @__PURE__ */ new WeakSet();
|
|
10700
10704
|
/** True once we've tried to self-heal camera parenting for this session. */
|
|
10701
10705
|
this.parentingChecked = false;
|
|
10702
10706
|
this.inputSystem = inputSystem;
|
|
@@ -10704,6 +10708,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
10704
10708
|
update(world, deltaTime) {
|
|
10705
10709
|
this.aimCurve = [];
|
|
10706
10710
|
this.landingPoint = null;
|
|
10711
|
+
this.aimValid = false;
|
|
10707
10712
|
if (!world.isXrPresenting()) {
|
|
10708
10713
|
this.parentingChecked = false;
|
|
10709
10714
|
return;
|
|
@@ -10711,6 +10716,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
10711
10716
|
if (!this.parentingChecked) {
|
|
10712
10717
|
this.parentingChecked = true;
|
|
10713
10718
|
this.ensureCameraUnderRig(world);
|
|
10719
|
+
this.warnOnIncompleteSetup(world);
|
|
10714
10720
|
}
|
|
10715
10721
|
const rigEntityId = world.query(XRRigComponent, TransformComponent)[0];
|
|
10716
10722
|
if (typeof rigEntityId !== "number") return;
|
|
@@ -10728,6 +10734,26 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
10728
10734
|
this.applySmoothMove(world, rig, rigTransform, inputs, deltaTime);
|
|
10729
10735
|
}
|
|
10730
10736
|
}
|
|
10737
|
+
/**
|
|
10738
|
+
* Name what is missing, once per session.
|
|
10739
|
+
*
|
|
10740
|
+
* Inside a headset there is no console and no inspector, so a scene that
|
|
10741
|
+
* simply cannot move gives the author nothing to go on. These messages are
|
|
10742
|
+
* visible over remote debugging and say exactly which entity to add.
|
|
10743
|
+
*/
|
|
10744
|
+
warnOnIncompleteSetup(world) {
|
|
10745
|
+
if (typeof world.query(XRRigComponent)[0] !== "number") {
|
|
10746
|
+
console.warn(
|
|
10747
|
+
"[XRLocomotion] No XR Rig in this scene \u2014 the player cannot move. Add one via Add Object \u2192 VR \u2192 XR Rig (the scene camera is parented to it automatically)."
|
|
10748
|
+
);
|
|
10749
|
+
return;
|
|
10750
|
+
}
|
|
10751
|
+
if (world.query(VRTeleportAreaComponent).length === 0) {
|
|
10752
|
+
console.warn(
|
|
10753
|
+
"[XRLocomotion] No Teleport Area in this scene \u2014 teleport has nowhere to land. Add one via Add Object \u2192 VR \u2192 Teleport Area, or add a Teleport Area component to an existing floor."
|
|
10754
|
+
);
|
|
10755
|
+
}
|
|
10756
|
+
}
|
|
10731
10757
|
/**
|
|
10732
10758
|
* Guarantee the render camera is a CHILD of the rig.
|
|
10733
10759
|
*
|
|
@@ -10795,29 +10821,60 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
10795
10821
|
}
|
|
10796
10822
|
applyTeleport(world, transform, inputs) {
|
|
10797
10823
|
const targets = this.collectTeleportTargets(world);
|
|
10798
|
-
if (targets.length === 0) return;
|
|
10799
10824
|
for (const input of inputs) {
|
|
10800
|
-
|
|
10825
|
+
const source = input;
|
|
10826
|
+
const stick = this.readStickAim(input, source);
|
|
10827
|
+
const aiming = input.select || stick.aiming;
|
|
10828
|
+
const commit = input.selectEnd || stick.released;
|
|
10829
|
+
if (!aiming && !commit) continue;
|
|
10801
10830
|
const points = sampleTeleportArc(
|
|
10802
10831
|
input.rayOrigin,
|
|
10803
10832
|
input.rayDirection,
|
|
10804
10833
|
this.arcPoints
|
|
10805
10834
|
);
|
|
10806
10835
|
const hit = this.raycastArc(points, targets);
|
|
10807
|
-
|
|
10808
|
-
this.landingPoint = hit.point;
|
|
10809
|
-
this.
|
|
10810
|
-
if (
|
|
10836
|
+
this.aimCurve = hit ? points.slice(0, hit.segmentIndex + 1).concat(hit.point) : points.slice();
|
|
10837
|
+
this.landingPoint = hit ? hit.point : null;
|
|
10838
|
+
this.aimValid = hit !== null;
|
|
10839
|
+
if (commit && hit) {
|
|
10811
10840
|
transform.position.x = hit.point.x;
|
|
10812
10841
|
transform.position.y = hit.point.y;
|
|
10813
10842
|
transform.position.z = hit.point.z;
|
|
10814
10843
|
this.aimCurve = [];
|
|
10815
10844
|
this.landingPoint = null;
|
|
10845
|
+
this.aimValid = false;
|
|
10846
|
+
} else if (commit) {
|
|
10847
|
+
this.aimCurve = [];
|
|
10848
|
+
this.aimValid = false;
|
|
10816
10849
|
}
|
|
10817
10850
|
}
|
|
10818
10851
|
}
|
|
10852
|
+
/**
|
|
10853
|
+
* Thumbstick-forward aiming with hysteresis.
|
|
10854
|
+
*
|
|
10855
|
+
* Engaging at 0.6 and releasing at 0.3 stops a stick resting near the
|
|
10856
|
+
* threshold from flickering the arc on and off — and the release edge is what
|
|
10857
|
+
* commits the teleport, so chatter there would teleport the player randomly.
|
|
10858
|
+
*/
|
|
10859
|
+
readStickAim(input, source) {
|
|
10860
|
+
if (!input.hasAxes || input.axes.length < 4) {
|
|
10861
|
+
return { aiming: false, released: false };
|
|
10862
|
+
}
|
|
10863
|
+
const forward = -(input.axes[3] ?? 0);
|
|
10864
|
+
const wasAiming = this.stickAiming.has(source);
|
|
10865
|
+
if (!wasAiming && forward > 0.6) {
|
|
10866
|
+
this.stickAiming.add(source);
|
|
10867
|
+
return { aiming: true, released: false };
|
|
10868
|
+
}
|
|
10869
|
+
if (wasAiming && forward < 0.3) {
|
|
10870
|
+
this.stickAiming.delete(source);
|
|
10871
|
+
return { aiming: false, released: true };
|
|
10872
|
+
}
|
|
10873
|
+
return { aiming: wasAiming, released: false };
|
|
10874
|
+
}
|
|
10819
10875
|
/** Walk the arc segment-by-segment, returning the first surface hit. */
|
|
10820
10876
|
raycastArc(points, targets) {
|
|
10877
|
+
if (targets.length === 0) return null;
|
|
10821
10878
|
for (let i = 1; i < points.length; i += 1) {
|
|
10822
10879
|
const from = points[i - 1];
|
|
10823
10880
|
const to = points[i];
|
|
@@ -10848,6 +10905,10 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
10848
10905
|
getAimCurve() {
|
|
10849
10906
|
return this.aimCurve;
|
|
10850
10907
|
}
|
|
10908
|
+
/** True when the aim lands on a valid teleport area. */
|
|
10909
|
+
isAimValid() {
|
|
10910
|
+
return this.aimValid;
|
|
10911
|
+
}
|
|
10851
10912
|
/** Where the arc currently lands, or null when not aiming at a valid area. */
|
|
10852
10913
|
getLandingPoint() {
|
|
10853
10914
|
return this.landingPoint;
|
|
@@ -11294,6 +11355,7 @@ __name(_XRControllerVisualSystem, "XRControllerVisualSystem");
|
|
|
11294
11355
|
var XRControllerVisualSystem = _XRControllerVisualSystem;
|
|
11295
11356
|
var MARKER_RADIUS = 0.28;
|
|
11296
11357
|
var ACCENT = new THREE39__namespace.Color("#4da3ff");
|
|
11358
|
+
var BLOCKED = new THREE39__namespace.Color("#ff5a5a");
|
|
11297
11359
|
var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
11298
11360
|
constructor(locomotionSystem) {
|
|
11299
11361
|
this.group = new THREE39__namespace.Group();
|
|
@@ -11324,16 +11386,22 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
11324
11386
|
}
|
|
11325
11387
|
const curve = this.locomotionSystem.getAimCurve();
|
|
11326
11388
|
const landing = this.locomotionSystem.getLandingPoint();
|
|
11327
|
-
|
|
11389
|
+
const valid = this.locomotionSystem.isAimValid();
|
|
11390
|
+
if (curve.length < 2) {
|
|
11328
11391
|
this.setVisible(false);
|
|
11329
11392
|
return;
|
|
11330
11393
|
}
|
|
11331
|
-
this.updateArcGeometry(curve);
|
|
11332
|
-
|
|
11333
|
-
|
|
11394
|
+
this.updateArcGeometry(curve, valid ? ACCENT : BLOCKED);
|
|
11395
|
+
if (valid && landing) {
|
|
11396
|
+
this.marker.position.copy(landing);
|
|
11397
|
+
this.marker.position.y += 0.01;
|
|
11398
|
+
this.marker.visible = true;
|
|
11399
|
+
} else {
|
|
11400
|
+
this.marker.visible = false;
|
|
11401
|
+
}
|
|
11334
11402
|
this.setVisible(true);
|
|
11335
11403
|
}
|
|
11336
|
-
updateArcGeometry(curve) {
|
|
11404
|
+
updateArcGeometry(curve, tint) {
|
|
11337
11405
|
const count = curve.length;
|
|
11338
11406
|
const positions = new Float32Array(count * 3);
|
|
11339
11407
|
const colors = new Float32Array(count * 3);
|
|
@@ -11344,9 +11412,9 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
11344
11412
|
positions[i * 3 + 2] = point.z;
|
|
11345
11413
|
const t = count > 1 ? i / (count - 1) : 0;
|
|
11346
11414
|
const fade = 1 - t * 0.75;
|
|
11347
|
-
colors[i * 3] =
|
|
11348
|
-
colors[i * 3 + 1] =
|
|
11349
|
-
colors[i * 3 + 2] =
|
|
11415
|
+
colors[i * 3] = tint.r * fade;
|
|
11416
|
+
colors[i * 3 + 1] = tint.g * fade;
|
|
11417
|
+
colors[i * 3 + 2] = tint.b * fade;
|
|
11350
11418
|
}
|
|
11351
11419
|
this.arcGeometry.setAttribute(
|
|
11352
11420
|
"position",
|