@nakednous/tree 0.0.23 → 0.0.24

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 CHANGED
@@ -33,13 +33,14 @@ import * as tree from '@nakednous/tree'
33
33
 
34
34
  The dependency direction is strict: `@nakednous/tree` never imports from the bridge or the DOM layer. This is what lets the same `PoseTrack` that drives a camera path also animate any object — headless, server-side, or in a future renderer.
35
35
 
36
- Source is organised into four focused modules:
36
+ Source is organised into five focused modules:
37
37
 
38
38
  ```
39
- form.js — you have specs, you want a matrix
40
- query.js — you have a matrix, you want information
41
- quat.js — quaternion algebra and mat4/mat3 conversions
42
- track.js — spline math and keyframe animation state machines
39
+ form.js — you have specs, you want a matrix
40
+ query.js — you have a matrix, you want information
41
+ quat.js — quaternion algebra and mat4/mat3 conversions
42
+ track.js — spline math and keyframe animation state machines
43
+ handle.js — constraint solver + ray primitives for interactive manipulators
43
44
  ```
44
45
 
45
46
  ---
@@ -370,6 +371,27 @@ Three-state result: `VISIBLE` (fully inside), `SEMIVISIBLE` (intersecting), `INV
370
371
 
371
372
  ---
372
373
 
374
+ ### Manipulator constraints
375
+
376
+ `handle.js` is the renderer-agnostic core of an interactive manipulator: ray-primitive intersections, az/el utilities, and a `Constraint` state machine. The `p5.tree` bridge wraps these into a draggable handle; this package supplies the math and the **contract** that makes the handle extensible.
377
+
378
+ ```js
379
+ import { createConstraint, SPHERE, PLANE, AXIS, POINT, DIRECTION,
380
+ raySphere, rayPlane, rayClosestPointOnAxis,
381
+ dirFromAzEl, azElFromDir } from '@nakednous/tree'
382
+
383
+ const c = createConstraint(SPHERE, { radius: 1 }) // or PLANE / AXIS
384
+ const out = [0, 0, 0]
385
+ c.solve(ox,oy,oz, dx,dy,dz) // ray (working space) → canonical state; chainable
386
+ c.value(out, DIRECTION) // write the reported value into out(3)
387
+ ```
388
+
389
+ `SPHERE` stores a unit direction (gimbal-free); `PLANE` / `AXIS` store a constrained point. `value` reports a `DIRECTION` (unit) or a `POINT` per kind. Ray primitives are out-first and assume a unit ray direction; `rayPlane` returns `Infinity` when the ray is parallel.
390
+
391
+ **Constraint contract (extension seam).** A constraint is any object exposing `kind`, `solve(ox,oy,oz, dx,dy,dz)`, `value(out, report)`, `seed(x,y,z)`, and optionally `scalar()` / `azEl(out2)`. The handle controller drives any conforming constraint, so a new kind — rotation, 6-DOF, or app-specific — implements this contract (portable, draw-free) plus a bridge-side locus draw, rather than forking the controller. The built-in `Constraint` is the reference implementation. Full design: [`handle-design.md`](./handle-design.md).
392
+
393
+ ---
394
+
373
395
  ### Quaternion and matrix math
374
396
 
375
397
  Exported individually for use in hot paths.
@@ -440,6 +462,10 @@ WEBGPU // 0 (z ∈ [0, 1])
440
462
  // Visibility results
441
463
  INVISIBLE, VISIBLE, SEMIVISIBLE
442
464
 
465
+ // Manipulator constraint kinds & report modes
466
+ SPHERE, PLANE, AXIS
467
+ POINT, DIRECTION
468
+
443
469
  // Basis vectors (frozen)
444
470
  ORIGIN, i, j, k, _i, _j, _k
445
471
  ```