@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.
- package/dist/{XRRig-Cu-EyliG.d.cts → XRRig-2686IqLQ.d.cts} +5 -5
- package/dist/{XRRig-CAmf04NX.d.ts → XRRig-D2QURXl1.d.ts} +5 -5
- package/dist/{chunk-67WGASUJ.js → chunk-2LVFGVWI.js} +3 -3
- package/dist/{chunk-67WGASUJ.js.map → chunk-2LVFGVWI.js.map} +1 -1
- package/dist/{chunk-JWTRFJBL.js → chunk-4BZYK3JP.js} +4 -4
- package/dist/{chunk-JWTRFJBL.js.map → chunk-4BZYK3JP.js.map} +1 -1
- package/dist/{chunk-U3MDYKPV.js → chunk-6QC2PJLD.js} +4 -3
- package/dist/chunk-6QC2PJLD.js.map +1 -0
- package/dist/{chunk-SALBG747.js → chunk-G53MZVKQ.js} +333 -25
- package/dist/chunk-G53MZVKQ.js.map +1 -0
- package/dist/components/index.cjs +2 -1
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +1 -1
- package/dist/factories/index.cjs +2 -1
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +1 -1
- package/dist/factories/index.d.ts +1 -1
- package/dist/factories/index.js +3 -3
- package/dist/{index-CRmfSYdj.d.ts → index-B-CViRMx.d.ts} +57 -10
- package/dist/{index-w1oqWl_M.d.ts → index-BtKOaHfY.d.ts} +1 -1
- package/dist/{index-Bc0YCz1A.d.cts → index-BvCmmuJ0.d.cts} +57 -10
- package/dist/{index-CUFd71ri.d.cts → index-Xu238jLn.d.cts} +1 -1
- package/dist/index.cjs +337 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -6
- package/dist/index.d.ts +50 -6
- package/dist/index.js +8 -8
- package/dist/systems/index.cjs +318 -21
- 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 +3 -3
- package/package.json +1 -1
- package/dist/chunk-SALBG747.js.map +0 -1
- package/dist/chunk-U3MDYKPV.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { resolveDracoDecoderPath, applyTransform, SHARED_MODEL_RESOURCE_FLAG } from './chunk-
|
|
2
|
-
import { AnimationComponent, ModelComponent, CameraComponent, Object3DRef, Environment, Postprocessing, TransformComponent, PhysicsComponent, setPhysicsLiveRef, LightComponent, MaterialComponent, DEFAULT_MESH_GEOMETRY_PARAMETERS, MeshGeometryComponent, InstancedMeshComponent, ParentId, ScriptComponent, ScriptObjectComponent, InstanceSlotComponent, Name, ImageComponent, SpriteComponent, VideoComponent, AudioComponent, ImageTarget, Selectable, PrefabNode, PrefabInstance
|
|
1
|
+
import { resolveDracoDecoderPath, applyTransform, SHARED_MODEL_RESOURCE_FLAG } from './chunk-2LVFGVWI.js';
|
|
2
|
+
import { AnimationComponent, ModelComponent, CameraComponent, Object3DRef, Environment, Postprocessing, TransformComponent, PhysicsComponent, setPhysicsLiveRef, LightComponent, MaterialComponent, DEFAULT_MESH_GEOMETRY_PARAMETERS, MeshGeometryComponent, InstancedMeshComponent, ParentId, ScriptComponent, ScriptObjectComponent, XRRigComponent, VRTeleportAreaComponent, XRInteractableComponent, InstanceSlotComponent, Name, ImageComponent, SpriteComponent, VideoComponent, AudioComponent, ImageTarget, Selectable, PrefabNode, PrefabInstance } from './chunk-6QC2PJLD.js';
|
|
3
3
|
import { __name } from './chunk-OY7ZODZP.js';
|
|
4
4
|
import * as THREE7 from 'three';
|
|
5
5
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
@@ -2782,6 +2782,15 @@ function buildComponentValueMaps(snapshot) {
|
|
|
2782
2782
|
snapshot.components,
|
|
2783
2783
|
"ScriptObjectComponent"
|
|
2784
2784
|
),
|
|
2785
|
+
xrRigValues: readByComponent(snapshot.components, "XRRigComponent"),
|
|
2786
|
+
vrTeleportAreaValues: readByComponent(
|
|
2787
|
+
snapshot.components,
|
|
2788
|
+
"VRTeleportAreaComponent"
|
|
2789
|
+
),
|
|
2790
|
+
xrInteractableValues: readByComponent(
|
|
2791
|
+
snapshot.components,
|
|
2792
|
+
"XRInteractableComponent"
|
|
2793
|
+
),
|
|
2785
2794
|
instancedMeshValues: readByComponent(snapshot.components, "InstancedMeshComponent"),
|
|
2786
2795
|
instanceSlotValues: readByComponent(snapshot.components, "InstanceSlotComponent"),
|
|
2787
2796
|
prefabNodeValues: readByComponent(snapshot.components, "PrefabNode"),
|
|
@@ -2907,6 +2916,67 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
2907
2916
|
soc.data = remapEntityRefsInScriptData(data, idMap);
|
|
2908
2917
|
}
|
|
2909
2918
|
}
|
|
2919
|
+
{
|
|
2920
|
+
const sourceXrRig = asRecord(values.xrRigValues.get(sourceEntityId));
|
|
2921
|
+
const rig = world.getComponent(targetEntityId, XRRigComponent);
|
|
2922
|
+
if (sourceXrRig && rig) {
|
|
2923
|
+
if (typeof sourceXrRig.locomotion === "string") {
|
|
2924
|
+
rig.locomotion = sourceXrRig.locomotion;
|
|
2925
|
+
}
|
|
2926
|
+
if (typeof sourceXrRig.moveSpeed === "number") {
|
|
2927
|
+
rig.moveSpeed = sourceXrRig.moveSpeed;
|
|
2928
|
+
}
|
|
2929
|
+
if (typeof sourceXrRig.snapTurn === "boolean") {
|
|
2930
|
+
rig.snapTurn = sourceXrRig.snapTurn;
|
|
2931
|
+
}
|
|
2932
|
+
if (typeof sourceXrRig.snapTurnDegrees === "number") {
|
|
2933
|
+
rig.snapTurnDegrees = sourceXrRig.snapTurnDegrees;
|
|
2934
|
+
}
|
|
2935
|
+
if (typeof sourceXrRig.fallbackEyeHeight === "number") {
|
|
2936
|
+
rig.fallbackEyeHeight = sourceXrRig.fallbackEyeHeight;
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
{
|
|
2941
|
+
const sourceArea = asRecord(values.vrTeleportAreaValues.get(sourceEntityId));
|
|
2942
|
+
const area = world.getComponent(targetEntityId, VRTeleportAreaComponent);
|
|
2943
|
+
if (sourceArea && area) {
|
|
2944
|
+
if (typeof sourceArea.enabled === "boolean") {
|
|
2945
|
+
area.enabled = sourceArea.enabled;
|
|
2946
|
+
}
|
|
2947
|
+
if (typeof sourceArea.shape === "string") {
|
|
2948
|
+
area.shape = sourceArea.shape === "cylinder" ? "circle" : sourceArea.shape;
|
|
2949
|
+
}
|
|
2950
|
+
if (typeof sourceArea.width === "number") area.width = sourceArea.width;
|
|
2951
|
+
if (typeof sourceArea.depth === "number") area.depth = sourceArea.depth;
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
{
|
|
2955
|
+
const sourceInteractable = asRecord(
|
|
2956
|
+
values.xrInteractableValues.get(sourceEntityId)
|
|
2957
|
+
);
|
|
2958
|
+
const interactable = world.getComponent(
|
|
2959
|
+
targetEntityId,
|
|
2960
|
+
XRInteractableComponent
|
|
2961
|
+
);
|
|
2962
|
+
if (sourceInteractable && interactable) {
|
|
2963
|
+
if (typeof sourceInteractable.enabled === "boolean") {
|
|
2964
|
+
interactable.enabled = sourceInteractable.enabled;
|
|
2965
|
+
}
|
|
2966
|
+
if (typeof sourceInteractable.grabbable === "boolean") {
|
|
2967
|
+
interactable.grabbable = sourceInteractable.grabbable;
|
|
2968
|
+
}
|
|
2969
|
+
if (typeof sourceInteractable.pointable === "boolean") {
|
|
2970
|
+
interactable.pointable = sourceInteractable.pointable;
|
|
2971
|
+
}
|
|
2972
|
+
if (typeof sourceInteractable.grabMode === "string") {
|
|
2973
|
+
interactable.grabMode = sourceInteractable.grabMode;
|
|
2974
|
+
}
|
|
2975
|
+
if (typeof sourceInteractable.highlightOnHover === "boolean") {
|
|
2976
|
+
interactable.highlightOnHover = sourceInteractable.highlightOnHover;
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2910
2980
|
{
|
|
2911
2981
|
const imComponent = world.getComponent(targetEntityId, InstancedMeshComponent);
|
|
2912
2982
|
if (imComponent && imComponent.instanceEntityIds.length > 0) {
|
|
@@ -6246,6 +6316,45 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6246
6316
|
};
|
|
6247
6317
|
__name(_XRInteractionSystem, "XRInteractionSystem");
|
|
6248
6318
|
var XRInteractionSystem = _XRInteractionSystem;
|
|
6319
|
+
var ARC_GRAVITY = 9.8;
|
|
6320
|
+
var ARC_SPEED = 7;
|
|
6321
|
+
var ARC_STEPS = 24;
|
|
6322
|
+
var ARC_MAX_TIME = 2;
|
|
6323
|
+
function sampleTeleportArc(origin, direction, out = [], options) {
|
|
6324
|
+
const speed = options?.speed ?? ARC_SPEED;
|
|
6325
|
+
const gravity = options?.gravity ?? ARC_GRAVITY;
|
|
6326
|
+
const steps = Math.max(2, options?.steps ?? ARC_STEPS);
|
|
6327
|
+
const maxTime = options?.maxTime ?? ARC_MAX_TIME;
|
|
6328
|
+
out.length = 0;
|
|
6329
|
+
const velocity = direction.clone().normalize().multiplyScalar(speed);
|
|
6330
|
+
for (let i = 0; i < steps; i += 1) {
|
|
6331
|
+
const t = i / (steps - 1) * maxTime;
|
|
6332
|
+
out.push(
|
|
6333
|
+
new THREE7.Vector3(
|
|
6334
|
+
origin.x + velocity.x * t,
|
|
6335
|
+
origin.y + velocity.y * t - 0.5 * gravity * t * t,
|
|
6336
|
+
origin.z + velocity.z * t
|
|
6337
|
+
)
|
|
6338
|
+
);
|
|
6339
|
+
}
|
|
6340
|
+
return out;
|
|
6341
|
+
}
|
|
6342
|
+
__name(sampleTeleportArc, "sampleTeleportArc");
|
|
6343
|
+
function arcGroundCrossing(points, groundY) {
|
|
6344
|
+
for (let i = 1; i < points.length; i += 1) {
|
|
6345
|
+
const previous = points[i - 1];
|
|
6346
|
+
const current = points[i];
|
|
6347
|
+
if (previous.y >= groundY && current.y <= groundY) {
|
|
6348
|
+
const span = previous.y - current.y;
|
|
6349
|
+
const alpha = span > 1e-6 ? (previous.y - groundY) / span : 0;
|
|
6350
|
+
return new THREE7.Vector3().lerpVectors(previous, current, alpha);
|
|
6351
|
+
}
|
|
6352
|
+
}
|
|
6353
|
+
return null;
|
|
6354
|
+
}
|
|
6355
|
+
__name(arcGroundCrossing, "arcGroundCrossing");
|
|
6356
|
+
|
|
6357
|
+
// core/systems/XRLocomotionSystem.ts
|
|
6249
6358
|
var UP = new THREE7.Vector3(0, 1, 0);
|
|
6250
6359
|
var AXIS_DEADZONE = 0.5;
|
|
6251
6360
|
var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
@@ -6253,13 +6362,26 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
6253
6362
|
this.raycaster = new THREE7.Raycaster();
|
|
6254
6363
|
/** Per-source latch so one stick push yields exactly one snap turn. */
|
|
6255
6364
|
this.turnLatched = /* @__PURE__ */ new WeakSet();
|
|
6256
|
-
/**
|
|
6257
|
-
this.
|
|
6365
|
+
/** Reused arc buffer — aiming runs every frame. */
|
|
6366
|
+
this.arcPoints = [];
|
|
6367
|
+
/** Curve up to the landing point, for the visual system. Empty when not aiming. */
|
|
6368
|
+
this.aimCurve = [];
|
|
6369
|
+
this.landingPoint = null;
|
|
6370
|
+
/** True once we've tried to self-heal camera parenting for this session. */
|
|
6371
|
+
this.parentingChecked = false;
|
|
6258
6372
|
this.inputSystem = inputSystem;
|
|
6259
6373
|
}
|
|
6260
6374
|
update(world, deltaTime) {
|
|
6261
|
-
this.
|
|
6262
|
-
|
|
6375
|
+
this.aimCurve = [];
|
|
6376
|
+
this.landingPoint = null;
|
|
6377
|
+
if (!world.isXrPresenting()) {
|
|
6378
|
+
this.parentingChecked = false;
|
|
6379
|
+
return;
|
|
6380
|
+
}
|
|
6381
|
+
if (!this.parentingChecked) {
|
|
6382
|
+
this.parentingChecked = true;
|
|
6383
|
+
this.ensureCameraUnderRig(world);
|
|
6384
|
+
}
|
|
6263
6385
|
const rigEntityId = world.query(XRRigComponent, TransformComponent)[0];
|
|
6264
6386
|
if (typeof rigEntityId !== "number") return;
|
|
6265
6387
|
const rig = world.getComponent(rigEntityId, XRRigComponent);
|
|
@@ -6276,9 +6398,37 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
6276
6398
|
this.applySmoothMove(world, rig, rigTransform, inputs, deltaTime);
|
|
6277
6399
|
}
|
|
6278
6400
|
}
|
|
6401
|
+
/**
|
|
6402
|
+
* Guarantee the render camera is a CHILD of the rig.
|
|
6403
|
+
*
|
|
6404
|
+
* Locomotion moves the rig, and three composes the head pose against
|
|
6405
|
+
* `camera.parent` — so if the camera sits at the scene root instead, moving
|
|
6406
|
+
* the rig does nothing at all and the player is frozen in place. Scenes
|
|
6407
|
+
* authored before the rig existed (or with the camera re-parented by hand)
|
|
6408
|
+
* would otherwise silently fail to move, which is exactly the symptom that is
|
|
6409
|
+
* hardest to diagnose from inside a headset. Repairing it via `ParentId` lets
|
|
6410
|
+
* `ObjectManagementSystem` reconcile the scene graph normally.
|
|
6411
|
+
*/
|
|
6412
|
+
ensureCameraUnderRig(world) {
|
|
6413
|
+
const rigEntityId = world.query(XRRigComponent)[0];
|
|
6414
|
+
if (typeof rigEntityId !== "number") return;
|
|
6415
|
+
const activeCamera = world.getCamera();
|
|
6416
|
+
for (const entityId of world.query(CameraComponent, Object3DRef)) {
|
|
6417
|
+
if (world.getComponent(entityId, Object3DRef)?.object !== activeCamera) {
|
|
6418
|
+
continue;
|
|
6419
|
+
}
|
|
6420
|
+
const parent = world.getComponent(entityId, ParentId);
|
|
6421
|
+
if (parent) {
|
|
6422
|
+
if (parent.value !== rigEntityId) parent.value = rigEntityId;
|
|
6423
|
+
} else {
|
|
6424
|
+
world.addComponent(entityId, new ParentId(rigEntityId));
|
|
6425
|
+
}
|
|
6426
|
+
return;
|
|
6427
|
+
}
|
|
6428
|
+
}
|
|
6279
6429
|
/**
|
|
6280
6430
|
* Snap turning, not smooth turning — rotating the view continuously is the
|
|
6281
|
-
* single biggest cause of VR nausea, so the comfort-safe option is
|
|
6431
|
+
* single biggest cause of VR nausea, so the comfort-safe option is what's
|
|
6282
6432
|
* wired to the stick.
|
|
6283
6433
|
*/
|
|
6284
6434
|
applySnapTurn(rig, transform, inputs) {
|
|
@@ -6292,8 +6442,7 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
6292
6442
|
}
|
|
6293
6443
|
if (this.turnLatched.has(source)) continue;
|
|
6294
6444
|
this.turnLatched.add(source);
|
|
6295
|
-
|
|
6296
|
-
transform.rotation.y -= Math.sign(x) * step;
|
|
6445
|
+
transform.rotation.y -= Math.sign(x) * THREE7.MathUtils.degToRad(rig.snapTurnDegrees);
|
|
6297
6446
|
}
|
|
6298
6447
|
}
|
|
6299
6448
|
applySmoothMove(world, rig, transform, inputs, deltaTime) {
|
|
@@ -6318,17 +6467,42 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
6318
6467
|
const targets = this.collectTeleportTargets(world);
|
|
6319
6468
|
if (targets.length === 0) return;
|
|
6320
6469
|
for (const input of inputs) {
|
|
6321
|
-
|
|
6322
|
-
const
|
|
6470
|
+
if (!input.select && !input.selectEnd) continue;
|
|
6471
|
+
const points = sampleTeleportArc(
|
|
6472
|
+
input.rayOrigin,
|
|
6473
|
+
input.rayDirection,
|
|
6474
|
+
this.arcPoints
|
|
6475
|
+
);
|
|
6476
|
+
const hit = this.raycastArc(points, targets);
|
|
6323
6477
|
if (!hit) continue;
|
|
6324
|
-
this.
|
|
6478
|
+
this.landingPoint = hit.point;
|
|
6479
|
+
this.aimCurve = points.slice(0, hit.segmentIndex + 1).concat(hit.point);
|
|
6325
6480
|
if (input.selectEnd) {
|
|
6326
6481
|
transform.position.x = hit.point.x;
|
|
6327
6482
|
transform.position.y = hit.point.y;
|
|
6328
6483
|
transform.position.z = hit.point.z;
|
|
6484
|
+
this.aimCurve = [];
|
|
6485
|
+
this.landingPoint = null;
|
|
6329
6486
|
}
|
|
6330
6487
|
}
|
|
6331
6488
|
}
|
|
6489
|
+
/** Walk the arc segment-by-segment, returning the first surface hit. */
|
|
6490
|
+
raycastArc(points, targets) {
|
|
6491
|
+
for (let i = 1; i < points.length; i += 1) {
|
|
6492
|
+
const from = points[i - 1];
|
|
6493
|
+
const to = points[i];
|
|
6494
|
+
const delta = new THREE7.Vector3().subVectors(to, from);
|
|
6495
|
+
const distance = delta.length();
|
|
6496
|
+
if (distance < 1e-6) continue;
|
|
6497
|
+
this.raycaster.set(from, delta.divideScalar(distance));
|
|
6498
|
+
this.raycaster.far = distance;
|
|
6499
|
+
const hit = this.raycaster.intersectObjects(targets, true)[0];
|
|
6500
|
+
if (hit) {
|
|
6501
|
+
return { point: hit.point.clone(), segmentIndex: i - 1 };
|
|
6502
|
+
}
|
|
6503
|
+
}
|
|
6504
|
+
return null;
|
|
6505
|
+
}
|
|
6332
6506
|
collectTeleportTargets(world) {
|
|
6333
6507
|
const objects = [];
|
|
6334
6508
|
for (const entityId of world.query(VRTeleportAreaComponent, Object3DRef)) {
|
|
@@ -6340,12 +6514,13 @@ var _XRLocomotionSystem = class _XRLocomotionSystem {
|
|
|
6340
6514
|
}
|
|
6341
6515
|
return objects;
|
|
6342
6516
|
}
|
|
6343
|
-
/**
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6517
|
+
/** Arc points up to the landing spot this frame; empty when not aiming. */
|
|
6518
|
+
getAimCurve() {
|
|
6519
|
+
return this.aimCurve;
|
|
6520
|
+
}
|
|
6521
|
+
/** Where the arc currently lands, or null when not aiming at a valid area. */
|
|
6522
|
+
getLandingPoint() {
|
|
6523
|
+
return this.landingPoint;
|
|
6349
6524
|
}
|
|
6350
6525
|
};
|
|
6351
6526
|
__name(_XRLocomotionSystem, "XRLocomotionSystem");
|
|
@@ -6468,7 +6643,7 @@ var _XRSessionSystem = class _XRSessionSystem {
|
|
|
6468
6643
|
__name(_XRSessionSystem, "XRSessionSystem");
|
|
6469
6644
|
var XRSessionSystem = _XRSessionSystem;
|
|
6470
6645
|
function buildGeometry2(area) {
|
|
6471
|
-
if (area.shape === "
|
|
6646
|
+
if (area.shape === "circle") {
|
|
6472
6647
|
const radius = Math.max(5e-3, area.width / 2);
|
|
6473
6648
|
return new THREE7.CircleGeometry(radius, 48);
|
|
6474
6649
|
}
|
|
@@ -6507,7 +6682,7 @@ var _VRTeleportAreaSystem = class _VRTeleportAreaSystem {
|
|
|
6507
6682
|
__name(_VRTeleportAreaSystem, "VRTeleportAreaSystem");
|
|
6508
6683
|
var VRTeleportAreaSystem = _VRTeleportAreaSystem;
|
|
6509
6684
|
var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
6510
|
-
constructor(
|
|
6685
|
+
constructor(options) {
|
|
6511
6686
|
this.controllerModelFactory = new XRControllerModelFactory();
|
|
6512
6687
|
this.handModelFactory = new XRHandModelFactory();
|
|
6513
6688
|
this.group = new THREE7.Group();
|
|
@@ -6515,7 +6690,9 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
6515
6690
|
this.attachedTo = null;
|
|
6516
6691
|
/** Index → whether we've already attached visuals for that slot. */
|
|
6517
6692
|
this.ready = /* @__PURE__ */ new Set();
|
|
6518
|
-
this.
|
|
6693
|
+
this.rays = [];
|
|
6694
|
+
this.slots = options?.slots ?? 2;
|
|
6695
|
+
this.interactionSystem = options?.interactionSystem ?? null;
|
|
6519
6696
|
this.group.name = "XRControllerVisuals";
|
|
6520
6697
|
this.group.userData.ecsPreviewHidden = true;
|
|
6521
6698
|
}
|
|
@@ -6523,6 +6700,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
6523
6700
|
const renderer = world.getRenderer();
|
|
6524
6701
|
if (!renderer.xr?.enabled) return;
|
|
6525
6702
|
this.ensureAttached(world);
|
|
6703
|
+
this.updateRayVisibility();
|
|
6526
6704
|
if (this.built) return;
|
|
6527
6705
|
for (let index = 0; index < this.slots; index += 1) {
|
|
6528
6706
|
if (this.ready.has(index)) continue;
|
|
@@ -6530,7 +6708,9 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
6530
6708
|
const grip = renderer.xr.getControllerGrip(index);
|
|
6531
6709
|
const hand = renderer.xr.getHand(index);
|
|
6532
6710
|
if (!controller || !grip || !hand) continue;
|
|
6533
|
-
|
|
6711
|
+
const ray = this.createRay();
|
|
6712
|
+
this.rays.push(ray);
|
|
6713
|
+
controller.add(ray);
|
|
6534
6714
|
this.group.add(controller);
|
|
6535
6715
|
grip.add(this.controllerModelFactory.createControllerModel(grip));
|
|
6536
6716
|
this.group.add(grip);
|
|
@@ -6542,6 +6722,17 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
6542
6722
|
this.built = true;
|
|
6543
6723
|
}
|
|
6544
6724
|
}
|
|
6725
|
+
/**
|
|
6726
|
+
* Show the aim ray only when it is meaningful: hovering something
|
|
6727
|
+
* interactive, or mid-grab. A permanently-drawn ray is visual noise, and it
|
|
6728
|
+
* implies everything is clickable when most of the scene is not. Teleport
|
|
6729
|
+
* aiming has its own arc, so the straight ray stays hidden for that.
|
|
6730
|
+
*/
|
|
6731
|
+
updateRayVisibility() {
|
|
6732
|
+
if (!this.interactionSystem) return;
|
|
6733
|
+
const active = this.interactionSystem.getHoveredEntityId() !== null || this.interactionSystem.isGrabbing();
|
|
6734
|
+
for (const ray of this.rays) ray.visible = active;
|
|
6735
|
+
}
|
|
6545
6736
|
/**
|
|
6546
6737
|
* Parent the visuals to the XR rig when there is one, so locomotion moves the
|
|
6547
6738
|
* hands with the player. Falls back to the scene root.
|
|
@@ -6567,6 +6758,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
6567
6758
|
const line = new THREE7.Line(geometry, material);
|
|
6568
6759
|
line.name = "XRPointerRay";
|
|
6569
6760
|
line.renderOrder = 999;
|
|
6761
|
+
line.visible = this.interactionSystem === null;
|
|
6570
6762
|
return line;
|
|
6571
6763
|
}
|
|
6572
6764
|
dispose() {
|
|
@@ -6582,6 +6774,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
6582
6774
|
}
|
|
6583
6775
|
});
|
|
6584
6776
|
this.group.clear();
|
|
6777
|
+
this.rays.length = 0;
|
|
6585
6778
|
this.ready.clear();
|
|
6586
6779
|
this.built = false;
|
|
6587
6780
|
this.attachedTo = null;
|
|
@@ -6589,7 +6782,122 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
6589
6782
|
};
|
|
6590
6783
|
__name(_XRControllerVisualSystem, "XRControllerVisualSystem");
|
|
6591
6784
|
var XRControllerVisualSystem = _XRControllerVisualSystem;
|
|
6785
|
+
var MARKER_RADIUS = 0.28;
|
|
6786
|
+
var ACCENT = new THREE7.Color("#4da3ff");
|
|
6787
|
+
var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
6788
|
+
constructor(locomotionSystem) {
|
|
6789
|
+
this.group = new THREE7.Group();
|
|
6790
|
+
this.arcGeometry = new THREE7.BufferGeometry();
|
|
6791
|
+
this.marker = new THREE7.Group();
|
|
6792
|
+
this.attached = false;
|
|
6793
|
+
this.locomotionSystem = locomotionSystem;
|
|
6794
|
+
this.group.name = "XRTeleportVisuals";
|
|
6795
|
+
this.group.userData.ecsPreviewHidden = true;
|
|
6796
|
+
const arcMaterial = new THREE7.LineBasicMaterial({
|
|
6797
|
+
vertexColors: true,
|
|
6798
|
+
transparent: true,
|
|
6799
|
+
depthTest: false
|
|
6800
|
+
});
|
|
6801
|
+
this.arc = new THREE7.Line(this.arcGeometry, arcMaterial);
|
|
6802
|
+
this.arc.frustumCulled = false;
|
|
6803
|
+
this.arc.renderOrder = 998;
|
|
6804
|
+
this.group.add(this.arc);
|
|
6805
|
+
this.marker.add(this.createRing(), this.createDot());
|
|
6806
|
+
this.marker.renderOrder = 999;
|
|
6807
|
+
this.group.add(this.marker);
|
|
6808
|
+
this.setVisible(false);
|
|
6809
|
+
}
|
|
6810
|
+
update(world) {
|
|
6811
|
+
if (!this.attached) {
|
|
6812
|
+
world.getScene().add(this.group);
|
|
6813
|
+
this.attached = true;
|
|
6814
|
+
}
|
|
6815
|
+
const curve = this.locomotionSystem.getAimCurve();
|
|
6816
|
+
const landing = this.locomotionSystem.getLandingPoint();
|
|
6817
|
+
if (!landing || curve.length < 2) {
|
|
6818
|
+
this.setVisible(false);
|
|
6819
|
+
return;
|
|
6820
|
+
}
|
|
6821
|
+
this.updateArcGeometry(curve);
|
|
6822
|
+
this.marker.position.copy(landing);
|
|
6823
|
+
this.marker.position.y += 0.01;
|
|
6824
|
+
this.setVisible(true);
|
|
6825
|
+
}
|
|
6826
|
+
updateArcGeometry(curve) {
|
|
6827
|
+
const count = curve.length;
|
|
6828
|
+
const positions = new Float32Array(count * 3);
|
|
6829
|
+
const colors = new Float32Array(count * 3);
|
|
6830
|
+
for (let i = 0; i < count; i += 1) {
|
|
6831
|
+
const point = curve[i];
|
|
6832
|
+
positions[i * 3] = point.x;
|
|
6833
|
+
positions[i * 3 + 1] = point.y;
|
|
6834
|
+
positions[i * 3 + 2] = point.z;
|
|
6835
|
+
const t = count > 1 ? i / (count - 1) : 0;
|
|
6836
|
+
const fade = 1 - t * 0.75;
|
|
6837
|
+
colors[i * 3] = ACCENT.r * fade;
|
|
6838
|
+
colors[i * 3 + 1] = ACCENT.g * fade;
|
|
6839
|
+
colors[i * 3 + 2] = ACCENT.b * fade;
|
|
6840
|
+
}
|
|
6841
|
+
this.arcGeometry.setAttribute(
|
|
6842
|
+
"position",
|
|
6843
|
+
new THREE7.BufferAttribute(positions, 3)
|
|
6844
|
+
);
|
|
6845
|
+
this.arcGeometry.setAttribute("color", new THREE7.BufferAttribute(colors, 3));
|
|
6846
|
+
this.arcGeometry.computeBoundingSphere();
|
|
6847
|
+
}
|
|
6848
|
+
createRing() {
|
|
6849
|
+
const geometry = new THREE7.RingGeometry(
|
|
6850
|
+
MARKER_RADIUS * 0.72,
|
|
6851
|
+
MARKER_RADIUS,
|
|
6852
|
+
48
|
|
6853
|
+
);
|
|
6854
|
+
geometry.rotateX(-Math.PI / 2);
|
|
6855
|
+
return new THREE7.Mesh(
|
|
6856
|
+
geometry,
|
|
6857
|
+
new THREE7.MeshBasicMaterial({
|
|
6858
|
+
color: ACCENT,
|
|
6859
|
+
transparent: true,
|
|
6860
|
+
opacity: 0.9,
|
|
6861
|
+
side: THREE7.DoubleSide,
|
|
6862
|
+
depthTest: false
|
|
6863
|
+
})
|
|
6864
|
+
);
|
|
6865
|
+
}
|
|
6866
|
+
createDot() {
|
|
6867
|
+
const geometry = new THREE7.CircleGeometry(MARKER_RADIUS * 0.16, 24);
|
|
6868
|
+
geometry.rotateX(-Math.PI / 2);
|
|
6869
|
+
return new THREE7.Mesh(
|
|
6870
|
+
geometry,
|
|
6871
|
+
new THREE7.MeshBasicMaterial({
|
|
6872
|
+
color: ACCENT,
|
|
6873
|
+
transparent: true,
|
|
6874
|
+
opacity: 0.55,
|
|
6875
|
+
side: THREE7.DoubleSide,
|
|
6876
|
+
depthTest: false
|
|
6877
|
+
})
|
|
6878
|
+
);
|
|
6879
|
+
}
|
|
6880
|
+
setVisible(visible) {
|
|
6881
|
+
this.group.visible = visible;
|
|
6882
|
+
}
|
|
6883
|
+
dispose() {
|
|
6884
|
+
this.group.removeFromParent();
|
|
6885
|
+
this.group.traverse((child) => {
|
|
6886
|
+
const mesh = child;
|
|
6887
|
+
mesh.geometry?.dispose?.();
|
|
6888
|
+
const material = mesh.material;
|
|
6889
|
+
if (Array.isArray(material)) {
|
|
6890
|
+
for (const entry of material) entry.dispose?.();
|
|
6891
|
+
} else {
|
|
6892
|
+
material?.dispose?.();
|
|
6893
|
+
}
|
|
6894
|
+
});
|
|
6895
|
+
this.attached = false;
|
|
6896
|
+
}
|
|
6897
|
+
};
|
|
6898
|
+
__name(_XRTeleportVisualSystem, "XRTeleportVisualSystem");
|
|
6899
|
+
var XRTeleportVisualSystem = _XRTeleportVisualSystem;
|
|
6592
6900
|
|
|
6593
|
-
export { ADDED_NODE_MARKER_COMPONENT, AnimationSystem, AudioSystem, Behaviour, CameraSyncSystem, EnvironmentSyncSystem, HYDRATABLE_ENTITY_KINDS, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, TransformSyncSystem, VRTeleportAreaSystem, VideoSystem, XRControllerVisualSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeInstanceOverrides, decanonicalizeComponentValue, despawnPrefab, encodeOverride, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, setPrefabAssetUrlResolver, spawnPrefab };
|
|
6594
|
-
//# sourceMappingURL=chunk-
|
|
6595
|
-
//# sourceMappingURL=chunk-
|
|
6901
|
+
export { ADDED_NODE_MARKER_COMPONENT, ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioSystem, Behaviour, CameraSyncSystem, EnvironmentSyncSystem, HYDRATABLE_ENTITY_KINDS, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, TransformSyncSystem, VRTeleportAreaSystem, VideoSystem, XRControllerVisualSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, arcGroundCrossing, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeInstanceOverrides, decanonicalizeComponentValue, despawnPrefab, encodeOverride, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, sampleTeleportArc, setPrefabAssetUrlResolver, spawnPrefab };
|
|
6902
|
+
//# sourceMappingURL=chunk-G53MZVKQ.js.map
|
|
6903
|
+
//# sourceMappingURL=chunk-G53MZVKQ.js.map
|