Picked focus distance
32-bit in partThe distance from the camera to the clicked surface, measured along the view direction.
focus = round(−(d · view axis ÷ |view axis|) × t × 100) ÷ 100
The camera matrices are read from a Float32Array view of the header, and the triangles the ray is cast against are stored in a Float32Array by the scene packer, so the hit distance carries 32-bit inputs. The value saved and shown is rounded to 0.01 m.
function pickFocus(x, y) {
// the ray through that pixel (the pack's own camera) → the distance it travels to the first surface
const hu = new Uint32Array(pk.header), hf = new Float32Array(pk.header), ro = [0, 0, 0], rd = [0, 0, 0], hit = {};
const lens = hf[87]; hf[87] = 0; // a pinhole ray from the middle of the lens
cameraRay(hf, hu, x, y, canvas.width, canvas.height, 0, 0, 0, 0, 0, ro, rd);
hf[87] = lens;
const sc = sceneFromV2({ records: new Uint32Array(pk.nodes.buffer, pk.nodes.byteOffset, pk.nodes.length), tris: pk.tris, header: { 3: hu[3], 62: hu[62], 63: hu[63] } });
if (!sceneHit(sc, ro, rd, 1e30, hit) || !(hit.t > 0)) { status(o.t('render.ipr.focus.none')); return; }
// the distance along the view direction (the focus plane is square to it)
const fl = Math.hypot(hf[24], hf[25], hf[26]) || 1, along = -(rd[0] * hf[24] + rd[1] * hf[25] + rd[2] * hf[26]) / fl * hit.t;
const s = { ...o.settings(), dof: true, focus: Math.round(along * 100) / 100 };
o.save?.(cleanSettings(s));
status(o.t('render.ipr.focus.set', { m: (Math.round(along * 100) / 100).toString() }));
api.mode = 'view';
}