@relu-interactives/spatial-ecs 0.3.17 → 0.3.19
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-LR4EhboN.d.cts → XRHandPose-CLl4MiHx.d.cts} +24 -2
- package/dist/{XRHandPose-SZ7ou63b.d.ts → XRHandPose-CrzI57JA.d.ts} +24 -2
- package/dist/{chunk-PNQ7HDQC.js → chunk-D6KXWNYT.js} +3 -3
- package/dist/{chunk-PNQ7HDQC.js.map → chunk-D6KXWNYT.js.map} +1 -1
- package/dist/{chunk-3LDQ4GVZ.js → chunk-H6DQ7JRE.js} +51 -18
- package/dist/chunk-H6DQ7JRE.js.map +1 -0
- package/dist/{chunk-CE2CPZSP.js → chunk-JYKFLQB5.js} +155 -36
- package/dist/chunk-JYKFLQB5.js.map +1 -0
- package/dist/{chunk-UHJ4MDIM.js → chunk-P42OE3RU.js} +4 -4
- package/dist/{chunk-UHJ4MDIM.js.map → chunk-P42OE3RU.js.map} +1 -1
- package/dist/components/index.cjs +36 -10
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +3 -3
- package/dist/components/index.d.ts +3 -3
- package/dist/components/index.js +1 -1
- package/dist/docs/guide/vr-and-hand-poses.md +68 -1
- package/dist/factories/index.cjs +11 -0
- package/dist/factories/index.cjs.map +1 -1
- package/dist/factories/index.d.cts +2 -2
- package/dist/factories/index.d.ts +2 -2
- package/dist/factories/index.js +3 -3
- package/dist/{handPose-dFxqbFFY.d.cts → handPose-DlcTtqgx.d.cts} +26 -1
- package/dist/{handPose-dFxqbFFY.d.ts → handPose-DlcTtqgx.d.ts} +26 -1
- package/dist/{index-ekS4iypo.d.cts → index-3pNbH0iP.d.cts} +23 -2
- package/dist/{index-uKFxVCmr.d.ts → index-C_589fc4.d.ts} +23 -2
- package/dist/{index-ByiUoIoh.d.ts → index-JRcoel9F.d.ts} +3 -2
- package/dist/{index-BL5EWkwY.d.cts → index-g777AmFv.d.cts} +3 -2
- package/dist/index.cjs +199 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -8
- package/dist/index.d.ts +11 -8
- package/dist/index.js +8 -8
- package/dist/systems/index.cjs +190 -46
- package/dist/systems/index.cjs.map +1 -1
- package/dist/systems/index.d.cts +2 -2
- package/dist/systems/index.d.ts +2 -2
- package/dist/systems/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-3LDQ4GVZ.js.map +0 -1
- package/dist/chunk-CE2CPZSP.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -2576,6 +2576,9 @@ var _XRRigComponent = class _XRRigComponent extends Component {
|
|
|
2576
2576
|
this.snapTurn = options?.snapTurn ?? true;
|
|
2577
2577
|
this.snapTurnDegrees = options?.snapTurnDegrees ?? 30;
|
|
2578
2578
|
this.fallbackEyeHeight = options?.fallbackEyeHeight ?? 1.6;
|
|
2579
|
+
this.teleportArcColor = options?.teleportArcColor ?? "#4da3ff";
|
|
2580
|
+
this.teleportArcInvalidColor = options?.teleportArcInvalidColor ?? "#ff5a5a";
|
|
2581
|
+
this.teleportArcThickness = options?.teleportArcThickness ?? 0.012;
|
|
2579
2582
|
}
|
|
2580
2583
|
};
|
|
2581
2584
|
__name(_XRRigComponent, "XRRigComponent");
|
|
@@ -2726,15 +2729,22 @@ function getHandPosePreset(id) {
|
|
|
2726
2729
|
return cloneHandPose(preset);
|
|
2727
2730
|
}
|
|
2728
2731
|
__name(getHandPosePreset, "getHandPosePreset");
|
|
2732
|
+
function cloneTarget(target) {
|
|
2733
|
+
return {
|
|
2734
|
+
...target,
|
|
2735
|
+
...target.directions ? { directions: [...target.directions] } : {}
|
|
2736
|
+
};
|
|
2737
|
+
}
|
|
2738
|
+
__name(cloneTarget, "cloneTarget");
|
|
2729
2739
|
function cloneHandPose(definition) {
|
|
2730
2740
|
return {
|
|
2731
2741
|
...definition,
|
|
2732
2742
|
fingers: {
|
|
2733
|
-
thumb:
|
|
2734
|
-
index:
|
|
2735
|
-
middle:
|
|
2736
|
-
ring:
|
|
2737
|
-
pinky:
|
|
2743
|
+
thumb: cloneTarget(definition.fingers.thumb),
|
|
2744
|
+
index: cloneTarget(definition.fingers.index),
|
|
2745
|
+
middle: cloneTarget(definition.fingers.middle),
|
|
2746
|
+
ring: cloneTarget(definition.fingers.ring),
|
|
2747
|
+
pinky: cloneTarget(definition.fingers.pinky)
|
|
2738
2748
|
},
|
|
2739
2749
|
pinch: definition.pinch ? { ...definition.pinch } : void 0,
|
|
2740
2750
|
orientation: definition.orientation ? { ...definition.orientation } : void 0
|
|
@@ -2743,22 +2753,27 @@ function cloneHandPose(definition) {
|
|
|
2743
2753
|
__name(cloneHandPose, "cloneHandPose");
|
|
2744
2754
|
function handPoseFromCurls(id, name, curls, options) {
|
|
2745
2755
|
const tolerance = options?.tolerance ?? NARROW;
|
|
2746
|
-
const target = /* @__PURE__ */ __name((curl) =>
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2756
|
+
const target = /* @__PURE__ */ __name((finger, curl) => {
|
|
2757
|
+
const directions = options?.directions?.[finger];
|
|
2758
|
+
return {
|
|
2759
|
+
curl: Math.min(1, Math.max(0, curl)),
|
|
2760
|
+
tolerance,
|
|
2761
|
+
...directions && directions.length > 0 ? { directions } : {}
|
|
2762
|
+
};
|
|
2763
|
+
}, "target");
|
|
2750
2764
|
return {
|
|
2751
2765
|
id,
|
|
2752
2766
|
name,
|
|
2753
2767
|
fingers: {
|
|
2754
|
-
thumb: target(curls.thumb),
|
|
2755
|
-
index: target(curls.index),
|
|
2756
|
-
middle: target(curls.middle),
|
|
2757
|
-
ring: target(curls.ring),
|
|
2758
|
-
pinky: target(curls.pinky)
|
|
2768
|
+
thumb: target("thumb", curls.thumb),
|
|
2769
|
+
index: target("index", curls.index),
|
|
2770
|
+
middle: target("middle", curls.middle),
|
|
2771
|
+
ring: target("ring", curls.ring),
|
|
2772
|
+
pinky: target("pinky", curls.pinky)
|
|
2759
2773
|
},
|
|
2760
2774
|
pinch: options?.pinch,
|
|
2761
2775
|
orientation: options?.orientation,
|
|
2776
|
+
directionToleranceDegrees: options?.directionToleranceDegrees,
|
|
2762
2777
|
hand: options?.hand
|
|
2763
2778
|
};
|
|
2764
2779
|
}
|
|
@@ -2772,6 +2787,13 @@ var DEFAULT_POSE_CURLS = {
|
|
|
2772
2787
|
ring: 0,
|
|
2773
2788
|
pinky: 0
|
|
2774
2789
|
};
|
|
2790
|
+
var DEFAULT_POSE_DIRECTIONS = {
|
|
2791
|
+
thumb: [],
|
|
2792
|
+
index: [],
|
|
2793
|
+
middle: [],
|
|
2794
|
+
ring: [],
|
|
2795
|
+
pinky: []
|
|
2796
|
+
};
|
|
2775
2797
|
function createHandPoseEntry(partial) {
|
|
2776
2798
|
return {
|
|
2777
2799
|
id: partial.id,
|
|
@@ -2779,6 +2801,14 @@ function createHandPoseEntry(partial) {
|
|
|
2779
2801
|
preset: partial.preset ?? null,
|
|
2780
2802
|
curls: { ...DEFAULT_POSE_CURLS, ...partial.curls },
|
|
2781
2803
|
tolerance: partial.tolerance ?? 0.25,
|
|
2804
|
+
directions: {
|
|
2805
|
+
thumb: [...partial.directions?.thumb ?? []],
|
|
2806
|
+
index: [...partial.directions?.index ?? []],
|
|
2807
|
+
middle: [...partial.directions?.middle ?? []],
|
|
2808
|
+
ring: [...partial.directions?.ring ?? []],
|
|
2809
|
+
pinky: [...partial.directions?.pinky ?? []]
|
|
2810
|
+
},
|
|
2811
|
+
directionTolerance: partial.directionTolerance ?? 45,
|
|
2782
2812
|
hand: partial.hand ?? null,
|
|
2783
2813
|
orientation: partial.orientation ?? null,
|
|
2784
2814
|
minHoldSeconds: partial.minHoldSeconds ?? 0.15,
|
|
@@ -2801,7 +2831,9 @@ function handPoseDefinitionFor(entry, resolvePreset) {
|
|
|
2801
2831
|
return handPoseFromCurls(entry.id, entry.name, entry.curls, {
|
|
2802
2832
|
tolerance: entry.tolerance,
|
|
2803
2833
|
orientation: entry.orientation ?? void 0,
|
|
2804
|
-
hand: entry.hand ?? void 0
|
|
2834
|
+
hand: entry.hand ?? void 0,
|
|
2835
|
+
directions: entry.directions,
|
|
2836
|
+
directionToleranceDegrees: entry.directionTolerance
|
|
2805
2837
|
});
|
|
2806
2838
|
}
|
|
2807
2839
|
__name(handPoseDefinitionFor, "handPoseDefinitionFor");
|
|
@@ -3957,6 +3989,7 @@ __export(components_exports, {
|
|
|
3957
3989
|
DEFAULT_MESH_GEOMETRY_PARAMETERS: () => DEFAULT_MESH_GEOMETRY_PARAMETERS,
|
|
3958
3990
|
DEFAULT_PHYSICS_STATE: () => DEFAULT_PHYSICS_STATE,
|
|
3959
3991
|
DEFAULT_POSE_CURLS: () => DEFAULT_POSE_CURLS,
|
|
3992
|
+
DEFAULT_POSE_DIRECTIONS: () => DEFAULT_POSE_DIRECTIONS,
|
|
3960
3993
|
DEFAULT_POSTPROCESSING_STATE: () => DEFAULT_POSTPROCESSING_STATE,
|
|
3961
3994
|
DEFAULT_RIGIDBODY_STATE: () => DEFAULT_RIGIDBODY_STATE,
|
|
3962
3995
|
EntityType: () => EntityType,
|
|
@@ -4831,6 +4864,15 @@ function restorePostCreateComponents(world, objectManagementSystem, targetEntity
|
|
|
4831
4864
|
if (typeof sourceXrRig.snapTurnDegrees === "number") {
|
|
4832
4865
|
rig.snapTurnDegrees = sourceXrRig.snapTurnDegrees;
|
|
4833
4866
|
}
|
|
4867
|
+
if (typeof sourceXrRig.teleportArcColor === "string") {
|
|
4868
|
+
rig.teleportArcColor = sourceXrRig.teleportArcColor;
|
|
4869
|
+
}
|
|
4870
|
+
if (typeof sourceXrRig.teleportArcInvalidColor === "string") {
|
|
4871
|
+
rig.teleportArcInvalidColor = sourceXrRig.teleportArcInvalidColor;
|
|
4872
|
+
}
|
|
4873
|
+
if (typeof sourceXrRig.teleportArcThickness === "number") {
|
|
4874
|
+
rig.teleportArcThickness = sourceXrRig.teleportArcThickness;
|
|
4875
|
+
}
|
|
4834
4876
|
if (typeof sourceXrRig.fallbackEyeHeight === "number") {
|
|
4835
4877
|
rig.fallbackEyeHeight = sourceXrRig.fallbackEyeHeight;
|
|
4836
4878
|
}
|
|
@@ -12625,24 +12667,33 @@ __name(_XRControllerVisualSystem, "XRControllerVisualSystem");
|
|
|
12625
12667
|
var XRControllerVisualSystem = _XRControllerVisualSystem;
|
|
12626
12668
|
var MARKER_RADIUS = 0.28;
|
|
12627
12669
|
var ACCENT = new THREE51__namespace.Color("#4da3ff");
|
|
12628
|
-
var
|
|
12670
|
+
var SEGMENT_AXIS = new THREE51__namespace.Vector3(0, 1, 0);
|
|
12671
|
+
var HEAD_CLEARANCE = 0.25;
|
|
12629
12672
|
var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
12630
12673
|
constructor(locomotionSystem) {
|
|
12631
12674
|
this.group = new THREE51__namespace.Group();
|
|
12632
|
-
|
|
12675
|
+
/** Holds the segment chain that draws the arc. */
|
|
12676
|
+
this.arc = new THREE51__namespace.Group();
|
|
12677
|
+
/**
|
|
12678
|
+
* Unit cylinder along +Y, reused by every segment.
|
|
12679
|
+
*
|
|
12680
|
+
* The arc was a `THREE.Line`, which WebGL always renders one pixel wide —
|
|
12681
|
+
* effectively invisible on a headset, and not thickenable at all. A chain of
|
|
12682
|
+
* scaled cylinders gives real thickness while rebuilding no geometry: each
|
|
12683
|
+
* frame only moves, rotates and scales meshes that already exist.
|
|
12684
|
+
*/
|
|
12685
|
+
this.segmentGeometry = new THREE51__namespace.CylinderGeometry(1, 1, 1, 6, 1);
|
|
12686
|
+
this.segments = [];
|
|
12633
12687
|
this.marker = new THREE51__namespace.Group();
|
|
12634
12688
|
this.attached = false;
|
|
12689
|
+
this.scratchDirection = new THREE51__namespace.Vector3();
|
|
12690
|
+
this.scratchHead = new THREE51__namespace.Vector3();
|
|
12691
|
+
this.validColor = new THREE51__namespace.Color();
|
|
12692
|
+
this.invalidColor = new THREE51__namespace.Color();
|
|
12635
12693
|
this.locomotionSystem = locomotionSystem;
|
|
12636
12694
|
this.group.name = "XRTeleportVisuals";
|
|
12637
12695
|
this.group.userData.ecsPreviewHidden = true;
|
|
12638
|
-
|
|
12639
|
-
vertexColors: true,
|
|
12640
|
-
transparent: true,
|
|
12641
|
-
depthTest: false
|
|
12642
|
-
});
|
|
12643
|
-
this.arc = new THREE51__namespace.Line(this.arcGeometry, arcMaterial);
|
|
12644
|
-
this.arc.frustumCulled = false;
|
|
12645
|
-
this.arc.renderOrder = 998;
|
|
12696
|
+
this.arc.name = "XRTeleportArc";
|
|
12646
12697
|
this.group.add(this.arc);
|
|
12647
12698
|
this.marker.add(this.createRing(), this.createDot());
|
|
12648
12699
|
this.marker.renderOrder = 999;
|
|
@@ -12654,15 +12705,27 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
12654
12705
|
world.getScene().add(this.group);
|
|
12655
12706
|
this.attached = true;
|
|
12656
12707
|
}
|
|
12657
|
-
const
|
|
12708
|
+
const raw = this.locomotionSystem.getAimCurve();
|
|
12658
12709
|
const landing = this.locomotionSystem.getLandingPoint();
|
|
12659
12710
|
const valid = this.locomotionSystem.isAimValid();
|
|
12711
|
+
if (raw.length < 2) {
|
|
12712
|
+
this.setVisible(false);
|
|
12713
|
+
return;
|
|
12714
|
+
}
|
|
12715
|
+
const curve = this.trimNearHead(world, raw);
|
|
12660
12716
|
if (curve.length < 2) {
|
|
12661
12717
|
this.setVisible(false);
|
|
12662
12718
|
return;
|
|
12663
12719
|
}
|
|
12664
|
-
this.
|
|
12720
|
+
const rig = this.resolveRig(world);
|
|
12721
|
+
const thickness = Math.min(
|
|
12722
|
+
0.1,
|
|
12723
|
+
Math.max(1e-3, rig?.teleportArcThickness ?? 0.012)
|
|
12724
|
+
);
|
|
12725
|
+
const tint = valid ? this.validColor.set(rig?.teleportArcColor ?? "#4da3ff") : this.invalidColor.set(rig?.teleportArcInvalidColor ?? "#ff5a5a");
|
|
12726
|
+
this.updateArcGeometry(curve, tint, thickness);
|
|
12665
12727
|
if (valid && landing) {
|
|
12728
|
+
this.tintMarker(tint);
|
|
12666
12729
|
this.marker.position.copy(landing);
|
|
12667
12730
|
this.marker.position.y += 0.01;
|
|
12668
12731
|
this.marker.visible = true;
|
|
@@ -12671,27 +12734,66 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
12671
12734
|
}
|
|
12672
12735
|
this.setVisible(true);
|
|
12673
12736
|
}
|
|
12674
|
-
updateArcGeometry(curve, tint) {
|
|
12675
|
-
const
|
|
12676
|
-
|
|
12677
|
-
const
|
|
12678
|
-
for (let i = 0; i <
|
|
12679
|
-
const
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12737
|
+
updateArcGeometry(curve, tint, thickness) {
|
|
12738
|
+
const needed = curve.length - 1;
|
|
12739
|
+
this.ensureSegments(needed);
|
|
12740
|
+
const radius = thickness / 2;
|
|
12741
|
+
for (let i = 0; i < this.segments.length; i += 1) {
|
|
12742
|
+
const segment = this.segments[i];
|
|
12743
|
+
if (i >= needed) {
|
|
12744
|
+
segment.visible = false;
|
|
12745
|
+
continue;
|
|
12746
|
+
}
|
|
12747
|
+
const from = curve[i];
|
|
12748
|
+
const to = curve[i + 1];
|
|
12749
|
+
this.scratchDirection.subVectors(to, from);
|
|
12750
|
+
const length = this.scratchDirection.length();
|
|
12751
|
+
if (length < 1e-6) {
|
|
12752
|
+
segment.visible = false;
|
|
12753
|
+
continue;
|
|
12754
|
+
}
|
|
12755
|
+
segment.visible = true;
|
|
12756
|
+
segment.position.copy(from).addScaledVector(this.scratchDirection, 0.5);
|
|
12757
|
+
segment.quaternion.setFromUnitVectors(
|
|
12758
|
+
SEGMENT_AXIS,
|
|
12759
|
+
this.scratchDirection.divideScalar(length)
|
|
12760
|
+
);
|
|
12761
|
+
segment.scale.set(radius, length, radius);
|
|
12762
|
+
const t = needed > 1 ? i / (needed - 1) : 0;
|
|
12684
12763
|
const fade = 1 - t * 0.75;
|
|
12685
|
-
|
|
12686
|
-
|
|
12687
|
-
|
|
12764
|
+
segment.material.color.copy(tint).multiplyScalar(fade);
|
|
12765
|
+
}
|
|
12766
|
+
}
|
|
12767
|
+
/** Grow the segment pool to cover the current arc. */
|
|
12768
|
+
ensureSegments(count) {
|
|
12769
|
+
while (this.segments.length < count) {
|
|
12770
|
+
const material = new THREE51__namespace.MeshBasicMaterial({
|
|
12771
|
+
transparent: true,
|
|
12772
|
+
depthTest: false,
|
|
12773
|
+
depthWrite: false
|
|
12774
|
+
});
|
|
12775
|
+
const mesh = new THREE51__namespace.Mesh(this.segmentGeometry, material);
|
|
12776
|
+
mesh.frustumCulled = false;
|
|
12777
|
+
mesh.renderOrder = 998;
|
|
12778
|
+
mesh.raycast = () => {
|
|
12779
|
+
};
|
|
12780
|
+
this.segments.push(mesh);
|
|
12781
|
+
this.arc.add(mesh);
|
|
12688
12782
|
}
|
|
12689
|
-
|
|
12690
|
-
|
|
12691
|
-
|
|
12692
|
-
);
|
|
12693
|
-
|
|
12694
|
-
|
|
12783
|
+
}
|
|
12784
|
+
/** Drop leading points that sit too close to the viewer's head. */
|
|
12785
|
+
trimNearHead(world, curve) {
|
|
12786
|
+
world.getCamera().getWorldPosition(this.scratchHead);
|
|
12787
|
+
let start = 0;
|
|
12788
|
+
while (start < curve.length - 2 && curve[start].distanceTo(this.scratchHead) < HEAD_CLEARANCE) {
|
|
12789
|
+
start += 1;
|
|
12790
|
+
}
|
|
12791
|
+
return start === 0 ? curve : curve.slice(start);
|
|
12792
|
+
}
|
|
12793
|
+
resolveRig(world) {
|
|
12794
|
+
const entityId = world.query(XRRigComponent)[0];
|
|
12795
|
+
if (typeof entityId !== "number") return null;
|
|
12796
|
+
return world.getComponent(entityId, XRRigComponent) ?? null;
|
|
12695
12797
|
}
|
|
12696
12798
|
createRing() {
|
|
12697
12799
|
const geometry = new THREE51__namespace.RingGeometry(
|
|
@@ -12725,6 +12827,15 @@ var _XRTeleportVisualSystem = class _XRTeleportVisualSystem {
|
|
|
12725
12827
|
})
|
|
12726
12828
|
);
|
|
12727
12829
|
}
|
|
12830
|
+
/** Recolour the landing marker to match the arc. */
|
|
12831
|
+
tintMarker(color) {
|
|
12832
|
+
this.marker.traverse((child) => {
|
|
12833
|
+
const material = child.material;
|
|
12834
|
+
if (material && !Array.isArray(material)) {
|
|
12835
|
+
material.color?.copy(color);
|
|
12836
|
+
}
|
|
12837
|
+
});
|
|
12838
|
+
}
|
|
12728
12839
|
setVisible(visible) {
|
|
12729
12840
|
this.group.visible = visible;
|
|
12730
12841
|
}
|
|
@@ -12951,10 +13062,22 @@ function computeHandShape(joints, handedness) {
|
|
|
12951
13062
|
const direction = new THREE51__namespace.Vector3().subVectors(thumbTip, thumbBase);
|
|
12952
13063
|
if (direction.lengthSq() > 1e-12) thumbDirection = direction.normalize();
|
|
12953
13064
|
}
|
|
13065
|
+
const fingerDirections = {};
|
|
13066
|
+
for (const finger of XR_FINGERS) {
|
|
13067
|
+
const base = joints[METACARPAL_JOINTS[finger]];
|
|
13068
|
+
const tip = joints[TIP_JOINTS[finger]];
|
|
13069
|
+
if (!base || !tip) {
|
|
13070
|
+
fingerDirections[finger] = null;
|
|
13071
|
+
continue;
|
|
13072
|
+
}
|
|
13073
|
+
const direction = new THREE51__namespace.Vector3().subVectors(tip, base);
|
|
13074
|
+
fingerDirections[finger] = direction.lengthSq() > 1e-12 ? direction.normalize() : null;
|
|
13075
|
+
}
|
|
12954
13076
|
return {
|
|
12955
13077
|
handedness,
|
|
12956
13078
|
fingers: fingers2,
|
|
12957
13079
|
pinch,
|
|
13080
|
+
fingerDirections,
|
|
12958
13081
|
spread: {
|
|
12959
13082
|
thumbIndex: computeSpread(joints, "thumb", "index") ?? 0,
|
|
12960
13083
|
indexMiddle: computeSpread(joints, "index", "middle") ?? 0,
|
|
@@ -12979,6 +13102,7 @@ function scoreAgainst(actual, target, tolerance) {
|
|
|
12979
13102
|
return clamp01(1 - (error - tolerance) / MATCH_FALLOFF);
|
|
12980
13103
|
}
|
|
12981
13104
|
__name(scoreAgainst, "scoreAgainst");
|
|
13105
|
+
var DEFAULT_DIRECTION_TOLERANCE = 45;
|
|
12982
13106
|
var WORLD_DIRECTIONS = {
|
|
12983
13107
|
up: new THREE51__namespace.Vector3(0, 1, 0),
|
|
12984
13108
|
down: new THREE51__namespace.Vector3(0, -1, 0),
|
|
@@ -13006,6 +13130,22 @@ function resolveDirection(direction, shape, context) {
|
|
|
13006
13130
|
return direction === "toward-head" ? toHead : toHead.multiplyScalar(-1);
|
|
13007
13131
|
}
|
|
13008
13132
|
__name(resolveDirection, "resolveDirection");
|
|
13133
|
+
function scoreDirections(actual, accepted, shape, toleranceDegrees, context) {
|
|
13134
|
+
if (!actual) return 0;
|
|
13135
|
+
let best = 0;
|
|
13136
|
+
for (const direction of accepted) {
|
|
13137
|
+
const wanted = resolveDirection(direction, shape, context);
|
|
13138
|
+
if (!wanted) continue;
|
|
13139
|
+
const angle = THREE51__namespace.MathUtils.radToDeg(
|
|
13140
|
+
Math.acos(THREE51__namespace.MathUtils.clamp(actual.dot(wanted), -1, 1))
|
|
13141
|
+
);
|
|
13142
|
+
const normalizedError = Math.max(0, angle - toleranceDegrees) / 90;
|
|
13143
|
+
const score = clamp01(1 - normalizedError / MATCH_FALLOFF);
|
|
13144
|
+
if (score > best) best = score;
|
|
13145
|
+
}
|
|
13146
|
+
return best;
|
|
13147
|
+
}
|
|
13148
|
+
__name(scoreDirections, "scoreDirections");
|
|
13009
13149
|
function matchHandPose(shape, definition, context) {
|
|
13010
13150
|
if (definition.hand && definition.hand !== shape.handedness) return NO_MATCH;
|
|
13011
13151
|
let confidence = 1;
|
|
@@ -13035,6 +13175,18 @@ function matchHandPose(shape, definition, context) {
|
|
|
13035
13175
|
`${finger} tip`
|
|
13036
13176
|
);
|
|
13037
13177
|
}
|
|
13178
|
+
if (target.directions && target.directions.length > 0) {
|
|
13179
|
+
consider(
|
|
13180
|
+
scoreDirections(
|
|
13181
|
+
shape.fingerDirections[finger],
|
|
13182
|
+
target.directions,
|
|
13183
|
+
shape,
|
|
13184
|
+
definition.directionToleranceDegrees ?? DEFAULT_DIRECTION_TOLERANCE,
|
|
13185
|
+
context
|
|
13186
|
+
),
|
|
13187
|
+
`${finger} direction`
|
|
13188
|
+
);
|
|
13189
|
+
}
|
|
13038
13190
|
}
|
|
13039
13191
|
if (definition.pinch) {
|
|
13040
13192
|
const { finger, target, tolerance } = definition.pinch;
|
|
@@ -14783,6 +14935,7 @@ exports.CURLED_COS = CURLED_COS;
|
|
|
14783
14935
|
exports.CameraSyncSystem = CameraSyncSystem;
|
|
14784
14936
|
exports.Component = Component;
|
|
14785
14937
|
exports.CoreComponents = components_exports;
|
|
14938
|
+
exports.DEFAULT_DIRECTION_TOLERANCE = DEFAULT_DIRECTION_TOLERANCE;
|
|
14786
14939
|
exports.DEFAULT_ENTER_CONFIDENCE = DEFAULT_ENTER_CONFIDENCE;
|
|
14787
14940
|
exports.DEFAULT_EXIT_CONFIDENCE = DEFAULT_EXIT_CONFIDENCE;
|
|
14788
14941
|
exports.DEFAULT_LOST_GRACE_SECONDS = DEFAULT_LOST_GRACE_SECONDS;
|