Add pressure-aware worker sculpting, bounded shared input, project files and history, and compact icon navigation with an XYZ orbit gizmo. Amp-Thread-ID: https://ampcode.com/threads/T-01a0b4b4-202c-73f1-984d-9a55c88f9c83 Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
31 lines
1.2 KiB
JavaScript
31 lines
1.2 KiB
JavaScript
export const add = (a, b) => a.map((v, i) => v + b[i]);
|
|
export const sub = (a, b) => a.map((v, i) => v - b[i]);
|
|
export const mul = (a, s) => a.map((v) => v * s);
|
|
export const dot = (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
export const cross = (a, b) => [
|
|
a[1] * b[2] - a[2] * b[1],
|
|
a[2] * b[0] - a[0] * b[2],
|
|
a[0] * b[1] - a[1] * b[0],
|
|
];
|
|
export const unit = (a) => mul(a, 1 / (Math.hypot(...a) || 1));
|
|
export const point = (p, i) => Array.from(p.subarray(i * 3, i * 3 + 3));
|
|
export const clamp = (n, a, b) => Math.max(a, Math.min(b, n));
|
|
|
|
// Bound apparent scale along the viewport's shorter side, in either orientation.
|
|
export function clampZoom(zoom, rect) {
|
|
const scale = Math.min(1, rect.width / rect.height);
|
|
return clamp(zoom * scale, 0.2, 14) / scale;
|
|
}
|
|
|
|
// Orthographic camera: the same basis drives rendering, rays and grab planes.
|
|
export function cameraBasis(yaw, pitch) {
|
|
const forward = [
|
|
Math.sin(yaw) * Math.cos(pitch),
|
|
Math.sin(pitch),
|
|
Math.cos(yaw) * Math.cos(pitch),
|
|
];
|
|
// Analytic basis remains defined at the top/bottom cardinal views.
|
|
const right = [Math.cos(yaw), 0, -Math.sin(yaw)];
|
|
return { right, up: cross(forward, right), forward };
|
|
}
|