@geometra/renderer-three 0.1.3 → 1.3.1

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.
Files changed (39) hide show
  1. package/dist/host-css-coerce.d.ts +39 -0
  2. package/dist/host-css-coerce.d.ts.map +1 -0
  3. package/dist/host-css-coerce.js +69 -0
  4. package/dist/host-css-coerce.js.map +1 -0
  5. package/dist/host-layout-plain.d.ts +164 -0
  6. package/dist/host-layout-plain.d.ts.map +1 -0
  7. package/dist/host-layout-plain.js +255 -0
  8. package/dist/host-layout-plain.js.map +1 -0
  9. package/dist/index.d.ts +43 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +42 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/layout-sync.d.ts +51 -0
  14. package/dist/layout-sync.d.ts.map +1 -0
  15. package/dist/layout-sync.js +59 -0
  16. package/dist/layout-sync.js.map +1 -0
  17. package/dist/scene3d-manager.d.ts +29 -0
  18. package/dist/scene3d-manager.d.ts.map +1 -0
  19. package/dist/scene3d-manager.js +339 -0
  20. package/dist/scene3d-manager.js.map +1 -0
  21. package/dist/split-host.d.ts +58 -17
  22. package/dist/split-host.d.ts.map +1 -1
  23. package/dist/split-host.js +105 -46
  24. package/dist/split-host.js.map +1 -1
  25. package/dist/stacked-host.d.ts +109 -0
  26. package/dist/stacked-host.d.ts.map +1 -0
  27. package/dist/stacked-host.js +218 -0
  28. package/dist/stacked-host.js.map +1 -0
  29. package/dist/three-scene-basics.d.ts +338 -0
  30. package/dist/three-scene-basics.d.ts.map +1 -0
  31. package/dist/three-scene-basics.js +435 -0
  32. package/dist/three-scene-basics.js.map +1 -0
  33. package/dist/utils.d.ts +165 -1
  34. package/dist/utils.d.ts.map +1 -1
  35. package/dist/utils.js +219 -3
  36. package/dist/utils.js.map +1 -1
  37. package/package.json +15 -16
  38. package/LICENSE +0 -21
  39. package/README.md +0 -81
