entangled-worlds-orbiters-shared 2.2.0 → 2.3.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/package.json
CHANGED
|
@@ -142,11 +142,11 @@ function resolveUrls(faceKeys) {
|
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
144
|
* Main loader function - always uses explicit face URLs.
|
|
145
|
-
* `renderer` binds the KTX2 transcoder to the right WebGL context
|
|
146
|
-
*
|
|
145
|
+
* `renderer` binds the KTX2 transcoder to the right WebGL context. REQUIRED (3.0) when the KTX2
|
|
146
|
+
* path is taken — the old `window.__EW_RENDERER` fallback is gone; thread the owning view's
|
|
147
|
+
* renderer. (The PNG/JPG path is renderer-agnostic, so its absence only bites on KTX2.)
|
|
147
148
|
*/
|
|
148
|
-
export async function loadCubeMap({ faceKeys, skycubeName, preferKTX2 = true, forceLow, renderer
|
|
149
|
-
const renderer = rendererOpt ?? (typeof window !== 'undefined' ? window.__EW_RENDERER : null);
|
|
149
|
+
export async function loadCubeMap({ faceKeys, skycubeName, preferKTX2 = true, forceLow, renderer } = {}) {
|
|
150
150
|
|
|
151
151
|
// If no face URLs provided, build them from skycube name
|
|
152
152
|
if (!faceKeys && skycubeName) {
|
package/src/loaders/glbLoader.js
CHANGED
|
@@ -5,13 +5,12 @@ import { getKTX2LoaderForRenderer } from './ktx2.js';
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {object} [opts]
|
|
8
|
-
* @param {import('three').WebGLRenderer}
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* @param {import('three').WebGLRenderer} opts.renderer REQUIRED (3.0): the renderer this GLB's
|
|
9
|
+
* textures bind to. A page with several renderers has no single correct global, so the old
|
|
10
|
+
* `window.__EW_RENDERER` fallback is gone — thread the owning view's renderer.
|
|
11
11
|
*/
|
|
12
|
-
export async function loadGLB(url, { retries = 3, signal, onProgress, applyFlags, withCredentials = false, renderer
|
|
13
|
-
|
|
14
|
-
if (!renderer) throw new Error('Renderer not ready for KTX2');
|
|
12
|
+
export async function loadGLB(url, { retries = 3, signal, onProgress, applyFlags, withCredentials = false, renderer } = {}) {
|
|
13
|
+
if (!renderer) throw new Error('[glb] loadGLB requires the owning renderer (KTX2 textures bind per WebGL context).');
|
|
15
14
|
|
|
16
15
|
let attempt = 0;
|
|
17
16
|
while (attempt < retries) {
|
package/src/loaders/ktx2.js
CHANGED
|
@@ -13,27 +13,22 @@ import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
|
|
|
13
13
|
* (Was: a single `window.__EW_KTX2_LOADER` global shared by bodyTexture/glb/cubeMap loaders.)
|
|
14
14
|
*/
|
|
15
15
|
const loadersByRenderer = new WeakMap();
|
|
16
|
-
let fallbackLoader = null;
|
|
17
16
|
|
|
18
17
|
function makeLoader(renderer) {
|
|
19
18
|
return new KTX2Loader().setTranscoderPath('/basis/').detectSupport(renderer);
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
|
-
* The KTX2Loader bound to `renderer
|
|
24
|
-
* sites
|
|
25
|
-
*
|
|
22
|
+
* The KTX2Loader bound to `renderer` — REQUIRED (3.0). The old `window.__EW_RENDERER` fallback let
|
|
23
|
+
* call sites compile while silently binding the transcoder to whichever renderer a page published
|
|
24
|
+
* last; on any multi-view page that meant untextured worlds. Every caller now threads its own
|
|
25
|
+
* renderer, so a missing one is a caller bug and fails loudly here rather than as a dark planet.
|
|
26
|
+
* @param {import('three').WebGLRenderer} renderer
|
|
26
27
|
* @returns {KTX2Loader}
|
|
27
28
|
*/
|
|
28
|
-
export function getKTX2LoaderForRenderer(
|
|
29
|
-
// `??` not a default param: callers thread an OPTIONAL renderer down several layers, so `null`
|
|
30
|
-
// arrives as often as `undefined` and must fall back the same way.
|
|
31
|
-
const renderer = rendererArg ?? (typeof window !== 'undefined' ? window.__EW_RENDERER : null);
|
|
29
|
+
export function getKTX2LoaderForRenderer(renderer) {
|
|
32
30
|
if (!renderer) {
|
|
33
|
-
|
|
34
|
-
// returning one keeps the caller's error local to the texture instead of throwing mid-scene.
|
|
35
|
-
if (!fallbackLoader) fallbackLoader = new KTX2Loader().setTranscoderPath('/basis/');
|
|
36
|
-
return fallbackLoader;
|
|
31
|
+
throw new Error('[ktx2] getKTX2LoaderForRenderer requires the owning renderer — thread it from the view that renders this texture.');
|
|
37
32
|
}
|
|
38
33
|
let loader = loadersByRenderer.get(renderer);
|
|
39
34
|
if (!loader) {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* solo-renders that voice. The host must not move the canvas itself.
|
|
25
25
|
* - It owns the realm clear: every frame it re-asserts a fully transparent clear colour.
|
|
26
26
|
*
|
|
27
|
-
* @see `
|
|
27
|
+
* @see `devHandleKey` — the one window global it can write, opt-in.
|
|
28
28
|
*/
|
|
29
29
|
import * as THREE from 'three';
|
|
30
30
|
|
|
@@ -46,11 +46,6 @@ const DEFAULT_RENDERER_PROFILE = {
|
|
|
46
46
|
* builds no grid of its own; when absent, the default `⌈√n⌉` grid is used.
|
|
47
47
|
* @param {Partial<typeof DEFAULT_RENDERER_PROFILE>} [opts.rendererProfile] renderer construction +
|
|
48
48
|
* pixel-ratio cap. Omit for the historical defaults.
|
|
49
|
-
* @param {boolean} [opts.publishRendererGlobal=false] write `window.__EW_RENDERER = renderer`.
|
|
50
|
-
* OPT-IN, and at most ONE compositor per page may set it: it is the fallback the shared loaders read
|
|
51
|
-
* when no renderer is threaded to them, so two realms both publishing would make one realm's loads
|
|
52
|
-
* bind their KTX2 transcoder to the OTHER realm's context (untextured worlds). Consumers that thread
|
|
53
|
-
* the renderer explicitly must leave this off.
|
|
54
49
|
* @param {string|null} [opts.devHandleKey=null] when set, publish the returned api on
|
|
55
50
|
* `window[devHandleKey]` so tooling can force a composited frame while rAF is throttled (a hidden
|
|
56
51
|
* tab during automated checks). Off by default — a library does not name globals for its host.
|
|
@@ -67,7 +62,6 @@ const DEFAULT_RENDERER_PROFILE = {
|
|
|
67
62
|
export function createViewportCompositor({
|
|
68
63
|
cellSource = null,
|
|
69
64
|
rendererProfile = null,
|
|
70
|
-
publishRendererGlobal = false,
|
|
71
65
|
devHandleKey = null,
|
|
72
66
|
} = {}) {
|
|
73
67
|
const profile = { ...DEFAULT_RENDERER_PROFILE, ...(rendererProfile || {}) };
|
|
@@ -83,12 +77,6 @@ export function createViewportCompositor({
|
|
|
83
77
|
document.body.appendChild(canvas);
|
|
84
78
|
|
|
85
79
|
const renderer = createRenderer(canvas, profile);
|
|
86
|
-
// The loaders fall back to `window.__EW_RENDERER` when nothing threads a renderer to them. Publishing
|
|
87
|
-
// it lets a realm whose voices still rely on that fallback upload every texture to THIS context.
|
|
88
|
-
// Opt-in, single-writer: see `publishRendererGlobal`.
|
|
89
|
-
if (publishRendererGlobal && typeof window !== 'undefined') {
|
|
90
|
-
window.__EW_RENDERER = renderer;
|
|
91
|
-
}
|
|
92
80
|
|
|
93
81
|
/** voiceId → { cell, controller, lastW, lastH, rect } */
|
|
94
82
|
const voices = new Map();
|
|
@@ -330,11 +318,8 @@ export function createViewportCompositor({
|
|
|
330
318
|
// If disposed while a voice was fullscreen, put the canvas style back before `canvas.remove()`.
|
|
331
319
|
restoreCanvasHome();
|
|
332
320
|
voices.clear();
|
|
333
|
-
if (typeof window !== 'undefined') {
|
|
334
|
-
|
|
335
|
-
if (devHandleKey && window[devHandleKey]?.renderer === renderer) {
|
|
336
|
-
delete window[devHandleKey];
|
|
337
|
-
}
|
|
321
|
+
if (typeof window !== 'undefined' && devHandleKey && window[devHandleKey]?.renderer === renderer) {
|
|
322
|
+
delete window[devHandleKey];
|
|
338
323
|
}
|
|
339
324
|
renderer.dispose();
|
|
340
325
|
grid?.remove();
|
|
@@ -7,8 +7,8 @@ export class WorldManager {
|
|
|
7
7
|
constructor(scene, { onLoadStart, onLoadEnd, renderer, externalTick = false } = {}) {
|
|
8
8
|
this.scene = scene;
|
|
9
9
|
// The renderer this world belongs to — threaded to the texture loaders so each view's textures
|
|
10
|
-
// bind to its OWN WebGL context (multi-view: N orbiters / N planets in one page).
|
|
11
|
-
//
|
|
10
|
+
// bind to its OWN WebGL context (multi-view: N orbiters / N planets in one page). REQUIRED for
|
|
11
|
+
// textured worlds (3.0): the window.__EW_RENDERER fallback is gone.
|
|
12
12
|
this.renderer = renderer ?? null;
|
|
13
13
|
// Shared-renderer hosts drive world animation from THEIR loop: with `externalTick` this manager
|
|
14
14
|
// starts no internal rAF for `userData.update` worlds — the host calls `tick(timeSec)` per
|
|
@@ -29,7 +29,7 @@ export class WorldManager {
|
|
|
29
29
|
if (!this.externalTick || !this.current) return;
|
|
30
30
|
const updater = this.current.userData?.update;
|
|
31
31
|
if (typeof updater !== 'function') return;
|
|
32
|
-
const renderer = this.renderer
|
|
32
|
+
const renderer = this.renderer;
|
|
33
33
|
if (!renderer) return;
|
|
34
34
|
try {
|
|
35
35
|
updater(renderer, timeSec);
|
|
@@ -60,7 +60,7 @@ export class WorldManager {
|
|
|
60
60
|
this.onLoadStart?.();
|
|
61
61
|
try {
|
|
62
62
|
let obj;
|
|
63
|
-
const renderer = this.renderer
|
|
63
|
+
const renderer = this.renderer;
|
|
64
64
|
|
|
65
65
|
// Check for custom creators first
|
|
66
66
|
if (this.customCreators.has(mode)) {
|
package/src/world/worldNormal.js
CHANGED
|
@@ -27,6 +27,7 @@ export async function makeNormalSphere({
|
|
|
27
27
|
cloudsColor = 0xffffff,
|
|
28
28
|
cloudsOpacity = 0.6,
|
|
29
29
|
cloudsSpeed = 0.015,
|
|
30
|
+
renderer = null,
|
|
30
31
|
} = {}) {
|
|
31
32
|
const radius = typeof sphereRadius === 'number' ? Math.max(0.0001, sphereRadius) : EARTH_RADIUS_UNITS;
|
|
32
33
|
const widthSegs = Number.isFinite(sphereWidthSegments) ? Math.max(3, Math.floor(sphereWidthSegments)) : 64;
|
|
@@ -63,6 +64,7 @@ export async function makeNormalSphere({
|
|
|
63
64
|
color: cloudsColor,
|
|
64
65
|
opacity: cloudsOpacity,
|
|
65
66
|
speed: cloudsSpeed,
|
|
67
|
+
renderer,
|
|
66
68
|
});
|
|
67
69
|
mesh.add(cloudMesh);
|
|
68
70
|
}
|