forked from EXT/VR180-Web-Player
102 lines
3.2 KiB
JavaScript
102 lines
3.2 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import {
|
|
beginPalmAimSelection,
|
|
computePalmAimRay,
|
|
createPalmAimLatch,
|
|
endPalmAimSelection,
|
|
getPalmAimSelectionRay,
|
|
recordStablePalmAimRay
|
|
} from '../vr180player/xr/hand-aim.js';
|
|
|
|
const wrist = { x: 0, y: 0, z: 0 };
|
|
const middleMetacarpal = { x: 0, y: 0.1, z: 0 };
|
|
const ringMetacarpal = { x: 0.025, y: 0.1, z: 0 };
|
|
const straightAheadRay = {
|
|
direction: { x: 0, y: 0, z: -1 },
|
|
origin: { x: 0, y: 1.4, z: -0.04 }
|
|
};
|
|
const pinchedRay = {
|
|
direction: { x: 0.4, y: -0.2, z: -0.8 },
|
|
origin: { x: 0.04, y: 1.32, z: -0.03 }
|
|
};
|
|
|
|
test('computePalmAimRay tilts a right palm ray toward the finger-forward axis', () => {
|
|
const ray = computePalmAimRay({
|
|
handedness: 'right',
|
|
indexMetacarpal: { x: -0.045, y: 0.1, z: 0 },
|
|
middleMetacarpal: { x: -0.015, y: 0.1, z: 0 },
|
|
pinkyMetacarpal: { x: 0.045, y: 0.1, z: 0 },
|
|
ringMetacarpal: { x: 0.015, y: 0.1, z: 0 },
|
|
wrist
|
|
});
|
|
|
|
assert.ok(ray);
|
|
assert.equal(Math.round(ray.direction.x * 1000) / 1000, 0);
|
|
assert.equal(Math.round(ray.direction.y * 1000) / 1000, 0.643);
|
|
assert.equal(Math.round(ray.direction.z * 1000) / 1000, -0.766);
|
|
assert.equal(Math.round(ray.origin.y * 1000) / 1000, 0.084);
|
|
assert.equal(Math.round(ray.origin.z * 1000) / 1000, -0.027);
|
|
});
|
|
|
|
test('computePalmAimRay flips the palm normal for a left hand while keeping forward tilt', () => {
|
|
const ray = computePalmAimRay({
|
|
handedness: 'left',
|
|
indexMetacarpal: { x: 0.045, y: 0.1, z: 0 },
|
|
middleMetacarpal: { x: 0.015, y: 0.1, z: 0 },
|
|
pinkyMetacarpal: { x: -0.045, y: 0.1, z: 0 },
|
|
ringMetacarpal: { x: -0.015, y: 0.1, z: 0 },
|
|
wrist
|
|
});
|
|
|
|
assert.ok(ray);
|
|
assert.equal(Math.round(ray.direction.y * 1000) / 1000, 0.643);
|
|
assert.equal(Math.round(ray.direction.z * 1000) / 1000, -0.766);
|
|
});
|
|
|
|
test('computePalmAimRay returns null when palm joints cannot define a stable ray', () => {
|
|
assert.equal(computePalmAimRay({ handedness: 'right', wrist }), null);
|
|
assert.equal(computePalmAimRay({
|
|
handedness: 'right',
|
|
indexMetacarpal: { x: 0, y: 0.1, z: 0 },
|
|
pinkyMetacarpal: { x: 0, y: 0.1, z: 0 },
|
|
wrist
|
|
}), null);
|
|
});
|
|
|
|
test('palm aim latch returns the latest fresh stable ray', () => {
|
|
const latch = createPalmAimLatch();
|
|
|
|
recordStablePalmAimRay(latch, straightAheadRay, 100);
|
|
|
|
assert.deepEqual(getPalmAimSelectionRay(latch, 120), straightAheadRay);
|
|
assert.equal(getPalmAimSelectionRay(latch, 500), null);
|
|
});
|
|
|
|
test('palm aim latch freezes the pre-selection ray while selecting', () => {
|
|
const latch = createPalmAimLatch();
|
|
|
|
recordStablePalmAimRay(latch, straightAheadRay, 100);
|
|
assert.deepEqual(beginPalmAimSelection(latch, 120), straightAheadRay);
|
|
|
|
recordStablePalmAimRay(latch, pinchedRay, 130);
|
|
|
|
assert.deepEqual(getPalmAimSelectionRay(latch, 140), straightAheadRay);
|
|
assert.deepEqual(getPalmAimSelectionRay(latch, 1000), straightAheadRay);
|
|
|
|
endPalmAimSelection(latch);
|
|
recordStablePalmAimRay(latch, pinchedRay, 150);
|
|
|
|
assert.deepEqual(getPalmAimSelectionRay(latch, 160), pinchedRay);
|
|
});
|
|
|
|
test('palm aim latch ignores stale rays when selection starts too late', () => {
|
|
const latch = createPalmAimLatch();
|
|
|
|
recordStablePalmAimRay(latch, straightAheadRay, 100);
|
|
|
|
assert.equal(beginPalmAimSelection(latch, 450), null);
|
|
assert.equal(getPalmAimSelectionRay(latch, 450), null);
|
|
});
|