@relu-interactives/spatial-ecs 0.3.10 → 0.3.11
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/{XRHandPose-CjacJ_16.d.ts → XRHandPose-B6I4y1lj.d.ts} +48 -14
- package/dist/{XRHandPose-hAtj9wm-.d.cts → XRHandPose-C-KJeYcJ.d.cts} +48 -14
- package/dist/{chunk-5UVBEAGW.js → chunk-FSHRPY65.js} +4 -4
- package/dist/{chunk-5UVBEAGW.js.map → chunk-FSHRPY65.js.map} +1 -1
- package/dist/{chunk-O2HSIZFC.js → chunk-KLU2M43M.js} +270 -33
- package/dist/chunk-KLU2M43M.js.map +1 -0
- package/dist/{chunk-ELSZ5U3F.js → chunk-TXEGYR76.js} +5 -4
- package/dist/chunk-TXEGYR76.js.map +1 -0
- package/dist/{chunk-NJOO7NO6.js → chunk-Y3AC3VZ2.js} +3 -3
- package/dist/{chunk-NJOO7NO6.js.map → chunk-Y3AC3VZ2.js.map} +1 -1
- package/dist/components/index.cjs +3 -2
- 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/docs/guide/vr-and-hand-poses.md +7 -3
- package/dist/factories/index.cjs +3 -2
- 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-B-KhN8Ox.d.ts → index-Bi_wIo1o.d.ts} +56 -1
- package/dist/{index-B7JDsx4a.d.ts → index-CEZp7qLL.d.ts} +2 -3
- package/dist/{index-B9JqYr3Q.d.cts → index-DPRnnSI-.d.cts} +2 -3
- package/dist/{index-DU-CF-3m.d.cts → index-jlgDou9W.d.cts} +56 -1
- package/dist/index.cjs +270 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +8 -8
- package/dist/systems/index.cjs +270 -30
- 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-ELSZ5U3F.js.map +0 -1
- package/dist/chunk-O2HSIZFC.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, XRRigComponent, VRTeleportAreaComponent, XRInteractableComponent, createAttachPoint, XRHandPoseComponent, createHandPoseEntry, XRInteractorComponent, XRInteractorSideComponent, InstanceSlotComponent, Name, ImageComponent, SpriteComponent, VideoComponent, AudioComponent, ImageTarget, Selectable, PrefabNode, PrefabInstance, handPoseDefinitionFor, getHandPosePreset } from './chunk-
|
|
1
|
+
import { resolveDracoDecoderPath, applyTransform, SHARED_MODEL_RESOURCE_FLAG } from './chunk-Y3AC3VZ2.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, createAttachPoint, XRHandPoseComponent, createHandPoseEntry, XRInteractorComponent, XRInteractorSideComponent, InstanceSlotComponent, Name, ImageComponent, SpriteComponent, VideoComponent, AudioComponent, ImageTarget, Selectable, PrefabNode, PrefabInstance, handPoseDefinitionFor, getHandPosePreset } from './chunk-TXEGYR76.js';
|
|
3
3
|
import { __name } from './chunk-OY7ZODZP.js';
|
|
4
4
|
import * as THREE19 from 'three';
|
|
5
5
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
@@ -901,6 +901,20 @@ var _PostprocessingSyncSystem = class _PostprocessingSyncSystem {
|
|
|
901
901
|
__name(_PostprocessingSyncSystem, "PostprocessingSyncSystem");
|
|
902
902
|
var PostprocessingSyncSystem = _PostprocessingSyncSystem;
|
|
903
903
|
var MIN_SIZE = 1e-4;
|
|
904
|
+
function toBodyType(RAPIER, bodyType) {
|
|
905
|
+
switch (bodyType) {
|
|
906
|
+
case "fixed":
|
|
907
|
+
return RAPIER.RigidBodyType.Fixed;
|
|
908
|
+
case "kinematicPosition":
|
|
909
|
+
return RAPIER.RigidBodyType.KinematicPositionBased;
|
|
910
|
+
case "kinematicVelocity":
|
|
911
|
+
return RAPIER.RigidBodyType.KinematicVelocityBased;
|
|
912
|
+
case "dynamic":
|
|
913
|
+
default:
|
|
914
|
+
return RAPIER.RigidBodyType.Dynamic;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
__name(toBodyType, "toBodyType");
|
|
904
918
|
function createRigidBodyDesc(RAPIER, bodyType) {
|
|
905
919
|
if (bodyType === "fixed") {
|
|
906
920
|
return RAPIER.RigidBodyDesc.fixed();
|
|
@@ -1199,7 +1213,8 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
|
|
|
1199
1213
|
setPhysicsLiveRef(physics, "collider", null);
|
|
1200
1214
|
continue;
|
|
1201
1215
|
}
|
|
1202
|
-
const
|
|
1216
|
+
const { type: _desiredBodyType, ...rigidBodyRebuildValues } = physics.values.rigidbody;
|
|
1217
|
+
const rigidBodySignature = JSON.stringify(rigidBodyRebuildValues);
|
|
1203
1218
|
const previousRigidBodySignature = this.rigidBodySignatures.get(entityId);
|
|
1204
1219
|
const hasRigidBody = this.rigidBodyHandles.has(entityId);
|
|
1205
1220
|
const shouldRecreateBody = !hasRigidBody || previousRigidBodySignature !== rigidBodySignature;
|
|
@@ -1254,6 +1269,25 @@ var _PhysicsSyncSystem = class _PhysicsSyncSystem {
|
|
|
1254
1269
|
continue;
|
|
1255
1270
|
}
|
|
1256
1271
|
setPhysicsLiveRef(physics, "rigidBody", body);
|
|
1272
|
+
const desiredBodyType = this.isEditorMode ? "fixed" : physics.values.rigidbody.type;
|
|
1273
|
+
const desiredRapierType = toBodyType(this.rapier, desiredBodyType);
|
|
1274
|
+
if (body.bodyType() !== desiredRapierType) {
|
|
1275
|
+
body.setBodyType(desiredRapierType, true);
|
|
1276
|
+
if (!this.isEditorMode && desiredBodyType === "dynamic") {
|
|
1277
|
+
body.setAdditionalMass(physics.values.rigidbody.mass, true);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
const pending = physics.pendingVelocity;
|
|
1281
|
+
if (pending) {
|
|
1282
|
+
setPhysicsLiveRef(physics, "pendingVelocity", null);
|
|
1283
|
+
if (!this.isEditorMode && desiredBodyType === "dynamic") {
|
|
1284
|
+
try {
|
|
1285
|
+
body.setLinvel(pending.linear, true);
|
|
1286
|
+
body.setAngvel(pending.angular, true);
|
|
1287
|
+
} catch {
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1257
1291
|
if (this.isEditorMode || physics.values.rigidbody.type !== "dynamic") {
|
|
1258
1292
|
syncBodyFromTransform(body, transform);
|
|
1259
1293
|
}
|
|
@@ -2981,9 +3015,6 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
2981
3015
|
if (typeof sourceInteractable.pointable === "boolean") {
|
|
2982
3016
|
interactable.pointable = sourceInteractable.pointable;
|
|
2983
3017
|
}
|
|
2984
|
-
if (typeof sourceInteractable.grabMode === "string") {
|
|
2985
|
-
interactable.grabMode = sourceInteractable.grabMode;
|
|
2986
|
-
}
|
|
2987
3018
|
if (typeof sourceInteractable.grabReach === "string") {
|
|
2988
3019
|
interactable.grabReach = sourceInteractable.grabReach;
|
|
2989
3020
|
}
|
|
@@ -3042,8 +3073,16 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
3042
3073
|
z: typeof grabRot.z === "number" ? grabRot.z : 0
|
|
3043
3074
|
};
|
|
3044
3075
|
}
|
|
3045
|
-
if (typeof sourceInteractable.
|
|
3046
|
-
interactable.
|
|
3076
|
+
if (typeof sourceInteractable.hoverBehavior === "string") {
|
|
3077
|
+
interactable.hoverBehavior = sourceInteractable.hoverBehavior;
|
|
3078
|
+
} else if (sourceInteractable.highlightOnHover === false) {
|
|
3079
|
+
interactable.hoverBehavior = "none";
|
|
3080
|
+
}
|
|
3081
|
+
if (typeof sourceInteractable.hoverColor === "string") {
|
|
3082
|
+
interactable.hoverColor = sourceInteractable.hoverColor;
|
|
3083
|
+
}
|
|
3084
|
+
if (typeof sourceInteractable.hoverScale === "number") {
|
|
3085
|
+
interactable.hoverScale = sourceInteractable.hoverScale;
|
|
3047
3086
|
}
|
|
3048
3087
|
}
|
|
3049
3088
|
}
|
|
@@ -6537,6 +6576,8 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6537
6576
|
this.raycaster = new THREE19.Raycaster();
|
|
6538
6577
|
this.grabs = /* @__PURE__ */ new Map();
|
|
6539
6578
|
this.hoveredEntityId = null;
|
|
6579
|
+
/** Per-hand hover, with the hit distance so the ray can stop at the surface. */
|
|
6580
|
+
this.hovers = /* @__PURE__ */ new Map();
|
|
6540
6581
|
/** Monotonic seconds, accumulated from deltaTime for velocity sampling. */
|
|
6541
6582
|
this.elapsed = 0;
|
|
6542
6583
|
this.inputSystem = inputSystem;
|
|
@@ -6550,6 +6591,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6550
6591
|
const inputs = this.inputSystem.getInputs();
|
|
6551
6592
|
const interactables = this.collectInteractables(world);
|
|
6552
6593
|
this.hoveredEntityId = null;
|
|
6594
|
+
this.hovers.clear();
|
|
6553
6595
|
for (const input of inputs) {
|
|
6554
6596
|
if (!input.connected) {
|
|
6555
6597
|
this.release(world, input);
|
|
@@ -6567,6 +6609,10 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6567
6609
|
if (this.hoveredEntityId === null) {
|
|
6568
6610
|
this.hoveredEntityId = candidate.entityId;
|
|
6569
6611
|
}
|
|
6612
|
+
this.hovers.set(input, {
|
|
6613
|
+
entityId: candidate.entityId,
|
|
6614
|
+
distance: candidate.distance
|
|
6615
|
+
});
|
|
6570
6616
|
const interactable = world.getComponent(
|
|
6571
6617
|
candidate.entityId,
|
|
6572
6618
|
XRInteractableComponent
|
|
@@ -6639,7 +6685,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6639
6685
|
transform.position.x - hand.x,
|
|
6640
6686
|
transform.position.y - hand.y,
|
|
6641
6687
|
transform.position.z - hand.z
|
|
6642
|
-
);
|
|
6688
|
+
).applyQuaternion(handQuaternion.clone().invert());
|
|
6643
6689
|
record.handRotationOffset = handQuaternion.clone().invert().multiply(objectQuaternion);
|
|
6644
6690
|
record.remote = false;
|
|
6645
6691
|
record.tracker.clear();
|
|
@@ -6750,13 +6796,22 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6750
6796
|
}
|
|
6751
6797
|
}
|
|
6752
6798
|
if (nearestId !== null) {
|
|
6753
|
-
return {
|
|
6799
|
+
return {
|
|
6800
|
+
entityId: nearestId,
|
|
6801
|
+
viaDistance: false,
|
|
6802
|
+
distance: nearestDistance
|
|
6803
|
+
};
|
|
6754
6804
|
}
|
|
6755
|
-
const
|
|
6756
|
-
if (
|
|
6805
|
+
const hit = this.raycast(input, interactables);
|
|
6806
|
+
if (hit === null) return null;
|
|
6807
|
+
const hitId = hit.entityId;
|
|
6757
6808
|
const interactable = world.getComponent(hitId, XRInteractableComponent);
|
|
6758
6809
|
const viaDistanceAllowed = interactable?.grabReach === "distance" || interactable?.grabReach === "both";
|
|
6759
|
-
return {
|
|
6810
|
+
return {
|
|
6811
|
+
entityId: hitId,
|
|
6812
|
+
viaDistance: viaDistanceAllowed,
|
|
6813
|
+
distance: hit.distance
|
|
6814
|
+
};
|
|
6760
6815
|
}
|
|
6761
6816
|
collectInteractables(world) {
|
|
6762
6817
|
const out = [];
|
|
@@ -6787,7 +6842,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6787
6842
|
nearestId = entry.entityId;
|
|
6788
6843
|
}
|
|
6789
6844
|
}
|
|
6790
|
-
return nearestId;
|
|
6845
|
+
return nearestId === null ? null : { entityId: nearestId, distance: nearestDistance };
|
|
6791
6846
|
}
|
|
6792
6847
|
/**
|
|
6793
6848
|
* Pick the authored hold this hand should take.
|
|
@@ -6862,7 +6917,7 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6862
6917
|
transform.position.x - hand.x,
|
|
6863
6918
|
transform.position.y - hand.y,
|
|
6864
6919
|
transform.position.z - hand.z
|
|
6865
|
-
);
|
|
6920
|
+
).applyQuaternion(handQuaternion.clone().invert());
|
|
6866
6921
|
}
|
|
6867
6922
|
const physics = world.getComponent(entityId, PhysicsComponent);
|
|
6868
6923
|
let restoreBodyType = null;
|
|
@@ -6997,9 +7052,10 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
6997
7052
|
transform.position.z = hand.z - anchor.z;
|
|
6998
7053
|
writeEuler(transform.rotation, objectQuaternion);
|
|
6999
7054
|
} else {
|
|
7000
|
-
|
|
7001
|
-
transform.position.
|
|
7002
|
-
transform.position.
|
|
7055
|
+
const carried = held.offset.clone().applyQuaternion(handQuaternion);
|
|
7056
|
+
transform.position.x = hand.x + carried.x;
|
|
7057
|
+
transform.position.y = hand.y + carried.y;
|
|
7058
|
+
transform.position.z = hand.z + carried.z;
|
|
7003
7059
|
writeEuler(transform.rotation, objectQuaternion);
|
|
7004
7060
|
}
|
|
7005
7061
|
held.tracker.record(
|
|
@@ -7052,19 +7108,14 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
7052
7108
|
const physics = world.getComponent(held.entityId, PhysicsComponent);
|
|
7053
7109
|
if (held.restoreBodyType !== null && physics) {
|
|
7054
7110
|
physics.values.rigidbody.type = held.restoreBodyType;
|
|
7055
|
-
const body = physics.rigidBody;
|
|
7056
7111
|
const dynamic = held.restoreBodyType === "dynamic";
|
|
7057
|
-
if (
|
|
7112
|
+
if (dynamic && interactable?.throwOnRelease) {
|
|
7058
7113
|
const velocity = held.tracker.computeVelocity(this.elapsed).multiplyScalar(interactable.throwStrength);
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
const spin = held.angularVelocity;
|
|
7065
|
-
body.setAngvel({ x: spin.x, y: spin.y, z: spin.z }, true);
|
|
7066
|
-
} catch {
|
|
7067
|
-
}
|
|
7114
|
+
const spin = held.angularVelocity;
|
|
7115
|
+
setPhysicsLiveRef(physics, "pendingVelocity", {
|
|
7116
|
+
linear: { x: velocity.x, y: velocity.y, z: velocity.z },
|
|
7117
|
+
angular: { x: spin.x, y: spin.y, z: spin.z }
|
|
7118
|
+
});
|
|
7068
7119
|
}
|
|
7069
7120
|
}
|
|
7070
7121
|
held.tracker.clear();
|
|
@@ -7112,6 +7163,30 @@ var _XRInteractionSystem = class _XRInteractionSystem {
|
|
|
7112
7163
|
getHoveredEntityId() {
|
|
7113
7164
|
return this.hoveredEntityId;
|
|
7114
7165
|
}
|
|
7166
|
+
/**
|
|
7167
|
+
* What this hand is pointing at, with the distance to it.
|
|
7168
|
+
*
|
|
7169
|
+
* The distance is what lets the pointer ray stop at the surface instead of
|
|
7170
|
+
* passing through the object.
|
|
7171
|
+
*/
|
|
7172
|
+
getHoverFor(handedness) {
|
|
7173
|
+
for (const [input, hover] of this.hovers) {
|
|
7174
|
+
if (input.handedness === handedness) return hover;
|
|
7175
|
+
}
|
|
7176
|
+
return null;
|
|
7177
|
+
}
|
|
7178
|
+
/** Every entity under a pointer this frame — drives hover feedback. */
|
|
7179
|
+
getHoveredEntityIds() {
|
|
7180
|
+
const ids = /* @__PURE__ */ new Set();
|
|
7181
|
+
for (const hover of this.hovers.values()) ids.add(hover.entityId);
|
|
7182
|
+
return ids;
|
|
7183
|
+
}
|
|
7184
|
+
/** Entities currently held, so hover feedback can skip them. */
|
|
7185
|
+
getHeldEntityIds() {
|
|
7186
|
+
const ids = /* @__PURE__ */ new Set();
|
|
7187
|
+
for (const record of this.grabs.values()) ids.add(record.entityId);
|
|
7188
|
+
return ids;
|
|
7189
|
+
}
|
|
7115
7190
|
/** True when any source is holding something. */
|
|
7116
7191
|
isGrabbing() {
|
|
7117
7192
|
return this.grabs.size > 0;
|
|
@@ -7672,6 +7747,9 @@ function applyHandMaterial(root, material) {
|
|
|
7672
7747
|
});
|
|
7673
7748
|
}
|
|
7674
7749
|
__name(applyHandMaterial, "applyHandMaterial");
|
|
7750
|
+
|
|
7751
|
+
// core/systems/XRControllerVisualSystem.ts
|
|
7752
|
+
var RAY_LENGTH = 5;
|
|
7675
7753
|
var SLOTS = [
|
|
7676
7754
|
{ index: 0, side: "left" },
|
|
7677
7755
|
{ index: 1, side: "right" }
|
|
@@ -7710,6 +7788,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
7710
7788
|
visuals.controllerModel.visible = showControllers && hasController;
|
|
7711
7789
|
visuals.handModel.visible = showHands && hasHand;
|
|
7712
7790
|
visuals.ray.visible = this.shouldShowRay(interactor);
|
|
7791
|
+
this.fitRayToHover(visuals.ray, side);
|
|
7713
7792
|
if (showHands && this.handMaterial) {
|
|
7714
7793
|
applyHandMaterial(visuals.handModel, this.handMaterial);
|
|
7715
7794
|
}
|
|
@@ -7790,6 +7869,18 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
7790
7869
|
if (!this.interactionSystem) return true;
|
|
7791
7870
|
return this.interactionSystem.getHoveredEntityId() !== null || this.interactionSystem.isGrabbing();
|
|
7792
7871
|
}
|
|
7872
|
+
/**
|
|
7873
|
+
* Stop the ray at whatever it is pointing at.
|
|
7874
|
+
*
|
|
7875
|
+
* A fixed-length ray drawn with depth testing off punches straight through the
|
|
7876
|
+
* object, so the user cannot tell where the pointer actually lands. Scaling it
|
|
7877
|
+
* to the hit distance turns it into a pointer that meets the surface.
|
|
7878
|
+
*/
|
|
7879
|
+
fitRayToHover(ray, side) {
|
|
7880
|
+
const hover = this.interactionSystem?.getHoverFor(side) ?? null;
|
|
7881
|
+
const length = hover && Number.isFinite(hover.distance) && hover.distance > 0 ? Math.min(hover.distance, RAY_LENGTH) : RAY_LENGTH;
|
|
7882
|
+
ray.scale.z = length / RAY_LENGTH;
|
|
7883
|
+
}
|
|
7793
7884
|
/** Lazily build per-slot visuals; the device reports profiles late. */
|
|
7794
7885
|
ensureSlots(world) {
|
|
7795
7886
|
const renderer = world.getRenderer();
|
|
@@ -7831,7 +7922,7 @@ var _XRControllerVisualSystem = class _XRControllerVisualSystem {
|
|
|
7831
7922
|
createRay() {
|
|
7832
7923
|
const geometry = new THREE19.BufferGeometry().setFromPoints([
|
|
7833
7924
|
new THREE19.Vector3(0, 0, 0),
|
|
7834
|
-
new THREE19.Vector3(0, 0, -
|
|
7925
|
+
new THREE19.Vector3(0, 0, -RAY_LENGTH)
|
|
7835
7926
|
]);
|
|
7836
7927
|
const material = new THREE19.LineBasicMaterial({
|
|
7837
7928
|
color: "#4da3ff",
|
|
@@ -8494,7 +8585,153 @@ var _XRHandPoseSystem = class _XRHandPoseSystem {
|
|
|
8494
8585
|
};
|
|
8495
8586
|
__name(_XRHandPoseSystem, "XRHandPoseSystem");
|
|
8496
8587
|
var XRHandPoseSystem = _XRHandPoseSystem;
|
|
8588
|
+
var XR_HOVER_SHELL_FLAG = "__xrHoverShell";
|
|
8589
|
+
var SHELL_INFLATE = 1.04;
|
|
8590
|
+
var SCALE_SMOOTH_SECONDS = 0.09;
|
|
8591
|
+
var _XRHoverVisualSystem = class _XRHoverVisualSystem {
|
|
8592
|
+
constructor(interactionSystem) {
|
|
8593
|
+
this.records = /* @__PURE__ */ new Map();
|
|
8594
|
+
this.interactionSystem = interactionSystem;
|
|
8595
|
+
}
|
|
8596
|
+
update(world, deltaTime) {
|
|
8597
|
+
if (!world.isXrPresenting()) {
|
|
8598
|
+
this.clearAll(world);
|
|
8599
|
+
return;
|
|
8600
|
+
}
|
|
8601
|
+
const hovered = this.interactionSystem.getHoveredEntityIds();
|
|
8602
|
+
const held = this.interactionSystem.getHeldEntityIds();
|
|
8603
|
+
for (const entityId of hovered) {
|
|
8604
|
+
if (held.has(entityId)) continue;
|
|
8605
|
+
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
8606
|
+
if (!interactable?.enabled) continue;
|
|
8607
|
+
if (interactable.hoverBehavior === "none") continue;
|
|
8608
|
+
this.begin(world, entityId, interactable);
|
|
8609
|
+
}
|
|
8610
|
+
for (const [entityId, record] of this.records) {
|
|
8611
|
+
if (!hovered.has(entityId) || held.has(entityId)) {
|
|
8612
|
+
record.active = false;
|
|
8613
|
+
}
|
|
8614
|
+
}
|
|
8615
|
+
this.animate(world, deltaTime);
|
|
8616
|
+
}
|
|
8617
|
+
begin(world, entityId, interactable) {
|
|
8618
|
+
const existing = this.records.get(entityId);
|
|
8619
|
+
if (existing) {
|
|
8620
|
+
existing.active = true;
|
|
8621
|
+
return;
|
|
8622
|
+
}
|
|
8623
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
8624
|
+
if (!transform) return;
|
|
8625
|
+
const wantsColor = interactable.hoverBehavior === "color" || interactable.hoverBehavior === "both";
|
|
8626
|
+
this.records.set(entityId, {
|
|
8627
|
+
shell: wantsColor ? this.addShell(world, entityId, interactable) : null,
|
|
8628
|
+
baseScale: new THREE19.Vector3(
|
|
8629
|
+
transform.scale.x,
|
|
8630
|
+
transform.scale.y,
|
|
8631
|
+
transform.scale.z
|
|
8632
|
+
),
|
|
8633
|
+
progress: 0,
|
|
8634
|
+
active: true
|
|
8635
|
+
});
|
|
8636
|
+
}
|
|
8637
|
+
/** Build an inflated back-face copy of the object's meshes. */
|
|
8638
|
+
addShell(world, entityId, interactable) {
|
|
8639
|
+
const object = world.getComponent(entityId, Object3DRef)?.object;
|
|
8640
|
+
if (!object) return null;
|
|
8641
|
+
const material = new THREE19.MeshBasicMaterial({
|
|
8642
|
+
color: new THREE19.Color(interactable.hoverColor),
|
|
8643
|
+
// Back faces only, so the shell shows just outside the silhouette instead
|
|
8644
|
+
// of covering the object.
|
|
8645
|
+
side: THREE19.BackSide,
|
|
8646
|
+
transparent: true,
|
|
8647
|
+
opacity: 0.85,
|
|
8648
|
+
depthWrite: false
|
|
8649
|
+
});
|
|
8650
|
+
const group = new THREE19.Group();
|
|
8651
|
+
group.name = "XRHoverShell";
|
|
8652
|
+
group.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
8653
|
+
group.renderOrder = 998;
|
|
8654
|
+
object.traverse((child) => {
|
|
8655
|
+
if (!(child instanceof THREE19.Mesh) || !child.geometry) return;
|
|
8656
|
+
if (child.userData[XR_HOVER_SHELL_FLAG]) return;
|
|
8657
|
+
const clone2 = new THREE19.Mesh(child.geometry, material);
|
|
8658
|
+
child.updateWorldMatrix(true, false);
|
|
8659
|
+
object.updateWorldMatrix(true, false);
|
|
8660
|
+
clone2.matrixAutoUpdate = false;
|
|
8661
|
+
clone2.matrix.copy(object.matrixWorld).invert().multiply(child.matrixWorld).scale(new THREE19.Vector3(SHELL_INFLATE, SHELL_INFLATE, SHELL_INFLATE));
|
|
8662
|
+
clone2.userData[XR_HOVER_SHELL_FLAG] = true;
|
|
8663
|
+
clone2.raycast = () => {
|
|
8664
|
+
};
|
|
8665
|
+
group.add(clone2);
|
|
8666
|
+
});
|
|
8667
|
+
if (group.children.length === 0) {
|
|
8668
|
+
material.dispose();
|
|
8669
|
+
return null;
|
|
8670
|
+
}
|
|
8671
|
+
object.add(group);
|
|
8672
|
+
return group;
|
|
8673
|
+
}
|
|
8674
|
+
animate(world, deltaTime) {
|
|
8675
|
+
const step = 1 - Math.exp(-Math.max(0, deltaTime) / SCALE_SMOOTH_SECONDS);
|
|
8676
|
+
for (const [entityId, record] of Array.from(this.records)) {
|
|
8677
|
+
const interactable = world.getComponent(entityId, XRInteractableComponent);
|
|
8678
|
+
const target = record.active ? 1 : 0;
|
|
8679
|
+
record.progress += (target - record.progress) * step;
|
|
8680
|
+
const wantsScale = interactable?.hoverBehavior === "scale" || interactable?.hoverBehavior === "both";
|
|
8681
|
+
if (wantsScale) {
|
|
8682
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
8683
|
+
if (transform) {
|
|
8684
|
+
const factor = 1 + (interactable.hoverScale - 1) * Math.min(1, record.progress);
|
|
8685
|
+
transform.scale.x = record.baseScale.x * factor;
|
|
8686
|
+
transform.scale.y = record.baseScale.y * factor;
|
|
8687
|
+
transform.scale.z = record.baseScale.z * factor;
|
|
8688
|
+
}
|
|
8689
|
+
}
|
|
8690
|
+
if (!record.active && record.progress < 0.01) {
|
|
8691
|
+
this.finish(world, entityId, record);
|
|
8692
|
+
}
|
|
8693
|
+
}
|
|
8694
|
+
}
|
|
8695
|
+
/** Remove the effect and restore the authored scale exactly. */
|
|
8696
|
+
finish(world, entityId, record) {
|
|
8697
|
+
const transform = world.getComponent(entityId, TransformComponent);
|
|
8698
|
+
if (transform) {
|
|
8699
|
+
transform.scale.x = record.baseScale.x;
|
|
8700
|
+
transform.scale.y = record.baseScale.y;
|
|
8701
|
+
transform.scale.z = record.baseScale.z;
|
|
8702
|
+
}
|
|
8703
|
+
this.disposeShell(record.shell);
|
|
8704
|
+
this.records.delete(entityId);
|
|
8705
|
+
}
|
|
8706
|
+
disposeShell(shell) {
|
|
8707
|
+
if (!shell) return;
|
|
8708
|
+
shell.parent?.remove(shell);
|
|
8709
|
+
shell.traverse((child) => {
|
|
8710
|
+
if (child instanceof THREE19.Mesh) {
|
|
8711
|
+
const material = child.material;
|
|
8712
|
+
if (Array.isArray(material)) {
|
|
8713
|
+
for (const entry of material) entry.dispose();
|
|
8714
|
+
} else {
|
|
8715
|
+
material?.dispose();
|
|
8716
|
+
}
|
|
8717
|
+
}
|
|
8718
|
+
});
|
|
8719
|
+
}
|
|
8720
|
+
clearAll(world) {
|
|
8721
|
+
for (const [entityId, record] of Array.from(this.records)) {
|
|
8722
|
+
this.finish(world, entityId, record);
|
|
8723
|
+
}
|
|
8724
|
+
}
|
|
8725
|
+
dispose() {
|
|
8726
|
+
for (const record of this.records.values()) {
|
|
8727
|
+
this.disposeShell(record.shell);
|
|
8728
|
+
}
|
|
8729
|
+
this.records.clear();
|
|
8730
|
+
}
|
|
8731
|
+
};
|
|
8732
|
+
__name(_XRHoverVisualSystem, "XRHoverVisualSystem");
|
|
8733
|
+
var XRHoverVisualSystem = _XRHoverVisualSystem;
|
|
8497
8734
|
|
|
8498
|
-
export { ADDED_NODE_MARKER_COMPONENT, ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioSystem, Behaviour, CURLED_COS, CameraSyncSystem, DEFAULT_ENTER_CONFIDENCE, DEFAULT_EXIT_CONFIDENCE, DEFAULT_LOST_GRACE_SECONDS, DEFAULT_MIN_HOLD_SECONDS, EnvironmentSyncSystem, FALLBACK_HAND_SCALE, HYDRATABLE_ENTITY_KINDS, HandPoseTracker, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MATCH_FALLOFF, MAX_PLAUSIBLE_SPEED, MAX_SAMPLE_AGE_SECONDS, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PINCH_FINGERS, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, STRAIGHT_COS, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, ThrowVelocityTracker, TransformSyncSystem, VELOCITY_SAMPLES, VRTeleportAreaSystem, VideoSystem, XRControllerVisualSystem, XRHandPoseSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, XR_FINGERS, angularVelocityFrom, applyHandMaterial, arcGroundCrossing, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeFingerCurl, computeHandShape, computeInstanceOverrides, computePalmPose, computePalmWidth, computePinch, computeSpread, createHandMaterial, decanonicalizeComponentValue, despawnPrefab, encodeOverride, estimateHandScale, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, matchHandPose, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, sampleTeleportArc, setPrefabAssetUrlResolver, spawnPrefab };
|
|
8499
|
-
//# sourceMappingURL=chunk-
|
|
8500
|
-
//# sourceMappingURL=chunk-
|
|
8735
|
+
export { ADDED_NODE_MARKER_COMPONENT, ARC_GRAVITY, ARC_MAX_TIME, ARC_SPEED, ARC_STEPS, AnimationSystem, AudioSystem, Behaviour, CURLED_COS, CameraSyncSystem, DEFAULT_ENTER_CONFIDENCE, DEFAULT_EXIT_CONFIDENCE, DEFAULT_LOST_GRACE_SECONDS, DEFAULT_MIN_HOLD_SECONDS, EnvironmentSyncSystem, FALLBACK_HAND_SCALE, HYDRATABLE_ENTITY_KINDS, HandPoseTracker, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MATCH_FALLOFF, MAX_PLAUSIBLE_SPEED, MAX_SAMPLE_AGE_SECONDS, MaterialSyncSystem, MeshGeometrySystem, NODE_KEY_SEPARATOR, NO_XR_CAPABILITIES, OVERRIDE_DIFF_EXCLUDED_COMPONENTS, OVERRIDE_ROOT_EXCLUDED_COMPONENTS, ObjectVisibilitySystem, PINCH_FINGERS, PREFAB_FILE_VERSION, PREFAB_FILE_VERSION_NESTED, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, SCRIPT_OBJECT_ROOT_FLAG, STRAIGHT_COS, ScriptBehaviourSystem, ScriptObject, ScriptObjectSystem, ThrowVelocityTracker, TransformSyncSystem, VELOCITY_SAMPLES, VRTeleportAreaSystem, VideoSystem, XRControllerVisualSystem, XRHandPoseSystem, XRHoverVisualSystem, XRInputSystem, XRInteractionSystem, XRLocomotionSystem, XRSessionSystem, XRTeleportVisualSystem, XR_FINGERS, XR_HOVER_SHELL_FLAG, angularVelocityFrom, applyHandMaterial, arcGroundCrossing, buildComponentValueMaps, buildNodeKeyMapsFromSnapshot, buildNodeMapsFromSnapshot, canonicalizeComponentValue, clearPrefabCache, collectDiffPaths, collectEntitySubtree, collectSnapshotSubtreeIds, computeFingerCurl, computeHandShape, computeInstanceOverrides, computePalmPose, computePalmWidth, computePinch, computeSpread, createHandMaterial, decanonicalizeComponentValue, despawnPrefab, encodeOverride, estimateHandScale, findSnapshotRootEntityIds, findTopLevelNestedRegions, groupOverridePaths, hydrateWorldFromSnapshot, hydrateWorldFromSnapshotDetailed, indexSnapshotByEntity, instantiateSubtree, loadPrefab, matchHandPose, mergeComponentValue, parseOverride, parsePrefabAsset, prefabFileVersionFor, readXrCapabilities, restoreComponentState, restorePostCreateComponents, sampleTeleportArc, setPrefabAssetUrlResolver, spawnPrefab };
|
|
8736
|
+
//# sourceMappingURL=chunk-KLU2M43M.js.map
|
|
8737
|
+
//# sourceMappingURL=chunk-KLU2M43M.js.map
|