@@ -0,0 +1,435 @@
1
+ import * as THREE from 'three';
2
+ import { GEOMETRA_HEADLESS_RAW_DEVICE_PIXEL_RATIO, isPlainGeometraThreeViewSizingState, resizeGeometraThreePerspectiveView, resolveHostDevicePixelRatio, toPlainGeometraThreeViewSizingState, toPlainGeometraThreeViewSizingStateHeadless, } from './utils.js';
3
+ const geometraDisposedWebGLRenderers = new WeakSet();
4
+ /**
5
+ * Scene and camera defaults shared by {@link createThreeGeometraSplitHost},
6
+ * {@link createThreeGeometraStackedHost}, and {@link createGeometraThreeSceneBasics}.
7
+ * Use in headless or custom renderer setups so numbers stay aligned with those hosts
8
+ * without copying literals from the README.
9
+ */
10
+ export const GEOMETRA_THREE_HOST_SCENE_DEFAULTS = {
11
+ threeBackground: 0x000000,
12
+ cameraFov: 50,
13
+ cameraNear: 0.1,
14
+ cameraFar: 2000,
15
+ cameraPosition: [0, 0, 5],
16
+ };
17
+ function coerceGeometraThreeSceneBasicsCamera(merged) {
18
+ const d = GEOMETRA_THREE_HOST_SCENE_DEFAULTS;
19
+ const cameraFov = Number.isFinite(merged.cameraFov) && merged.cameraFov > 0 && merged.cameraFov < 180
20
+ ? merged.cameraFov
21
+ : d.cameraFov;
22
+ let cameraNear = Number.isFinite(merged.cameraNear) && merged.cameraNear > 0 ? merged.cameraNear : d.cameraNear;
23
+ let cameraFar = merged.cameraFar;
24
+ if (!Number.isFinite(cameraFar) || cameraFar <= cameraNear) {
25
+ cameraFar = d.cameraFar > cameraNear ? d.cameraFar : cameraNear * 2;
26
+ }
27
+ const [px, py, pz] = merged.cameraPosition;
28
+ const [dx, dy, dz] = d.cameraPosition;
29
+ const cameraPosition = [
30
+ Number.isFinite(px) ? px : dx,
31
+ Number.isFinite(py) ? py : dy,
32
+ Number.isFinite(pz) ? pz : dz,
33
+ ];
34
+ return { cameraFov, cameraNear, cameraFar, cameraPosition };
35
+ }
36
+ /**
37
+ * Fully merged and coerced {@link GeometraThreeSceneBasicsOptions} using the same rules as
38
+ * {@link createGeometraThreeSceneBasics} (and split/stacked hosts).
39
+ *
40
+ * Use when you need host-aligned numbers for logging, tests, or agent-side protocol payloads without
41
+ * constructing a {@link THREE.Scene} or {@link THREE.PerspectiveCamera}.
42
+ */
43
+ export function resolveGeometraThreeSceneBasicsOptions(options = {}) {
44
+ const merged = { ...GEOMETRA_THREE_HOST_SCENE_DEFAULTS, ...options };
45
+ const { cameraFov, cameraNear, cameraFar, cameraPosition } = coerceGeometraThreeSceneBasicsCamera(merged);
46
+ return {
47
+ threeBackground: merged.threeBackground,
48
+ cameraFov,
49
+ cameraNear,
50
+ cameraFar,
51
+ cameraPosition,
52
+ };
53
+ }
54
+ /**
55
+ * Same coercion as {@link resolveGeometraThreeSceneBasicsOptions}, plus a hex background for stable JSON.
56
+ */
57
+ export function toPlainGeometraThreeSceneBasicsOptions(options = {}) {
58
+ const resolved = resolveGeometraThreeSceneBasicsOptions(options);
59
+ const threeBackgroundHex = new THREE.Color(resolved.threeBackground).getHex();
60
+ return {
61
+ threeBackgroundHex,
62
+ cameraFov: resolved.cameraFov,
63
+ cameraNear: resolved.cameraNear,
64
+ cameraFar: resolved.cameraFar,
65
+ cameraPosition: [...resolved.cameraPosition],
66
+ };
67
+ }
68
+ /**
69
+ * Build {@link GeometraThreeSceneBasics} from {@link PlainGeometraThreeSceneBasicsOptions} (for example
70
+ * `JSON.parse` of logs, tests, or agent payloads). Maps `threeBackgroundHex` to {@link GeometraThreeSceneBasicsOptions.threeBackground}
71
+ * and forwards camera fields through {@link createGeometraThreeSceneBasics}, so invalid numbers get the same
72
+ * coercion as split/stacked hosts and {@link toPlainGeometraThreeSceneBasicsOptions} output round-trips when
73
+ * re-applied here.
74
+ */
75
+ export function createGeometraThreeSceneBasicsFromPlain(plain) {
76
+ return createGeometraThreeSceneBasics({
77
+ threeBackground: plain.threeBackgroundHex,
78
+ cameraFov: plain.cameraFov,
79
+ cameraNear: plain.cameraNear,
80
+ cameraFar: plain.cameraFar,
81
+ cameraPosition: [...plain.cameraPosition],
82
+ });
83
+ }
84
+ function isPlainCameraPosition(value) {
85
+ return (Array.isArray(value) &&
86
+ value.length === 3 &&
87
+ value.every((n) => typeof n === 'number' && Number.isFinite(n)));
88
+ }
89
+ function isPlainGeometraThreeSceneBasicsOptionsRecord(o) {
90
+ if (typeof o.threeBackgroundHex !== 'number' || !Number.isFinite(o.threeBackgroundHex)) {
91
+ return false;
92
+ }
93
+ const fov = o.cameraFov;
94
+ if (typeof fov !== 'number' || !Number.isFinite(fov) || fov <= 0 || fov >= 180) {
95
+ return false;
96
+ }
97
+ const near = o.cameraNear;
98
+ const far = o.cameraFar;
99
+ if (typeof near !== 'number' || !Number.isFinite(near) || near <= 0)
100
+ return false;
101
+ if (typeof far !== 'number' || !Number.isFinite(far) || far <= near)
102
+ return false;
103
+ return isPlainCameraPosition(o.cameraPosition);
104
+ }
105
+ /**
106
+ * Narrow `unknown` (e.g. `JSON.parse`) to {@link PlainGeometraThreeSceneBasicsOptions} — the scene/camera
107
+ * fields from {@link toPlainGeometraThreeSceneBasicsOptions} without viewport sizing. Extra keys are allowed.
108
+ * Pair with {@link isPlainGeometraThreeViewSizingState} when you need both slices before merging or calling
109
+ * {@link createGeometraThreeSceneBasicsFromPlain}.
110
+ */
111
+ export function isPlainGeometraThreeSceneBasicsOptions(value) {
112
+ if (value === null || typeof value !== 'object')
113
+ return false;
114
+ return isPlainGeometraThreeSceneBasicsOptionsRecord(value);
115
+ }
116
+ /**
117
+ * Narrow `unknown` (e.g. `JSON.parse`) to {@link PlainGeometraThreeHostSnapshot} when the object matches
118
+ * the shape from {@link toPlainGeometraThreeHostSnapshot} / {@link toPlainGeometraThreeHostSnapshotHeadless} /
119
+ * {@link toPlainGeometraThreeHostSnapshotFromViewSizing}. Extra keys (e.g. hybrid layout fields) are allowed.
120
+ * Composite payloads use {@link isPlainGeometraThreeSplitHostSnapshot} / {@link isPlainGeometraThreeStackedHostSnapshot}.
121
+ */
122
+ export function isPlainGeometraThreeHostSnapshot(value) {
123
+ if (!isPlainGeometraThreeViewSizingState(value))
124
+ return false;
125
+ return isPlainGeometraThreeSceneBasicsOptionsRecord(value);
126
+ }
127
+ /**
128
+ * Merge host-aligned viewport sizing and scene/camera plain fields for stable JSON.
129
+ *
130
+ * @see PlainGeometraThreeHostSnapshot
131
+ */
132
+ export function toPlainGeometraThreeHostSnapshot(cssWidth, cssHeight, rawDevicePixelRatio, maxDevicePixelRatio, sceneBasicsOptions = {}) {
133
+ return {
134
+ ...toPlainGeometraThreeViewSizingState(cssWidth, cssHeight, rawDevicePixelRatio, maxDevicePixelRatio),
135
+ ...toPlainGeometraThreeSceneBasicsOptions(sceneBasicsOptions),
136
+ };
137
+ }
138
+ /**
139
+ * Same plain snapshot as {@link toPlainGeometraThreeHostSnapshot} with raw device pixel ratio **1** —
140
+ * the baseline after `win.devicePixelRatio || 1` when the ratio is missing, and the same raw input as
141
+ * {@link resolveHeadlessHostDevicePixelRatio} when you only apply an optional cap.
142
+ *
143
+ * Viewport fields match {@link toPlainGeometraThreeViewSizingStateHeadless}; for sizing-only JSON, call
144
+ * that helper directly.
145
+ *
146
+ * For headless GL, Node, tests, or agent payloads without a browser `window`, call this instead of
147
+ * passing a literal `1` as `rawDevicePixelRatio` everywhere.
148
+ */
149
+ export function toPlainGeometraThreeHostSnapshotHeadless(cssWidth, cssHeight, maxDevicePixelRatio, sceneBasicsOptions = {}) {
150
+ return {
151
+ ...toPlainGeometraThreeViewSizingStateHeadless(cssWidth, cssHeight, maxDevicePixelRatio),
152
+ ...toPlainGeometraThreeSceneBasicsOptions(sceneBasicsOptions),
153
+ };
154
+ }
155
+ /**
156
+ * Merge an existing {@link PlainGeometraThreeViewSizingState} (from {@link toPlainGeometraThreeViewSizingState}
157
+ * or your own pipeline) with {@link toPlainGeometraThreeSceneBasicsOptions} into one
158
+ * {@link PlainGeometraThreeHostSnapshot}.
159
+ *
160
+ * Use in headless loops, tests, or agent payloads when layout/DPR sizing is computed once and scene/camera
161
+ * options are added later, without re-running {@link toPlainGeometraThreeViewSizingState}.
162
+ */
163
+ export function toPlainGeometraThreeHostSnapshotFromViewSizing(sizing, sceneBasicsOptions = {}) {
164
+ return {
165
+ ...sizing,
166
+ ...toPlainGeometraThreeSceneBasicsOptions(sceneBasicsOptions),
167
+ };
168
+ }
169
+ /**
170
+ * Combine an existing {@link PlainGeometraThreeViewSizingState} with an already-plain scene slice
171
+ * {@link PlainGeometraThreeSceneBasicsOptions} (for example after {@link isPlainGeometraThreeViewSizingState}
172
+ * and {@link isPlainGeometraThreeSceneBasicsOptions}) into one {@link PlainGeometraThreeHostSnapshot}.
173
+ *
174
+ * Same object shape as {@link toPlainGeometraThreeHostSnapshotFromViewSizing} when `scene` is the output of
175
+ * {@link toPlainGeometraThreeSceneBasicsOptions}, but skips a redundant {@link THREE.Color} round-trip when
176
+ * the scene fields are already JSON-stable.
177
+ */
178
+ export function mergePlainGeometraThreeHostSnapshot(sizing, scene) {
179
+ return { ...sizing, ...scene };
180
+ }
181
+ /**
182
+ * `WebGLRenderer` constructor options (excluding `canvas`) used by
183
+ * {@link createThreeGeometraSplitHost} and {@link createThreeGeometraStackedHost}.
184
+ *
185
+ * Typed as {@link WebGLRendererParameters} minus `canvas` so custom renderers stay compatible with
186
+ * Three’s constructor surface when you extend or mirror these flags.
187
+ *
188
+ * Spread into your own `new WebGLRenderer({ canvas, ...GEOMETRA_HOST_WEBGL_RENDERER_OPTIONS })` when
189
+ * you manage the renderer (headless GL, offscreen canvas, tests) so flags stay aligned with those hosts.
190
+ */
191
+ export const GEOMETRA_HOST_WEBGL_RENDERER_OPTIONS = {
192
+ antialias: true,
193
+ alpha: false,
194
+ };
195
+ /**
196
+ * Full {@link WebGLRendererParameters} for `new WebGLRenderer(...)`, with the same flags as
197
+ * {@link createThreeGeometraSplitHost} and {@link createThreeGeometraStackedHost} plus your `canvas`.
198
+ *
199
+ * Use in headless GL, offscreen canvas, or custom hosts so constructor input stays aligned with
200
+ * those packages without copying {@link GEOMETRA_HOST_WEBGL_RENDERER_OPTIONS} at every call site.
201
+ */
202
+ export function createGeometraHostWebGLRendererParams(canvas) {
203
+ return { canvas, ...GEOMETRA_HOST_WEBGL_RENDERER_OPTIONS };
204
+ }
205
+ /**
206
+ * `new WebGLRenderer(createGeometraHostWebGLRendererParams(canvas))` with the same flags as
207
+ * {@link createThreeGeometraSplitHost} and {@link createThreeGeometraStackedHost}.
208
+ *
209
+ * Use in the browser or any environment where Three can create a GL context (offscreen canvas,
210
+ * custom hosts). Prefer {@link createGeometraHostWebGLRendererParams} when you need to spread
211
+ * into a larger parameter object.
212
+ */
213
+ export function createGeometraThreeWebGLRenderer(canvas) {
214
+ return new THREE.WebGLRenderer(createGeometraHostWebGLRendererParams(canvas));
215
+ }
216
+ /**
217
+ * Create a scene, perspective camera, and clock with the same defaults as
218
+ * {@link createThreeGeometraSplitHost} and {@link createThreeGeometraStackedHost}.
219
+ *
220
+ * Use this when you want Three.js state aligned with those hosts but manage your own
221
+ * `WebGLRenderer` (for example headless GL, offscreen canvas, or custom render targets).
222
+ *
223
+ * Non-finite or invalid perspective settings fall back to {@link GEOMETRA_THREE_HOST_SCENE_DEFAULTS}
224
+ * (or `far = max(default far, near × 2)` when the default far is not past a coerced near plane).
225
+ *
226
+ * @returns A {@link GeometraThreeSceneBasics} value aligned with split/stacked host defaults.
227
+ */
228
+ export function createGeometraThreeSceneBasics(options = {}) {
229
+ const resolved = resolveGeometraThreeSceneBasicsOptions(options);
230
+ const { threeBackground, cameraFov, cameraNear, cameraFar, cameraPosition } = resolved;
231
+ const scene = new THREE.Scene();
232
+ scene.background = new THREE.Color(threeBackground);
233
+ const camera = new THREE.PerspectiveCamera(cameraFov, 1, cameraNear, cameraFar);
234
+ camera.position.set(cameraPosition[0], cameraPosition[1], cameraPosition[2]);
235
+ const clock = new THREE.Clock();
236
+ return { scene, camera, clock };
237
+ }
238
+ /**
239
+ * Create a {@link THREE.WebGLRenderer} and {@link GeometraThreeSceneBasics} in one call, using the same
240
+ * constructor flags and scene defaults as {@link createThreeGeometraSplitHost} and
241
+ * {@link createThreeGeometraStackedHost}.
242
+ *
243
+ * Equivalent to {@link createGeometraThreeWebGLRenderer} on `canvas` plus
244
+ * {@link createGeometraThreeSceneBasics} with the same `options` — useful for offscreen canvas, custom hosts, or
245
+ * agent-side bootstrap where you want parity without duplicating the two factories.
246
+ *
247
+ * Requires a WebGL-capable environment (same as `new WebGLRenderer(...)`).
248
+ */
249
+ export function createGeometraThreeWebGLWithSceneBasics(canvas, options = {}) {
250
+ const renderer = createGeometraThreeWebGLRenderer(canvas);
251
+ const { scene, camera, clock } = createGeometraThreeSceneBasics(options);
252
+ return { renderer, scene, camera, clock };
253
+ }
254
+ /**
255
+ * Same host-aligned renderer + scene bundle as {@link createGeometraThreeWebGLWithSceneBasics}, but scene and
256
+ * camera are built from {@link PlainGeometraThreeSceneBasicsOptions} (for example `JSON.parse` of logs, tests,
257
+ * or agent payloads) via {@link createGeometraThreeSceneBasicsFromPlain}, so invalid fields get the same coercion
258
+ * as split/stacked hosts without manually mapping `threeBackgroundHex` into {@link GeometraThreeSceneBasicsOptions}.
259
+ *
260
+ * Requires a WebGL-capable environment (same as `new WebGLRenderer(...)`).
261
+ */
262
+ export function createGeometraThreeWebGLWithSceneBasicsFromPlain(canvas, plain) {
263
+ const renderer = createGeometraThreeWebGLRenderer(canvas);
264
+ const { scene, camera, clock } = createGeometraThreeSceneBasicsFromPlain(plain);
265
+ return { renderer, scene, camera, clock };
266
+ }
267
+ /**
268
+ * Tear down the {@link THREE.WebGLRenderer} from {@link createGeometraThreeWebGLWithSceneBasics}
269
+ * (or any bundle that shares the same `renderer` reference).
270
+ *
271
+ * When `clock` is passed (for example the same bundle from {@link createGeometraThreeWebGLWithSceneBasics}),
272
+ * calls {@link THREE.Clock.stop} before {@link THREE.WebGLRenderer.dispose} so `getDelta` / `elapsedTime`
273
+ * do not keep advancing after teardown in headless ticks or agent loops.
274
+ *
275
+ * Calls {@link THREE.WebGLRenderer.dispose}; it does not traverse the scene or dispose meshes,
276
+ * materials, or textures — keep that cleanup in app code or a future helper if you need it.
277
+ *
278
+ * Registers the renderer so {@link tickGeometraThreeWebGLWithSceneBasicsFrame} skips a subsequent
279
+ * `render` when teardown runs inside `onFrame`, matching split/stacked hosts after {@link ThreeRuntimeContext.destroy}.
280
+ */
281
+ export function disposeGeometraThreeWebGLWithSceneBasics(bundle) {
282
+ bundle.clock?.stop();
283
+ geometraDisposedWebGLRenderers.add(bundle.renderer);
284
+ bundle.renderer.dispose();
285
+ }
286
+ /**
287
+ * Resize renderer and camera from {@link createGeometraThreeWebGLWithSceneBasics} using the same CSS layout,
288
+ * {@link resolveHostDevicePixelRatio} capping, and {@link resizeGeometraThreePerspectiveView} path as
289
+ * {@link createThreeGeometraSplitHost} and {@link createThreeGeometraStackedHost}.
290
+ *
291
+ * Use in headless GL, offscreen canvas, or custom hosts when you already hold the bundle and a layout size
292
+ * (e.g. from your own layout pass). Pass `rawDevicePixelRatio` from `window.devicePixelRatio` in the browser
293
+ * or `1` when there is no window.
294
+ *
295
+ * Equivalent to calling {@link resizeGeometraThreePerspectiveView} on `bundle.renderer` and `bundle.camera` with
296
+ * `resolveHostDevicePixelRatio(rawDevicePixelRatio, maxDevicePixelRatio)`.
297
+ */
298
+ export function resizeGeometraThreeWebGLWithSceneBasicsView(bundle, cssWidth, cssHeight, rawDevicePixelRatio, maxDevicePixelRatio) {
299
+ resizeGeometraThreePerspectiveView(bundle.renderer, bundle.camera, cssWidth, cssHeight, resolveHostDevicePixelRatio(rawDevicePixelRatio, maxDevicePixelRatio));
300
+ }
301
+ /**
302
+ * Same as {@link resizeGeometraThreeWebGLWithSceneBasicsView} with raw device pixel ratio fixed at **1** —
303
+ * parity with {@link resolveHeadlessHostDevicePixelRatio} and {@link toPlainGeometraThreeHostSnapshotHeadless}
304
+ * for headless GL, Node, tests, or agent loops without a browser `window`.
305
+ */
306
+ export function resizeGeometraThreeWebGLWithSceneBasicsViewHeadless(bundle, cssWidth, cssHeight, maxDevicePixelRatio) {
307
+ resizeGeometraThreeWebGLWithSceneBasicsView(bundle, cssWidth, cssHeight, GEOMETRA_HEADLESS_RAW_DEVICE_PIXEL_RATIO, maxDevicePixelRatio);
308
+ }
309
+ /**
310
+ * Resize from {@link PlainGeometraThreeViewSizingState} using `layoutWidth`, `layoutHeight`, and
311
+ * `effectiveDevicePixelRatio` — equivalent to
312
+ * {@link resizeGeometraThreeWebGLWithSceneBasicsView} with those dimensions and the same effective ratio
313
+ * the plain helpers compute from raw DPR and optional cap.
314
+ *
315
+ * Accepts any object with those fields, including a full {@link PlainGeometraThreeHostSnapshot} or composite
316
+ * split/stacked snapshot (extra keys ignored). Use when logs, tests, or agents already validated viewport JSON
317
+ * via {@link isPlainGeometraThreeHostSnapshot} and should not re-derive {@link resolveHostDevicePixelRatio}
318
+ * from partial inputs.
319
+ */
320
+ export function resizeGeometraThreeWebGLWithSceneBasicsViewFromPlainViewSizing(bundle, sizing) {
321
+ resizeGeometraThreePerspectiveView(bundle.renderer, bundle.camera, sizing.layoutWidth, sizing.layoutHeight, sizing.effectiveDevicePixelRatio);
322
+ }
323
+ /**
324
+ * One `renderer.render(scene, camera)` pass for a {@link GeometraThreeWebGLWithSceneBasics} bundle.
325
+ *
326
+ * Use in headless GL, tests, or agent-style loops after
327
+ * {@link resizeGeometraThreeWebGLWithSceneBasicsView} (or your own sizing) so a single frame matches
328
+ * the same scene/camera/renderer wiring as {@link createThreeGeometraSplitHost} /
329
+ * {@link createThreeGeometraStackedHost} without duplicating the render call.
330
+ *
331
+ * No-ops when the same `renderer` was already passed to {@link disposeGeometraThreeWebGLWithSceneBasics}
332
+ * — same skip-after-dispose registration as {@link tickGeometraThreeWebGLWithSceneBasicsFrame}.
333
+ */
334
+ export function renderGeometraThreeWebGLWithSceneBasicsFrame(bundle) {
335
+ if (geometraDisposedWebGLRenderers.has(bundle.renderer)) {
336
+ return;
337
+ }
338
+ bundle.renderer.render(bundle.scene, bundle.camera);
339
+ }
340
+ /**
341
+ * Same per-frame ordering as {@link createThreeGeometraSplitHost} and {@link createThreeGeometraStackedHost}:
342
+ * `clock.getDelta()` / `elapsedTime`, optional callback, then `renderer.render`.
343
+ *
344
+ * If `onFrame` returns **`false`**, `renderer.render` is skipped and this function returns **`false`** —
345
+ * parity with {@link ThreeGeometraSplitHostOptions.onThreeFrame} / stacked host `onThreeFrame` returning `false`.
346
+ * If `onFrame` calls {@link disposeGeometraThreeWebGLWithSceneBasics} on the same bundle (same idea as
347
+ * {@link ThreeRuntimeContext.destroy} in browser hosts), `render` is skipped and this returns **`false`** even when
348
+ * the callback does not return `false`. `undefined` and other return values still render when the renderer was not
349
+ * disposed through that helper, and the function returns **`true`** when `render` runs.
350
+ *
351
+ * If `onFrame` **throws**, the error propagates and `renderer.render` is not called — same ordering as browser
352
+ * hosts, which run the frame callback before `render`.
353
+ *
354
+ * Use in headless GL, tests, or agent loops when you want {@link THREE.Clock} timing parity with those hosts
355
+ * without duplicating the loop body. Omit the callback to match a tick that only advances the clock and renders.
356
+ *
357
+ * @returns `true` if `renderer.render` ran, `false` if `onFrame` returned `false` (draw skipped).
358
+ */
359
+ export function tickGeometraThreeWebGLWithSceneBasicsFrame(bundle, onFrame) {
360
+ const { renderer, scene, camera, clock } = bundle;
361
+ const delta = clock.getDelta();
362
+ const elapsed = clock.elapsedTime;
363
+ if (onFrame?.({ renderer, scene, camera, clock, delta, elapsed }) === false) {
364
+ return false;
365
+ }
366
+ if (geometraDisposedWebGLRenderers.has(renderer)) {
367
+ return false;
368
+ }
369
+ renderer.render(scene, camera);
370
+ return true;
371
+ }
372
+ /**
373
+ * One-step frame: {@link resizeGeometraThreeWebGLWithSceneBasicsView}, then
374
+ * {@link tickGeometraThreeWebGLWithSceneBasicsFrame} — same as calling those two in sequence (resize
375
+ * before `clock.getDelta()` / `onFrame` / `render`).
376
+ *
377
+ * Use when you have an explicit raw device pixel ratio (for example `window.devicePixelRatio || 1` from a
378
+ * provided `window`, or a simulated value in tests and agent loops) and want the same resize + frame
379
+ * ordering as {@link createThreeGeometraSplitHost} / {@link createThreeGeometraStackedHost} without inlining
380
+ * both calls.
381
+ *
382
+ * For raw DPR **1** without repeating that literal, prefer {@link resizeTickGeometraThreeWebGLWithSceneBasicsHeadless}.
383
+ *
384
+ * @returns Same boolean as {@link tickGeometraThreeWebGLWithSceneBasicsFrame}.
385
+ */
386
+ export function resizeTickGeometraThreeWebGLWithSceneBasics(bundle, cssWidth, cssHeight, rawDevicePixelRatio, maxDevicePixelRatio, onFrame) {
387
+ resizeGeometraThreeWebGLWithSceneBasicsView(bundle, cssWidth, cssHeight, rawDevicePixelRatio, maxDevicePixelRatio);
388
+ return tickGeometraThreeWebGLWithSceneBasicsFrame(bundle, onFrame);
389
+ }
390
+ /**
391
+ * Headless one-step frame: {@link resizeGeometraThreeWebGLWithSceneBasicsViewHeadless}, then
392
+ * {@link tickGeometraThreeWebGLWithSceneBasicsFrame} — same as calling those two in sequence (resize
393
+ * before `clock.getDelta()` / `onFrame` / `render`).
394
+ *
395
+ * Equivalent to {@link resizeTickGeometraThreeWebGLWithSceneBasics} with `rawDevicePixelRatio` **1** and
396
+ * the same optional `maxDevicePixelRatio` / `onFrame` arguments.
397
+ *
398
+ * For Node, headless WebGL, tests, or agent loops that need buffer + camera sync on every tick with raw
399
+ * DPR **1** and the same optional cap as the browser hosts, without repeating the pair at every call site.
400
+ *
401
+ * @returns Same boolean as {@link tickGeometraThreeWebGLWithSceneBasicsFrame}.
402
+ */
403
+ export function resizeTickGeometraThreeWebGLWithSceneBasicsHeadless(bundle, cssWidth, cssHeight, maxDevicePixelRatio, onFrame) {
404
+ return resizeTickGeometraThreeWebGLWithSceneBasics(bundle, cssWidth, cssHeight, GEOMETRA_HEADLESS_RAW_DEVICE_PIXEL_RATIO, maxDevicePixelRatio, onFrame);
405
+ }
406
+ /**
407
+ * Resize from {@link PlainGeometraThreeViewSizingState}, then {@link tickGeometraThreeWebGLWithSceneBasicsFrame} —
408
+ * same as calling those two in sequence (resize before `clock.getDelta()` / `onFrame` / `render`).
409
+ *
410
+ * Use in headless GL, tests, or agent loops when viewport JSON is already validated (for example with
411
+ * {@link isPlainGeometraThreeHostSnapshot}) and you want the same one-step flow as
412
+ * {@link resizeTickGeometraThreeWebGLWithSceneBasics} without re-supplying raw DPR and `maxDevicePixelRatio` on
413
+ * every tick.
414
+ *
415
+ * @returns Same boolean as {@link tickGeometraThreeWebGLWithSceneBasicsFrame}.
416
+ */
417
+ export function resizeTickGeometraThreeWebGLWithSceneBasicsFromPlainViewSizing(bundle, sizing, onFrame) {
418
+ resizeGeometraThreeWebGLWithSceneBasicsViewFromPlainViewSizing(bundle, sizing);
419
+ return tickGeometraThreeWebGLWithSceneBasicsFrame(bundle, onFrame);
420
+ }
421
+ /**
422
+ * Same as {@link resizeTickGeometraThreeWebGLWithSceneBasicsFromPlainViewSizing} but takes a full
423
+ * {@link PlainGeometraThreeHostSnapshot} (viewport + scene plain fields) — for example from
424
+ * {@link toPlainGeometraThreeHostSnapshot}, {@link toPlainGeometraThreeHostSnapshotHeadless},
425
+ * {@link toPlainGeometraThreeHostSnapshotFromViewSizing}, or composite split/stacked snapshots that
426
+ * include those keys. Only the {@link PlainGeometraThreeViewSizingState} slice is read for resize;
427
+ * extra fields (scene/camera hex, hybrid layout) are ignored here but often live on the same object
428
+ * you already validated with {@link isPlainGeometraThreeHostSnapshot}.
429
+ *
430
+ * @returns Same boolean as {@link tickGeometraThreeWebGLWithSceneBasicsFrame}.
431
+ */
432
+ export function resizeTickGeometraThreeWebGLWithSceneBasicsFromPlainHostSnapshot(bundle, snapshot, onFrame) {
433
+ return resizeTickGeometraThreeWebGLWithSceneBasicsFromPlainViewSizing(bundle, snapshot, onFrame);
434
+ }
435
+ //# sourceMappingURL=three-scene-basics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"three-scene-basics.js","sourceRoot":"","sources":["../src/three-scene-basics.ts"],"names":[],"mappings":"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"}
package/dist/utils.d.ts CHANGED
@@ -1,7 +1,171 @@
1
- import type { WebGLRenderer } from 'three';
1
+ import type { PerspectiveCamera, WebGLRenderer } from 'three';
2
+ /**
3
+ * Same integer flooring and minimum size as {@link createThreeGeometraSplitHost} and
4
+ * {@link createThreeGeometraStackedHost} use for CSS layout sizes and drawing-buffer dimensions.
5
+ *
6
+ * Use in custom or headless `WebGLRenderer` setups so width/height math stays aligned with those hosts.
7
+ *
8
+ * @returns A positive integer width or height in layout pixels (at least 1).
9
+ */
10
+ export declare function normalizeGeometraLayoutPixels(n: number): number;
11
+ /**
12
+ * Perspective `aspect` value for the same CSS layout → camera path as
13
+ * {@link resizeGeometraThreePerspectiveView} and the built-in split/stacked hosts
14
+ * (`setPixelRatio` + `setSize` with layout pixels, not raw drawing-buffer dimensions).
15
+ *
16
+ * Use in headless or custom renderers when you resize the drawing buffer yourself but want
17
+ * projection to stay aligned with {@link createThreeGeometraSplitHost} /
18
+ * {@link createThreeGeometraStackedHost}. For buffer-sized projection, use
19
+ * {@link syncGeometraThreePerspectiveFromBuffer} instead — flooring differs when width and height
20
+ * are scaled to physical pixels separately.
21
+ */
22
+ export declare function geometraHostPerspectiveAspectFromCss(cssWidth: number, cssHeight: number): number;
23
+ /**
24
+ * Device pixel ratio for split/stacked hosts and custom renderers: full raw ratio, optionally capped.
25
+ * Use with {@link resizeGeometraThreePerspectiveView} or {@link setWebGLDrawingBufferSize} so headless
26
+ * or offscreen setups match the same `maxDevicePixelRatio` behavior as {@link createThreeGeometraSplitHost}
27
+ * and {@link createThreeGeometraStackedHost}.
28
+ *
29
+ * @returns A finite positive ratio, capped when `maxDevicePixelRatio` is a finite positive number.
30
+ */
31
+ export declare function resolveHostDevicePixelRatio(rawDevicePixelRatio: number, maxDevicePixelRatio?: number): number;
32
+ /**
33
+ * Raw device pixel ratio used by headless / no-`window` helpers that mirror browser hosts where
34
+ * `win.devicePixelRatio || 1` would apply, but the baseline is fixed at **1** (see
35
+ * {@link resolveHeadlessHostDevicePixelRatio}, {@link toPlainGeometraThreeViewSizingStateHeadless},
36
+ * {@link createGeometraThreePerspectiveResizeHandlerHeadless}). Prefer this export over a bare `1`
37
+ * in agent payloads, tests, or custom hosts so the baseline stays grep-stable and documented.
38
+ */
39
+ export declare const GEOMETRA_HEADLESS_RAW_DEVICE_PIXEL_RATIO: 1;
40
+ /**
41
+ * Same optional {@link maxDevicePixelRatio} cap as {@link createThreeGeometraSplitHost} and
42
+ * {@link createThreeGeometraStackedHost}, but with raw ratio **1** for environments without a
43
+ * browser `window` (headless WebGL, Node, tests).
44
+ *
45
+ * Equivalent to
46
+ * `resolveHostDevicePixelRatio(GEOMETRA_HEADLESS_RAW_DEVICE_PIXEL_RATIO, maxDevicePixelRatio)`.
47
+ */
48
+ export declare function resolveHeadlessHostDevicePixelRatio(maxDevicePixelRatio?: number): number;
49
+ /**
50
+ * JSON-friendly viewport sizing aligned with {@link resizeGeometraThreePerspectiveView} and the
51
+ * split/stacked hosts (floored CSS layout pixels, then × effective DPR for buffer dimensions).
52
+ *
53
+ * Use beside {@link toPlainGeometraThreeSceneBasicsOptions} for logs, tests, or agent payloads that
54
+ * describe the same numbers the hosts use without constructing a renderer.
55
+ */
56
+ export interface PlainGeometraThreeViewSizingState {
57
+ /** Floored CSS layout width (at least 1), same as {@link normalizeGeometraLayoutPixels}. */
58
+ layoutWidth: number;
59
+ /** Floored CSS layout height (at least 1). */
60
+ layoutHeight: number;
61
+ /** `layoutWidth / layoutHeight` — same as {@link geometraHostPerspectiveAspectFromCss} for these inputs. */
62
+ perspectiveAspect: number;
63
+ /**
64
+ * Finite positive device pixel ratio before optional cap (invalid raw values become `1`, matching
65
+ * `win.devicePixelRatio || 1` behavior in the hosts).
66
+ */
67
+ sanitizedRawDevicePixelRatio: number;
68
+ /** Same as {@link resolveHostDevicePixelRatio}(raw, maxDevicePixelRatio). */
69
+ effectiveDevicePixelRatio: number;
70
+ /**
71
+ * Nominal drawing-buffer width: {@link normalizeGeometraLayoutPixels}(`layoutWidth` × `effectiveDevicePixelRatio`).
72
+ * Aligns with the buffer scale after {@link resizeGeometraThreePerspectiveView}, not the
73
+ * {@link setWebGLDrawingBufferSize} path (which floors CSS×DPR before separating axes).
74
+ */
75
+ drawingBufferWidth: number;
76
+ /** Nominal drawing-buffer height (same rules as {@link PlainGeometraThreeViewSizingState.drawingBufferWidth}). */
77
+ drawingBufferHeight: number;
78
+ }
79
+ /**
80
+ * Coerce CSS layout size and DPR into the same integers the built-in hosts use for perspective resize
81
+ * and nominal buffer dimensions (floored layout × effective DPR per axis).
82
+ */
83
+ export declare function toPlainGeometraThreeViewSizingState(cssWidth: number, cssHeight: number, rawDevicePixelRatio: number, maxDevicePixelRatio?: number): PlainGeometraThreeViewSizingState;
84
+ /**
85
+ * Same plain viewport sizing as {@link toPlainGeometraThreeViewSizingState} with raw device pixel ratio
86
+ * fixed at **1** — parity with {@link resolveHeadlessHostDevicePixelRatio},
87
+ * {@link toPlainGeometraThreeHostSnapshotHeadless}, and {@link resizeGeometraThreeWebGLWithSceneBasicsViewHeadless}
88
+ * for headless GL, Node, tests, or agent payloads without a browser `window`.
89
+ *
90
+ * Equivalent to
91
+ * `toPlainGeometraThreeViewSizingState(cssWidth, cssHeight, GEOMETRA_HEADLESS_RAW_DEVICE_PIXEL_RATIO, maxDevicePixelRatio)`.
92
+ */
93
+ export declare function toPlainGeometraThreeViewSizingStateHeadless(cssWidth: number, cssHeight: number, maxDevicePixelRatio?: number): PlainGeometraThreeViewSizingState;
94
+ /**
95
+ * Narrow `unknown` (e.g. `JSON.parse`) to {@link PlainGeometraThreeViewSizingState} when the object has the
96
+ * viewport fields produced by {@link toPlainGeometraThreeViewSizingState} and
97
+ * {@link toPlainGeometraThreeViewSizingStateHeadless}. Extra keys are allowed. Objects that also include scene
98
+ * fields may satisfy this guard; for the full viewport + scene shape use `isPlainGeometraThreeHostSnapshot`
99
+ * from this package’s entry (re-exported next to the host snapshot helpers).
100
+ */
101
+ export declare function isPlainGeometraThreeViewSizingState(value: unknown): value is PlainGeometraThreeViewSizingState;
2
102
  /**
3
103
  * Resize drawing buffer to match CSS pixel size × device pixel ratio.
4
104
  * Use when you manage your own canvas layout (no `renderer.setSize`).
105
+ * Non-finite CSS sizes or products fall back to 1; non-finite or non-positive `pixelRatio` becomes 1.
5
106
  */
