Files
healer-man/scripts/runewaker-pipeline/lib/source-anchor-support.mjs
T
2026-10-06 22:25:34 -04:00

36 lines
2.1 KiB
JavaScript

import { sourceTerrainToThreeMatrix } from '../sand-vortex/terrain-geometry.mjs';
import { Vector3 } from 'three';
const BOX_FACES = [
[0, 3, 2], [0, 2, 1], [4, 5, 6], [4, 6, 7],
[0, 1, 5], [0, 5, 4], [1, 2, 6], [1, 6, 5],
[2, 3, 7], [2, 7, 6], [3, 0, 4], [3, 4, 7],
];
/** Match the native ROS exporter: inverse primary TRS followed by reflected Z. */
export function sourceAnchorSupportGeometry(points, placement, {
halfExtent = 60, thickness = 3, metersPerSourceUnit = 1, omitPointIndices = [],
} = {}) {
if (!Array.isArray(points) || !Number.isFinite(halfExtent) || halfExtent <= 0
|| !Number.isFinite(thickness) || thickness <= 0) throw new Error('Invalid source-anchor support dimensions.');
const transform = sourceTerrainToThreeMatrix(placement, metersPerSourceUnit);
if (!Array.isArray(omitPointIndices) || new Set(omitPointIndices).size !== omitPointIndices.length
|| omitPointIndices.some(i => !Number.isInteger(i) || i < 0 || i >= points.length)) throw new Error('Invalid source-anchor support omissions.');
const omitted = new Set(omitPointIndices);
const faces = transform.determinant() < 0 ? BOX_FACES.map(([a, b, c]) => [a, c, b]) : BOX_FACES;
const positions = [], indices = [], navigationPositions = [];
for (const [pointIndex, point] of points.entries()) {
if (omitted.has(pointIndex)) continue;
if (!Array.isArray(point) || point.length !== 3 || !point.every(Number.isFinite)) throw new Error('Invalid source-anchor support point.');
const [x, y, z] = point, h = halfExtent;
const vertices = [[x-h,y,z-h],[x+h,y,z-h],[x+h,y,z+h],[x-h,y,z+h],
[x-h,y-thickness,z-h],[x+h,y-thickness,z-h],[x+h,y-thickness,z+h],[x-h,y-thickness,z+h]]
.map(p => new Vector3(...p).applyMatrix4(transform).toArray());
const offset = positions.length / 3;
positions.push(...vertices.flat());
for (const face of faces) indices.push(...face.map(i => offset + i));
for (const face of faces.slice(0, 2)) for (const i of face) navigationPositions.push(...vertices[i]);
}
return { positions, indices, navigationPositions };
}