36 lines
2.3 KiB
JavaScript
36 lines
2.3 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { Matrix4, Vector3 } from 'three';
|
|
import { sourceAnchorSupportGeometry } from './source-anchor-support.mjs';
|
|
import { descriptorSourceMatrix } from './environment-assembly.mjs';
|
|
|
|
test('support OBJ and nav use the ROS reflected-Z bridge and upward floor winding', () => {
|
|
const placement = { translation: [10, 20, 30], rotation: [0, 0, 0, 1], scale: [1, 1, 1] };
|
|
const obj = sourceAnchorSupportGeometry([[12, 25, 60]], placement, { halfExtent: 1, thickness: 2 });
|
|
const nav = sourceAnchorSupportGeometry([[12, 25, 60]], placement, { halfExtent: 1, thickness: 2, metersPerSourceUnit: 0.1 });
|
|
assert.deepEqual(obj.positions.slice(0, 3), [1, 5, -29]);
|
|
assert.ok(nav.navigationPositions.every((v, i) => Math.abs(v - obj.navigationPositions[i] * 0.1) < 1e-12));
|
|
const [a, b, c] = obj.indices.slice(0, 3).map(i => new Vector3().fromArray(obj.positions, i * 3));
|
|
assert.ok(b.sub(a).cross(c.sub(a)).y > 0);
|
|
});
|
|
|
|
test('rotated nonuniform primary placements preserve the source support footprint', () => {
|
|
const placement = { translation: [10, 20, 30], rotation: [0, Math.sin(0.4), 0, Math.cos(0.4)], scale: [2, 3, 4] };
|
|
const geometry = sourceAnchorSupportGeometry([[12, 25, 60]], placement, { halfExtent: 1, thickness: 2, metersPerSourceUnit: 0.1 });
|
|
const toSource = descriptorSourceMatrix(placement).multiply(new Matrix4().makeScale(10, 10, -10));
|
|
const first = new Vector3().fromArray(geometry.positions).applyMatrix4(toSource);
|
|
assert.ok(first.distanceTo(new Vector3(11, 25, 59)) < 1e-10);
|
|
assert.equal(geometry.indices.length, 36);
|
|
assert.equal(geometry.navigationPositions.length, 18);
|
|
});
|
|
|
|
test('a reviewed native-ground omission removes the same footprint from mesh and nav', () => {
|
|
const placement = { translation: [0, 0, 0], rotation: [0, 0, 0, 1], scale: [1, 1, 1] };
|
|
const result = sourceAnchorSupportGeometry([[0, 0, 1], [20, 0, 2]], placement, { omitPointIndices: [0] });
|
|
assert.equal(result.positions.length, 24);
|
|
assert.equal(result.indices.length, 36);
|
|
assert.equal(result.navigationPositions.length, 18);
|
|
assert.ok(result.positions.filter((_, i) => i % 3 === 0).every(x => x === -40 || x === 80));
|
|
assert.throws(() => sourceAnchorSupportGeometry([[0, 0, 1]], placement, { omitPointIndices: [1] }), /omissions/);
|
|
});
|