@weasel-js/kernel3d 1.11.1 → 1.13.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/index.d.ts +41 -5
- package/dist/index.js +228 -51
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -73,6 +73,16 @@ carries a unit cube by the pose; override it when a primitive knows better. A
|
|
|
73
73
|
sphere is the case that forces the seam to be shaped this way — its box is the
|
|
74
74
|
same under every rotation, and no transform of a local box reproduces that.
|
|
75
75
|
|
|
76
|
+
## Aims
|
|
77
|
+
|
|
78
|
+
A kernel3d viewport answers core's `ViewAim` contract, so a 2D view and a 3D
|
|
79
|
+
pane can mark each other. `aimOf3d(viewport, viewId)` is the `Aim3d` its camera
|
|
80
|
+
sees, whose extent is a `Frustum3d`: the eye and the near and far rectangles.
|
|
81
|
+
Outlined in a 3D space it draws its far rectangle; in a 2D one, its footprint on
|
|
82
|
+
z = 0, or nothing when any corner ray misses that plane. `aimSpace3d` makes a
|
|
83
|
+
pane a target, unprojecting onto z = 0, and `cameraOfAim3d` gives back the camera
|
|
84
|
+
a dragged aim stands for — what an `AimSource`'s `setAim` writes.
|
|
85
|
+
|
|
76
86
|
## Math
|
|
77
87
|
|
|
78
88
|
Vectors, quaternions, 4×4 matrices and ray intersection live in
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Vec3, Mat4, Quat, Aabb, Ray } from '@weasel-js/geom/3d';
|
|
2
|
-
import { SceneNode, Scene, SnapSource, SnapOutcomeStore,
|
|
2
|
+
import { SceneNode, Scene, NodeId, SnapSource, SnapOutcomeStore, AreaSelectDep, NodeAtPointDep, PoseDescriptor, SnapDep, InsertExtras, InsertDep, ViewAim, AimSpace, SnapMark, OngoingHandle, Action, Tool } from '@weasel-js/core';
|
|
3
3
|
import { KitSettingsStore } from '@weasel-js/react';
|
|
4
4
|
import * as _weasel_js_prefs from '@weasel-js/prefs';
|
|
5
5
|
|
|
@@ -210,6 +210,9 @@ type Node3d<TData, TLayer extends string> = SceneNode<TData, TLayer, Pose3>;
|
|
|
210
210
|
* box reproduces that — rotate a cube and it widens.
|
|
211
211
|
*
|
|
212
212
|
* Omitted, a node is a unit cube carried by its pose.
|
|
213
|
+
*
|
|
214
|
+
* A function of the node alone; a result that depends on anything else must
|
|
215
|
+
* come with a scene change, or picks go stale.
|
|
213
216
|
*/
|
|
214
217
|
type NodeBounds<TData, TLayer extends string> = (node: Node3d<TData, TLayer>) => Aabb;
|
|
215
218
|
/** What every 3D dep is built from: the scene, the viewport, and optionally
|
|
@@ -222,6 +225,16 @@ interface World3d<TData, TLayer extends string> {
|
|
|
222
225
|
up?: Vec3;
|
|
223
226
|
}
|
|
224
227
|
|
|
228
|
+
/**
|
|
229
|
+
* The 3D world's pick index: one BVH over every node's world box, rebuilt
|
|
230
|
+
* whole on the first pick after the scene, its overrides or the world's
|
|
231
|
+
* `bounds` function can have changed. A node whose box the tree refuses
|
|
232
|
+
* (non-finite or inverted) is tested on every pick, the way the scan did.
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
/** The screen box a node covers, or null when it projects to nothing visible. */
|
|
236
|
+
declare function screenBoxOf<TData, TLayer extends string>(world: World3d<TData, TLayer>, id: NodeId, viewport: Viewport3d): ScreenBox | null;
|
|
237
|
+
|
|
225
238
|
/**
|
|
226
239
|
* The kit's deps, implemented against a 3D world.
|
|
227
240
|
*
|
|
@@ -230,8 +243,6 @@ interface World3d<TData, TLayer extends string> {
|
|
|
230
243
|
* something in 3D is the camera each dep already closes over.
|
|
231
244
|
*/
|
|
232
245
|
|
|
233
|
-
/** The screen box a node covers, or null when it projects to nothing visible. */
|
|
234
|
-
declare function screenBoxOf<TData, TLayer extends string>(world: World3d<TData, TLayer>, id: NodeId, viewport: Viewport3d): ScreenBox | null;
|
|
235
246
|
/**
|
|
236
247
|
* Nearest node along the ray the screen point names.
|
|
237
248
|
*
|
|
@@ -240,7 +251,7 @@ declare function screenBoxOf<TData, TLayer extends string>(world: World3d<TData,
|
|
|
240
251
|
* point, which is exactly what a ray needs.
|
|
241
252
|
*/
|
|
242
253
|
declare function createNodeAtPoint<TData, TLayer extends string>(world: World3d<TData, TLayer>): NodeAtPointDep;
|
|
243
|
-
/** Marquee: the nodes whose projected box the screen rectangle touches. */
|
|
254
|
+
/** Marquee: the nodes whose projected box the screen rectangle touches, in render order. */
|
|
244
255
|
declare function createAreaSelect<TData, TLayer extends string>(world: World3d<TData, TLayer>, selection: {
|
|
245
256
|
get(): readonly NodeId[];
|
|
246
257
|
set(ids: NodeId[]): void;
|
|
@@ -308,6 +319,31 @@ declare function createInsert(opts: {
|
|
|
308
319
|
mint(footprint: Footprint, extras: InsertExtras): NodeId | null;
|
|
309
320
|
}): InsertDep;
|
|
310
321
|
|
|
322
|
+
/**
|
|
323
|
+
* A kernel3d viewport as a view aim: the frustum its camera shows, drawn into
|
|
324
|
+
* any target view, and the pane itself as a target. Core's aim contract names
|
|
325
|
+
* no 3D type, so this is the side that knows the camera.
|
|
326
|
+
*/
|
|
327
|
+
|
|
328
|
+
type Quad = readonly [Vec3, Vec3, Vec3, Vec3];
|
|
329
|
+
/** The frustum a camera shows: its eye, and its near and far rectangles, corners clockwise from the top-left as seen. */
|
|
330
|
+
interface Frustum3d {
|
|
331
|
+
eye: Vec3;
|
|
332
|
+
near: Quad;
|
|
333
|
+
far: Quad;
|
|
334
|
+
}
|
|
335
|
+
/** A kernel3d view's aim: the frustum its camera sees, with the viewport it was read from. */
|
|
336
|
+
type Aim3d = ViewAim<Frustum3d> & {
|
|
337
|
+
readonly kind: 'frustum';
|
|
338
|
+
readonly viewport: Viewport3d;
|
|
339
|
+
};
|
|
340
|
+
/** The aim of view `viewId` (`null`: a surface's root): the frustum `viewport`'s camera sees. */
|
|
341
|
+
declare function aimOf3d(viewport: Viewport3d, viewId: string | null): Aim3d;
|
|
342
|
+
/** A 3D pane as a target. It projects through `projectPoint` and unprojects onto the plane z = 0, where 2D worlds lie. */
|
|
343
|
+
declare function aimSpace3d(viewport: Viewport3d, viewId: string | null): AimSpace;
|
|
344
|
+
/** The camera an aim was read from, which is what a by-value source's writer sets. */
|
|
345
|
+
declare function cameraOfAim3d(aim: Aim3d): Camera3d;
|
|
346
|
+
|
|
311
347
|
/** What a 3D scene offers a snap session: its boxes' corners, edges, faces
|
|
312
348
|
* and centers, the planes through their sides and centers, and a grid on
|
|
313
349
|
* the ground. */
|
|
@@ -480,4 +516,4 @@ declare const kernel3dKitSettingsSchema: Omit<_weasel_js_prefs.PrefGroup, "child
|
|
|
480
516
|
};
|
|
481
517
|
};
|
|
482
518
|
|
|
483
|
-
export { type Camera3d, type Camera3dDep, type ChromeBox, DEFAULT_ORBIT_LIMITS, type Footprint, type GroundGridSourceOptions, MAX_PITCH, type Node3d, type NodeBounds, type Orbit3dKitSettings, type OrbitLimits, type Pose3, type Scene3d, type ScreenBox, type ScreenLine, type ScreenPoint, type Snap3dOptions, UNIT_CUBE, type Viewport3d, type ViewportSource, type World3d, aabbOfPose, alignPlaneSource, boxSnapSource, cameraEye, cameraView, cameraViewProjection, clampCamera, collectOverlayBoxes, createAreaSelect, createCamera, createInsert, createNodeAtPoint, createPoseDescriptor, createSnap, dollyAction, dollyBy, dollyToward, groundGridSource, homeAction, kernel3dKitSettingsSchema, ndcToScreen, orbitAction, orbitBy, panAction, panBy, pinchDollyAction, pose3, poseMatrix, projectAabbToScreen, projectPoint, projectSnapMarks, rayThroughScreenPoint, screenBoxOf, screenToNdc, useOrbitTool };
|
|
519
|
+
export { type Aim3d, type Camera3d, type Camera3dDep, type ChromeBox, DEFAULT_ORBIT_LIMITS, type Footprint, type Frustum3d, type GroundGridSourceOptions, MAX_PITCH, type Node3d, type NodeBounds, type Orbit3dKitSettings, type OrbitLimits, type Pose3, type Scene3d, type ScreenBox, type ScreenLine, type ScreenPoint, type Snap3dOptions, UNIT_CUBE, type Viewport3d, type ViewportSource, type World3d, aabbOfPose, aimOf3d, aimSpace3d, alignPlaneSource, boxSnapSource, cameraEye, cameraOfAim3d, cameraView, cameraViewProjection, clampCamera, collectOverlayBoxes, createAreaSelect, createCamera, createInsert, createNodeAtPoint, createPoseDescriptor, createSnap, dollyAction, dollyBy, dollyToward, groundGridSource, homeAction, kernel3dKitSettingsSchema, ndcToScreen, orbitAction, orbitBy, panAction, panBy, pinchDollyAction, pose3, poseMatrix, projectAabbToScreen, projectPoint, projectSnapMarks, rayThroughScreenPoint, screenBoxOf, screenToNdc, useOrbitTool };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { lookAt, multiply, perspective, add, scale, quatIdentity, compose, transformAabb, invert, transformPoint, normalize, sub, transformPoint4,
|
|
1
|
+
import { lookAt, multiply, perspective, add, scale, quatIdentity, compose, transformAabb, invert, transformPoint, normalize, sub, transformPoint4, distance, dot, len, intersectRayPlane, pointOnRay, cross, intersectRayAabb, aabbOfPoints } from '@weasel-js/geom/3d';
|
|
2
2
|
import { createSnapOutcomeStore, assertSnapSourceIds, DEFAULT_SNAP_PX, overlaysOf, resolveOverlays, defineTool, snapSourcesFor, resolvedSnapMarks, SNAP_AXIS_STEP, gatherSnapCandidates } from '@weasel-js/core';
|
|
3
3
|
import { isDev } from '@weasel-js/react';
|
|
4
|
-
import { closestOnFlat, resolveSnap, stepLine } from '@weasel-js/geom/nd';
|
|
4
|
+
import { closestOnFlat, resolveSnap, createBvh, stepLine } from '@weasel-js/geom/nd';
|
|
5
5
|
import { useMemo } from 'react';
|
|
6
6
|
import { pref } from '@weasel-js/prefs';
|
|
7
7
|
|
|
@@ -85,8 +85,8 @@ var UNIT_CUBE = {
|
|
|
85
85
|
min: { x: -0.5, y: -0.5, z: -0.5 },
|
|
86
86
|
max: { x: 0.5, y: 0.5, z: 0.5 }
|
|
87
87
|
};
|
|
88
|
-
function pose3(position,
|
|
89
|
-
return { position, rotation, scale:
|
|
88
|
+
function pose3(position, scale6 = { x: 1, y: 1, z: 1 }, rotation = quatIdentity()) {
|
|
89
|
+
return { position, rotation, scale: scale6 };
|
|
90
90
|
}
|
|
91
91
|
function poseMatrix(pose) {
|
|
92
92
|
return compose(pose.position, pose.rotation, pose.scale);
|
|
@@ -200,6 +200,128 @@ var DEFAULT_UP = { x: 0, y: 1, z: 0 };
|
|
|
200
200
|
function boundsOfNode(world, node) {
|
|
201
201
|
return world.bounds ? world.bounds(node) : aabbOfPose(node.pose);
|
|
202
202
|
}
|
|
203
|
+
|
|
204
|
+
// src/pickIndex.ts
|
|
205
|
+
function screenBoxOf(world, id, viewport) {
|
|
206
|
+
const node = world.scene.get(id);
|
|
207
|
+
if (!node) return null;
|
|
208
|
+
return projectAabbToScreen(
|
|
209
|
+
boundsOfNode(world, node),
|
|
210
|
+
viewProjectionOf(viewport),
|
|
211
|
+
rectOf(viewport)
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
function overlaps(a, b) {
|
|
215
|
+
return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;
|
|
216
|
+
}
|
|
217
|
+
function boxValid({ min, max }) {
|
|
218
|
+
return Number.isFinite(min.x) && Number.isFinite(min.y) && Number.isFinite(min.z) && Number.isFinite(max.x) && Number.isFinite(max.y) && Number.isFinite(max.z) && min.x <= max.x && min.y <= max.y && min.z <= max.z;
|
|
219
|
+
}
|
|
220
|
+
var NDC_SLACK = 1e-9;
|
|
221
|
+
function sidePlanes(vp, rect) {
|
|
222
|
+
const m = viewProjectionOf(vp);
|
|
223
|
+
const pane = rectOf(vp);
|
|
224
|
+
const lo = screenToNdc({ x: rect.x, y: rect.y + rect.height }, pane);
|
|
225
|
+
const hi = screenToNdc({ x: rect.x + rect.width, y: rect.y }, pane);
|
|
226
|
+
const row = (r) => [m[r], m[4 + r], m[8 + r], m[12 + r]];
|
|
227
|
+
const w = row(3);
|
|
228
|
+
const plane = (r, a, sign) => {
|
|
229
|
+
const c = row(r);
|
|
230
|
+
const e = [0, 1, 2, 3].map((j) => sign * (c[j] - a * w[j]));
|
|
231
|
+
return { normal: [e[0], e[1], e[2]], offset: e[3] };
|
|
232
|
+
};
|
|
233
|
+
return [
|
|
234
|
+
plane(0, lo.x - NDC_SLACK, 1),
|
|
235
|
+
plane(0, hi.x + NDC_SLACK, -1),
|
|
236
|
+
plane(1, lo.y - NDC_SLACK, 1),
|
|
237
|
+
plane(1, hi.y + NDC_SLACK, -1)
|
|
238
|
+
];
|
|
239
|
+
}
|
|
240
|
+
var BuiltIndex = class {
|
|
241
|
+
constructor(world, order, boxes, tree, always) {
|
|
242
|
+
this.world = world;
|
|
243
|
+
this.order = order;
|
|
244
|
+
this.boxes = boxes;
|
|
245
|
+
this.tree = tree;
|
|
246
|
+
this.always = always;
|
|
247
|
+
}
|
|
248
|
+
world;
|
|
249
|
+
order;
|
|
250
|
+
boxes;
|
|
251
|
+
tree;
|
|
252
|
+
always;
|
|
253
|
+
nearestOnRay(ray, excluded) {
|
|
254
|
+
const { order, boxes } = this;
|
|
255
|
+
let best = -1;
|
|
256
|
+
let bestT = Infinity;
|
|
257
|
+
const consider = (i) => {
|
|
258
|
+
if (excluded?.has(order[i].id)) return;
|
|
259
|
+
const t = intersectRayAabb(ray, boxes[i].min, boxes[i].max);
|
|
260
|
+
if (t !== null && (t < bestT || t === bestT && i < best)) {
|
|
261
|
+
bestT = t;
|
|
262
|
+
best = i;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
for (const i of this.always) consider(i);
|
|
266
|
+
const { origin: o, direction: d } = ray;
|
|
267
|
+
this.tree.raycast([o.x, o.y, o.z], [d.x, d.y, d.z], (i, entryT) => {
|
|
268
|
+
if (entryT > bestT * (1 + 1e-12) + 1e-12) return false;
|
|
269
|
+
consider(i);
|
|
270
|
+
return true;
|
|
271
|
+
});
|
|
272
|
+
return best < 0 ? null : order[best].id;
|
|
273
|
+
}
|
|
274
|
+
inScreenRect(vp, rect) {
|
|
275
|
+
const candidates = [...this.always];
|
|
276
|
+
this.tree.queryHalfSpaces(sidePlanes(vp, rect), (i) => {
|
|
277
|
+
candidates.push(i);
|
|
278
|
+
});
|
|
279
|
+
candidates.sort((a, b) => a - b);
|
|
280
|
+
const hits = [];
|
|
281
|
+
for (const i of candidates) {
|
|
282
|
+
const id = this.order[i].id;
|
|
283
|
+
const box = screenBoxOf(this.world, id, vp);
|
|
284
|
+
if (box && overlaps(box, rect)) hits.push(id);
|
|
285
|
+
}
|
|
286
|
+
return hits;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
var CACHE = /* @__PURE__ */ new WeakMap();
|
|
290
|
+
function padded({ min, max }) {
|
|
291
|
+
const m = Math.max(
|
|
292
|
+
Math.abs(min.x),
|
|
293
|
+
Math.abs(min.y),
|
|
294
|
+
Math.abs(min.z),
|
|
295
|
+
Math.abs(max.x),
|
|
296
|
+
Math.abs(max.y),
|
|
297
|
+
Math.abs(max.z)
|
|
298
|
+
);
|
|
299
|
+
const e = 1e-9 * (1 + m);
|
|
300
|
+
return [min.x - e, min.y - e, min.z - e, max.x + e, max.y + e, max.z + e];
|
|
301
|
+
}
|
|
302
|
+
function build(world, order) {
|
|
303
|
+
const boxes = order.map((node) => boundsOfNode(world, node));
|
|
304
|
+
const entries = [];
|
|
305
|
+
const always = [];
|
|
306
|
+
boxes.forEach((b, i) => {
|
|
307
|
+
if (boxValid(b)) entries.push([i, padded(b)]);
|
|
308
|
+
else always.push(i);
|
|
309
|
+
});
|
|
310
|
+
return new BuiltIndex(world, order, boxes, createBvh(3, entries), always);
|
|
311
|
+
}
|
|
312
|
+
function worldPickIndex(world) {
|
|
313
|
+
const { scene } = world;
|
|
314
|
+
const version = scene.getVersion();
|
|
315
|
+
const overrides = scene.overrides.getGeneration();
|
|
316
|
+
const order = scene.renderOrderNodes();
|
|
317
|
+
const hit = CACHE.get(world);
|
|
318
|
+
if (hit && hit.version === version && hit.overrides === overrides && hit.bounds === world.bounds && hit.order === order) {
|
|
319
|
+
return hit.index;
|
|
320
|
+
}
|
|
321
|
+
const index = build(world, order);
|
|
322
|
+
CACHE.set(world, { version, overrides, bounds: world.bounds, order, index });
|
|
323
|
+
return index;
|
|
324
|
+
}
|
|
203
325
|
var ZERO = { x: 0, y: 0, z: 0 };
|
|
204
326
|
var tuple = (p) => [p.x, p.y, p.z];
|
|
205
327
|
var vec3Of = (t) => ({ x: t[0], y: t[1], z: t[2] });
|
|
@@ -381,49 +503,16 @@ function onPlane(vp, plane, point) {
|
|
|
381
503
|
const t = intersectRayPlane(ray, plane.normal, plane.offset);
|
|
382
504
|
return t === null ? null : pointOnRay(ray, t);
|
|
383
505
|
}
|
|
384
|
-
function overlaps(a, b) {
|
|
385
|
-
return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;
|
|
386
|
-
}
|
|
387
|
-
function screenBoxOf(world, id, viewport) {
|
|
388
|
-
const node = world.scene.get(id);
|
|
389
|
-
if (!node) return null;
|
|
390
|
-
return projectAabbToScreen(
|
|
391
|
-
boundsOfNode(world, node),
|
|
392
|
-
viewProjectionOf(viewport),
|
|
393
|
-
rectOf(viewport)
|
|
394
|
-
);
|
|
395
|
-
}
|
|
396
506
|
function createNodeAtPoint(world) {
|
|
397
507
|
return (point, exclude) => {
|
|
398
|
-
const
|
|
399
|
-
const vp = world.viewport();
|
|
400
|
-
const ray = rayAt(vp, point);
|
|
508
|
+
const ray = rayAt(world.viewport(), point);
|
|
401
509
|
if (!ray) return null;
|
|
402
|
-
|
|
403
|
-
let bestT = Infinity;
|
|
404
|
-
for (const node of world.scene.renderOrderNodes()) {
|
|
405
|
-
if (excluded?.has(node.id)) continue;
|
|
406
|
-
const { min, max } = boundsOfNode(world, node);
|
|
407
|
-
const t = intersectRayAabb(ray, min, max);
|
|
408
|
-
if (t !== null && t < bestT) {
|
|
409
|
-
bestT = t;
|
|
410
|
-
best = node.id;
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
return best;
|
|
510
|
+
return worldPickIndex(world).nearestOnRay(ray, exclude ? new Set(exclude) : null);
|
|
414
511
|
};
|
|
415
512
|
}
|
|
416
513
|
function createAreaSelect(world, selection) {
|
|
417
514
|
return {
|
|
418
|
-
hitTestArea(bounds)
|
|
419
|
-
const vp = world.viewport();
|
|
420
|
-
const hits = [];
|
|
421
|
-
for (const node of world.scene.renderOrderNodes()) {
|
|
422
|
-
const box = screenBoxOf(world, node.id, vp);
|
|
423
|
-
if (box && overlaps(box, bounds)) hits.push(node.id);
|
|
424
|
-
}
|
|
425
|
-
return hits;
|
|
426
|
-
},
|
|
515
|
+
hitTestArea: (bounds) => worldPickIndex(world).inScreenRect(world.viewport(), bounds),
|
|
427
516
|
getSelection: () => [...selection.get()],
|
|
428
517
|
setSelection: (ids) => selection.set([...ids])
|
|
429
518
|
};
|
|
@@ -466,14 +555,14 @@ function createPoseDescriptor(world) {
|
|
|
466
555
|
if (rayAt(vp, { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 })) lastCastable = vp;
|
|
467
556
|
return lastCastable;
|
|
468
557
|
}
|
|
469
|
-
function
|
|
558
|
+
function build2(worldBox) {
|
|
470
559
|
const boundsIn = (vp, pose) => projectAabbToScreen(worldBox(pose), viewProjectionOf(vp), rectOf(vp));
|
|
471
560
|
const boundsOf = (pose) => boundsIn(world.viewport(), pose);
|
|
472
561
|
const descriptor = {
|
|
473
562
|
forNode(node) {
|
|
474
563
|
let d = specialized.get(node);
|
|
475
564
|
if (!d) {
|
|
476
|
-
d =
|
|
565
|
+
d = build2((pose) => boundsOfNode(world, { ...node, pose }));
|
|
477
566
|
specialized.set(node, d);
|
|
478
567
|
}
|
|
479
568
|
return d;
|
|
@@ -588,7 +677,7 @@ function createPoseDescriptor(world) {
|
|
|
588
677
|
};
|
|
589
678
|
return descriptor;
|
|
590
679
|
}
|
|
591
|
-
return
|
|
680
|
+
return build2((pose) => aabbOfPose(pose));
|
|
592
681
|
}
|
|
593
682
|
function footprintPoints(bounds, ends, cast) {
|
|
594
683
|
if (ends) {
|
|
@@ -641,6 +730,94 @@ function createInsert(opts) {
|
|
|
641
730
|
}
|
|
642
731
|
};
|
|
643
732
|
}
|
|
733
|
+
var GROUND_NORMAL = { x: 0, y: 0, z: 1 };
|
|
734
|
+
function paneCorners(viewport) {
|
|
735
|
+
const { x, y, width, height } = rectOf(viewport);
|
|
736
|
+
return [
|
|
737
|
+
{ x, y },
|
|
738
|
+
{ x: x + width, y },
|
|
739
|
+
{ x: x + width, y: y + height },
|
|
740
|
+
{ x, y: y + height }
|
|
741
|
+
];
|
|
742
|
+
}
|
|
743
|
+
function frustumOf(viewport) {
|
|
744
|
+
const { camera } = viewport;
|
|
745
|
+
const eye = cameraEye(camera);
|
|
746
|
+
const forward = normalize(sub(camera.target, eye));
|
|
747
|
+
const at = (depth) => paneCorners(viewport).map((c) => {
|
|
748
|
+
const ray = rayAt(viewport, c);
|
|
749
|
+
if (!ray) return eye;
|
|
750
|
+
const d = normalize(ray.direction);
|
|
751
|
+
return add(eye, scale(d, depth / dot(d, forward)));
|
|
752
|
+
});
|
|
753
|
+
return {
|
|
754
|
+
eye,
|
|
755
|
+
near: at(camera.near),
|
|
756
|
+
far: at(camera.far)
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
function groundHit(viewport, point) {
|
|
760
|
+
const ray = rayAt(viewport, point);
|
|
761
|
+
const t = ray && intersectRayPlane(ray, GROUND_NORMAL, 0);
|
|
762
|
+
return ray && t !== null ? pointOnRay(ray, t) : null;
|
|
763
|
+
}
|
|
764
|
+
function toZ(p) {
|
|
765
|
+
return { x: p.x, y: p.y, z: p.z ?? 0 };
|
|
766
|
+
}
|
|
767
|
+
function projectAll(space, points) {
|
|
768
|
+
const out = [];
|
|
769
|
+
for (const p of points) {
|
|
770
|
+
const px = space.project(p);
|
|
771
|
+
if (!px) return null;
|
|
772
|
+
out.push(px);
|
|
773
|
+
}
|
|
774
|
+
return out;
|
|
775
|
+
}
|
|
776
|
+
function aimOf3d(viewport, viewId) {
|
|
777
|
+
const extent = frustumOf(viewport);
|
|
778
|
+
return {
|
|
779
|
+
viewId,
|
|
780
|
+
kind: "frustum",
|
|
781
|
+
extent,
|
|
782
|
+
viewport,
|
|
783
|
+
outlineIn(space) {
|
|
784
|
+
if (space.kind === "3d") return projectAll(space, extent.far);
|
|
785
|
+
const onGround = [];
|
|
786
|
+
for (const c of paneCorners(viewport)) {
|
|
787
|
+
const hit = groundHit(viewport, c);
|
|
788
|
+
if (!hit) return null;
|
|
789
|
+
onGround.push(hit);
|
|
790
|
+
}
|
|
791
|
+
return projectAll(space, onGround);
|
|
792
|
+
},
|
|
793
|
+
pannedIn(space, from, to) {
|
|
794
|
+
const a = space.unproject(from);
|
|
795
|
+
const b = space.unproject(to);
|
|
796
|
+
if (!a || !b) return null;
|
|
797
|
+
const { camera } = viewport;
|
|
798
|
+
const target = add(camera.target, sub(toZ(b), toZ(a)));
|
|
799
|
+
return aimOf3d({ ...viewport, camera: { ...camera, target } }, viewId);
|
|
800
|
+
}
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
function aimSpace3d(viewport, viewId) {
|
|
804
|
+
const { x: ox, y: oy } = rectOf(viewport);
|
|
805
|
+
return {
|
|
806
|
+
viewId,
|
|
807
|
+
kind: "3d",
|
|
808
|
+
size: { width: viewport.width, height: viewport.height },
|
|
809
|
+
project(p) {
|
|
810
|
+
const s = projectPoint(toZ(p), viewport);
|
|
811
|
+
return s && { x: s.x - ox, y: s.y - oy };
|
|
812
|
+
},
|
|
813
|
+
unproject(px) {
|
|
814
|
+
return groundHit(viewport, { x: px.x + ox, y: px.y + oy });
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
function cameraOfAim3d(aim) {
|
|
819
|
+
return aim.viewport.camera;
|
|
820
|
+
}
|
|
644
821
|
var AXES = ["x", "y", "z"];
|
|
645
822
|
var BITS = [1, 2, 4];
|
|
646
823
|
var UNIT = { x: { x: 1, y: 0, z: 0 }, y: { x: 0, y: 1, z: 0 }, z: { x: 0, y: 0, z: 1 } };
|
|
@@ -870,10 +1047,10 @@ var dollyAction = {
|
|
|
870
1047
|
label: "Dolly",
|
|
871
1048
|
group: "viewport",
|
|
872
1049
|
defaultBinding: [
|
|
873
|
-
{ spec: { kind: "wheel" }, opts: {} },
|
|
1050
|
+
{ spec: { kind: "wheel" }, opts: { id: "camera.dolly.wheel" } },
|
|
874
1051
|
// Unbound, a trackpad pinch zooms the page instead.
|
|
875
|
-
{ spec: { kind: "wheel", mods: { ctrl: true } }, opts: {} },
|
|
876
|
-
{ spec: { kind: "pinch" }, opts: {} }
|
|
1052
|
+
{ spec: { kind: "wheel", mods: { ctrl: true } }, opts: { id: "camera.dolly.trackpadPinch" } },
|
|
1053
|
+
{ spec: { kind: "pinch" }, opts: { id: "camera.dolly.pinch" } }
|
|
877
1054
|
],
|
|
878
1055
|
requires: ["camera3d", "kitSettings"],
|
|
879
1056
|
invoker: {
|
|
@@ -894,7 +1071,7 @@ var pinchDollyAction = {
|
|
|
894
1071
|
id: "camera.pinchDolly",
|
|
895
1072
|
label: "Pinch Dolly",
|
|
896
1073
|
group: "viewport",
|
|
897
|
-
defaultBinding: { kind: "multiTouch", fingers: 2 },
|
|
1074
|
+
defaultBinding: [{ spec: { kind: "multiTouch", fingers: 2 }, opts: { id: "camera.pinchDolly.multiTouch" } }],
|
|
898
1075
|
requires: ["camera3d"],
|
|
899
1076
|
invoker: {
|
|
900
1077
|
timing: "ongoing",
|
|
@@ -920,7 +1097,7 @@ var homeAction = {
|
|
|
920
1097
|
id: "camera.home",
|
|
921
1098
|
label: "Reset Camera",
|
|
922
1099
|
group: "viewport",
|
|
923
|
-
defaultBinding: { kind: "doubleClick" },
|
|
1100
|
+
defaultBinding: [{ spec: { kind: "doubleClick" }, opts: { id: "camera.home.doubleClick" } }],
|
|
924
1101
|
requires: ["camera3d"],
|
|
925
1102
|
invoker: {
|
|
926
1103
|
timing: "immediate",
|
|
@@ -938,8 +1115,8 @@ function useOrbitTool() {
|
|
|
938
1115
|
cursor: "grab",
|
|
939
1116
|
presentation: { label: "Orbit", group: "viewport" },
|
|
940
1117
|
bindings: [
|
|
941
|
-
{ spec: { kind: "drag" }, actionId: "camera.orbit" },
|
|
942
|
-
{ spec: { kind: "drag", mods: { shift: true } }, actionId: "camera.pan" }
|
|
1118
|
+
{ spec: { kind: "drag" }, actionId: "camera.orbit", opts: { id: "orbit.orbit" } },
|
|
1119
|
+
{ spec: { kind: "drag", mods: { shift: true } }, actionId: "camera.pan", opts: { id: "orbit.pan" } }
|
|
943
1120
|
]
|
|
944
1121
|
}), []);
|
|
945
1122
|
}
|
|
@@ -950,6 +1127,6 @@ var kernel3dKitSettingsSchema = pref.group("3D camera", {
|
|
|
950
1127
|
})
|
|
951
1128
|
});
|
|
952
1129
|
|
|
953
|
-
export { DEFAULT_ORBIT_LIMITS, MAX_PITCH, UNIT_CUBE, aabbOfPose, alignPlaneSource, boxSnapSource, cameraEye, cameraView, cameraViewProjection, clampCamera, collectOverlayBoxes, createAreaSelect, createCamera, createInsert, createNodeAtPoint, createPoseDescriptor, createSnap, dollyAction, dollyBy, dollyToward, groundGridSource, homeAction, kernel3dKitSettingsSchema, ndcToScreen, orbitAction, orbitBy, panAction, panBy, pinchDollyAction, pose3, poseMatrix, projectAabbToScreen, projectPoint, projectSnapMarks, rayThroughScreenPoint, screenBoxOf, screenToNdc, useOrbitTool };
|
|
1130
|
+
export { DEFAULT_ORBIT_LIMITS, MAX_PITCH, UNIT_CUBE, aabbOfPose, aimOf3d, aimSpace3d, alignPlaneSource, boxSnapSource, cameraEye, cameraOfAim3d, cameraView, cameraViewProjection, clampCamera, collectOverlayBoxes, createAreaSelect, createCamera, createInsert, createNodeAtPoint, createPoseDescriptor, createSnap, dollyAction, dollyBy, dollyToward, groundGridSource, homeAction, kernel3dKitSettingsSchema, ndcToScreen, orbitAction, orbitBy, panAction, panBy, pinchDollyAction, pose3, poseMatrix, projectAabbToScreen, projectPoint, projectSnapMarks, rayThroughScreenPoint, screenBoxOf, screenToNdc, useOrbitTool };
|
|
954
1131
|
//# sourceMappingURL=index.js.map
|
|
955
1132
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/camera.ts","../src/pose3.ts","../src/screen.ts","../src/project.ts","../src/world.ts","../src/snap/plane.ts","../src/snap/probes3d.ts","../src/snap/session3d.ts","../src/deps.ts","../src/insert.ts","../src/snap/sources.ts","../src/snap/marks.ts","../src/overlays.ts","../src/tools.ts","../src/kitSettings.ts"],"names":["distance","scale","transformPoint4","normalize","sub","dot","add","ZERO","cross","intersectRayPlane","pointOnRay","scaleBy","len","quatIdentity"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * An orbit camera: a target, two angles and a distance. Immutable — every\n * gesture returns a new one, so it can live in instrument state.\n *\n * This is the shape `ViewApi` cannot hold, and the reason the kernel declares a\n * `camera3d` dep of its own rather than reusing the kit's `view`.\n */\n\nimport {\n add,\n lookAt,\n multiply,\n perspective,\n scale,\n type Mat4,\n type Vec3,\n} from '@weasel-js/geom/3d';\n\n/** An orbit camera. The eye sits `distance` world units from `target` at\n * `yaw`/`pitch`; `fov` is the vertical field of view in radians, and\n * `near`/`far` the clip distances. */\nexport interface Camera3d {\n target: Vec3;\n /** Radians about +y, measured from +z. */\n yaw: number;\n /** Radians above the xz plane. */\n pitch: number;\n distance: number;\n fov: number;\n near: number;\n far: number;\n}\n\n/** Short of vertical: at exactly ±π/2 the eye lands on the up axis and `lookAt` degenerates. */\nexport const MAX_PITCH = Math.PI / 2 - 0.01;\nconst UP: Vec3 = { x: 0, y: 1, z: 0 };\n\n/** A camera with defaults for every field not given: origin target, level at\n * yaw 0, distance 10, fov π/4, near 0.1, far 1000. */\nexport function createCamera(init: Partial<Camera3d>): Camera3d {\n return {\n target: init.target ?? { x: 0, y: 0, z: 0 },\n yaw: init.yaw ?? 0,\n pitch: init.pitch ?? 0,\n distance: init.distance ?? 10,\n fov: init.fov ?? Math.PI / 4,\n near: init.near ?? 0.1,\n far: init.far ?? 1000,\n };\n}\n\n/** The eye's world position. */\nexport function cameraEye(camera: Camera3d): Vec3 {\n const { target, yaw, pitch, distance } = camera;\n const horizontal = Math.cos(pitch) * distance;\n return {\n x: target.x + horizontal * Math.sin(yaw),\n y: target.y + Math.sin(pitch) * distance,\n z: target.z + horizontal * Math.cos(yaw),\n };\n}\n\n/** World-to-view matrix, with +y up. */\nexport function cameraView(camera: Camera3d): Mat4 {\n return lookAt(cameraEye(camera), camera.target, UP);\n}\n\n/** World-to-clip matrix for a pane of the given width/height `aspect`. */\nexport function cameraViewProjection(camera: Camera3d, aspect: number): Mat4 {\n return multiply(perspective(camera.fov, aspect, camera.near, camera.far), cameraView(camera));\n}\n\n/** How far an orbit camera may turn and travel. Distances are in world units,\n * so a scene measured in millimeters and one in kilometers want different ones. */\nexport interface OrbitLimits {\n minDistance: number;\n maxDistance: number;\n /** Radians. Held inside ±`MAX_PITCH` whatever is asked for. */\n minPitch: number;\n maxPitch: number;\n}\n\n/** Pitch short of the poles, distance 0.5..500. */\nexport const DEFAULT_ORBIT_LIMITS: OrbitLimits = {\n minDistance: 0.5,\n maxDistance: 500,\n minPitch: -MAX_PITCH,\n maxPitch: MAX_PITCH,\n};\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, v));\n\n/** The camera with its pitch and distance inside `limits`. Returns `camera`\n * itself when it already holds. */\nexport function clampCamera(camera: Camera3d, limits: Partial<OrbitLimits> = {}): Camera3d {\n const l = { ...DEFAULT_ORBIT_LIMITS, ...limits };\n const pitch = clamp(camera.pitch, Math.max(-MAX_PITCH, l.minPitch), Math.min(MAX_PITCH, l.maxPitch));\n const distance = clamp(camera.distance, l.minDistance, l.maxDistance);\n if (pitch === camera.pitch && distance === camera.distance) return camera;\n return { ...camera, pitch, distance };\n}\n\n/** The camera turned about its target by the given radians, pitch held inside\n * `limits`. Yaw is not wrapped. */\nexport function orbitBy(\n camera: Camera3d,\n deltaYaw: number,\n deltaPitch: number,\n limits?: Partial<OrbitLimits>,\n): Camera3d {\n return clampCamera(\n { ...camera, yaw: camera.yaw + deltaYaw, pitch: camera.pitch + deltaPitch },\n limits,\n );\n}\n\n/** The camera with its distance multiplied by `factor`, held inside `limits`. */\nexport function dollyBy(camera: Camera3d, factor: number, limits?: Partial<OrbitLimits>): Camera3d {\n return clampCamera({ ...camera, distance: camera.distance * factor }, limits);\n}\n\n/**\n * The camera with its target slid across the screen plane, so the point at the\n * target follows a pointer that moved `dx`, `dy` CSS pixels in a pane\n * `paneHeight` pixels tall. Neither angle nor distance changes.\n */\nexport function panBy(camera: Camera3d, dx: number, dy: number, paneHeight: number): Camera3d {\n if (!(paneHeight > 0)) return camera;\n const perPixel = (2 * camera.distance * Math.tan(camera.fov / 2)) / paneHeight;\n const { yaw, pitch } = camera;\n const right: Vec3 = { x: Math.cos(yaw), y: 0, z: -Math.sin(yaw) };\n const up: Vec3 = {\n x: -Math.sin(yaw) * Math.sin(pitch),\n y: Math.cos(pitch),\n z: -Math.cos(yaw) * Math.sin(pitch),\n };\n const shift = add(scale(right, -dx * perPixel), scale(up, dy * perPixel));\n return { ...camera, target: add(camera.target, shift) };\n}\n\n/**\n * `dollyBy` about a point on the pane rather than its middle: the point in the\n * target's screen-facing plane under `at` — CSS pixels from the pane's\n * top-left, in a pane of `pane` size — stays under it, as a 2D camera's wheel\n * zoom keeps the point under the pointer. The target slides toward that point\n * by as much as the distance shrank, so the next turn pivots nearer it.\n */\nexport function dollyToward(\n camera: Camera3d,\n factor: number,\n at: { x: number; y: number },\n pane: { width: number; height: number },\n limits?: Partial<OrbitLimits>,\n): Camera3d {\n const dollied = dollyBy(camera, factor, limits);\n const kept = 1 - dollied.distance / camera.distance;\n const moved = panBy(\n camera,\n -kept * (at.x - pane.width / 2),\n -kept * (at.y - pane.height / 2),\n pane.height,\n );\n return { ...dollied, target: moved.target };\n}\n","/**\n * A 3D pose, and the two things every consumer of one needs: its matrix, and\n * the world box it occupies.\n *\n * `Scene<TData, TLayer, Pose3>` is the whole of how this reaches weasel —\n * `Scene` is generic over its pose and holds this one with no adapter, no\n * subclass and no special case.\n */\n\nimport {\n compose, quatIdentity, transformAabb, type Aabb, type Mat4, type Quat, type Vec3,\n} from '@weasel-js/geom/3d';\n\n/** Position, rotation and scale of a 3D node. */\nexport interface Pose3 {\n position: Vec3;\n rotation: Quat;\n scale: Vec3;\n}\n\n/** The box a primitive occupies before its pose. A unit primitive centred on\n * its own origin — which is what the kernel assumes nothing about — is\n * `UNIT_CUBE`. */\nexport const UNIT_CUBE: Aabb = {\n min: { x: -0.5, y: -0.5, z: -0.5 },\n max: { x: 0.5, y: 0.5, z: 0.5 },\n};\n\n/** A pose at `position`, unscaled and unrotated unless given. */\nexport function pose3(\n position: Vec3,\n scale: Vec3 = { x: 1, y: 1, z: 1 },\n rotation: Quat = quatIdentity(),\n): Pose3 {\n return { position, rotation, scale };\n}\n\n/** The pose as a matrix: scale, then rotation, then translation to\n * `position`. */\nexport function poseMatrix(pose: Pose3): Mat4 {\n return compose(pose.position, pose.rotation, pose.scale);\n}\n\n/**\n * The world box a posed primitive occupies, given the box it occupies in its\n * own space.\n *\n * Which local box a primitive has is the consumer's answer, not the kernel's:\n * a sphere's is rotation-invariant and a mesh's comes from its vertices, and\n * neither is something a pose can tell you.\n */\nexport function aabbOfPose(pose: Pose3, local: Aabb = UNIT_CUBE): Aabb {\n return transformAabb(poseMatrix(pose), local);\n}\n","/**\n * The screen side of the kernel: where a pointer points, and what rectangle a\n * world box covers. This is the seam weasel's 2D chrome meets — everything\n * here speaks `Bounds`-shaped screen rectangles, which is why a 3D host can\n * pass the dispatcher's world point through unchanged.\n */\n\nimport {\n invert,\n normalize,\n sub,\n transformPoint,\n transformPoint4,\n type Aabb,\n type Mat4,\n type Ray,\n type Vec3,\n} from '@weasel-js/geom/3d';\n\n/** A screen rectangle in CSS pixels, in the shape core's `Bounds` uses. Both\n * a pane's own rect and a projected world box are this — one spelling, so the\n * two never need converting between. */\nexport interface ScreenBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** A `ScreenBox` a host is being asked to outline. `tint` says why: warm for\n * what is selected, cool for what the gesture in hand is proposing. */\nexport interface ChromeBox extends ScreenBox {\n tint?: 'selection' | 'gesture';\n}\n\n/** Screen point (y down, rect-relative) to normalized device coordinates (y up). */\nexport function screenToNdc(\n point: { x: number; y: number },\n rect: ScreenBox,\n): { x: number; y: number } {\n return {\n x: ((point.x - rect.x) / rect.width) * 2 - 1,\n y: 1 - ((point.y - rect.y) / rect.height) * 2,\n };\n}\n\n/** Inverse of `screenToNdc`: normalized device coordinates (y up) to a point\n * in `rect`'s space (y down). */\nexport function ndcToScreen(\n ndc: { x: number; y: number },\n rect: ScreenBox,\n): { x: number; y: number } {\n return {\n x: rect.x + (ndc.x * 0.5 + 0.5) * rect.width,\n y: rect.y + (1 - (ndc.y * 0.5 + 0.5)) * rect.height,\n };\n}\n\n/**\n * The ray a screen point names, given the camera that drew the rect. This is\n * the whole of what 3D picking needs from a pointer — which is why the world\n * point the dispatcher carries stays two numbers.\n *\n * `null` when the point names no ray: the view-projection has no inverse (a\n * camera on its own target, a degenerate projection) or the pane has no area.\n */\nexport function rayThroughScreenPoint(\n point: { x: number; y: number },\n rect: ScreenBox,\n viewProjection: Mat4,\n eye: Vec3,\n): Ray | null {\n const inv = invert(viewProjection);\n if (!inv) return null;\n const ndc = screenToNdc(point, rect);\n const near = transformPoint(inv, { x: ndc.x, y: ndc.y, z: -1 });\n const far = transformPoint(inv, { x: ndc.x, y: ndc.y, z: 1 });\n const direction = normalize(sub(far, near));\n // normalize answers zero for a non-finite difference, which is no direction.\n if (direction.x === 0 && direction.y === 0 && direction.z === 0) return null;\n return { origin: eye, direction };\n}\n\ntype Clip = readonly [number, number, number, number];\n\n/** Signed distance to the near plane in clip space; `>= 0` is in front of it.\n * GL puts the near plane at `z = -w`. */\nfunction nearSide(p: Clip): number {\n return p[2] + p[3];\n}\n\nfunction lerpClip(a: Clip, b: Clip, t: number): Clip {\n return [\n a[0] + (b[0] - a[0]) * t,\n a[1] + (b[1] - a[1]) * t,\n a[2] + (b[2] - a[2]) * t,\n a[3] + (b[3] - a[3]) * t,\n ];\n}\n\n/** The three edges leaving corner `i` toward a higher bit, as bit masks. */\nconst EDGE_BITS = [1, 2, 4] as const;\n\n/**\n * The screen rectangle a world-space box covers — the currency weasel's chrome\n * and `PoseDescriptor.getBounds` speak in. `null` when the box is entirely\n * behind the near plane.\n *\n * Each of the twelve edges is clipped against the near plane before it is\n * projected, rather than dropping the corners behind it. Dropping them reports\n * a box that is too small for anything straddling the near plane, and the error\n * grows as the camera moves in: a solid the pointer is inside of would outline\n * as a sliver, or as nothing.\n */\nexport function projectAabbToScreen(\n box: Aabb,\n viewProjection: Mat4,\n rect: ScreenBox,\n): ScreenBox | null {\n const corners: Clip[] = [];\n for (let i = 0; i < 8; i++) {\n const corner: Vec3 = {\n x: i & 1 ? box.max.x : box.min.x,\n y: i & 2 ? box.max.y : box.min.y,\n z: i & 4 ? box.max.z : box.min.z,\n };\n corners.push(transformPoint4(viewProjection, corner));\n }\n\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n let any = false;\n\n const extend = (p: Clip): void => {\n if (!(p[3] > 0)) return;\n const screen = ndcToScreen({ x: p[0] / p[3], y: p[1] / p[3] }, rect);\n minX = Math.min(minX, screen.x);\n minY = Math.min(minY, screen.y);\n maxX = Math.max(maxX, screen.x);\n maxY = Math.max(maxY, screen.y);\n any = true;\n };\n\n for (let i = 0; i < 8; i++) {\n for (const bit of EDGE_BITS) {\n if (i & bit) continue;\n let a = corners[i];\n let b = corners[i | bit];\n const da = nearSide(a);\n const db = nearSide(b);\n if (da < 0 && db < 0) continue;\n if (da < 0) a = lerpClip(a, b, da / (da - db));\n else if (db < 0) b = lerpClip(b, a, db / (db - da));\n extend(a);\n extend(b);\n }\n }\n\n if (!any) return null;\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n","/**\n * A viewport's two directions: a screen point to the ray it names, and a\n * world point to the screen point it draws at. Both speak the coordinate\n * space the host's pointer points arrive in.\n */\n\nimport { transformPoint4, type Ray, type Vec3 } from '@weasel-js/geom/3d';\nimport { cameraEye, cameraViewProjection, type Camera3d } from './camera';\nimport { ndcToScreen, rayThroughScreenPoint, type ScreenBox } from './screen';\n\n/** The camera and the pane it draws into; `width`/`height` are the pane's\n * size in the same units as the pointer points. */\nexport interface Viewport3d {\n camera: Camera3d;\n width: number;\n height: number;\n /**\n * Where the pane sits in client coordinates. A 3D host works in one space\n * from the event to the ray — it passes the dispatcher an identity\n * `clientToWorld` — so the deps subtract this rather than the dispatcher.\n */\n originX?: number;\n originY?: number;\n}\n\n/** Read on every dep call, so a dep always sees the current camera and pane. */\nexport type ViewportSource = () => Viewport3d;\n\ntype Point = { x: number; y: number };\n\n/** The pane, in the coordinate space the host's points arrive in. The origin\n * defaults to the client origin — a host that fills the window passes none. */\nexport function rectOf(viewport: Viewport3d): ScreenBox {\n return {\n x: viewport.originX ?? 0,\n y: viewport.originY ?? 0,\n width: viewport.width,\n height: viewport.height,\n };\n}\n\nexport function viewProjectionOf(viewport: Viewport3d) {\n return cameraViewProjection(viewport.camera, viewport.width / Math.max(1, viewport.height));\n}\n\nexport function rayAt(viewport: Viewport3d, point: Point): Ray | null {\n return rayThroughScreenPoint(\n point,\n rectOf(viewport),\n viewProjectionOf(viewport),\n cameraEye(viewport.camera),\n );\n}\n\n/** Where `p` draws in the viewport, or null when it is behind the near plane\n * or projects to nothing finite. */\nexport function projectPoint(p: Vec3, viewport: Viewport3d): Point | null {\n const [x, y, z, w] = transformPoint4(viewProjectionOf(viewport), p);\n // GL's near plane is z = -w.\n if (!(w > 0) || z < -w) return null;\n const screen = ndcToScreen({ x: x / w, y: y / w }, rectOf(viewport));\n return Number.isFinite(screen.x) && Number.isFinite(screen.y) ? screen : null;\n}\n","/** The 3D world every dep is built from: core's scene with a `Pose3`, the\n * viewport it is seen through, and how wide each node is. */\n\nimport type { Scene, SceneNode } from '@weasel-js/core';\nimport type { Aabb, Vec3 } from '@weasel-js/geom/3d';\nimport { aabbOfPose, type Pose3 } from './pose3';\nimport type { ViewportSource } from './project';\n\n/** A 3D scene is core's scene with a `Pose3`. Nothing wraps it. */\nexport type Scene3d<TData, TLayer extends string> = Scene<TData, TLayer, Pose3>;\n/** A node of a `Scene3d`. */\nexport type Node3d<TData, TLayer extends string> = SceneNode<TData, TLayer, Pose3>;\n\n/**\n * The world box a node occupies, rather than a local box to transform: a\n * sphere's box is the same under every rotation, and no transform of a local\n * box reproduces that — rotate a cube and it widens.\n *\n * Omitted, a node is a unit cube carried by its pose.\n */\nexport type NodeBounds<TData, TLayer extends string> = (\n node: Node3d<TData, TLayer>,\n) => Aabb;\n\n/** What every 3D dep is built from: the scene, the viewport, and optionally\n * each node's world box. */\nexport interface World3d<TData, TLayer extends string> {\n scene: Scene3d<TData, TLayer>;\n viewport: ViewportSource;\n bounds?: NodeBounds<TData, TLayer>;\n /** The axis gestures resolve against. Default `+y`. */\n up?: Vec3;\n}\n\nexport const DEFAULT_UP: Vec3 = { x: 0, y: 1, z: 0 };\n\nexport function boundsOfNode<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n node: Node3d<TData, TLayer>,\n): Aabb {\n return world.bounds ? world.bounds(node) : aabbOfPose(node.pose);\n}\n","import { SNAP_AXIS_STEP, type SnapConstrain } from '@weasel-js/core';\nimport { stepLine, type Flat } from '@weasel-js/geom/nd';\nimport { cross, dot, normalize, scale, sub, type Vec3 } from '@weasel-js/geom/3d';\n\nconst ZERO: Vec3 = { x: 0, y: 0, z: 0 };\n\nexport const tuple = (p: Vec3): number[] => [p.x, p.y, p.z];\nexport const vec3Of = (t: readonly number[]): Vec3 => ({ x: t[0]!, y: t[1]!, z: t[2]! });\n\n/** Two unit directions spanning the plane normal to `up`. For an axis `up`\n * they are the other two world axes, so a ground grid runs along them. */\nexport function planeBasis(up: Vec3): readonly [Vec3, Vec3] {\n const n = normalize(up);\n const e: Vec3 = Math.abs(n.x) < 0.9 ? { x: 1, y: 0, z: 0 } : { x: 0, y: 0, z: 1 };\n const u = normalize(sub(e, scale(n, dot(n, e))));\n return [u, cross(u, n)];\n}\n\n/**\n * `H` for a 3D gesture: the plane `basis` spans, through the origin of\n * δ-space. While `snap.constrain` is held, an `'axis'` constraint holds δ to\n * the axes and diagonals of that plane, and an angle step holds it to the\n * line through `about` at the nearest multiple of the step.\n */\nexport function inputFlat3d(\n c: SnapConstrain | undefined, held: boolean, basis: readonly [Vec3, Vec3], delta0: Vec3, about: Vec3,\n): Flat {\n const [u, v] = basis;\n if (!held || c === undefined || c === 'aspect') return { at: [0, 0, 0], dirs: [tuple(u), tuple(v)] };\n const step = c === 'axis' ? SNAP_AXIS_STEP : c.step;\n return stepLine(tuple(c === 'axis' ? ZERO : about), tuple(delta0), [tuple(u), tuple(v)], step);\n}\n","import type { NodeId, SnapProbeAt } from '@weasel-js/core';\nimport { add, dot, scale, type Aabb, type Vec3 } from '@weasel-js/geom/3d';\nimport { boundsOfNode, type Node3d, type World3d } from '../world';\n\n/** What a 3D move drags, at press. */\nexport interface Subject3d {\n /** The union of the subject's world boxes. */\n box: Aabb;\n /** The node whose `translate` the session answers for exactly: the first\n * of the subject still in the scene. */\n anchor: { box: Aabb; height: number };\n}\n\nexport function subjectOf<TData, TLayer extends string>(\n world: World3d<TData, TLayer>, ids: readonly string[], up: Vec3,\n): Subject3d | null {\n let box: Aabb | null = null;\n let anchor: Subject3d['anchor'] | null = null;\n for (const id of ids) {\n const node = world.scene.get(id as NodeId) as Node3d<TData, TLayer> | undefined;\n if (!node) continue;\n const b = boundsOfNode(world, node);\n anchor ??= { box: b, height: dot(up, node.pose.position) };\n box = box ? union(box, b) : b;\n }\n return box && anchor ? { box, anchor } : null;\n}\n\nfunction union(a: Aabb, b: Aabb): Aabb {\n return {\n min: { x: Math.min(a.min.x, b.min.x), y: Math.min(a.min.y, b.min.y), z: Math.min(a.min.z, b.min.z) },\n max: { x: Math.max(a.max.x, b.max.x), y: Math.max(a.max.y, b.max.y), z: Math.max(a.max.z, b.max.z) },\n };\n}\n\n/** Corner `i` of `box`: bit 1 picks max x, bit 2 max y, bit 4 max z. */\nexport function boxCorner(box: Aabb, i: number): Vec3 {\n return {\n x: i & 1 ? box.max.x : box.min.x,\n y: i & 2 ? box.max.y : box.min.y,\n z: i & 4 ? box.max.z : box.min.z,\n };\n}\n\n/** A move's probes: the box's 8 corners and center as its geometry, and its\n * min, center and max as its box. */\nexport function boxProbes(box: Aabb): SnapProbeAt<Vec3>[] {\n const center = scale(add(box.min, box.max), 0.5);\n const out: SnapProbeAt<Vec3>[] = [];\n for (let i = 0; i < 8; i++) {\n out.push({ id: `corner:${i}`, at: boxCorner(box, i), role: 'geometry' });\n }\n out.push(\n { id: 'center', at: center, role: 'geometry' },\n { id: 'box.min', at: box.min, role: 'box' },\n { id: 'box.center', at: center, role: 'box' },\n { id: 'box.max', at: box.max, role: 'box' },\n );\n return out;\n}\n","import {\n gatherSnapCandidates, resolvedSnapMarks, snapSourcesFor,\n type SnapBegin, type SnapCandidateMark, type SnapOutcome, type SnapOutcomeStore,\n type SnapProbeAt, type SnapSession, type SnapSource,\n} from '@weasel-js/core';\nimport { closestOnFlat, resolveSnap, type Flat, type SnapCandidate } from '@weasel-js/geom/nd';\nimport {\n add, cross, dot, intersectRayPlane, len, normalize, pointOnRay, sub, type Vec3,\n} from '@weasel-js/geom/3d';\nimport { cameraEye } from '../camera';\nimport { projectPoint, rayAt, rectOf, viewProjectionOf, type Viewport3d } from '../project';\nimport { projectAabbToScreen } from '../screen';\nimport { DEFAULT_UP, type World3d } from '../world';\nimport { inputFlat3d, planeBasis, tuple, vec3Of } from './plane';\nimport { boxProbes, subjectOf } from './probes3d';\n\ntype Point = { x: number; y: number };\n\nconst ZERO: Vec3 = { x: 0, y: 0, z: 0 };\n\n/** What a 3D session runs on. */\nexport interface Session3dInputs<TData, TLayer extends string> {\n req: SnapBegin;\n world: World3d<TData, TLayer>;\n /** In source order: earlier wins a full tie. */\n sources: readonly SnapSource<Vec3>[];\n /** The reach of a source that sets none, in screen px. */\n reachPx: number;\n store: SnapOutcomeStore<Vec3>;\n}\n\n/**\n * The plane a gesture moves on, `up · p = offset`, and how its δ is read: as\n * the world distance between where `anchor` and the pointer's offset from the\n * press cast onto that plane. For a move, `anchor` is the screen point\n * `translate` casts from, so a δ handed back as a screen point is the delta\n * `translate` makes of it.\n */\ninterface Frame {\n offset: number;\n anchor(vp: Viewport3d): Point | null;\n probes(anchorWorld: Vec3): readonly SnapProbeAt<Vec3>[];\n}\n\n/**\n * A snap session over a 3D world: ctx points are screen points. A move runs\n * on the plane through its subject normal to `up`, an insert on the ground,\n * and each returns the screen point whose cast lands where the snap put it.\n * Other gestures pass their input through.\n */\nexport function createSession3d<TData, TLayer extends string>(inputs: Session3dInputs<TData, TLayer>): SnapSession {\n const { req, world, store } = inputs;\n const up = normalize(world.up ?? DEFAULT_UP);\n const basis = planeBasis(up);\n const frame = frameOf(req, world, up);\n const sources = snapSourcesFor(inputs.sources, req.gesture);\n const unsnapped = (p: Point): SnapOutcome => {\n store.set([]);\n return { point: p, held: false, marks: [] };\n };\n return {\n at(p, mods) {\n if (!frame) return unsnapped(p);\n const vp = world.viewport();\n const screen = frame.anchor(vp);\n const anchor = screen && castOnto(vp, screen, up, frame.offset);\n const hit = screen && castOnto(vp, { x: screen.x + p.x - req.press.x, y: screen.y + p.y - req.press.y }, up, frame.offset);\n if (!screen || !anchor || !hit) return unsnapped(p);\n const delta0 = sub(hit, anchor);\n const origin = req.origin ? castOnto(vp, req.origin, up, frame.offset) : null;\n const input = inputFlat3d(req.constrain, mods.constrain, basis, delta0, origin ? sub(origin, anchor) : ZERO);\n let delta: Vec3;\n let held = false;\n if (mods.suspend) {\n delta = vec3Of(closestOnFlat(input, tuple(delta0)));\n store.set([]);\n } else {\n const probes = frame.probes(anchor);\n const res = resolveSnap({\n probes: probes.map((q) => ({ id: q.id, at: tuple(q.at), role: q.role })),\n input,\n delta0: tuple(delta0),\n candidates: candidatesOf(inputs, sources, probes, delta0, vp, origin, up),\n toScreen: (w) => {\n const s = projectPoint(vec3Of(w), vp);\n return s ? [s.x, s.y] : [NaN, NaN];\n },\n });\n delta = vec3Of(res.delta);\n held = res.members.length > 0;\n store.set(resolvedSnapMarks(res.satisfied, delta));\n }\n const landed = projectPoint(add(anchor, delta), vp);\n if (!landed) return unsnapped(p);\n return {\n point: { x: req.press.x + landed.x - screen.x, y: req.press.y + landed.y - screen.y },\n held,\n marks: store.get(),\n };\n },\n angle: (theta) => ({ theta, marks: [] }),\n end() {\n store.set([]);\n },\n };\n}\n\nfunction frameOf<TData, TLayer extends string>(req: SnapBegin, world: World3d<TData, TLayer>, up: Vec3): Frame | null {\n if (req.gesture === 'point') {\n return {\n offset: 0,\n anchor: () => req.press,\n probes: (at) => [{ id: 'pointer', at, role: 'pointer' }],\n };\n }\n if (req.gesture !== 'move') return null;\n const subject = subjectOf(world, req.ids ?? [], up);\n if (!subject) return null;\n const probes = boxProbes(subject.box);\n return {\n offset: subject.anchor.height,\n anchor(vp) {\n const box = projectAabbToScreen(subject.anchor.box, viewProjectionOf(vp), rectOf(vp));\n return box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : null;\n },\n probes: () => probes,\n };\n}\n\nfunction castOnto(vp: Viewport3d, s: Point, up: Vec3, offset: number): Vec3 | null {\n const ray = rayAt(vp, s);\n const t = ray && intersectRayPlane(ray, up, offset);\n return ray && t !== null ? pointOnRay(ray, t) : null;\n}\n\nfunction candidatesOf<TData, TLayer extends string>(\n inputs: Session3dInputs<TData, TLayer>, sources: readonly SnapSource<Vec3>[], probes: readonly SnapProbeAt<Vec3>[],\n delta0: Vec3, vp: Viewport3d, origin: Vec3 | null, up: Vec3,\n): SnapCandidate<SnapCandidateMark<Vec3>>[] {\n const { req } = inputs;\n const shifted = probes.map((q) => ({ ...q, at: add(q.at, delta0) }));\n const perPx = worldPerPx(vp, shifted);\n const found = gatherSnapCandidates(sources, shifted, (_source, offered, reachPx) => ({\n gesture: req.gesture, probes: offered, delta0, exclude: req.ids ?? [],\n ...(req.ids ? { ids: req.ids } : {}),\n ...(req.parent !== undefined ? { parent: req.parent } : {}),\n ...(origin ? { origin } : {}),\n reachWorld: (px) => px * perPx,\n reachPx,\n }), { toVec: tuple, reachPx: inputs.reachPx, ...(origin ? { origin } : {}) });\n return found.filter((c) => !level(c.locus, up));\n}\n\n/** Whether `locus` is a plane normal to `up`: the gesture's own plane or one\n * parallel to it, which height alone meets or misses. */\nfunction level(locus: Flat, up: Vec3): boolean {\n if (locus.dirs.length !== 2) return false;\n const n = cross(vec3Of(locus.dirs[0]!), vec3Of(locus.dirs[1]!));\n return Math.abs(dot(n, up)) >= (1 - 1e-9) * len(n);\n}\n\n/** World units per screen px at the farthest probe in front of the camera:\n * the radius that culls by reach without dropping anything in it. */\nfunction worldPerPx(vp: Viewport3d, probes: readonly SnapProbeAt<Vec3>[]): number {\n const eye = cameraEye(vp.camera);\n const forward = normalize(sub(vp.camera.target, eye));\n const k = (2 * Math.tan(vp.camera.fov / 2)) / Math.max(1, vp.height);\n let depth = 0;\n for (const q of probes) depth = Math.max(depth, dot(sub(q.at, eye), forward));\n return depth * k;\n}\n","/**\n * The kit's deps, implemented against a 3D world.\n *\n * Every one of these takes its camera from a thunk rather than an argument:\n * the dispatcher keeps handing actions two numbers, and what makes them mean\n * something in 3D is the camera each dep already closes over.\n */\n\nimport type {\n AreaSelectDep,\n NodeAtPointDep,\n NodeId,\n PoseDescriptor,\n SnapDep,\n SnapOutcomeStore,\n SnapSource,\n} from '@weasel-js/core';\nimport { DEFAULT_SNAP_PX, createSnapOutcomeStore, assertSnapSourceIds } from '@weasel-js/core';\nimport { isDev, type KitSettingsStore } from '@weasel-js/react';\nimport {\n aabbOfPoints,\n add,\n dot,\n intersectRayAabb,\n intersectRayPlane,\n len,\n normalize,\n pointOnRay,\n quatIdentity,\n scale as scaleBy,\n sub,\n type Aabb,\n type Vec3,\n} from '@weasel-js/geom/3d';\nimport { cameraEye, type Camera3d } from './camera';\nimport { aabbOfPose, type Pose3 } from './pose3';\nimport { rayAt, rectOf, viewProjectionOf, type Viewport3d } from './project';\nimport { projectAabbToScreen, type ScreenBox } from './screen';\nimport { createSession3d } from './snap/session3d';\n\nimport { DEFAULT_UP, boundsOfNode, type Node3d, type World3d } from './world';\n\nexport type { Viewport3d, ViewportSource } from './project';\nexport type { NodeBounds, Node3d, Scene3d, World3d } from './world';\n\n/**\n * The plane through `p` that faces the camera.\n *\n * This is the depth choice the kit's reverse contracts need: a screen\n * rectangle names a pose only once something says how far away it is, and the\n * answer is \"as far as it already was\". Nothing resolved on this plane changes\n * depth, and one screen pixel is the same world distance everywhere on it.\n */\nfunction viewPlaneAt(camera: Camera3d, p: Vec3): { normal: Vec3; offset: number } {\n const normal = normalize(sub(camera.target, cameraEye(camera)));\n return { normal, offset: dot(normal, p) };\n}\n\n/** Where a screen point lands on `plane`, or `null` when it casts no ray. */\nfunction onPlane(\n vp: Viewport3d,\n plane: { normal: Vec3; offset: number },\n point: { x: number; y: number },\n): Vec3 | null {\n const ray = rayAt(vp, point);\n if (!ray) return null;\n const t = intersectRayPlane(ray, plane.normal, plane.offset);\n return t === null ? null : pointOnRay(ray, t);\n}\n\nfunction overlaps(a: ScreenBox, b: ScreenBox): boolean {\n return (\n a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y\n );\n}\n\n/** The screen box a node covers, or null when it projects to nothing visible. */\nexport function screenBoxOf<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n id: NodeId,\n viewport: Viewport3d,\n): ScreenBox | null {\n const node = world.scene.get(id) as Node3d<TData, TLayer> | undefined;\n if (!node) return null;\n return projectAabbToScreen(\n boundsOfNode(world, node),\n viewProjectionOf(viewport),\n rectOf(viewport),\n );\n}\n\n/**\n * Nearest node along the ray the screen point names.\n *\n * The kit calls this with what it believes is a world point; a 3D host feeds\n * the dispatcher an identity `clientToWorld`, so it is the pane-relative screen\n * point, which is exactly what a ray needs.\n */\nexport function createNodeAtPoint<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n): NodeAtPointDep {\n return (point, exclude) => {\n const excluded = exclude ? new Set(exclude) : null;\n const vp = world.viewport();\n const ray = rayAt(vp, point);\n if (!ray) return null;\n let best: NodeId | null = null;\n let bestT = Infinity;\n for (const node of world.scene.renderOrderNodes() as readonly Node3d<TData, TLayer>[]) {\n if (excluded?.has(node.id)) continue;\n const { min, max } = boundsOfNode(world, node);\n const t = intersectRayAabb(ray, min, max);\n if (t !== null && t < bestT) {\n bestT = t;\n best = node.id;\n }\n }\n return best;\n };\n}\n\n/** Marquee: the nodes whose projected box the screen rectangle touches. */\nexport function createAreaSelect<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n selection: { get(): readonly NodeId[]; set(ids: NodeId[]): void },\n): AreaSelectDep {\n return {\n hitTestArea(bounds) {\n const vp = world.viewport();\n const hits: NodeId[] = [];\n for (const node of world.scene.renderOrderNodes()) {\n const box = screenBoxOf(world, node.id, vp);\n if (box && overlaps(box, bounds)) hits.push(node.id);\n }\n return hits;\n },\n getSelection: () => [...selection.get()],\n setSelection: (ids) => selection.set([...ids]),\n };\n}\n\n/** Options for `createSnap`. */\nexport interface Snap3dOptions {\n /** What a gesture snaps to, in order: earlier wins a full tie. Two sharing\n * an id throw. Default none, which leaves only the gesture's own constraint. */\n sources?: readonly SnapSource<Vec3>[];\n /** The reach of a source that sets none, in screen px. Overrides the kit\n * setting `targets.snapPx`. */\n reachPx?: number;\n /** Where `targets.snapPx` is read, when each gesture begins. Absent, and\n * with no `reachPx`, reach is `DEFAULT_SNAP_PX`. */\n kitSettings?: KitSettingsStore;\n /** Where the marks of the snap in flight are written, for a host to draw\n * with `projectSnapMarks`. */\n store?: SnapOutcomeStore<Vec3>;\n}\n\nlet warnedGestureSources = false;\n\nfunction warnGestureSources(): void {\n if (warnedGestureSources || !isDev()) return;\n warnedGestureSources = true;\n console.warn(\n '[kernel3d] a gesture passed snap `sources`, which are 2D and are not asked in a 3D host. ' +\n 'List 3D sources in createSnap({ sources }).',\n );\n}\n\n/**\n * The `snap` dep over a 3D world. A gesture's `omit` is honored; its 2D\n * `sources` are not asked. A move snaps its subject's world box on the\n * plane it already moves on; an insert snaps the pointer on the ground. Both\n * answer in screen points, which `translate` and `createInsert` cast back\n * onto the same plane, landing exactly where the snap put them.\n */\nexport function createSnap<TData, TLayer extends string>(\n world: World3d<TData, TLayer>, opts: Snap3dOptions = {},\n): SnapDep {\n const store = opts.store ?? createSnapOutcomeStore<Vec3>();\n const listed = opts.sources ?? [];\n assertSnapSourceIds(listed);\n return {\n begin: (req) => {\n if (req.sources?.length) warnGestureSources();\n const omit = new Set(req.omit);\n const sources = listed.filter((s) => !omit.has(s.id));\n return createSession3d({\n req, world, sources, store,\n reachPx: opts.reachPx ?? opts.kitSettings?.get('targets.snapPx') ?? DEFAULT_SNAP_PX,\n });\n },\n };\n}\n\n/**\n * `PoseDescriptor` over a 3D pose, with `Bounds` read as the screen box the\n * node covers.\n *\n * `forNode` is what lets a sphere bound itself as a sphere: the shape lives\n * on `node.data`. Unspecialized — the kit calling with only a pose in hand —\n * it answers with the default local box, which is the looser of the two.\n *\n * `remapBounds` and `fromBounds` take a screen rectangle, which names a pose\n * only once something supplies a depth. Both resolve it against the plane\n * through the pose they were handed, facing the camera, so nothing they\n * produce changes depth.\n */\nexport function createPoseDescriptor<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n): PoseDescriptor<Pose3, Node3d<TData, TLayer>> {\n const up = world.up ?? DEFAULT_UP;\n const upAxis = up.y !== 0 ? 'y' : up.x !== 0 ? 'x' : 'z';\n const specialized = new WeakMap<object, PoseDescriptor<Pose3, Node3d<TData, TLayer>>>();\n\n // A drag whose camera stops casting rays mid-gesture keeps moving through the\n // last one that did, rather than snapping the node back.\n let lastCastable: Viewport3d | null = null;\n function castableViewport(): Viewport3d | null {\n const vp = world.viewport();\n const rect = rectOf(vp);\n if (rayAt(vp, { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 })) lastCastable = vp;\n return lastCastable;\n }\n\n function build(worldBox: (pose: Pose3) => Aabb): PoseDescriptor<Pose3, Node3d<TData, TLayer>> {\n const boundsIn = (vp: Viewport3d, pose: Pose3) =>\n projectAabbToScreen(worldBox(pose), viewProjectionOf(vp), rectOf(vp));\n const boundsOf = (pose: Pose3) => boundsIn(world.viewport(), pose);\n\n const descriptor: PoseDescriptor<Pose3, Node3d<TData, TLayer>> = {\n forNode(node) {\n let d = specialized.get(node);\n if (!d) {\n // The pose arriving here is often an in-flight override rather than\n // `node.pose`, so the consumer is asked about that pose on this node\n // rather than about the node as committed.\n d = build((pose) => boundsOfNode(world, { ...node, pose }));\n specialized.set(node, d);\n }\n return d;\n },\n\n getBounds(pose) {\n return boundsOf(pose) ?? { x: 0, y: 0, width: 0, height: 0 };\n },\n\n /**\n * The src→dst screen map, applied at the pose's own depth: the node's\n * screen anchor moves the way the rectangle does, and both ends of that\n * move are read back off the plane through its position, so the world\n * delta is exact rather than a scaled screen one.\n *\n * The scale is uniform. The rectangle names two extents and a pose has\n * three, so there is no reading in which a screen box resizes a solid\n * per-axis; the geometric mean is the one factor that agrees with both\n * of the extents it does name.\n */\n remapBounds(pose, src, dst) {\n const vp = castableViewport();\n if (!vp) return pose;\n const box = boundsIn(vp, pose);\n if (!box) return pose;\n\n const kx = src.width === 0 ? 1 : dst.width / src.width;\n const ky = src.height === 0 ? 1 : dst.height / src.height;\n const from = { x: box.x + box.width / 2, y: box.y + box.height / 2 };\n const to = {\n x: dst.x + (from.x - src.x) * kx,\n y: dst.y + (from.y - src.y) * ky,\n };\n\n const plane = viewPlaneAt(vp.camera, pose.position);\n const before = onPlane(vp, plane, from);\n const after = onPlane(vp, plane, to);\n if (!before || !after) return pose;\n\n const k = Math.sqrt(Math.abs(kx * ky));\n return {\n ...pose,\n position: add(pose.position, sub(after, before)),\n scale: scaleBy(pose.scale, k),\n };\n },\n\n /**\n * The world box the rectangle covers at the template's depth, as a pose.\n *\n * The rectangle is flat and a box is not, so the third extent — the one\n * no screen rectangle names — is the mean of the two it does. The result\n * is world-axis-aligned and unrotated: the pose carries none of the\n * template's shape, which is the contract, and it takes only its depth.\n *\n * Extents are written as `scale`, so this reads a pose as carrying a\n * unit primitive — the same assumption `aabbOfPose` makes by default.\n */\n fromBounds(bounds, template) {\n const vp = castableViewport();\n if (!vp) return template;\n const plane = viewPlaneAt(vp.camera, template.position);\n\n const corners: Vec3[] = [];\n for (const [x, y] of [\n [bounds.x, bounds.y],\n [bounds.x + bounds.width, bounds.y],\n [bounds.x, bounds.y + bounds.height],\n [bounds.x + bounds.width, bounds.y + bounds.height],\n ]) {\n const corner = onPlane(vp, plane, { x, y });\n if (!corner) return template;\n corners.push(corner);\n }\n\n const width = len(sub(corners[1]!, corners[0]!));\n const height = len(sub(corners[2]!, corners[0]!));\n const half = Math.sqrt(width * height) / 2;\n const box = aabbOfPoints(\n corners.flatMap((c) => [\n add(c, scaleBy(plane.normal, half)),\n sub(c, scaleBy(plane.normal, half)),\n ]),\n );\n return {\n position: scaleBy(add(box.min, box.max), 0.5),\n rotation: quatIdentity(),\n scale: sub(box.max, box.min),\n };\n },\n\n /** Screen-space deltas resolve against the plane the node already sits on. */\n translate(pose, dx, dy) {\n const vp = castableViewport();\n if (!vp) return pose;\n const box = boundsIn(vp, pose);\n if (!box) return pose;\n const from = { x: box.x + box.width / 2, y: box.y + box.height / 2 };\n const to = { x: from.x + dx, y: from.y + dy };\n const offset = dot(up, pose.position);\n\n const ray = rayAt(vp, to);\n if (!ray) return pose;\n const t = intersectRayPlane(ray, up, offset);\n if (t === null) return pose;\n\n const anchorRay = rayAt(vp, from);\n if (!anchorRay) return pose;\n const anchorT = intersectRayPlane(anchorRay, up, offset);\n if (anchorT === null) return pose;\n\n const delta = sub(pointOnRay(ray, t), pointOnRay(anchorRay, anchorT));\n const position = {\n x: pose.position.x + delta.x,\n y: pose.position.y + delta.y,\n z: pose.position.z + delta.z,\n };\n position[upAxis] = pose.position[upAxis];\n return { ...pose, position };\n },\n\n supportsRotation() {\n return false;\n },\n };\n\n return descriptor;\n }\n\n return build((pose) => aabbOfPose(pose));\n}\n","/** The `insert` dep over a 3D world: a drag becomes a footprint on the ground. */\n\nimport type { InsertDep, InsertEnds, InsertExtras, NodeId } from '@weasel-js/core';\nimport { intersectRayPlane, pointOnRay, scale as scaleBy, sub, type Vec3 } from '@weasel-js/geom/3d';\nimport { rayAt, type ViewportSource } from './project';\nimport { DEFAULT_UP } from './world';\n\n/** The ground-plane rectangle a drag swept out, in world units. */\nexport interface Footprint {\n /** Centre of the swept rectangle, on the ground plane. */\n center: Vec3;\n /** Extent along the two axes the up axis is not. */\n width: number;\n depth: number;\n}\n\n/** The ground points a footprint spans. A drag's two ends are cast rather\n * than its box's corners: in perspective the other two corners land outside\n * the rectangle the ends make, and would carry the footprint past a corner\n * the drag snapped to. */\nfunction footprintPoints(\n bounds: { x: number; y: number; width: number; height: number },\n ends: InsertEnds | undefined,\n cast: (p: { x: number; y: number }) => Vec3 | null,\n): Vec3[] {\n if (ends) {\n const start = cast(ends.start);\n const end = cast(ends.end);\n if (!start || !end) return [];\n return ends.fromCenter ? [end, sub(scaleBy(start, 2), end)] : [start, end];\n }\n const corners = [\n { x: bounds.x, y: bounds.y },\n { x: bounds.x + bounds.width, y: bounds.y },\n { x: bounds.x, y: bounds.y + bounds.height },\n { x: bounds.x + bounds.width, y: bounds.y + bounds.height },\n ];\n return corners.map(cast).filter((h): h is Vec3 => h !== null);\n}\n\n/**\n * A drag becomes a footprint on the ground plane: its ends, or without them\n * its box's four corners, are cast onto the plane and the hit points give the\n * extent. What node that implies is the consumer's answer — the kernel does\n * not know what it is inserting. The depth the 2D contract cannot express\n * comes from the plane, not from the caller.\n */\nexport function createInsert(opts: {\n viewport: ViewportSource;\n up?: Vec3;\n /** Smallest footprint a click-sized drag produces. Default 0.25. */\n minExtent?: number;\n mint(footprint: Footprint, extras: InsertExtras): NodeId | null;\n}): InsertDep {\n const up = opts.up ?? DEFAULT_UP;\n const minExtent = opts.minExtent ?? 0.25;\n // The two axes the up axis is not, so a footprint reads the same whichever\n // way up the world is.\n const axes: readonly ['x' | 'y' | 'z', 'x' | 'y' | 'z'] =\n up.y !== 0 ? ['x', 'z'] : up.x !== 0 ? ['y', 'z'] : ['x', 'y'];\n\n return {\n commit(bounds, extras, ends) {\n const vp = opts.viewport();\n const cast = (p: { x: number; y: number }): Vec3 | null => {\n const ray = rayAt(vp, p);\n const t = ray && intersectRayPlane(ray, up, 0);\n return ray && t !== null ? pointOnRay(ray, t) : null;\n };\n const hits = footprintPoints(bounds, ends, cast);\n if (hits.length === 0) return null;\n\n const [u, v] = axes;\n let minU = Infinity, maxU = -Infinity, minV = Infinity, maxV = -Infinity;\n for (const h of hits) {\n minU = Math.min(minU, h[u]); maxU = Math.max(maxU, h[u]);\n minV = Math.min(minV, h[v]); maxV = Math.max(maxV, h[v]);\n }\n\n const center = { x: 0, y: 0, z: 0 };\n center[u] = (minU + maxU) / 2;\n center[v] = (minV + maxV) / 2;\n return opts.mint(\n {\n center,\n width: Math.max(minExtent, maxU - minU),\n depth: Math.max(minExtent, maxV - minV),\n },\n extras,\n );\n },\n };\n}\n","/** What a 3D scene offers a snap session: its boxes' corners, edges, faces\n * and centers, the planes through their sides and centers, and a grid on\n * the ground. */\n\nimport type { SnapCollect, SnapMark, SnapSource, SourceCandidate } from '@weasel-js/core';\nimport { add, distance, dot, len, normalize, scale, sub, type Aabb, type Vec3 } from '@weasel-js/geom/3d';\nimport { DEFAULT_UP, boundsOfNode, type Node3d, type World3d } from '../world';\nimport { planeBasis } from './plane';\nimport { boxCorner } from './probes3d';\n\ntype Axis = 'x' | 'y' | 'z';\ntype Candidate = SourceCandidate<Vec3>;\n\nconst AXES: readonly Axis[] = ['x', 'y', 'z'];\nconst BITS = [1, 2, 4] as const;\nconst UNIT: Record<Axis, Vec3> = { x: { x: 1, y: 0, z: 0 }, y: { x: 0, y: 1, z: 0 }, z: { x: 0, y: 0, z: 1 } };\nconst ACROSS: Record<Axis, readonly Vec3[]> = { x: [UNIT.y, UNIT.z], y: [UNIT.x, UNIT.z], z: [UNIT.x, UNIT.y] };\n\nfunction boxesOf<TData, TLayer extends string>(world: World3d<TData, TLayer>, q: SnapCollect<Vec3>): Aabb[] {\n const excluded = new Set(q.exclude);\n const out: Aabb[] = [];\n for (const node of world.scene.renderOrderNodes() as readonly Node3d<TData, TLayer>[]) {\n if (!excluded.has(node.id)) out.push(boundsOfNode(world, node));\n }\n return out;\n}\n\nfunction distanceToBox(p: Vec3, box: Aabb): number {\n const d = (a: Axis) => Math.max(box.min[a] - p[a], 0, p[a] - box.max[a]);\n return Math.hypot(d('x'), d('y'), d('z'));\n}\n\nconst centerOf = (box: Aabb): Vec3 => scale(add(box.min, box.max), 0.5);\nconst isZero = (v: Vec3) => v.x === 0 && v.y === 0 && v.z === 0;\n\n/**\n * Each node's world box as targets for geometry and pointer probes: its 8\n * corners and its center as points, its 12 edges as segments, and its 6\n * faces as bounded planes. Targets past the reach are not offered.\n */\nexport function boxSnapSource<TData, TLayer extends string>(world: World3d<TData, TLayer>): SnapSource<Vec3> {\n return {\n id: 'box',\n roles: ['geometry', 'pointer'],\n *collect(q) {\n const r = q.reachWorld(q.reachPx);\n for (const box of boxesOf(world, q)) {\n for (const p of q.probes) {\n if (distanceToBox(p.at, box) <= r) yield* boxLoci(p.id, p.at, box, r);\n }\n }\n },\n };\n}\n\nfunction* boxLoci(probe: string, at: Vec3, box: Aabb, r: number): Generator<Candidate> {\n for (let i = 0; i < 8; i++) {\n const c = boxCorner(box, i);\n if (distance(at, c) <= r) yield { probe, locus: { at: c, dirs: [] }, mark: { kind: 'point', at: c, glyph: 'corner' } };\n }\n const center = centerOf(box);\n if (distance(at, center) <= r) {\n yield { probe, locus: { at: center, dirs: [] }, mark: { kind: 'point', at: center, glyph: 'center' } };\n }\n for (let i = 0; i < 8; i++) {\n for (const bit of BITS) {\n if (i & bit) continue;\n const a = boxCorner(box, i);\n const b = boxCorner(box, i | bit);\n const dir = sub(b, a);\n if (isZero(dir) || distanceToBox(at, { min: a, max: b }) > r) continue;\n yield { probe, locus: { at: a, dirs: [dir], span: [[0, 1]] }, mark: { kind: 'line', from: a, to: b } };\n }\n }\n for (const bit of BITS) {\n const [b1, b2] = BITS.filter((b) => b !== bit) as [number, number];\n for (const base of [0, bit]) {\n const o = boxCorner(box, base);\n const far = boxCorner(box, base | b1 | b2);\n const d1 = sub(boxCorner(box, base | b1), o);\n const d2 = sub(boxCorner(box, base | b2), o);\n if (isZero(d1) || isZero(d2) || distanceToBox(at, { min: o, max: far }) > r) continue;\n yield {\n probe,\n locus: { at: o, dirs: [d1, d2], span: [[0, 1], [0, 1]] },\n mark: () => outline([o, boxCorner(box, base | b1), far, boxCorner(box, base | b2)]),\n };\n }\n }\n}\n\nfunction outline(ring: readonly Vec3[]): SnapMark<Vec3>[] {\n return ring.map((from, i) => ({ kind: 'line', from, to: ring[(i + 1) % ring.length]! }));\n}\n\n/**\n * The planes through each node's world box at its min, center and max on\n * every axis, as targets for box and pointer probes: alignment in depth as\n * well as across. Boxes sharing a plane offer it once, and its mark reaches\n * each of them.\n */\nexport function alignPlaneSource<TData, TLayer extends string>(world: World3d<TData, TLayer>): SnapSource<Vec3> {\n return {\n id: 'align-plane',\n roles: ['box', 'pointer'],\n *collect(q) {\n const r = q.reachWorld(q.reachPx);\n for (const [axis, planes] of planesOf(boxesOf(world, q))) {\n for (const [value, ends] of planes) {\n for (const p of q.probes) {\n if (Math.abs(p.at[axis] - value) > r) continue;\n yield {\n probe: p.id,\n locus: { at: ends[0]!, dirs: ACROSS[axis] },\n mark: (delta: Vec3): SnapMark<Vec3>[] => {\n const from = add(sub(p.at, q.delta0), delta);\n return ends.map((to) => ({ kind: 'line', from, to }));\n },\n };\n }\n }\n }\n },\n };\n}\n\n/** Per axis, each plane value the boxes have a side or center on, and the\n * point on it at each such box's center. */\nfunction planesOf(boxes: readonly Aabb[]): Map<Axis, Map<number, Vec3[]>> {\n const out = new Map<Axis, Map<number, Vec3[]>>(AXES.map((a) => [a, new Map()]));\n for (const box of boxes) {\n const center = centerOf(box);\n for (const axis of AXES) {\n const planes = out.get(axis)!;\n for (const value of new Set([box.min[axis], center[axis], box.max[axis]])) {\n const on = { ...center, [axis]: value };\n const ends = planes.get(value);\n if (ends) ends.push(on);\n else planes.set(value, [on]);\n }\n }\n }\n return out;\n}\n\n/** Options for `groundGridSource`. */\nexport interface GroundGridSourceOptions {\n /** The grid's pitch, in world units. */\n step: number;\n /** The ground's normal; the grid lies on `up · p = 0`. Default `+y`. */\n up?: Vec3;\n}\n\n/**\n * A grid on the ground plane as snap targets: for each pointer or geometry\n * probe on the ground, the grid line on either side of it along each of the\n * ground's two axes. Its reach is unlimited and it is a fallback, so it\n * holds every axis no target claims and never displaces one.\n */\nexport function groundGridSource(opts: GroundGridSourceOptions): SnapSource<Vec3> {\n const up = normalize(opts.up ?? DEFAULT_UP);\n const [u, v] = planeBasis(up);\n const lines = (c: number): [number, number] => {\n const near = Math.round(c / opts.step) * opts.step;\n return [near, near + (c >= near ? opts.step : -opts.step)];\n };\n return {\n id: 'ground-grid',\n tier: 'fallback',\n reachPx: Infinity,\n roles: ['pointer', 'geometry'],\n *collect(q) {\n for (const p of q.probes) {\n if (Math.abs(dot(p.at, up)) > 1e-6 * Math.max(1, len(p.at))) continue;\n const a = dot(p.at, u);\n const b = dot(p.at, v);\n for (const at of lines(a)) yield { probe: p.id, locus: { at: add(scale(u, at), scale(v, b)), dirs: [v] } };\n for (const at of lines(b)) yield { probe: p.id, locus: { at: add(scale(u, a), scale(v, at)), dirs: [u] } };\n }\n },\n };\n}\n","import type { SnapMark } from '@weasel-js/core';\nimport type { Vec3 } from '@weasel-js/geom/3d';\nimport { projectPoint, type Viewport3d } from '../project';\n\ntype Point = { x: number; y: number };\n\n/** A snap mark's segment on screen: a line, a gap, or a distance. */\nexport interface ScreenLine {\n from: Point;\n to: Point;\n /** A gap's or distance's value, in world units. */\n value?: number;\n color?: string;\n}\n\n/** A snap mark's point on screen. */\nexport interface ScreenPoint {\n at: Point;\n glyph: string;\n label?: string;\n color?: string;\n}\n\n/**\n * The marks a 3D snap session draws, in the viewport's screen space, for a\n * host to draw through its own renderer. A mark with any point that does not\n * project — behind the camera — is dropped whole.\n */\nexport function projectSnapMarks(\n marks: readonly SnapMark<Vec3>[], viewport: Viewport3d,\n): { lines: ScreenLine[]; points: ScreenPoint[] } {\n const lines: ScreenLine[] = [];\n const points: ScreenPoint[] = [];\n for (const m of marks) {\n if (m.kind === 'point') {\n const at = projectPoint(m.at, viewport);\n if (at) {\n points.push({\n at, glyph: m.glyph,\n ...(m.label !== undefined ? { label: m.label } : {}),\n ...(m.color ? { color: m.color } : {}),\n });\n }\n continue;\n }\n const from = projectPoint(m.from, viewport);\n const to = projectPoint(m.to, viewport);\n if (!from || !to) continue;\n lines.push({\n from, to,\n ...('value' in m ? { value: m.value } : {}),\n ...(m.color ? { color: m.color } : {}),\n });\n }\n return { lines, points };\n}\n","/**\n * What a host paints for a gesture that proposes chrome rather than a pose.\n *\n * A marquee sweep and a box-drag both publish an `OngoingOverlay`.\n * `resolveOverlays` hands back world geometry with no renderer in it, so the\n * same call `<SceneCanvas>` makes serves a consumer-owned 3D renderer.\n *\n * A 3D host's `clientToWorld` is identity, so an overlay's world bounds are the\n * client rect the deps already work in, and the pane origin comes off exactly\n * once. Only the rectangular variants resolve here: a lasso, a pencil, and a run\n * of points are paths, and a path is geometry this cannot flatten to a box.\n */\n\nimport { overlaysOf, resolveOverlays, type OngoingHandle } from '@weasel-js/core';\nimport type { ChromeBox } from './screen';\n\n/** Gesture chrome, in CSS pixels relative to the pane's top-left. */\nexport function collectOverlayBoxes(\n handles: Iterable<OngoingHandle>,\n origin: { x: number; y: number },\n): ChromeBox[] {\n const overlays = [];\n for (const handle of handles) overlays.push(...overlaysOf(handle));\n\n const boxes: ChromeBox[] = [];\n for (const resolved of resolveOverlays(overlays)) {\n if (resolved.kind !== 'marquee' && resolved.kind !== 'insertPreview') continue;\n const { x, y, width, height } = resolved.bounds;\n boxes.push({ x: x - origin.x, y: y - origin.y, width, height, tint: 'gesture' });\n }\n return boxes;\n}\n","/**\n * Camera tools and their actions.\n *\n * Shape tools transfer from the kit untouched — a 3D host mounts core's own\n * `useSelectTool` and a rectangle-style insert binding and neither notices the\n * dimension. Only the viewport tools are written here, which is the one\n * exception the kernel doc predicted: `useHandTool` routes to\n * `viewport.dragPan`, and that wants the 2D `view`.\n */\n\nimport { useMemo } from 'react';\nimport { defineTool, type Action, type InvocationCtx, type Tool } from '@weasel-js/core';\nimport { dollyToward, orbitBy, panBy, type Camera3d } from './camera';\nimport type { Camera3dDep } from './cameraDep';\n\n/** Radians per CSS pixel of drag. A full pane width is a bit over half a turn. */\nexport const ORBIT_RATE = 0.006;\n/** Dolly exponent per unit of wheel `deltaY`. */\nexport const DOLLY_RATE = 0.0015;\n\n/**\n * The drag's cumulative client-pixel delta.\n *\n * The fallback is only sound because a 3D host's `clientToWorld` is identity\n * (see `overlays.ts`), so the world delta already is the client one. Don't copy\n * this to a host with a 2D view — there the two spaces differ by the zoom.\n */\nfunction screenDelta(move: InvocationCtx): { x: number; y: number } | undefined {\n return move.drag?.screenDelta ?? move.drag?.delta;\n}\n\n/** An ongoing drag replacing the `camera3d` dep with `step` of the camera as\n * it was when the drag began. `drag.delta` runs from the drag origin, not the\n * previous move, so every move composes against that one camera. */\nfunction dragCamera(\n ctx: InvocationCtx,\n kind: string,\n step: (origin: Camera3d, delta: { x: number; y: number }, dep: Camera3dDep) => Camera3d,\n) {\n const dep = ctx.deps.camera3d;\n const origin: Camera3d | undefined = dep?.get();\n return {\n kind,\n onMove(move: InvocationCtx) {\n const delta = screenDelta(move);\n if (!dep || !origin || !delta) return;\n dep.set(step(origin, delta, dep));\n },\n };\n}\n\n/** `camera.orbit`: an ongoing drag that turns the `camera3d` dep about its\n * target. */\nexport const orbitAction: Action = {\n id: 'camera.orbit',\n label: 'Orbit',\n group: 'viewport',\n cursor: 'grab',\n activeCursor: 'grabbing',\n requires: ['camera3d', 'kitSettings'],\n invoker: {\n timing: 'ongoing',\n start(ctx) {\n const rate = ctx.deps.kitSettings?.get('orbit3d.orbitRate') ?? ORBIT_RATE;\n return dragCamera(ctx, 'orbit', (origin, d, dep) =>\n orbitBy(origin, -d.x * rate, d.y * rate, dep.limits?.()));\n },\n },\n};\n\n/** `camera.pan`: an ongoing drag that slides the `camera3d` dep's target\n * across the screen plane, so the point at the target follows the pointer. */\nexport const panAction: Action = {\n id: 'camera.pan',\n label: 'Pan',\n group: 'viewport',\n cursor: 'move',\n requires: ['camera3d'],\n invoker: {\n timing: 'ongoing',\n start(ctx) {\n return dragCamera(ctx, 'pan', (origin, d, dep) =>\n panBy(origin, d.x, d.y, dep.size().height));\n },\n },\n};\n\n/** Where on the pane a dolly anchors: the canvas-local point the event\n * carries, or the middle when it carries none. */\nfunction anchorOf(\n params: Record<string, unknown> | undefined,\n pane: { width: number; height: number },\n): { x: number; y: number } {\n const x = params?.clientX;\n const y = params?.clientY;\n return typeof x === 'number' && typeof y === 'number'\n ? { x, y }\n : { x: pane.width / 2, y: pane.height / 2 };\n}\n\n/** `camera.dolly`: moves the `camera3d` dep in or out about the point under\n * the pointer, as a 2D camera's wheel zooms about it. A wheel's `deltaY`, and\n * a trackpad pinch delivered as ctrl+wheel, dolly by `exp(deltaY × rate)` —\n * one rate for both, as a 2D camera zooms by both. Safari's pinch arrives as\n * a `scale` and divides the distance by it. Bound to all three by default, in\n * every tool. */\nexport const dollyAction: Action = {\n id: 'camera.dolly',\n label: 'Dolly',\n group: 'viewport',\n defaultBinding: [\n { spec: { kind: 'wheel' }, opts: {} },\n // Unbound, a trackpad pinch zooms the page instead.\n { spec: { kind: 'wheel', mods: { ctrl: true } }, opts: {} },\n { spec: { kind: 'pinch' }, opts: {} },\n ],\n requires: ['camera3d', 'kitSettings'],\n invoker: {\n timing: 'immediate',\n run(deps, params) {\n const dep = deps.camera3d;\n if (!dep) return;\n const factor = typeof params?.scale === 'number'\n ? 1 / params.scale\n : Math.exp(\n (typeof params?.deltaY === 'number' ? params.deltaY : 0)\n * (deps.kitSettings?.get('orbit3d.dollyRate') ?? DOLLY_RATE),\n );\n if (!(factor > 0) || !Number.isFinite(factor)) return;\n const pane = dep.size();\n dep.set(dollyToward(dep.get(), factor, anchorOf(params, pane), pane, dep.limits?.()));\n },\n },\n};\n\n/** `camera.pinchDolly`: two fingers spreading dolly the `camera3d` dep in and\n * closing dolly it out, by the ratio of their spread, about where they began. */\nexport const pinchDollyAction: Action = {\n id: 'camera.pinchDolly',\n label: 'Pinch Dolly',\n group: 'viewport',\n defaultBinding: { kind: 'multiTouch', fingers: 2 },\n requires: ['camera3d'],\n invoker: {\n timing: 'ongoing',\n start(ctx) {\n const dep = ctx.deps.camera3d;\n const origin: Camera3d | undefined = dep?.get();\n const startSpread = ctx.multiTouch?.spread ?? 0;\n const at = ctx.multiTouch?.centroid;\n return {\n kind: 'pinch',\n onMove(move) {\n const spread = move.multiTouch?.pinch?.currentSpread ?? 0;\n if (!dep || !origin || !(startSpread > 0) || !(spread > 0)) return;\n const pane = dep.size();\n const anchor = at ?? { x: pane.width / 2, y: pane.height / 2 };\n dep.set(dollyToward(origin, startSpread / spread, anchor, pane, dep.limits?.()));\n },\n };\n },\n },\n};\n\n/** `camera.home`: returns the `camera3d` dep to its `home`. Bound to a double\n * click by default. */\nexport const homeAction: Action = {\n id: 'camera.home',\n label: 'Reset Camera',\n group: 'viewport',\n defaultBinding: { kind: 'doubleClick' },\n requires: ['camera3d'],\n invoker: {\n timing: 'immediate',\n run(deps) {\n const dep = deps.camera3d;\n const home = dep?.home?.();\n if (dep && home) dep.set(home);\n },\n },\n};\n\n/** A tool that binds a drag to `camera.orbit` and Shift+drag to `camera.pan`.\n * Register both actions alongside it; the tool only declares the bindings. */\nexport function useOrbitTool(): Tool {\n return useMemo(() => defineTool({\n id: 'orbit',\n hookName: 'useOrbitTool',\n cursor: 'grab',\n presentation: { label: 'Orbit', group: 'viewport' },\n bindings: [\n { spec: { kind: 'drag' }, actionId: 'camera.orbit' },\n { spec: { kind: 'drag', mods: { shift: true } }, actionId: 'camera.pan' },\n ],\n }), []);\n}\n","import type {} from '@weasel-js/react';\nimport { pref } from '@weasel-js/prefs';\nimport { DOLLY_RATE, ORBIT_RATE } from './tools';\n\n/** The `orbit3d` kit settings area: how far the camera tools move per input. */\nexport interface Orbit3dKitSettings {\n /** Radians of orbit per CSS pixel of drag. */\n orbitRate: number;\n /** Dolly exponent per unit of wheel `deltaY`. */\n dollyRate: number;\n}\n\ndeclare module '@weasel-js/react' {\n interface KitSettings {\n orbit3d: Orbit3dKitSettings;\n }\n}\n\n/** The `orbit3d` area as a prefs group whose paths are the `KitSettings` paths. */\nexport const kernel3dKitSettingsSchema = pref.group('3D camera', {\n orbit3d: pref.group('Orbit', {\n orbitRate: pref.number('Orbit speed', ORBIT_RATE, { min: 0.001, max: 0.03, step: 0.001 }),\n dollyRate: pref.number('Dolly speed', DOLLY_RATE, { min: 0.0002, max: 0.01, step: 0.0001 }),\n }),\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/camera.ts","../src/pose3.ts","../src/screen.ts","../src/project.ts","../src/world.ts","../src/pickIndex.ts","../src/snap/plane.ts","../src/snap/probes3d.ts","../src/snap/session3d.ts","../src/deps.ts","../src/insert.ts","../src/aim.ts","../src/snap/sources.ts","../src/snap/marks.ts","../src/overlays.ts","../src/tools.ts","../src/kitSettings.ts"],"names":["distance","scale","transformPoint4","normalize","sub","dot","add","ZERO","cross","intersectRayPlane","pointOnRay","build","scaleBy","len","quatIdentity"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * An orbit camera: a target, two angles and a distance. Immutable — every\n * gesture returns a new one, so it can live in instrument state.\n *\n * This is the shape `ViewApi` cannot hold, and the reason the kernel declares a\n * `camera3d` dep of its own rather than reusing the kit's `view`.\n */\n\nimport {\n add,\n lookAt,\n multiply,\n perspective,\n scale,\n type Mat4,\n type Vec3,\n} from '@weasel-js/geom/3d';\n\n/** An orbit camera. The eye sits `distance` world units from `target` at\n * `yaw`/`pitch`; `fov` is the vertical field of view in radians, and\n * `near`/`far` the clip distances. */\nexport interface Camera3d {\n target: Vec3;\n /** Radians about +y, measured from +z. */\n yaw: number;\n /** Radians above the xz plane. */\n pitch: number;\n distance: number;\n fov: number;\n near: number;\n far: number;\n}\n\n/** Short of vertical: at exactly ±π/2 the eye lands on the up axis and `lookAt` degenerates. */\nexport const MAX_PITCH = Math.PI / 2 - 0.01;\nconst UP: Vec3 = { x: 0, y: 1, z: 0 };\n\n/** A camera with defaults for every field not given: origin target, level at\n * yaw 0, distance 10, fov π/4, near 0.1, far 1000. */\nexport function createCamera(init: Partial<Camera3d>): Camera3d {\n return {\n target: init.target ?? { x: 0, y: 0, z: 0 },\n yaw: init.yaw ?? 0,\n pitch: init.pitch ?? 0,\n distance: init.distance ?? 10,\n fov: init.fov ?? Math.PI / 4,\n near: init.near ?? 0.1,\n far: init.far ?? 1000,\n };\n}\n\n/** The eye's world position. */\nexport function cameraEye(camera: Camera3d): Vec3 {\n const { target, yaw, pitch, distance } = camera;\n const horizontal = Math.cos(pitch) * distance;\n return {\n x: target.x + horizontal * Math.sin(yaw),\n y: target.y + Math.sin(pitch) * distance,\n z: target.z + horizontal * Math.cos(yaw),\n };\n}\n\n/** World-to-view matrix, with +y up. */\nexport function cameraView(camera: Camera3d): Mat4 {\n return lookAt(cameraEye(camera), camera.target, UP);\n}\n\n/** World-to-clip matrix for a pane of the given width/height `aspect`. */\nexport function cameraViewProjection(camera: Camera3d, aspect: number): Mat4 {\n return multiply(perspective(camera.fov, aspect, camera.near, camera.far), cameraView(camera));\n}\n\n/** How far an orbit camera may turn and travel. Distances are in world units,\n * so a scene measured in millimeters and one in kilometers want different ones. */\nexport interface OrbitLimits {\n minDistance: number;\n maxDistance: number;\n /** Radians. Held inside ±`MAX_PITCH` whatever is asked for. */\n minPitch: number;\n maxPitch: number;\n}\n\n/** Pitch short of the poles, distance 0.5..500. */\nexport const DEFAULT_ORBIT_LIMITS: OrbitLimits = {\n minDistance: 0.5,\n maxDistance: 500,\n minPitch: -MAX_PITCH,\n maxPitch: MAX_PITCH,\n};\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.max(lo, Math.min(hi, v));\n\n/** The camera with its pitch and distance inside `limits`. Returns `camera`\n * itself when it already holds. */\nexport function clampCamera(camera: Camera3d, limits: Partial<OrbitLimits> = {}): Camera3d {\n const l = { ...DEFAULT_ORBIT_LIMITS, ...limits };\n const pitch = clamp(camera.pitch, Math.max(-MAX_PITCH, l.minPitch), Math.min(MAX_PITCH, l.maxPitch));\n const distance = clamp(camera.distance, l.minDistance, l.maxDistance);\n if (pitch === camera.pitch && distance === camera.distance) return camera;\n return { ...camera, pitch, distance };\n}\n\n/** The camera turned about its target by the given radians, pitch held inside\n * `limits`. Yaw is not wrapped. */\nexport function orbitBy(\n camera: Camera3d,\n deltaYaw: number,\n deltaPitch: number,\n limits?: Partial<OrbitLimits>,\n): Camera3d {\n return clampCamera(\n { ...camera, yaw: camera.yaw + deltaYaw, pitch: camera.pitch + deltaPitch },\n limits,\n );\n}\n\n/** The camera with its distance multiplied by `factor`, held inside `limits`. */\nexport function dollyBy(camera: Camera3d, factor: number, limits?: Partial<OrbitLimits>): Camera3d {\n return clampCamera({ ...camera, distance: camera.distance * factor }, limits);\n}\n\n/**\n * The camera with its target slid across the screen plane, so the point at the\n * target follows a pointer that moved `dx`, `dy` CSS pixels in a pane\n * `paneHeight` pixels tall. Neither angle nor distance changes.\n */\nexport function panBy(camera: Camera3d, dx: number, dy: number, paneHeight: number): Camera3d {\n if (!(paneHeight > 0)) return camera;\n const perPixel = (2 * camera.distance * Math.tan(camera.fov / 2)) / paneHeight;\n const { yaw, pitch } = camera;\n const right: Vec3 = { x: Math.cos(yaw), y: 0, z: -Math.sin(yaw) };\n const up: Vec3 = {\n x: -Math.sin(yaw) * Math.sin(pitch),\n y: Math.cos(pitch),\n z: -Math.cos(yaw) * Math.sin(pitch),\n };\n const shift = add(scale(right, -dx * perPixel), scale(up, dy * perPixel));\n return { ...camera, target: add(camera.target, shift) };\n}\n\n/**\n * `dollyBy` about a point on the pane rather than its middle: the point in the\n * target's screen-facing plane under `at` — CSS pixels from the pane's\n * top-left, in a pane of `pane` size — stays under it, as a 2D camera's wheel\n * zoom keeps the point under the pointer. The target slides toward that point\n * by as much as the distance shrank, so the next turn pivots nearer it.\n */\nexport function dollyToward(\n camera: Camera3d,\n factor: number,\n at: { x: number; y: number },\n pane: { width: number; height: number },\n limits?: Partial<OrbitLimits>,\n): Camera3d {\n const dollied = dollyBy(camera, factor, limits);\n const kept = 1 - dollied.distance / camera.distance;\n const moved = panBy(\n camera,\n -kept * (at.x - pane.width / 2),\n -kept * (at.y - pane.height / 2),\n pane.height,\n );\n return { ...dollied, target: moved.target };\n}\n","/**\n * A 3D pose, and the two things every consumer of one needs: its matrix, and\n * the world box it occupies.\n *\n * `Scene<TData, TLayer, Pose3>` is the whole of how this reaches weasel —\n * `Scene` is generic over its pose and holds this one with no adapter, no\n * subclass and no special case.\n */\n\nimport {\n compose, quatIdentity, transformAabb, type Aabb, type Mat4, type Quat, type Vec3,\n} from '@weasel-js/geom/3d';\n\n/** Position, rotation and scale of a 3D node. */\nexport interface Pose3 {\n position: Vec3;\n rotation: Quat;\n scale: Vec3;\n}\n\n/** The box a primitive occupies before its pose. A unit primitive centred on\n * its own origin — which is what the kernel assumes nothing about — is\n * `UNIT_CUBE`. */\nexport const UNIT_CUBE: Aabb = {\n min: { x: -0.5, y: -0.5, z: -0.5 },\n max: { x: 0.5, y: 0.5, z: 0.5 },\n};\n\n/** A pose at `position`, unscaled and unrotated unless given. */\nexport function pose3(\n position: Vec3,\n scale: Vec3 = { x: 1, y: 1, z: 1 },\n rotation: Quat = quatIdentity(),\n): Pose3 {\n return { position, rotation, scale };\n}\n\n/** The pose as a matrix: scale, then rotation, then translation to\n * `position`. */\nexport function poseMatrix(pose: Pose3): Mat4 {\n return compose(pose.position, pose.rotation, pose.scale);\n}\n\n/**\n * The world box a posed primitive occupies, given the box it occupies in its\n * own space.\n *\n * Which local box a primitive has is the consumer's answer, not the kernel's:\n * a sphere's is rotation-invariant and a mesh's comes from its vertices, and\n * neither is something a pose can tell you.\n */\nexport function aabbOfPose(pose: Pose3, local: Aabb = UNIT_CUBE): Aabb {\n return transformAabb(poseMatrix(pose), local);\n}\n","/**\n * The screen side of the kernel: where a pointer points, and what rectangle a\n * world box covers. This is the seam weasel's 2D chrome meets — everything\n * here speaks `Bounds`-shaped screen rectangles, which is why a 3D host can\n * pass the dispatcher's world point through unchanged.\n */\n\nimport {\n invert,\n normalize,\n sub,\n transformPoint,\n transformPoint4,\n type Aabb,\n type Mat4,\n type Ray,\n type Vec3,\n} from '@weasel-js/geom/3d';\n\n/** A screen rectangle in CSS pixels, in the shape core's `Bounds` uses. Both\n * a pane's own rect and a projected world box are this — one spelling, so the\n * two never need converting between. */\nexport interface ScreenBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** A `ScreenBox` a host is being asked to outline. `tint` says why: warm for\n * what is selected, cool for what the gesture in hand is proposing. */\nexport interface ChromeBox extends ScreenBox {\n tint?: 'selection' | 'gesture';\n}\n\n/** Screen point (y down, rect-relative) to normalized device coordinates (y up). */\nexport function screenToNdc(\n point: { x: number; y: number },\n rect: ScreenBox,\n): { x: number; y: number } {\n return {\n x: ((point.x - rect.x) / rect.width) * 2 - 1,\n y: 1 - ((point.y - rect.y) / rect.height) * 2,\n };\n}\n\n/** Inverse of `screenToNdc`: normalized device coordinates (y up) to a point\n * in `rect`'s space (y down). */\nexport function ndcToScreen(\n ndc: { x: number; y: number },\n rect: ScreenBox,\n): { x: number; y: number } {\n return {\n x: rect.x + (ndc.x * 0.5 + 0.5) * rect.width,\n y: rect.y + (1 - (ndc.y * 0.5 + 0.5)) * rect.height,\n };\n}\n\n/**\n * The ray a screen point names, given the camera that drew the rect. This is\n * the whole of what 3D picking needs from a pointer — which is why the world\n * point the dispatcher carries stays two numbers.\n *\n * `null` when the point names no ray: the view-projection has no inverse (a\n * camera on its own target, a degenerate projection) or the pane has no area.\n */\nexport function rayThroughScreenPoint(\n point: { x: number; y: number },\n rect: ScreenBox,\n viewProjection: Mat4,\n eye: Vec3,\n): Ray | null {\n const inv = invert(viewProjection);\n if (!inv) return null;\n const ndc = screenToNdc(point, rect);\n const near = transformPoint(inv, { x: ndc.x, y: ndc.y, z: -1 });\n const far = transformPoint(inv, { x: ndc.x, y: ndc.y, z: 1 });\n const direction = normalize(sub(far, near));\n // normalize answers zero for a non-finite difference, which is no direction.\n if (direction.x === 0 && direction.y === 0 && direction.z === 0) return null;\n return { origin: eye, direction };\n}\n\ntype Clip = readonly [number, number, number, number];\n\n/** Signed distance to the near plane in clip space; `>= 0` is in front of it.\n * GL puts the near plane at `z = -w`. */\nfunction nearSide(p: Clip): number {\n return p[2] + p[3];\n}\n\nfunction lerpClip(a: Clip, b: Clip, t: number): Clip {\n return [\n a[0] + (b[0] - a[0]) * t,\n a[1] + (b[1] - a[1]) * t,\n a[2] + (b[2] - a[2]) * t,\n a[3] + (b[3] - a[3]) * t,\n ];\n}\n\n/** The three edges leaving corner `i` toward a higher bit, as bit masks. */\nconst EDGE_BITS = [1, 2, 4] as const;\n\n/**\n * The screen rectangle a world-space box covers — the currency weasel's chrome\n * and `PoseDescriptor.getBounds` speak in. `null` when the box is entirely\n * behind the near plane.\n *\n * Each of the twelve edges is clipped against the near plane before it is\n * projected, rather than dropping the corners behind it. Dropping them reports\n * a box that is too small for anything straddling the near plane, and the error\n * grows as the camera moves in: a solid the pointer is inside of would outline\n * as a sliver, or as nothing.\n */\nexport function projectAabbToScreen(\n box: Aabb,\n viewProjection: Mat4,\n rect: ScreenBox,\n): ScreenBox | null {\n const corners: Clip[] = [];\n for (let i = 0; i < 8; i++) {\n const corner: Vec3 = {\n x: i & 1 ? box.max.x : box.min.x,\n y: i & 2 ? box.max.y : box.min.y,\n z: i & 4 ? box.max.z : box.min.z,\n };\n corners.push(transformPoint4(viewProjection, corner));\n }\n\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n let any = false;\n\n const extend = (p: Clip): void => {\n if (!(p[3] > 0)) return;\n const screen = ndcToScreen({ x: p[0] / p[3], y: p[1] / p[3] }, rect);\n minX = Math.min(minX, screen.x);\n minY = Math.min(minY, screen.y);\n maxX = Math.max(maxX, screen.x);\n maxY = Math.max(maxY, screen.y);\n any = true;\n };\n\n for (let i = 0; i < 8; i++) {\n for (const bit of EDGE_BITS) {\n if (i & bit) continue;\n let a = corners[i];\n let b = corners[i | bit];\n const da = nearSide(a);\n const db = nearSide(b);\n if (da < 0 && db < 0) continue;\n if (da < 0) a = lerpClip(a, b, da / (da - db));\n else if (db < 0) b = lerpClip(b, a, db / (db - da));\n extend(a);\n extend(b);\n }\n }\n\n if (!any) return null;\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n","/**\n * A viewport's two directions: a screen point to the ray it names, and a\n * world point to the screen point it draws at. Both speak the coordinate\n * space the host's pointer points arrive in.\n */\n\nimport { transformPoint4, type Ray, type Vec3 } from '@weasel-js/geom/3d';\nimport { cameraEye, cameraViewProjection, type Camera3d } from './camera';\nimport { ndcToScreen, rayThroughScreenPoint, type ScreenBox } from './screen';\n\n/** The camera and the pane it draws into; `width`/`height` are the pane's\n * size in the same units as the pointer points. */\nexport interface Viewport3d {\n camera: Camera3d;\n width: number;\n height: number;\n /**\n * Where the pane sits in client coordinates. A 3D host works in one space\n * from the event to the ray — it passes the dispatcher an identity\n * `clientToWorld` — so the deps subtract this rather than the dispatcher.\n */\n originX?: number;\n originY?: number;\n}\n\n/** Read on every dep call, so a dep always sees the current camera and pane. */\nexport type ViewportSource = () => Viewport3d;\n\ntype Point = { x: number; y: number };\n\n/** The pane, in the coordinate space the host's points arrive in. The origin\n * defaults to the client origin — a host that fills the window passes none. */\nexport function rectOf(viewport: Viewport3d): ScreenBox {\n return {\n x: viewport.originX ?? 0,\n y: viewport.originY ?? 0,\n width: viewport.width,\n height: viewport.height,\n };\n}\n\nexport function viewProjectionOf(viewport: Viewport3d) {\n return cameraViewProjection(viewport.camera, viewport.width / Math.max(1, viewport.height));\n}\n\nexport function rayAt(viewport: Viewport3d, point: Point): Ray | null {\n return rayThroughScreenPoint(\n point,\n rectOf(viewport),\n viewProjectionOf(viewport),\n cameraEye(viewport.camera),\n );\n}\n\n/** Where `p` draws in the viewport, or null when it is behind the near plane\n * or projects to nothing finite. */\nexport function projectPoint(p: Vec3, viewport: Viewport3d): Point | null {\n const [x, y, z, w] = transformPoint4(viewProjectionOf(viewport), p);\n // GL's near plane is z = -w.\n if (!(w > 0) || z < -w) return null;\n const screen = ndcToScreen({ x: x / w, y: y / w }, rectOf(viewport));\n return Number.isFinite(screen.x) && Number.isFinite(screen.y) ? screen : null;\n}\n","/** The 3D world every dep is built from: core's scene with a `Pose3`, the\n * viewport it is seen through, and how wide each node is. */\n\nimport type { Scene, SceneNode } from '@weasel-js/core';\nimport type { Aabb, Vec3 } from '@weasel-js/geom/3d';\nimport { aabbOfPose, type Pose3 } from './pose3';\nimport type { ViewportSource } from './project';\n\n/** A 3D scene is core's scene with a `Pose3`. Nothing wraps it. */\nexport type Scene3d<TData, TLayer extends string> = Scene<TData, TLayer, Pose3>;\n/** A node of a `Scene3d`. */\nexport type Node3d<TData, TLayer extends string> = SceneNode<TData, TLayer, Pose3>;\n\n/**\n * The world box a node occupies, rather than a local box to transform: a\n * sphere's box is the same under every rotation, and no transform of a local\n * box reproduces that — rotate a cube and it widens.\n *\n * Omitted, a node is a unit cube carried by its pose.\n *\n * A function of the node alone; a result that depends on anything else must\n * come with a scene change, or picks go stale.\n */\nexport type NodeBounds<TData, TLayer extends string> = (\n node: Node3d<TData, TLayer>,\n) => Aabb;\n\n/** What every 3D dep is built from: the scene, the viewport, and optionally\n * each node's world box. */\nexport interface World3d<TData, TLayer extends string> {\n scene: Scene3d<TData, TLayer>;\n viewport: ViewportSource;\n bounds?: NodeBounds<TData, TLayer>;\n /** The axis gestures resolve against. Default `+y`. */\n up?: Vec3;\n}\n\nexport const DEFAULT_UP: Vec3 = { x: 0, y: 1, z: 0 };\n\nexport function boundsOfNode<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n node: Node3d<TData, TLayer>,\n): Aabb {\n return world.bounds ? world.bounds(node) : aabbOfPose(node.pose);\n}\n","/**\n * The 3D world's pick index: one BVH over every node's world box, rebuilt\n * whole on the first pick after the scene, its overrides or the world's\n * `bounds` function can have changed. A node whose box the tree refuses\n * (non-finite or inverted) is tested on every pick, the way the scan did.\n */\n\nimport type { NodeId } from '@weasel-js/core';\nimport { intersectRayAabb, type Aabb, type Ray } from '@weasel-js/geom/3d';\nimport { createBvh, type Bvh, type HalfSpace } from '@weasel-js/geom/nd';\nimport { rectOf, viewProjectionOf, type Viewport3d } from './project';\nimport { projectAabbToScreen, screenToNdc, type ScreenBox } from './screen';\nimport { boundsOfNode, type Node3d, type World3d } from './world';\n\nexport interface WorldPickIndex {\n /** The nearest node the ray enters; a tie on distance goes to the first in render order. */\n nearestOnRay(ray: Ray, excluded: ReadonlySet<NodeId> | null): NodeId | null;\n /** The nodes whose projected box overlaps `rect`, in render order. */\n inScreenRect(vp: Viewport3d, rect: ScreenBox): NodeId[];\n}\n\n/** The screen box a node covers, or null when it projects to nothing visible. */\nexport function screenBoxOf<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n id: NodeId,\n viewport: Viewport3d,\n): ScreenBox | null {\n const node = world.scene.get(id) as Node3d<TData, TLayer> | undefined;\n if (!node) return null;\n return projectAabbToScreen(\n boundsOfNode(world, node),\n viewProjectionOf(viewport),\n rectOf(viewport),\n );\n}\n\nfunction overlaps(a: ScreenBox, b: ScreenBox): boolean {\n return (\n a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y\n );\n}\n\nfunction boxValid({ min, max }: Aabb): boolean {\n return (\n Number.isFinite(min.x) && Number.isFinite(min.y) && Number.isFinite(min.z) &&\n Number.isFinite(max.x) && Number.isFinite(max.y) && Number.isFinite(max.z) &&\n min.x <= max.x && min.y <= max.y && min.z <= max.z\n );\n}\n\n/** Widens each side plane, in NDC, past the rounding between it and the exact screen test. */\nconst NDC_SLACK = 1e-9;\n\n/**\n * The four half-spaces a point must sit in for its screen point to fall in\n * `rect`'s columns and rows: `ndc.x >= a` is `clip.x - a * clip.w >= 0`\n * wherever `clip.w > 0`, which is linear in the world point. Each plane is\n * kept or dropped on its own, so a box survives exactly when its projection's\n * x span and y span each reach the rect — what the screen-box test asks —\n * and points behind the eye only ever add candidates.\n */\nfunction sidePlanes(vp: Viewport3d, rect: ScreenBox): HalfSpace[] {\n const m = viewProjectionOf(vp);\n const pane = rectOf(vp);\n const lo = screenToNdc({ x: rect.x, y: rect.y + rect.height }, pane);\n const hi = screenToNdc({ x: rect.x + rect.width, y: rect.y }, pane);\n // Column-major: row r of the matrix is m[r], m[4 + r], m[8 + r], m[12 + r].\n const row = (r: number) => [m[r]!, m[4 + r]!, m[8 + r]!, m[12 + r]!];\n const w = row(3);\n const plane = (r: number, a: number, sign: 1 | -1): HalfSpace => {\n const c = row(r);\n const e = [0, 1, 2, 3].map((j) => sign * (c[j]! - a * w[j]!));\n return { normal: [e[0]!, e[1]!, e[2]!], offset: e[3]! };\n };\n return [\n plane(0, lo.x - NDC_SLACK, 1),\n plane(0, hi.x + NDC_SLACK, -1),\n plane(1, lo.y - NDC_SLACK, 1),\n plane(1, hi.y + NDC_SLACK, -1),\n ];\n}\n\nclass BuiltIndex<TData, TLayer extends string> implements WorldPickIndex {\n constructor(\n private readonly world: World3d<TData, TLayer>,\n private readonly order: readonly Node3d<TData, TLayer>[],\n private readonly boxes: readonly Aabb[],\n private readonly tree: Bvh<number>,\n private readonly always: readonly number[],\n ) {}\n\n nearestOnRay(ray: Ray, excluded: ReadonlySet<NodeId> | null): NodeId | null {\n const { order, boxes } = this;\n let best = -1;\n let bestT = Infinity;\n const consider = (i: number) => {\n if (excluded?.has(order[i]!.id)) return;\n const t = intersectRayAabb(ray, boxes[i]!.min, boxes[i]!.max);\n if (t !== null && (t < bestT || (t === bestT && i < best))) {\n bestT = t;\n best = i;\n }\n };\n for (const i of this.always) consider(i);\n const { origin: o, direction: d } = ray;\n this.tree.raycast([o.x, o.y, o.z], [d.x, d.y, d.z], (i, entryT) => {\n // The tree's slab test rounds differently from intersectRayAabb's.\n if (entryT > bestT * (1 + 1e-12) + 1e-12) return false;\n consider(i);\n return true;\n });\n return best < 0 ? null : order[best]!.id;\n }\n\n inScreenRect(vp: Viewport3d, rect: ScreenBox): NodeId[] {\n const candidates = [...this.always];\n this.tree.queryHalfSpaces(sidePlanes(vp, rect), (i) => {\n candidates.push(i);\n });\n candidates.sort((a, b) => a - b);\n const hits: NodeId[] = [];\n for (const i of candidates) {\n const id = this.order[i]!.id;\n const box = screenBoxOf(this.world, id, vp);\n if (box && overlaps(box, rect)) hits.push(id);\n }\n return hits;\n }\n}\n\ninterface Cached {\n version: number;\n overrides: number;\n bounds: unknown;\n order: readonly unknown[];\n index: WorldPickIndex;\n}\n\nconst CACHE = new WeakMap<object, Cached>();\n\n/** The box grown by a relative epsilon, so rounding in the tree's tests can\n * only add candidates for the exact ones to drop. */\nfunction padded({ min, max }: Aabb): number[] {\n const m = Math.max(\n Math.abs(min.x), Math.abs(min.y), Math.abs(min.z),\n Math.abs(max.x), Math.abs(max.y), Math.abs(max.z),\n );\n const e = 1e-9 * (1 + m);\n return [min.x - e, min.y - e, min.z - e, max.x + e, max.y + e, max.z + e];\n}\n\nfunction build<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n order: readonly Node3d<TData, TLayer>[],\n): WorldPickIndex {\n const boxes = order.map((node) => boundsOfNode(world, node));\n const entries: [number, number[]][] = [];\n const always: number[] = [];\n boxes.forEach((b, i) => {\n if (boxValid(b)) entries.push([i, padded(b)]);\n else always.push(i);\n });\n return new BuiltIndex(world, order, boxes, createBvh<number>(3, entries), always);\n}\n\n/** The index for `world`, current as of this call. */\nexport function worldPickIndex<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n): WorldPickIndex {\n const { scene } = world;\n const version = scene.getVersion();\n const overrides = scene.overrides.getGeneration();\n const order = scene.renderOrderNodes() as readonly Node3d<TData, TLayer>[];\n const hit = CACHE.get(world);\n if (\n hit && hit.version === version && hit.overrides === overrides &&\n hit.bounds === world.bounds && hit.order === order\n ) {\n return hit.index;\n }\n const index = build(world, order);\n CACHE.set(world, { version, overrides, bounds: world.bounds, order, index });\n return index;\n}\n","import { SNAP_AXIS_STEP, type SnapConstrain } from '@weasel-js/core';\nimport { stepLine, type Flat } from '@weasel-js/geom/nd';\nimport { cross, dot, normalize, scale, sub, type Vec3 } from '@weasel-js/geom/3d';\n\nconst ZERO: Vec3 = { x: 0, y: 0, z: 0 };\n\nexport const tuple = (p: Vec3): number[] => [p.x, p.y, p.z];\nexport const vec3Of = (t: readonly number[]): Vec3 => ({ x: t[0]!, y: t[1]!, z: t[2]! });\n\n/** Two unit directions spanning the plane normal to `up`. For an axis `up`\n * they are the other two world axes, so a ground grid runs along them. */\nexport function planeBasis(up: Vec3): readonly [Vec3, Vec3] {\n const n = normalize(up);\n const e: Vec3 = Math.abs(n.x) < 0.9 ? { x: 1, y: 0, z: 0 } : { x: 0, y: 0, z: 1 };\n const u = normalize(sub(e, scale(n, dot(n, e))));\n return [u, cross(u, n)];\n}\n\n/**\n * `H` for a 3D gesture: the plane `basis` spans, through the origin of\n * δ-space. While `snap.constrain` is held, an `'axis'` constraint holds δ to\n * the axes and diagonals of that plane, and an angle step holds it to the\n * line through `about` at the nearest multiple of the step.\n */\nexport function inputFlat3d(\n c: SnapConstrain | undefined, held: boolean, basis: readonly [Vec3, Vec3], delta0: Vec3, about: Vec3,\n): Flat {\n const [u, v] = basis;\n if (!held || c === undefined || c === 'aspect') return { at: [0, 0, 0], dirs: [tuple(u), tuple(v)] };\n const step = c === 'axis' ? SNAP_AXIS_STEP : c.step;\n return stepLine(tuple(c === 'axis' ? ZERO : about), tuple(delta0), [tuple(u), tuple(v)], step);\n}\n","import type { NodeId, SnapProbeAt } from '@weasel-js/core';\nimport { add, dot, scale, type Aabb, type Vec3 } from '@weasel-js/geom/3d';\nimport { boundsOfNode, type Node3d, type World3d } from '../world';\n\n/** What a 3D move drags, at press. */\nexport interface Subject3d {\n /** The union of the subject's world boxes. */\n box: Aabb;\n /** The node whose `translate` the session answers for exactly: the first\n * of the subject still in the scene. */\n anchor: { box: Aabb; height: number };\n}\n\nexport function subjectOf<TData, TLayer extends string>(\n world: World3d<TData, TLayer>, ids: readonly string[], up: Vec3,\n): Subject3d | null {\n let box: Aabb | null = null;\n let anchor: Subject3d['anchor'] | null = null;\n for (const id of ids) {\n const node = world.scene.get(id as NodeId) as Node3d<TData, TLayer> | undefined;\n if (!node) continue;\n const b = boundsOfNode(world, node);\n anchor ??= { box: b, height: dot(up, node.pose.position) };\n box = box ? union(box, b) : b;\n }\n return box && anchor ? { box, anchor } : null;\n}\n\nfunction union(a: Aabb, b: Aabb): Aabb {\n return {\n min: { x: Math.min(a.min.x, b.min.x), y: Math.min(a.min.y, b.min.y), z: Math.min(a.min.z, b.min.z) },\n max: { x: Math.max(a.max.x, b.max.x), y: Math.max(a.max.y, b.max.y), z: Math.max(a.max.z, b.max.z) },\n };\n}\n\n/** Corner `i` of `box`: bit 1 picks max x, bit 2 max y, bit 4 max z. */\nexport function boxCorner(box: Aabb, i: number): Vec3 {\n return {\n x: i & 1 ? box.max.x : box.min.x,\n y: i & 2 ? box.max.y : box.min.y,\n z: i & 4 ? box.max.z : box.min.z,\n };\n}\n\n/** A move's probes: the box's 8 corners and center as its geometry, and its\n * min, center and max as its box. */\nexport function boxProbes(box: Aabb): SnapProbeAt<Vec3>[] {\n const center = scale(add(box.min, box.max), 0.5);\n const out: SnapProbeAt<Vec3>[] = [];\n for (let i = 0; i < 8; i++) {\n out.push({ id: `corner:${i}`, at: boxCorner(box, i), role: 'geometry' });\n }\n out.push(\n { id: 'center', at: center, role: 'geometry' },\n { id: 'box.min', at: box.min, role: 'box' },\n { id: 'box.center', at: center, role: 'box' },\n { id: 'box.max', at: box.max, role: 'box' },\n );\n return out;\n}\n","import {\n gatherSnapCandidates, resolvedSnapMarks, snapSourcesFor,\n type SnapBegin, type SnapCandidateMark, type SnapOutcome, type SnapOutcomeStore,\n type SnapProbeAt, type SnapSession, type SnapSource,\n} from '@weasel-js/core';\nimport { closestOnFlat, resolveSnap, type Flat, type SnapCandidate } from '@weasel-js/geom/nd';\nimport {\n add, cross, dot, intersectRayPlane, len, normalize, pointOnRay, sub, type Vec3,\n} from '@weasel-js/geom/3d';\nimport { cameraEye } from '../camera';\nimport { projectPoint, rayAt, rectOf, viewProjectionOf, type Viewport3d } from '../project';\nimport { projectAabbToScreen } from '../screen';\nimport { DEFAULT_UP, type World3d } from '../world';\nimport { inputFlat3d, planeBasis, tuple, vec3Of } from './plane';\nimport { boxProbes, subjectOf } from './probes3d';\n\ntype Point = { x: number; y: number };\n\nconst ZERO: Vec3 = { x: 0, y: 0, z: 0 };\n\n/** What a 3D session runs on. */\nexport interface Session3dInputs<TData, TLayer extends string> {\n req: SnapBegin;\n world: World3d<TData, TLayer>;\n /** In source order: earlier wins a full tie. */\n sources: readonly SnapSource<Vec3>[];\n /** The reach of a source that sets none, in screen px. */\n reachPx: number;\n store: SnapOutcomeStore<Vec3>;\n}\n\n/**\n * The plane a gesture moves on, `up · p = offset`, and how its δ is read: as\n * the world distance between where `anchor` and the pointer's offset from the\n * press cast onto that plane. For a move, `anchor` is the screen point\n * `translate` casts from, so a δ handed back as a screen point is the delta\n * `translate` makes of it.\n */\ninterface Frame {\n offset: number;\n anchor(vp: Viewport3d): Point | null;\n probes(anchorWorld: Vec3): readonly SnapProbeAt<Vec3>[];\n}\n\n/**\n * A snap session over a 3D world: ctx points are screen points. A move runs\n * on the plane through its subject normal to `up`, an insert on the ground,\n * and each returns the screen point whose cast lands where the snap put it.\n * Other gestures pass their input through.\n */\nexport function createSession3d<TData, TLayer extends string>(inputs: Session3dInputs<TData, TLayer>): SnapSession {\n const { req, world, store } = inputs;\n const up = normalize(world.up ?? DEFAULT_UP);\n const basis = planeBasis(up);\n const frame = frameOf(req, world, up);\n const sources = snapSourcesFor(inputs.sources, req.gesture);\n const unsnapped = (p: Point): SnapOutcome => {\n store.set([]);\n return { point: p, held: false, marks: [] };\n };\n return {\n at(p, mods) {\n if (!frame) return unsnapped(p);\n const vp = world.viewport();\n const screen = frame.anchor(vp);\n const anchor = screen && castOnto(vp, screen, up, frame.offset);\n const hit = screen && castOnto(vp, { x: screen.x + p.x - req.press.x, y: screen.y + p.y - req.press.y }, up, frame.offset);\n if (!screen || !anchor || !hit) return unsnapped(p);\n const delta0 = sub(hit, anchor);\n const origin = req.origin ? castOnto(vp, req.origin, up, frame.offset) : null;\n const input = inputFlat3d(req.constrain, mods.constrain, basis, delta0, origin ? sub(origin, anchor) : ZERO);\n let delta: Vec3;\n let held = false;\n if (mods.suspend) {\n delta = vec3Of(closestOnFlat(input, tuple(delta0)));\n store.set([]);\n } else {\n const probes = frame.probes(anchor);\n const res = resolveSnap({\n probes: probes.map((q) => ({ id: q.id, at: tuple(q.at), role: q.role })),\n input,\n delta0: tuple(delta0),\n candidates: candidatesOf(inputs, sources, probes, delta0, vp, origin, up),\n toScreen: (w) => {\n const s = projectPoint(vec3Of(w), vp);\n return s ? [s.x, s.y] : [NaN, NaN];\n },\n });\n delta = vec3Of(res.delta);\n held = res.members.length > 0;\n store.set(resolvedSnapMarks(res.satisfied, delta));\n }\n const landed = projectPoint(add(anchor, delta), vp);\n if (!landed) return unsnapped(p);\n return {\n point: { x: req.press.x + landed.x - screen.x, y: req.press.y + landed.y - screen.y },\n held,\n marks: store.get(),\n };\n },\n angle: (theta) => ({ theta, marks: [] }),\n end() {\n store.set([]);\n },\n };\n}\n\nfunction frameOf<TData, TLayer extends string>(req: SnapBegin, world: World3d<TData, TLayer>, up: Vec3): Frame | null {\n if (req.gesture === 'point') {\n return {\n offset: 0,\n anchor: () => req.press,\n probes: (at) => [{ id: 'pointer', at, role: 'pointer' }],\n };\n }\n if (req.gesture !== 'move') return null;\n const subject = subjectOf(world, req.ids ?? [], up);\n if (!subject) return null;\n const probes = boxProbes(subject.box);\n return {\n offset: subject.anchor.height,\n anchor(vp) {\n const box = projectAabbToScreen(subject.anchor.box, viewProjectionOf(vp), rectOf(vp));\n return box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : null;\n },\n probes: () => probes,\n };\n}\n\nfunction castOnto(vp: Viewport3d, s: Point, up: Vec3, offset: number): Vec3 | null {\n const ray = rayAt(vp, s);\n const t = ray && intersectRayPlane(ray, up, offset);\n return ray && t !== null ? pointOnRay(ray, t) : null;\n}\n\nfunction candidatesOf<TData, TLayer extends string>(\n inputs: Session3dInputs<TData, TLayer>, sources: readonly SnapSource<Vec3>[], probes: readonly SnapProbeAt<Vec3>[],\n delta0: Vec3, vp: Viewport3d, origin: Vec3 | null, up: Vec3,\n): SnapCandidate<SnapCandidateMark<Vec3>>[] {\n const { req } = inputs;\n const shifted = probes.map((q) => ({ ...q, at: add(q.at, delta0) }));\n const perPx = worldPerPx(vp, shifted);\n const found = gatherSnapCandidates(sources, shifted, (_source, offered, reachPx) => ({\n gesture: req.gesture, probes: offered, delta0, exclude: req.ids ?? [],\n ...(req.ids ? { ids: req.ids } : {}),\n ...(req.parent !== undefined ? { parent: req.parent } : {}),\n ...(origin ? { origin } : {}),\n reachWorld: (px) => px * perPx,\n reachPx,\n }), { toVec: tuple, reachPx: inputs.reachPx, ...(origin ? { origin } : {}) });\n return found.filter((c) => !level(c.locus, up));\n}\n\n/** Whether `locus` is a plane normal to `up`: the gesture's own plane or one\n * parallel to it, which height alone meets or misses. */\nfunction level(locus: Flat, up: Vec3): boolean {\n if (locus.dirs.length !== 2) return false;\n const n = cross(vec3Of(locus.dirs[0]!), vec3Of(locus.dirs[1]!));\n return Math.abs(dot(n, up)) >= (1 - 1e-9) * len(n);\n}\n\n/** World units per screen px at the farthest probe in front of the camera:\n * the radius that culls by reach without dropping anything in it. */\nfunction worldPerPx(vp: Viewport3d, probes: readonly SnapProbeAt<Vec3>[]): number {\n const eye = cameraEye(vp.camera);\n const forward = normalize(sub(vp.camera.target, eye));\n const k = (2 * Math.tan(vp.camera.fov / 2)) / Math.max(1, vp.height);\n let depth = 0;\n for (const q of probes) depth = Math.max(depth, dot(sub(q.at, eye), forward));\n return depth * k;\n}\n","/**\n * The kit's deps, implemented against a 3D world.\n *\n * Every one of these takes its camera from a thunk rather than an argument:\n * the dispatcher keeps handing actions two numbers, and what makes them mean\n * something in 3D is the camera each dep already closes over.\n */\n\nimport type {\n AreaSelectDep,\n NodeAtPointDep,\n NodeId,\n PoseDescriptor,\n SnapDep,\n SnapOutcomeStore,\n SnapSource,\n} from '@weasel-js/core';\nimport { DEFAULT_SNAP_PX, createSnapOutcomeStore, assertSnapSourceIds } from '@weasel-js/core';\nimport { isDev, type KitSettingsStore } from '@weasel-js/react';\nimport {\n aabbOfPoints,\n add,\n dot,\n intersectRayPlane,\n len,\n normalize,\n pointOnRay,\n quatIdentity,\n scale as scaleBy,\n sub,\n type Aabb,\n type Vec3,\n} from '@weasel-js/geom/3d';\nimport { cameraEye, type Camera3d } from './camera';\nimport { aabbOfPose, type Pose3 } from './pose3';\nimport { rayAt, rectOf, viewProjectionOf, type Viewport3d } from './project';\nimport { worldPickIndex } from './pickIndex';\nimport { projectAabbToScreen } from './screen';\nimport { createSession3d } from './snap/session3d';\n\nimport { DEFAULT_UP, boundsOfNode, type Node3d, type World3d } from './world';\n\nexport type { Viewport3d, ViewportSource } from './project';\nexport type { NodeBounds, Node3d, Scene3d, World3d } from './world';\n\n/**\n * The plane through `p` that faces the camera.\n *\n * This is the depth choice the kit's reverse contracts need: a screen\n * rectangle names a pose only once something says how far away it is, and the\n * answer is \"as far as it already was\". Nothing resolved on this plane changes\n * depth, and one screen pixel is the same world distance everywhere on it.\n */\nfunction viewPlaneAt(camera: Camera3d, p: Vec3): { normal: Vec3; offset: number } {\n const normal = normalize(sub(camera.target, cameraEye(camera)));\n return { normal, offset: dot(normal, p) };\n}\n\n/** Where a screen point lands on `plane`, or `null` when it casts no ray. */\nfunction onPlane(\n vp: Viewport3d,\n plane: { normal: Vec3; offset: number },\n point: { x: number; y: number },\n): Vec3 | null {\n const ray = rayAt(vp, point);\n if (!ray) return null;\n const t = intersectRayPlane(ray, plane.normal, plane.offset);\n return t === null ? null : pointOnRay(ray, t);\n}\n\nexport { screenBoxOf } from './pickIndex';\n\n/**\n * Nearest node along the ray the screen point names.\n *\n * The kit calls this with what it believes is a world point; a 3D host feeds\n * the dispatcher an identity `clientToWorld`, so it is the pane-relative screen\n * point, which is exactly what a ray needs.\n */\nexport function createNodeAtPoint<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n): NodeAtPointDep {\n return (point, exclude) => {\n const ray = rayAt(world.viewport(), point);\n if (!ray) return null;\n return worldPickIndex(world).nearestOnRay(ray, exclude ? new Set(exclude) : null);\n };\n}\n\n/** Marquee: the nodes whose projected box the screen rectangle touches, in render order. */\nexport function createAreaSelect<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n selection: { get(): readonly NodeId[]; set(ids: NodeId[]): void },\n): AreaSelectDep {\n return {\n hitTestArea: (bounds) => worldPickIndex(world).inScreenRect(world.viewport(), bounds),\n getSelection: () => [...selection.get()],\n setSelection: (ids) => selection.set([...ids]),\n };\n}\n\n/** Options for `createSnap`. */\nexport interface Snap3dOptions {\n /** What a gesture snaps to, in order: earlier wins a full tie. Two sharing\n * an id throw. Default none, which leaves only the gesture's own constraint. */\n sources?: readonly SnapSource<Vec3>[];\n /** The reach of a source that sets none, in screen px. Overrides the kit\n * setting `targets.snapPx`. */\n reachPx?: number;\n /** Where `targets.snapPx` is read, when each gesture begins. Absent, and\n * with no `reachPx`, reach is `DEFAULT_SNAP_PX`. */\n kitSettings?: KitSettingsStore;\n /** Where the marks of the snap in flight are written, for a host to draw\n * with `projectSnapMarks`. */\n store?: SnapOutcomeStore<Vec3>;\n}\n\nlet warnedGestureSources = false;\n\nfunction warnGestureSources(): void {\n if (warnedGestureSources || !isDev()) return;\n warnedGestureSources = true;\n console.warn(\n '[kernel3d] a gesture passed snap `sources`, which are 2D and are not asked in a 3D host. ' +\n 'List 3D sources in createSnap({ sources }).',\n );\n}\n\n/**\n * The `snap` dep over a 3D world. A gesture's `omit` is honored; its 2D\n * `sources` are not asked. A move snaps its subject's world box on the\n * plane it already moves on; an insert snaps the pointer on the ground. Both\n * answer in screen points, which `translate` and `createInsert` cast back\n * onto the same plane, landing exactly where the snap put them.\n */\nexport function createSnap<TData, TLayer extends string>(\n world: World3d<TData, TLayer>, opts: Snap3dOptions = {},\n): SnapDep {\n const store = opts.store ?? createSnapOutcomeStore<Vec3>();\n const listed = opts.sources ?? [];\n assertSnapSourceIds(listed);\n return {\n begin: (req) => {\n if (req.sources?.length) warnGestureSources();\n const omit = new Set(req.omit);\n const sources = listed.filter((s) => !omit.has(s.id));\n return createSession3d({\n req, world, sources, store,\n reachPx: opts.reachPx ?? opts.kitSettings?.get('targets.snapPx') ?? DEFAULT_SNAP_PX,\n });\n },\n };\n}\n\n/**\n * `PoseDescriptor` over a 3D pose, with `Bounds` read as the screen box the\n * node covers.\n *\n * `forNode` is what lets a sphere bound itself as a sphere: the shape lives\n * on `node.data`. Unspecialized — the kit calling with only a pose in hand —\n * it answers with the default local box, which is the looser of the two.\n *\n * `remapBounds` and `fromBounds` take a screen rectangle, which names a pose\n * only once something supplies a depth. Both resolve it against the plane\n * through the pose they were handed, facing the camera, so nothing they\n * produce changes depth.\n */\nexport function createPoseDescriptor<TData, TLayer extends string>(\n world: World3d<TData, TLayer>,\n): PoseDescriptor<Pose3, Node3d<TData, TLayer>> {\n const up = world.up ?? DEFAULT_UP;\n const upAxis = up.y !== 0 ? 'y' : up.x !== 0 ? 'x' : 'z';\n const specialized = new WeakMap<object, PoseDescriptor<Pose3, Node3d<TData, TLayer>>>();\n\n // A drag whose camera stops casting rays mid-gesture keeps moving through the\n // last one that did, rather than snapping the node back.\n let lastCastable: Viewport3d | null = null;\n function castableViewport(): Viewport3d | null {\n const vp = world.viewport();\n const rect = rectOf(vp);\n if (rayAt(vp, { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 })) lastCastable = vp;\n return lastCastable;\n }\n\n function build(worldBox: (pose: Pose3) => Aabb): PoseDescriptor<Pose3, Node3d<TData, TLayer>> {\n const boundsIn = (vp: Viewport3d, pose: Pose3) =>\n projectAabbToScreen(worldBox(pose), viewProjectionOf(vp), rectOf(vp));\n const boundsOf = (pose: Pose3) => boundsIn(world.viewport(), pose);\n\n const descriptor: PoseDescriptor<Pose3, Node3d<TData, TLayer>> = {\n forNode(node) {\n let d = specialized.get(node);\n if (!d) {\n // The pose arriving here is often an in-flight override rather than\n // `node.pose`, so the consumer is asked about that pose on this node\n // rather than about the node as committed.\n d = build((pose) => boundsOfNode(world, { ...node, pose }));\n specialized.set(node, d);\n }\n return d;\n },\n\n getBounds(pose) {\n return boundsOf(pose) ?? { x: 0, y: 0, width: 0, height: 0 };\n },\n\n /**\n * The src→dst screen map, applied at the pose's own depth: the node's\n * screen anchor moves the way the rectangle does, and both ends of that\n * move are read back off the plane through its position, so the world\n * delta is exact rather than a scaled screen one.\n *\n * The scale is uniform. The rectangle names two extents and a pose has\n * three, so there is no reading in which a screen box resizes a solid\n * per-axis; the geometric mean is the one factor that agrees with both\n * of the extents it does name.\n */\n remapBounds(pose, src, dst) {\n const vp = castableViewport();\n if (!vp) return pose;\n const box = boundsIn(vp, pose);\n if (!box) return pose;\n\n const kx = src.width === 0 ? 1 : dst.width / src.width;\n const ky = src.height === 0 ? 1 : dst.height / src.height;\n const from = { x: box.x + box.width / 2, y: box.y + box.height / 2 };\n const to = {\n x: dst.x + (from.x - src.x) * kx,\n y: dst.y + (from.y - src.y) * ky,\n };\n\n const plane = viewPlaneAt(vp.camera, pose.position);\n const before = onPlane(vp, plane, from);\n const after = onPlane(vp, plane, to);\n if (!before || !after) return pose;\n\n const k = Math.sqrt(Math.abs(kx * ky));\n return {\n ...pose,\n position: add(pose.position, sub(after, before)),\n scale: scaleBy(pose.scale, k),\n };\n },\n\n /**\n * The world box the rectangle covers at the template's depth, as a pose.\n *\n * The rectangle is flat and a box is not, so the third extent — the one\n * no screen rectangle names — is the mean of the two it does. The result\n * is world-axis-aligned and unrotated: the pose carries none of the\n * template's shape, which is the contract, and it takes only its depth.\n *\n * Extents are written as `scale`, so this reads a pose as carrying a\n * unit primitive — the same assumption `aabbOfPose` makes by default.\n */\n fromBounds(bounds, template) {\n const vp = castableViewport();\n if (!vp) return template;\n const plane = viewPlaneAt(vp.camera, template.position);\n\n const corners: Vec3[] = [];\n for (const [x, y] of [\n [bounds.x, bounds.y],\n [bounds.x + bounds.width, bounds.y],\n [bounds.x, bounds.y + bounds.height],\n [bounds.x + bounds.width, bounds.y + bounds.height],\n ]) {\n const corner = onPlane(vp, plane, { x, y });\n if (!corner) return template;\n corners.push(corner);\n }\n\n const width = len(sub(corners[1]!, corners[0]!));\n const height = len(sub(corners[2]!, corners[0]!));\n const half = Math.sqrt(width * height) / 2;\n const box = aabbOfPoints(\n corners.flatMap((c) => [\n add(c, scaleBy(plane.normal, half)),\n sub(c, scaleBy(plane.normal, half)),\n ]),\n );\n return {\n position: scaleBy(add(box.min, box.max), 0.5),\n rotation: quatIdentity(),\n scale: sub(box.max, box.min),\n };\n },\n\n /** Screen-space deltas resolve against the plane the node already sits on. */\n translate(pose, dx, dy) {\n const vp = castableViewport();\n if (!vp) return pose;\n const box = boundsIn(vp, pose);\n if (!box) return pose;\n const from = { x: box.x + box.width / 2, y: box.y + box.height / 2 };\n const to = { x: from.x + dx, y: from.y + dy };\n const offset = dot(up, pose.position);\n\n const ray = rayAt(vp, to);\n if (!ray) return pose;\n const t = intersectRayPlane(ray, up, offset);\n if (t === null) return pose;\n\n const anchorRay = rayAt(vp, from);\n if (!anchorRay) return pose;\n const anchorT = intersectRayPlane(anchorRay, up, offset);\n if (anchorT === null) return pose;\n\n const delta = sub(pointOnRay(ray, t), pointOnRay(anchorRay, anchorT));\n const position = {\n x: pose.position.x + delta.x,\n y: pose.position.y + delta.y,\n z: pose.position.z + delta.z,\n };\n position[upAxis] = pose.position[upAxis];\n return { ...pose, position };\n },\n\n supportsRotation() {\n return false;\n },\n };\n\n return descriptor;\n }\n\n return build((pose) => aabbOfPose(pose));\n}\n","/** The `insert` dep over a 3D world: a drag becomes a footprint on the ground. */\n\nimport type { InsertDep, InsertEnds, InsertExtras, NodeId } from '@weasel-js/core';\nimport { intersectRayPlane, pointOnRay, scale as scaleBy, sub, type Vec3 } from '@weasel-js/geom/3d';\nimport { rayAt, type ViewportSource } from './project';\nimport { DEFAULT_UP } from './world';\n\n/** The ground-plane rectangle a drag swept out, in world units. */\nexport interface Footprint {\n /** Centre of the swept rectangle, on the ground plane. */\n center: Vec3;\n /** Extent along the two axes the up axis is not. */\n width: number;\n depth: number;\n}\n\n/** The ground points a footprint spans. A drag's two ends are cast rather\n * than its box's corners: in perspective the other two corners land outside\n * the rectangle the ends make, and would carry the footprint past a corner\n * the drag snapped to. */\nfunction footprintPoints(\n bounds: { x: number; y: number; width: number; height: number },\n ends: InsertEnds | undefined,\n cast: (p: { x: number; y: number }) => Vec3 | null,\n): Vec3[] {\n if (ends) {\n const start = cast(ends.start);\n const end = cast(ends.end);\n if (!start || !end) return [];\n return ends.fromCenter ? [end, sub(scaleBy(start, 2), end)] : [start, end];\n }\n const corners = [\n { x: bounds.x, y: bounds.y },\n { x: bounds.x + bounds.width, y: bounds.y },\n { x: bounds.x, y: bounds.y + bounds.height },\n { x: bounds.x + bounds.width, y: bounds.y + bounds.height },\n ];\n return corners.map(cast).filter((h): h is Vec3 => h !== null);\n}\n\n/**\n * A drag becomes a footprint on the ground plane: its ends, or without them\n * its box's four corners, are cast onto the plane and the hit points give the\n * extent. What node that implies is the consumer's answer — the kernel does\n * not know what it is inserting. The depth the 2D contract cannot express\n * comes from the plane, not from the caller.\n */\nexport function createInsert(opts: {\n viewport: ViewportSource;\n up?: Vec3;\n /** Smallest footprint a click-sized drag produces. Default 0.25. */\n minExtent?: number;\n mint(footprint: Footprint, extras: InsertExtras): NodeId | null;\n}): InsertDep {\n const up = opts.up ?? DEFAULT_UP;\n const minExtent = opts.minExtent ?? 0.25;\n // The two axes the up axis is not, so a footprint reads the same whichever\n // way up the world is.\n const axes: readonly ['x' | 'y' | 'z', 'x' | 'y' | 'z'] =\n up.y !== 0 ? ['x', 'z'] : up.x !== 0 ? ['y', 'z'] : ['x', 'y'];\n\n return {\n commit(bounds, extras, ends) {\n const vp = opts.viewport();\n const cast = (p: { x: number; y: number }): Vec3 | null => {\n const ray = rayAt(vp, p);\n const t = ray && intersectRayPlane(ray, up, 0);\n return ray && t !== null ? pointOnRay(ray, t) : null;\n };\n const hits = footprintPoints(bounds, ends, cast);\n if (hits.length === 0) return null;\n\n const [u, v] = axes;\n let minU = Infinity, maxU = -Infinity, minV = Infinity, maxV = -Infinity;\n for (const h of hits) {\n minU = Math.min(minU, h[u]); maxU = Math.max(maxU, h[u]);\n minV = Math.min(minV, h[v]); maxV = Math.max(maxV, h[v]);\n }\n\n const center = { x: 0, y: 0, z: 0 };\n center[u] = (minU + maxU) / 2;\n center[v] = (minV + maxV) / 2;\n return opts.mint(\n {\n center,\n width: Math.max(minExtent, maxU - minU),\n depth: Math.max(minExtent, maxV - minV),\n },\n extras,\n );\n },\n };\n}\n","/**\n * A kernel3d viewport as a view aim: the frustum its camera shows, drawn into\n * any target view, and the pane itself as a target. Core's aim contract names\n * no 3D type, so this is the side that knows the camera.\n */\n\nimport type { AimOutline, AimPoint, AimSpace, ViewAim } from '@weasel-js/core';\nimport { add, dot, intersectRayPlane, normalize, pointOnRay, scale, sub, type Vec3 } from '@weasel-js/geom/3d';\nimport { cameraEye, type Camera3d } from './camera';\nimport { projectPoint, rayAt, rectOf, type Viewport3d } from './project';\n\ntype Quad = readonly [Vec3, Vec3, Vec3, Vec3];\n\n/** The frustum a camera shows: its eye, and its near and far rectangles, corners clockwise from the top-left as seen. */\nexport interface Frustum3d {\n eye: Vec3;\n near: Quad;\n far: Quad;\n}\n\n/** A kernel3d view's aim: the frustum its camera sees, with the viewport it was read from. */\nexport type Aim3d = ViewAim<Frustum3d> & { readonly kind: 'frustum'; readonly viewport: Viewport3d };\n\nconst GROUND_NORMAL: Vec3 = { x: 0, y: 0, z: 1 };\n\nfunction paneCorners(viewport: Viewport3d): { x: number; y: number }[] {\n const { x, y, width, height } = rectOf(viewport);\n return [\n { x, y },\n { x: x + width, y },\n { x: x + width, y: y + height },\n { x, y: y + height },\n ];\n}\n\nfunction frustumOf(viewport: Viewport3d): Frustum3d {\n const { camera } = viewport;\n const eye = cameraEye(camera);\n const forward = normalize(sub(camera.target, eye));\n const at = (depth: number): Vec3[] =>\n paneCorners(viewport).map((c) => {\n const ray = rayAt(viewport, c);\n if (!ray) return eye;\n const d = normalize(ray.direction);\n return add(eye, scale(d, depth / dot(d, forward)));\n });\n return {\n eye,\n near: at(camera.near) as unknown as Quad,\n far: at(camera.far) as unknown as Quad,\n };\n}\n\n/** Where the ray through a point in the pane's own coordinates meets z = 0, or `null`. */\nfunction groundHit(viewport: Viewport3d, point: { x: number; y: number }): Vec3 | null {\n const ray = rayAt(viewport, point);\n const t = ray && intersectRayPlane(ray, GROUND_NORMAL, 0);\n return ray && t !== null ? pointOnRay(ray, t) : null;\n}\n\nfunction toZ(p: AimPoint): Vec3 {\n return { x: p.x, y: p.y, z: p.z ?? 0 };\n}\n\nfunction projectAll(space: AimSpace, points: readonly AimPoint[]): AimOutline | null {\n const out: { x: number; y: number }[] = [];\n for (const p of points) {\n const px = space.project(p);\n if (!px) return null;\n out.push(px);\n }\n return out;\n}\n\n/** The aim of view `viewId` (`null`: a surface's root): the frustum `viewport`'s camera sees. */\nexport function aimOf3d(viewport: Viewport3d, viewId: string | null): Aim3d {\n const extent = frustumOf(viewport);\n return {\n viewId,\n kind: 'frustum',\n extent,\n viewport,\n outlineIn(space) {\n if (space.kind === '3d') return projectAll(space, extent.far);\n const onGround: Vec3[] = [];\n for (const c of paneCorners(viewport)) {\n const hit = groundHit(viewport, c);\n if (!hit) return null;\n onGround.push(hit);\n }\n return projectAll(space, onGround);\n },\n pannedIn(space, from, to) {\n const a = space.unproject(from);\n const b = space.unproject(to);\n if (!a || !b) return null;\n const { camera } = viewport;\n const target = add(camera.target, sub(toZ(b), toZ(a)));\n return aimOf3d({ ...viewport, camera: { ...camera, target } }, viewId);\n },\n };\n}\n\n/** A 3D pane as a target. It projects through `projectPoint` and unprojects onto the plane z = 0, where 2D worlds lie. */\nexport function aimSpace3d(viewport: Viewport3d, viewId: string | null): AimSpace {\n const { x: ox, y: oy } = rectOf(viewport);\n return {\n viewId,\n kind: '3d',\n size: { width: viewport.width, height: viewport.height },\n project(p) {\n const s = projectPoint(toZ(p), viewport);\n return s && { x: s.x - ox, y: s.y - oy };\n },\n unproject(px) {\n return groundHit(viewport, { x: px.x + ox, y: px.y + oy });\n },\n };\n}\n\n/** The camera an aim was read from, which is what a by-value source's writer sets. */\nexport function cameraOfAim3d(aim: Aim3d): Camera3d {\n return aim.viewport.camera;\n}\n","/** What a 3D scene offers a snap session: its boxes' corners, edges, faces\n * and centers, the planes through their sides and centers, and a grid on\n * the ground. */\n\nimport type { SnapCollect, SnapMark, SnapSource, SourceCandidate } from '@weasel-js/core';\nimport { add, distance, dot, len, normalize, scale, sub, type Aabb, type Vec3 } from '@weasel-js/geom/3d';\nimport { DEFAULT_UP, boundsOfNode, type Node3d, type World3d } from '../world';\nimport { planeBasis } from './plane';\nimport { boxCorner } from './probes3d';\n\ntype Axis = 'x' | 'y' | 'z';\ntype Candidate = SourceCandidate<Vec3>;\n\nconst AXES: readonly Axis[] = ['x', 'y', 'z'];\nconst BITS = [1, 2, 4] as const;\nconst UNIT: Record<Axis, Vec3> = { x: { x: 1, y: 0, z: 0 }, y: { x: 0, y: 1, z: 0 }, z: { x: 0, y: 0, z: 1 } };\nconst ACROSS: Record<Axis, readonly Vec3[]> = { x: [UNIT.y, UNIT.z], y: [UNIT.x, UNIT.z], z: [UNIT.x, UNIT.y] };\n\nfunction boxesOf<TData, TLayer extends string>(world: World3d<TData, TLayer>, q: SnapCollect<Vec3>): Aabb[] {\n const excluded = new Set(q.exclude);\n const out: Aabb[] = [];\n for (const node of world.scene.renderOrderNodes() as readonly Node3d<TData, TLayer>[]) {\n if (!excluded.has(node.id)) out.push(boundsOfNode(world, node));\n }\n return out;\n}\n\nfunction distanceToBox(p: Vec3, box: Aabb): number {\n const d = (a: Axis) => Math.max(box.min[a] - p[a], 0, p[a] - box.max[a]);\n return Math.hypot(d('x'), d('y'), d('z'));\n}\n\nconst centerOf = (box: Aabb): Vec3 => scale(add(box.min, box.max), 0.5);\nconst isZero = (v: Vec3) => v.x === 0 && v.y === 0 && v.z === 0;\n\n/**\n * Each node's world box as targets for geometry and pointer probes: its 8\n * corners and its center as points, its 12 edges as segments, and its 6\n * faces as bounded planes. Targets past the reach are not offered.\n */\nexport function boxSnapSource<TData, TLayer extends string>(world: World3d<TData, TLayer>): SnapSource<Vec3> {\n return {\n id: 'box',\n roles: ['geometry', 'pointer'],\n *collect(q) {\n const r = q.reachWorld(q.reachPx);\n for (const box of boxesOf(world, q)) {\n for (const p of q.probes) {\n if (distanceToBox(p.at, box) <= r) yield* boxLoci(p.id, p.at, box, r);\n }\n }\n },\n };\n}\n\nfunction* boxLoci(probe: string, at: Vec3, box: Aabb, r: number): Generator<Candidate> {\n for (let i = 0; i < 8; i++) {\n const c = boxCorner(box, i);\n if (distance(at, c) <= r) yield { probe, locus: { at: c, dirs: [] }, mark: { kind: 'point', at: c, glyph: 'corner' } };\n }\n const center = centerOf(box);\n if (distance(at, center) <= r) {\n yield { probe, locus: { at: center, dirs: [] }, mark: { kind: 'point', at: center, glyph: 'center' } };\n }\n for (let i = 0; i < 8; i++) {\n for (const bit of BITS) {\n if (i & bit) continue;\n const a = boxCorner(box, i);\n const b = boxCorner(box, i | bit);\n const dir = sub(b, a);\n if (isZero(dir) || distanceToBox(at, { min: a, max: b }) > r) continue;\n yield { probe, locus: { at: a, dirs: [dir], span: [[0, 1]] }, mark: { kind: 'line', from: a, to: b } };\n }\n }\n for (const bit of BITS) {\n const [b1, b2] = BITS.filter((b) => b !== bit) as [number, number];\n for (const base of [0, bit]) {\n const o = boxCorner(box, base);\n const far = boxCorner(box, base | b1 | b2);\n const d1 = sub(boxCorner(box, base | b1), o);\n const d2 = sub(boxCorner(box, base | b2), o);\n if (isZero(d1) || isZero(d2) || distanceToBox(at, { min: o, max: far }) > r) continue;\n yield {\n probe,\n locus: { at: o, dirs: [d1, d2], span: [[0, 1], [0, 1]] },\n mark: () => outline([o, boxCorner(box, base | b1), far, boxCorner(box, base | b2)]),\n };\n }\n }\n}\n\nfunction outline(ring: readonly Vec3[]): SnapMark<Vec3>[] {\n return ring.map((from, i) => ({ kind: 'line', from, to: ring[(i + 1) % ring.length]! }));\n}\n\n/**\n * The planes through each node's world box at its min, center and max on\n * every axis, as targets for box and pointer probes: alignment in depth as\n * well as across. Boxes sharing a plane offer it once, and its mark reaches\n * each of them.\n */\nexport function alignPlaneSource<TData, TLayer extends string>(world: World3d<TData, TLayer>): SnapSource<Vec3> {\n return {\n id: 'align-plane',\n roles: ['box', 'pointer'],\n *collect(q) {\n const r = q.reachWorld(q.reachPx);\n for (const [axis, planes] of planesOf(boxesOf(world, q))) {\n for (const [value, ends] of planes) {\n for (const p of q.probes) {\n if (Math.abs(p.at[axis] - value) > r) continue;\n yield {\n probe: p.id,\n locus: { at: ends[0]!, dirs: ACROSS[axis] },\n mark: (delta: Vec3): SnapMark<Vec3>[] => {\n const from = add(sub(p.at, q.delta0), delta);\n return ends.map((to) => ({ kind: 'line', from, to }));\n },\n };\n }\n }\n }\n },\n };\n}\n\n/** Per axis, each plane value the boxes have a side or center on, and the\n * point on it at each such box's center. */\nfunction planesOf(boxes: readonly Aabb[]): Map<Axis, Map<number, Vec3[]>> {\n const out = new Map<Axis, Map<number, Vec3[]>>(AXES.map((a) => [a, new Map()]));\n for (const box of boxes) {\n const center = centerOf(box);\n for (const axis of AXES) {\n const planes = out.get(axis)!;\n for (const value of new Set([box.min[axis], center[axis], box.max[axis]])) {\n const on = { ...center, [axis]: value };\n const ends = planes.get(value);\n if (ends) ends.push(on);\n else planes.set(value, [on]);\n }\n }\n }\n return out;\n}\n\n/** Options for `groundGridSource`. */\nexport interface GroundGridSourceOptions {\n /** The grid's pitch, in world units. */\n step: number;\n /** The ground's normal; the grid lies on `up · p = 0`. Default `+y`. */\n up?: Vec3;\n}\n\n/**\n * A grid on the ground plane as snap targets: for each pointer or geometry\n * probe on the ground, the grid line on either side of it along each of the\n * ground's two axes. Its reach is unlimited and it is a fallback, so it\n * holds every axis no target claims and never displaces one.\n */\nexport function groundGridSource(opts: GroundGridSourceOptions): SnapSource<Vec3> {\n const up = normalize(opts.up ?? DEFAULT_UP);\n const [u, v] = planeBasis(up);\n const lines = (c: number): [number, number] => {\n const near = Math.round(c / opts.step) * opts.step;\n return [near, near + (c >= near ? opts.step : -opts.step)];\n };\n return {\n id: 'ground-grid',\n tier: 'fallback',\n reachPx: Infinity,\n roles: ['pointer', 'geometry'],\n *collect(q) {\n for (const p of q.probes) {\n if (Math.abs(dot(p.at, up)) > 1e-6 * Math.max(1, len(p.at))) continue;\n const a = dot(p.at, u);\n const b = dot(p.at, v);\n for (const at of lines(a)) yield { probe: p.id, locus: { at: add(scale(u, at), scale(v, b)), dirs: [v] } };\n for (const at of lines(b)) yield { probe: p.id, locus: { at: add(scale(u, a), scale(v, at)), dirs: [u] } };\n }\n },\n };\n}\n","import type { SnapMark } from '@weasel-js/core';\nimport type { Vec3 } from '@weasel-js/geom/3d';\nimport { projectPoint, type Viewport3d } from '../project';\n\ntype Point = { x: number; y: number };\n\n/** A snap mark's segment on screen: a line, a gap, or a distance. */\nexport interface ScreenLine {\n from: Point;\n to: Point;\n /** A gap's or distance's value, in world units. */\n value?: number;\n color?: string;\n}\n\n/** A snap mark's point on screen. */\nexport interface ScreenPoint {\n at: Point;\n glyph: string;\n label?: string;\n color?: string;\n}\n\n/**\n * The marks a 3D snap session draws, in the viewport's screen space, for a\n * host to draw through its own renderer. A mark with any point that does not\n * project — behind the camera — is dropped whole.\n */\nexport function projectSnapMarks(\n marks: readonly SnapMark<Vec3>[], viewport: Viewport3d,\n): { lines: ScreenLine[]; points: ScreenPoint[] } {\n const lines: ScreenLine[] = [];\n const points: ScreenPoint[] = [];\n for (const m of marks) {\n if (m.kind === 'point') {\n const at = projectPoint(m.at, viewport);\n if (at) {\n points.push({\n at, glyph: m.glyph,\n ...(m.label !== undefined ? { label: m.label } : {}),\n ...(m.color ? { color: m.color } : {}),\n });\n }\n continue;\n }\n const from = projectPoint(m.from, viewport);\n const to = projectPoint(m.to, viewport);\n if (!from || !to) continue;\n lines.push({\n from, to,\n ...('value' in m ? { value: m.value } : {}),\n ...(m.color ? { color: m.color } : {}),\n });\n }\n return { lines, points };\n}\n","/**\n * What a host paints for a gesture that proposes chrome rather than a pose.\n *\n * A marquee sweep and a box-drag both publish an `OngoingOverlay`.\n * `resolveOverlays` hands back world geometry with no renderer in it, so the\n * same call `<SceneCanvas>` makes serves a consumer-owned 3D renderer.\n *\n * A 3D host's `clientToWorld` is identity, so an overlay's world bounds are the\n * client rect the deps already work in, and the pane origin comes off exactly\n * once. Only the rectangular variants resolve here: a lasso, a pencil, and a run\n * of points are paths, and a path is geometry this cannot flatten to a box.\n */\n\nimport { overlaysOf, resolveOverlays, type OngoingHandle } from '@weasel-js/core';\nimport type { ChromeBox } from './screen';\n\n/** Gesture chrome, in CSS pixels relative to the pane's top-left. */\nexport function collectOverlayBoxes(\n handles: Iterable<OngoingHandle>,\n origin: { x: number; y: number },\n): ChromeBox[] {\n const overlays = [];\n for (const handle of handles) overlays.push(...overlaysOf(handle));\n\n const boxes: ChromeBox[] = [];\n for (const resolved of resolveOverlays(overlays)) {\n if (resolved.kind !== 'marquee' && resolved.kind !== 'insertPreview') continue;\n const { x, y, width, height } = resolved.bounds;\n boxes.push({ x: x - origin.x, y: y - origin.y, width, height, tint: 'gesture' });\n }\n return boxes;\n}\n","/**\n * Camera tools and their actions.\n *\n * Shape tools transfer from the kit untouched — a 3D host mounts core's own\n * `useSelectTool` and a rectangle-style insert binding and neither notices the\n * dimension. Only the viewport tools are written here, which is the one\n * exception the kernel doc predicted: `useHandTool` routes to\n * `viewport.dragPan`, and that wants the 2D `view`.\n */\n\nimport { useMemo } from 'react';\nimport { defineTool, type Action, type InvocationCtx, type Tool } from '@weasel-js/core';\nimport { dollyToward, orbitBy, panBy, type Camera3d } from './camera';\nimport type { Camera3dDep } from './cameraDep';\n\n/** Radians per CSS pixel of drag. A full pane width is a bit over half a turn. */\nexport const ORBIT_RATE = 0.006;\n/** Dolly exponent per unit of wheel `deltaY`. */\nexport const DOLLY_RATE = 0.0015;\n\n/**\n * The drag's cumulative client-pixel delta.\n *\n * The fallback is only sound because a 3D host's `clientToWorld` is identity\n * (see `overlays.ts`), so the world delta already is the client one. Don't copy\n * this to a host with a 2D view — there the two spaces differ by the zoom.\n */\nfunction screenDelta(move: InvocationCtx): { x: number; y: number } | undefined {\n return move.drag?.screenDelta ?? move.drag?.delta;\n}\n\n/** An ongoing drag replacing the `camera3d` dep with `step` of the camera as\n * it was when the drag began. `drag.delta` runs from the drag origin, not the\n * previous move, so every move composes against that one camera. */\nfunction dragCamera(\n ctx: InvocationCtx,\n kind: string,\n step: (origin: Camera3d, delta: { x: number; y: number }, dep: Camera3dDep) => Camera3d,\n) {\n const dep = ctx.deps.camera3d;\n const origin: Camera3d | undefined = dep?.get();\n return {\n kind,\n onMove(move: InvocationCtx) {\n const delta = screenDelta(move);\n if (!dep || !origin || !delta) return;\n dep.set(step(origin, delta, dep));\n },\n };\n}\n\n/** `camera.orbit`: an ongoing drag that turns the `camera3d` dep about its\n * target. */\nexport const orbitAction: Action = {\n id: 'camera.orbit',\n label: 'Orbit',\n group: 'viewport',\n cursor: 'grab',\n activeCursor: 'grabbing',\n requires: ['camera3d', 'kitSettings'],\n invoker: {\n timing: 'ongoing',\n start(ctx) {\n const rate = ctx.deps.kitSettings?.get('orbit3d.orbitRate') ?? ORBIT_RATE;\n return dragCamera(ctx, 'orbit', (origin, d, dep) =>\n orbitBy(origin, -d.x * rate, d.y * rate, dep.limits?.()));\n },\n },\n};\n\n/** `camera.pan`: an ongoing drag that slides the `camera3d` dep's target\n * across the screen plane, so the point at the target follows the pointer. */\nexport const panAction: Action = {\n id: 'camera.pan',\n label: 'Pan',\n group: 'viewport',\n cursor: 'move',\n requires: ['camera3d'],\n invoker: {\n timing: 'ongoing',\n start(ctx) {\n return dragCamera(ctx, 'pan', (origin, d, dep) =>\n panBy(origin, d.x, d.y, dep.size().height));\n },\n },\n};\n\n/** Where on the pane a dolly anchors: the canvas-local point the event\n * carries, or the middle when it carries none. */\nfunction anchorOf(\n params: Record<string, unknown> | undefined,\n pane: { width: number; height: number },\n): { x: number; y: number } {\n const x = params?.clientX;\n const y = params?.clientY;\n return typeof x === 'number' && typeof y === 'number'\n ? { x, y }\n : { x: pane.width / 2, y: pane.height / 2 };\n}\n\n/** `camera.dolly`: moves the `camera3d` dep in or out about the point under\n * the pointer, as a 2D camera's wheel zooms about it. A wheel's `deltaY`, and\n * a trackpad pinch delivered as ctrl+wheel, dolly by `exp(deltaY × rate)` —\n * one rate for both, as a 2D camera zooms by both. Safari's pinch arrives as\n * a `scale` and divides the distance by it. Bound to all three by default, in\n * every tool. */\nexport const dollyAction: Action = {\n id: 'camera.dolly',\n label: 'Dolly',\n group: 'viewport',\n defaultBinding: [\n { spec: { kind: 'wheel' }, opts: { id: 'camera.dolly.wheel' } },\n // Unbound, a trackpad pinch zooms the page instead.\n { spec: { kind: 'wheel', mods: { ctrl: true } }, opts: { id: 'camera.dolly.trackpadPinch' } },\n { spec: { kind: 'pinch' }, opts: { id: 'camera.dolly.pinch' } },\n ],\n requires: ['camera3d', 'kitSettings'],\n invoker: {\n timing: 'immediate',\n run(deps, params) {\n const dep = deps.camera3d;\n if (!dep) return;\n const factor = typeof params?.scale === 'number'\n ? 1 / params.scale\n : Math.exp(\n (typeof params?.deltaY === 'number' ? params.deltaY : 0)\n * (deps.kitSettings?.get('orbit3d.dollyRate') ?? DOLLY_RATE),\n );\n if (!(factor > 0) || !Number.isFinite(factor)) return;\n const pane = dep.size();\n dep.set(dollyToward(dep.get(), factor, anchorOf(params, pane), pane, dep.limits?.()));\n },\n },\n};\n\n/** `camera.pinchDolly`: two fingers spreading dolly the `camera3d` dep in and\n * closing dolly it out, by the ratio of their spread, about where they began. */\nexport const pinchDollyAction: Action = {\n id: 'camera.pinchDolly',\n label: 'Pinch Dolly',\n group: 'viewport',\n defaultBinding: [{ spec: { kind: 'multiTouch', fingers: 2 }, opts: { id: 'camera.pinchDolly.multiTouch' } }],\n requires: ['camera3d'],\n invoker: {\n timing: 'ongoing',\n start(ctx) {\n const dep = ctx.deps.camera3d;\n const origin: Camera3d | undefined = dep?.get();\n const startSpread = ctx.multiTouch?.spread ?? 0;\n const at = ctx.multiTouch?.centroid;\n return {\n kind: 'pinch',\n onMove(move) {\n const spread = move.multiTouch?.pinch?.currentSpread ?? 0;\n if (!dep || !origin || !(startSpread > 0) || !(spread > 0)) return;\n const pane = dep.size();\n const anchor = at ?? { x: pane.width / 2, y: pane.height / 2 };\n dep.set(dollyToward(origin, startSpread / spread, anchor, pane, dep.limits?.()));\n },\n };\n },\n },\n};\n\n/** `camera.home`: returns the `camera3d` dep to its `home`. Bound to a double\n * click by default. */\nexport const homeAction: Action = {\n id: 'camera.home',\n label: 'Reset Camera',\n group: 'viewport',\n defaultBinding: [{ spec: { kind: 'doubleClick' }, opts: { id: 'camera.home.doubleClick' } }],\n requires: ['camera3d'],\n invoker: {\n timing: 'immediate',\n run(deps) {\n const dep = deps.camera3d;\n const home = dep?.home?.();\n if (dep && home) dep.set(home);\n },\n },\n};\n\n/** A tool that binds a drag to `camera.orbit` and Shift+drag to `camera.pan`.\n * Register both actions alongside it; the tool only declares the bindings. */\nexport function useOrbitTool(): Tool {\n return useMemo(() => defineTool({\n id: 'orbit',\n hookName: 'useOrbitTool',\n cursor: 'grab',\n presentation: { label: 'Orbit', group: 'viewport' },\n bindings: [\n { spec: { kind: 'drag' }, actionId: 'camera.orbit', opts: { id: 'orbit.orbit' } },\n { spec: { kind: 'drag', mods: { shift: true } }, actionId: 'camera.pan', opts: { id: 'orbit.pan' } },\n ],\n }), []);\n}\n","import type {} from '@weasel-js/react';\nimport { pref } from '@weasel-js/prefs';\nimport { DOLLY_RATE, ORBIT_RATE } from './tools';\n\n/** The `orbit3d` kit settings area: how far the camera tools move per input. */\nexport interface Orbit3dKitSettings {\n /** Radians of orbit per CSS pixel of drag. */\n orbitRate: number;\n /** Dolly exponent per unit of wheel `deltaY`. */\n dollyRate: number;\n}\n\ndeclare module '@weasel-js/react' {\n interface KitSettings {\n orbit3d: Orbit3dKitSettings;\n }\n}\n\n/** The `orbit3d` area as a prefs group whose paths are the `KitSettings` paths. */\nexport const kernel3dKitSettingsSchema = pref.group('3D camera', {\n orbit3d: pref.group('Orbit', {\n orbitRate: pref.number('Orbit speed', ORBIT_RATE, { min: 0.001, max: 0.03, step: 0.001 }),\n dollyRate: pref.number('Dolly speed', DOLLY_RATE, { min: 0.0002, max: 0.01, step: 0.0001 }),\n }),\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/kernel3d",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0-rc.0",
|
|
4
4
|
"description": "3D kernel for weasel: poses, orbit camera, ray picking and screen-projected chrome geometry over core's scene graph and dispatcher. Hosts a renderer rather than owning one.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
"build": "tsup"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@weasel-js/geom": "1.
|
|
41
|
-
"@weasel-js/prefs": "1.
|
|
42
|
-
"@weasel-js/react": "1.
|
|
40
|
+
"@weasel-js/geom": "1.13.0-rc.0",
|
|
41
|
+
"@weasel-js/prefs": "1.13.0-rc.0",
|
|
42
|
+
"@weasel-js/react": "1.13.0-rc.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@weasel-js/core": "1.
|
|
45
|
+
"@weasel-js/core": "1.13.0-rc.0",
|
|
46
46
|
"react": ">=18"
|
|
47
47
|
},
|
|
48
48
|
"publishConfig": {
|