6
107
  export declare function setWebGLDrawingBufferSize(renderer: WebGLRenderer, cssWidth: number, cssHeight: number, pixelRatio?: number): void;
108
+ /**
109
+ * Size the WebGL drawing buffer from CSS layout × pixel ratio and update the perspective camera aspect
110
+ * to match, in one step.
111
+ *
112
+ * Use this on the **drawing-buffer** path (with {@link setWebGLDrawingBufferSize}) instead of
113
+ * {@link resizeGeometraThreePerspectiveView} when you do not use `setPixelRatio` + `setSize` on the
114
+ * renderer — for example headless GL, offscreen canvas, or custom buffer management. Equivalent to calling
115
+ * {@link setWebGLDrawingBufferSize} then {@link syncGeometraThreePerspectiveFromBuffer} with the
116
+ * resulting buffer dimensions (read from {@link WebGLRenderer.domElement} after resize).
117
+ */
118
+ export declare function resizeGeometraThreeDrawingBufferView(renderer: WebGLRenderer, camera: PerspectiveCamera, cssWidth: number, cssHeight: number, pixelRatio?: number): void;
119
+ /**
120
+ * Same as {@link resizeGeometraThreeDrawingBufferView} with pixel ratio from
121
+ * {@link resolveHeadlessHostDevicePixelRatio} — raw ratio **1** and the same optional
122
+ * `maxDevicePixelRatio` cap as split/stacked hosts.
123
+ *
124
+ * Parity with {@link resizeGeometraThreeWebGLWithSceneBasicsViewHeadless} for the
125
+ * {@link setWebGLDrawingBufferSize} / drawing-buffer path (headless GL, offscreen canvas, Node tests).
126
+ *
127
+ * Equivalent to calling {@link resizeGeometraThreeDrawingBufferView} with
128
+ * `resolveHeadlessHostDevicePixelRatio(maxDevicePixelRatio)` as the pixel ratio argument.
129
+ */
130
+ export declare function resizeGeometraThreeDrawingBufferViewHeadless(renderer: WebGLRenderer, camera: PerspectiveCamera, cssWidth: number, cssHeight: number, maxDevicePixelRatio?: number): void;
131
+ /**
132
+ * Apply the same CSS-size → aspect ratio → WebGL buffer sizing path as
133
+ * {@link createThreeGeometraSplitHost} and {@link createThreeGeometraStackedHost}.
134
+ *
135
+ * Use with {@link createGeometraThreeSceneBasics} when you own the `WebGLRenderer` (headless GL,
136
+ * offscreen canvas, tests) but want buffer dimensions and projection to stay aligned with those hosts.
137
+ * Non-finite or non-positive CSS sizes (including negative values) normalize to at least 1 layout
138
+ * pixel each, matching {@link normalizeGeometraLayoutPixels}; non-finite or non-positive `pixelRatio`
139
+ * becomes 1.
140
+ */
141
+ export declare function resizeGeometraThreePerspectiveView(renderer: WebGLRenderer, camera: PerspectiveCamera, cssWidth: number, cssHeight: number, pixelRatio: number): void;
142
+ /**
143
+ * Build a resize callback that applies the same CSS layout → DPR → `setPixelRatio` / `setSize` path as
144
+ * {@link createThreeGeometraSplitHost} and {@link createThreeGeometraStackedHost}.
145
+ *
146
+ * Use in headless GL, offscreen canvas, tests, or custom hosts where you resize on a timer or explicit
147
+ * layout pass instead of the built-in `ResizeObserver`, but want {@link resolveHostDevicePixelRatio}
148
+ * capping and layout-pixel normalization without duplicating that wiring at every call site.
149
+ *
150
+ * @param getRawDevicePixelRatio - e.g. `() => win.devicePixelRatio || 1` or `() => 1` when no `window`.
151
+ */
152
+ export declare function createGeometraThreePerspectiveResizeHandler(renderer: WebGLRenderer, camera: PerspectiveCamera, getRawDevicePixelRatio: () => number, maxDevicePixelRatio?: number): (cssWidth: number, cssHeight: number) => void;
153
+ /**
154
+ * Same as {@link createGeometraThreePerspectiveResizeHandler} with raw device pixel ratio fixed at **1** —
155
+ * parity with {@link resolveHeadlessHostDevicePixelRatio}, {@link resizeGeometraThreeWebGLWithSceneBasicsViewHeadless},
156
+ * {@link toPlainGeometraThreeViewSizingStateHeadless}, and {@link toPlainGeometraThreeHostSnapshotHeadless} for headless GL, Node, tests, or agent loops without a browser
157
+ * `window`.
158
+ *
159
+ * Equivalent to `createGeometraThreePerspectiveResizeHandler(renderer, camera, () => 1, maxDevicePixelRatio)`.
160
+ */
161
+ export declare function createGeometraThreePerspectiveResizeHandlerHeadless(renderer: WebGLRenderer, camera: PerspectiveCamera, maxDevicePixelRatio?: number): (cssWidth: number, cssHeight: number) => void;
162
+ /**
163
+ * Update perspective projection from **drawing-buffer** pixel dimensions (physical pixels), not CSS size.
164
+ *
165
+ * Use when you size WebGL with {@link setWebGLDrawingBufferSize} or `renderer.setDrawingBufferSize` directly
166
+ * (headless GL, offscreen canvas, tests) and still want the same aspect handling as
167
+ * {@link resizeGeometraThreePerspectiveView}. Does not touch the renderer — only the camera.
168
+ * Non-finite buffer dimensions fall back to 1.
169
+ */
170
+ export declare function syncGeometraThreePerspectiveFromBuffer(camera: PerspectiveCamera, drawingBufferWidth: number, drawingBufferHeight: number): void;
7
171
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,IAAI,CAKN"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}