@nakednous/host 0.0.10 → 0.0.12
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 +6 -1
- package/dist/index.js +32 -12
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -70,7 +70,7 @@ dependency first and an options object last, and registers with the context so
|
|
|
70
70
|
|
|
71
71
|
| member | what it is |
|
|
72
72
|
|---|---|
|
|
73
|
-
| `createHost(canvas, opts)` | the context: `ndcZMin` (WEBGL default, or WEBGPU), `onFrame(dt, host)` for the host's own loop, `onSize(w, h, dpr)` for the bridge's buffer, `raf` / `caf` overrides |
|
|
73
|
+
| `createHost(canvas, opts)` | the context: `ndcZMin` (WEBGL default, or WEBGPU), `onFrame(dt, host)` for the host's own loop, `afterFrame(dt, host)` after the pointer flush — the frame's last draw, a pointer handler's included, where a WebGPU bridge submits its command encoder — `onSize(w, h, dpr)` for the bridge's buffer, `raf` / `caf` overrides |
|
|
74
74
|
| `host.view` | the view bag — `mat4Proj` · `mat4View` · `mat4PV` · `mat4PVInv` · `mat4Eye`, `vp`, `ndcZMin`, `stale`; `set(P, V)`, `setCamera(cam)`, `resize(w, h)` |
|
|
75
75
|
| `host.pointer` | the pointer source — presses queued per frame, per-pointer entries with a move counter, claims that capture on the canvas, Esc cancel, `flush()` |
|
|
76
76
|
| `host.players` | the registry ticked each frame — `{ tick(dt) → boolean }`, removed on `false` |
|
|
@@ -116,6 +116,10 @@ one wrote:
|
|
|
116
116
|
5. **draw** — the bridge reads the camera state, the handles' values, the tracks' paths.
|
|
117
117
|
6. **labels tick** — world anchors projected through the current bag, transforms written.
|
|
118
118
|
7. **pointer flush** — the press queue empties, released pointers leave.
|
|
119
|
+
8. **the post-frame hook** — `afterFrame(dt, host)`, when it was given: the frame's last draw,
|
|
120
|
+
a pointer handler's included, so a WebGPU bridge submits its command encoder there. It is
|
|
121
|
+
the host's loop's step and nothing in external tick — there the caller writes the frame's
|
|
122
|
+
end — and `host.dispose()` clears it.
|
|
119
123
|
|
|
120
124
|
`dt` is seconds, clamped to 50 ms so a stalled tab never integrates a leap.
|
|
121
125
|
|
|
@@ -126,6 +130,7 @@ one wrote:
|
|
|
126
130
|
| seam | direction | contract |
|
|
127
131
|
|---|---|---|
|
|
128
132
|
| view bag | bridge → host | the bridge's `setCamera(cam)` also calls `host.view.setCamera(cam)`; without a host the bridge keeps its own matrices |
|
|
133
|
+
| frame end | host → bridge | `afterFrame(dt, host)` runs after `pointer.flush()`; a WebGPU bridge submits its command encoder there, and without the hook the application calls the bridge's `endFrame` itself |
|
|
129
134
|
| external tick | adapter → host | `host.tick(dt)` from the adapter's predraw; `host.labels.tick()` after the adapter set `host.view` from renderer state |
|
|
130
135
|
| proxies · locus | tree → host → bridge | constraint objects carry `proxy` and `locus`; the host tests, the bridge draws |
|
|
131
136
|
| label anchors | tree → bridge → host | a generator writes `out.labels`; the bridge forwards each to `labels.set` |
|
package/dist/index.js
CHANGED
|
@@ -760,7 +760,7 @@ class Handle {
|
|
|
760
760
|
c.s = this._savedS;
|
|
761
761
|
c._dialPoint();
|
|
762
762
|
} else {
|
|
763
|
-
c.seed(this._saved[0], this._saved[1], this._saved[2]);
|
|
763
|
+
c.seed(this._saved[0], this._saved[1], this._saved[2], POINT);
|
|
764
764
|
}
|
|
765
765
|
if (this._binder) this._binder.set(this.value(this._bindVal));
|
|
766
766
|
this._grabbed = false;
|
|
@@ -854,7 +854,7 @@ class Handle {
|
|
|
854
854
|
_v3[1] = gy > 0 ? Math.round(c.pt[1] / gy) * gy : c.pt[1];
|
|
855
855
|
_v3[2] = gz > 0 ? Math.round(c.pt[2] / gz) * gz : c.pt[2];
|
|
856
856
|
if (this._isView) { c.pt[0] = _v3[0]; c.pt[1] = _v3[1]; c.pt[2] = _v3[2]; }
|
|
857
|
-
else c.seed(_v3[0], _v3[1], _v3[2]);
|
|
857
|
+
else c.seed(_v3[0], _v3[1], _v3[2], POINT);
|
|
858
858
|
} else if (c.kind === AXIS || c.kind === DIAL) {
|
|
859
859
|
const step = Array.isArray(sn) ? sn[0] : sn;
|
|
860
860
|
if (!(step > 0)) return;
|
|
@@ -901,6 +901,11 @@ class Handle {
|
|
|
901
901
|
* accessor, or a vec3 array mutated in place (a camera state's eye or
|
|
902
902
|
* center is one). get() seeds the constraint now; each solve calls
|
|
903
903
|
* set(value) with the reused value array, then fires onChange. Chainable.
|
|
904
|
+
*
|
|
905
|
+
* The array lives in the handle's `report` space, both ways: a SPHERE handle
|
|
906
|
+
* (DIRECTION by default) binds and receives a **unit heading**, not a point on
|
|
907
|
+
* its sphere; a PLANE / AXIS handle binds and receives a world point. Construct
|
|
908
|
+
* the handle with `report: POINT` to bind a point to a sphere instead.
|
|
904
909
|
* @param {number[]|{ get:Function, set:Function }} target
|
|
905
910
|
* @returns {Handle} this
|
|
906
911
|
*/
|
|
@@ -920,7 +925,9 @@ class Handle {
|
|
|
920
925
|
return this;
|
|
921
926
|
}
|
|
922
927
|
|
|
923
|
-
/** Re-seed the constraint from the bound target after it changed externally
|
|
928
|
+
/** Re-seed the constraint from the bound target after it changed externally —
|
|
929
|
+
* the target holds the handle's own `report` space, as the write-back does, so
|
|
930
|
+
* seed → solve → write never changes what the array means. Chainable. */
|
|
924
931
|
sync() {
|
|
925
932
|
if (this._binder) this._seedFromBinding();
|
|
926
933
|
return this;
|
|
@@ -931,7 +938,7 @@ class Handle {
|
|
|
931
938
|
if (g == null) return;
|
|
932
939
|
const x = _vx$1(g, 0, 0), y = _vx$1(g, 1, 0), z = _vx$1(g, 2, 0);
|
|
933
940
|
if (this._isView) { const pt = this._constraint.pt; pt[0] = x; pt[1] = y; pt[2] = z; }
|
|
934
|
-
else this._constraint.seed(x, y, z);
|
|
941
|
+
else this._constraint.seed(x, y, z, this._constraint.report);
|
|
935
942
|
}
|
|
936
943
|
|
|
937
944
|
// Push the freshly solved value to the binding and fire onChange, once per solve.
|
|
@@ -982,7 +989,7 @@ class Handle {
|
|
|
982
989
|
c.pt[0] = c.anchor[0] + c.s * c.u[0];
|
|
983
990
|
c.pt[1] = c.anchor[1] + c.s * c.u[1];
|
|
984
991
|
c.pt[2] = c.anchor[2] + c.s * c.u[2];
|
|
985
|
-
} else if (c.kind === PLANE) c.seed(c.pt[0], c.pt[1], c.pt[2]);
|
|
992
|
+
} else if (c.kind === PLANE) c.seed(c.pt[0], c.pt[1], c.pt[2], POINT);
|
|
986
993
|
}
|
|
987
994
|
return this;
|
|
988
995
|
}
|
|
@@ -3091,10 +3098,14 @@ function decodeRGBE(bytes, opts) {
|
|
|
3091
3098
|
*
|
|
3092
3099
|
* Two loop modes. With { onFrame } the host runs requestAnimationFrame
|
|
3093
3100
|
* (overridable through { raf, caf }): each frame computes dt (clamped to
|
|
3094
|
-
* 50 ms), ticks the players, calls onFrame(dt, host),
|
|
3095
|
-
*
|
|
3096
|
-
*
|
|
3097
|
-
*
|
|
3101
|
+
* 50 ms), ticks the players, calls onFrame(dt, host), flushes the pointer
|
|
3102
|
+
* source, then calls afterFrame(dt, host) when one was given — the frame's
|
|
3103
|
+
* last draw, a pointer handler's included, which is where a WebGPU bridge
|
|
3104
|
+
* submits its command encoder. Without it the application, or the p5
|
|
3105
|
+
* adapter from predraw, calls host.tick(dt) = players.tick(dt) and
|
|
3106
|
+
* host.pointer.flush() once its consumers ran: external tick gains no
|
|
3107
|
+
* frame end, so afterFrame belongs to the host's own loop. Nothing else in
|
|
3108
|
+
* the host cares who owns the loop.
|
|
3098
3109
|
*
|
|
3099
3110
|
* The frame order inside onFrame: install the camera (which fills
|
|
3100
3111
|
* host.view), update handles or routers, fall through to the orbit when
|
|
@@ -3108,12 +3119,18 @@ const _now = () => (typeof performance !== 'undefined' && performance.now) ? per
|
|
|
3108
3119
|
* Create the host context of a canvas.
|
|
3109
3120
|
*
|
|
3110
3121
|
* @param {HTMLCanvasElement} canvas
|
|
3111
|
-
* @param {{ ndcZMin?:number, onFrame?:function(number, object):void,
|
|
3122
|
+
* @param {{ ndcZMin?:number, onFrame?:function(number, object):void,
|
|
3123
|
+
* afterFrame?:function(number, object):void, raf?:function,
|
|
3112
3124
|
* caf?:function, onSize?:function(number, number, number):void }} [opts]
|
|
3113
3125
|
* ndcZMin: the GPU API's NDC-z convention, WEBGL (default) or WEBGPU —
|
|
3114
3126
|
* written once, never detected. onFrame: the host's own loop; absent,
|
|
3115
|
-
* external-tick mode.
|
|
3116
|
-
*
|
|
3127
|
+
* external-tick mode. afterFrame: called after the pointer source
|
|
3128
|
+
* flushes, so the frame's last draw — a pointer handler's included —
|
|
3129
|
+
* is behind it; the submit seam of a WebGPU bridge, which ends its
|
|
3130
|
+
* command encoder there. The host's loop only: an external tick has
|
|
3131
|
+
* no frame end but the one its caller writes. dispose() clears it.
|
|
3132
|
+
* onSize(width, height, dpr): the bridge's chance to resize its
|
|
3133
|
+
* drawing buffer.
|
|
3117
3134
|
* @returns {object} The host.
|
|
3118
3135
|
*/
|
|
3119
3136
|
function createHost(canvas, opts) {
|
|
@@ -3121,6 +3138,7 @@ function createHost(canvas, opts) {
|
|
|
3121
3138
|
const t0 = _now();
|
|
3122
3139
|
const constructs = new Set();
|
|
3123
3140
|
let loop = null, observer = null, labels = null;
|
|
3141
|
+
let afterFrame = typeof o.afterFrame === 'function' ? o.afterFrame : null;
|
|
3124
3142
|
const host = {
|
|
3125
3143
|
canvas,
|
|
3126
3144
|
width: 0, height: 0, dpr: 1,
|
|
@@ -3202,6 +3220,7 @@ function createHost(canvas, opts) {
|
|
|
3202
3220
|
|
|
3203
3221
|
/** Stop the loop, disconnect the observer, remove every listener, dispose every construct. */
|
|
3204
3222
|
dispose() {
|
|
3223
|
+
afterFrame = null;
|
|
3205
3224
|
if (loop) loop.stop();
|
|
3206
3225
|
for (const c of [...constructs]) { if (typeof c.dispose === 'function') c.dispose(); }
|
|
3207
3226
|
constructs.clear();
|
|
@@ -3230,6 +3249,7 @@ function createHost(canvas, opts) {
|
|
|
3230
3249
|
host.players.tick(dt);
|
|
3231
3250
|
o.onFrame(dt, host);
|
|
3232
3251
|
host.pointer.flush();
|
|
3252
|
+
if (afterFrame !== null) afterFrame(dt, host);
|
|
3233
3253
|
},
|
|
3234
3254
|
});
|
|
3235
3255
|
loop.start();
|