@scenography/engine 0.5.0 → 0.7.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/dist/index.cjs +262 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -3
- package/dist/index.d.mts +40 -3
- package/dist/index.mjs +261 -115
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let three = require("three");
|
|
3
|
+
//#region src/loading.ts
|
|
4
|
+
const pending = /* @__PURE__ */ new Set();
|
|
5
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
let state = {
|
|
7
|
+
loaded: 0,
|
|
8
|
+
total: 0,
|
|
9
|
+
done: true
|
|
10
|
+
};
|
|
11
|
+
const notify = () => {
|
|
12
|
+
for (const listener of listeners) listener(state);
|
|
13
|
+
};
|
|
14
|
+
/** Begin tracking a new initial asset set; resets the previous one. */
|
|
15
|
+
const startLoading = (urls) => {
|
|
16
|
+
pending.clear();
|
|
17
|
+
for (const url of urls) pending.add(url);
|
|
18
|
+
state = {
|
|
19
|
+
loaded: 0,
|
|
20
|
+
total: pending.size,
|
|
21
|
+
done: pending.size === 0
|
|
22
|
+
};
|
|
23
|
+
notify();
|
|
24
|
+
};
|
|
25
|
+
/** Mark one initial asset as loaded; unknown URLs (lazy assets) are ignored. */
|
|
26
|
+
const trackAsset = (url) => {
|
|
27
|
+
if (!pending.delete(url)) return;
|
|
28
|
+
state = {
|
|
29
|
+
loaded: state.total - pending.size,
|
|
30
|
+
total: state.total,
|
|
31
|
+
done: pending.size === 0
|
|
32
|
+
};
|
|
33
|
+
notify();
|
|
34
|
+
};
|
|
35
|
+
/** Current loading progress. */
|
|
36
|
+
const loadingState = () => state;
|
|
37
|
+
/** Subscribe to progress; the listener runs immediately with the current state. */
|
|
38
|
+
const onLoading = (listener) => {
|
|
39
|
+
listeners.add(listener);
|
|
40
|
+
listener(state);
|
|
41
|
+
return () => {
|
|
42
|
+
listeners.delete(listener);
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
3
46
|
//#region src/environment/EnvironmentController.ts
|
|
4
47
|
/** Load an equirectangular HDRI, picking the loader by extension. */
|
|
5
48
|
const loadHDRI = (src, onLoad) => {
|
|
@@ -31,6 +74,7 @@ var EnvironmentController = class {
|
|
|
31
74
|
this.clear();
|
|
32
75
|
if (!env) return;
|
|
33
76
|
loadHDRI(env.src, (tex) => {
|
|
77
|
+
trackAsset(env.src);
|
|
34
78
|
if (this.hash !== hash) {
|
|
35
79
|
tex.dispose();
|
|
36
80
|
return;
|
|
@@ -60,6 +104,189 @@ var EnvironmentController = class {
|
|
|
60
104
|
}
|
|
61
105
|
};
|
|
62
106
|
//#endregion
|
|
107
|
+
//#region src/builders/ktx2.ts
|
|
108
|
+
let loader = null;
|
|
109
|
+
/**
|
|
110
|
+
* Configure the shared KTX2 loader. Called by the kernel once the renderer
|
|
111
|
+
* exists; `.ktx2` textures and glTF models then decode through it.
|
|
112
|
+
*/
|
|
113
|
+
const configureKtx2 = (renderer, path) => {
|
|
114
|
+
loader = import("three/examples/jsm/loaders/KTX2Loader.js").then(({ KTX2Loader }) => {
|
|
115
|
+
const instance = new KTX2Loader();
|
|
116
|
+
instance.setTranscoderPath(path);
|
|
117
|
+
instance.detectSupport(renderer);
|
|
118
|
+
return instance;
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
/** The configured loader, or null when the gallery did not set `ktx2Path`. */
|
|
122
|
+
const getKtx2Loader = () => loader;
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/builders/textureCache.ts
|
|
125
|
+
/** Two surfaces can share a texture only at the same tiling and color space. */
|
|
126
|
+
const textureKey = (src, repeat, srgb) => `${src}|${repeat[0]}x${repeat[1]}|${srgb ? "srgb" : "linear"}`;
|
|
127
|
+
/** Tiling and color space of a texture; the image arrives later from the loader. */
|
|
128
|
+
const configureTexture = (texture, repeat, srgb) => {
|
|
129
|
+
texture.wrapS = three.RepeatWrapping;
|
|
130
|
+
texture.wrapT = three.RepeatWrapping;
|
|
131
|
+
texture.repeat.set(repeat[0], repeat[1]);
|
|
132
|
+
texture.colorSpace = srgb ? three.SRGBColorSpace : three.NoColorSpace;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Shares textures between materials: the same source at the same tiling and
|
|
136
|
+
* color space becomes one texture, loaded once and uploaded to the GPU once.
|
|
137
|
+
* Reference counted, so releasing a material keeps the texture alive while
|
|
138
|
+
* another one still samples it.
|
|
139
|
+
*/
|
|
140
|
+
var TextureCache = class {
|
|
141
|
+
source;
|
|
142
|
+
entries = /* @__PURE__ */ new Map();
|
|
143
|
+
owners = /* @__PURE__ */ new Map();
|
|
144
|
+
constructor(source) {
|
|
145
|
+
this.source = source;
|
|
146
|
+
}
|
|
147
|
+
/** The shared texture for a source, created on first use. */
|
|
148
|
+
acquire(src, repeat, srgb) {
|
|
149
|
+
const key = textureKey(src, repeat, srgb);
|
|
150
|
+
const existing = this.entries.get(key);
|
|
151
|
+
if (existing) {
|
|
152
|
+
existing.refs += 1;
|
|
153
|
+
return existing.texture;
|
|
154
|
+
}
|
|
155
|
+
const texture = this.source(src);
|
|
156
|
+
configureTexture(texture, repeat, srgb);
|
|
157
|
+
const entry = {
|
|
158
|
+
key,
|
|
159
|
+
texture,
|
|
160
|
+
refs: 1
|
|
161
|
+
};
|
|
162
|
+
this.entries.set(key, entry);
|
|
163
|
+
this.owners.set(texture, entry);
|
|
164
|
+
return texture;
|
|
165
|
+
}
|
|
166
|
+
/** Drop one reference; the texture is disposed when the last one goes. */
|
|
167
|
+
release(texture) {
|
|
168
|
+
const entry = this.owners.get(texture);
|
|
169
|
+
if (!entry) {
|
|
170
|
+
texture.dispose();
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
entry.refs -= 1;
|
|
174
|
+
if (entry.refs > 0) return;
|
|
175
|
+
this.entries.delete(entry.key);
|
|
176
|
+
this.owners.delete(texture);
|
|
177
|
+
texture.dispose();
|
|
178
|
+
}
|
|
179
|
+
/** Textures currently shared. */
|
|
180
|
+
get size() {
|
|
181
|
+
return this.entries.size;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/builders/texture.ts
|
|
186
|
+
const textureLoader = new three.TextureLoader();
|
|
187
|
+
const cache = new TextureCache((src) => textureLoader.load(src, () => trackAsset(src)));
|
|
188
|
+
const ktx2Entries = /* @__PURE__ */ new Map();
|
|
189
|
+
const ktx2Owners = /* @__PURE__ */ new Map();
|
|
190
|
+
/**
|
|
191
|
+
* KTX2 textures resolve asynchronously, so the material slot is filled through
|
|
192
|
+
* a waiter list. One entry per source and tiling is shared by every material
|
|
193
|
+
* that samples it, just like the image cache.
|
|
194
|
+
*/
|
|
195
|
+
const loadKtx2 = (material, slot, src, repeat, srgb) => {
|
|
196
|
+
const loader = getKtx2Loader();
|
|
197
|
+
if (!loader) {
|
|
198
|
+
console.warn(`KTX2 texture "${src}" needs the gallery's ktx2Path option.`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const key = textureKey(src, repeat, srgb);
|
|
202
|
+
let entry = ktx2Entries.get(key);
|
|
203
|
+
if (!entry) {
|
|
204
|
+
entry = {
|
|
205
|
+
key,
|
|
206
|
+
refs: 0,
|
|
207
|
+
waiters: []
|
|
208
|
+
};
|
|
209
|
+
ktx2Entries.set(key, entry);
|
|
210
|
+
const created = entry;
|
|
211
|
+
loader.then((ktx2) => ktx2.load(src, (texture) => {
|
|
212
|
+
configureTexture(texture, repeat, srgb);
|
|
213
|
+
texture.needsUpdate = true;
|
|
214
|
+
trackAsset(src);
|
|
215
|
+
created.texture = texture;
|
|
216
|
+
ktx2Owners.set(texture, created);
|
|
217
|
+
for (const assign of created.waiters) assign(texture);
|
|
218
|
+
created.waiters = [];
|
|
219
|
+
}, void 0, (error) => console.error(`Failed to load KTX2 texture "${src}".`, error)));
|
|
220
|
+
}
|
|
221
|
+
entry.refs += 1;
|
|
222
|
+
if (entry.texture) {
|
|
223
|
+
material[slot] = entry.texture;
|
|
224
|
+
material.needsUpdate = true;
|
|
225
|
+
} else entry.waiters.push((texture) => {
|
|
226
|
+
material[slot] = texture;
|
|
227
|
+
material.needsUpdate = true;
|
|
228
|
+
});
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Load one map into `material[slot]`. Textures are shared: every material that
|
|
232
|
+
* samples the same source at the same tiling reuses one texture object. `.exr`
|
|
233
|
+
* maps go through EXRLoader, imported on demand, and are not shared because
|
|
234
|
+
* they resolve asynchronously; `.ktx2` maps share through their own cache.
|
|
235
|
+
*/
|
|
236
|
+
const loadMap = (material, slot, src, repeat, srgb) => {
|
|
237
|
+
if (src.toLowerCase().endsWith(".ktx2")) {
|
|
238
|
+
loadKtx2(material, slot, src, repeat, srgb);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (src.toLowerCase().endsWith(".exr")) {
|
|
242
|
+
import("three/examples/jsm/loaders/EXRLoader.js").then(({ EXRLoader }) => {
|
|
243
|
+
new EXRLoader().load(src, (texture) => {
|
|
244
|
+
configureTexture(texture, repeat, srgb);
|
|
245
|
+
texture.needsUpdate = true;
|
|
246
|
+
trackAsset(src);
|
|
247
|
+
material[slot] = texture;
|
|
248
|
+
material.needsUpdate = true;
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
material[slot] = cache.acquire(src, repeat, srgb);
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* Apply a `SurfaceTexture` to a standard material. Returns whether a second UV
|
|
257
|
+
* set (`uv1`) is needed — three samples `aoMap` from it, so the geometry must
|
|
258
|
+
* provide one.
|
|
259
|
+
*/
|
|
260
|
+
const applyTexture = (material, texture) => {
|
|
261
|
+
const repeat = texture.repeat ?? [1, 1];
|
|
262
|
+
loadMap(material, "map", texture.src, repeat, true);
|
|
263
|
+
if (texture.normal) {
|
|
264
|
+
loadMap(material, "normalMap", texture.normal, repeat, false);
|
|
265
|
+
const scale = texture.normalScale ?? 1;
|
|
266
|
+
material.normalScale = new three.Vector2(scale, scale);
|
|
267
|
+
}
|
|
268
|
+
if (texture.roughness) loadMap(material, "roughnessMap", texture.roughness, repeat, false);
|
|
269
|
+
if (texture.ao) loadMap(material, "aoMap", texture.ao, repeat, false);
|
|
270
|
+
material.needsUpdate = true;
|
|
271
|
+
return texture.ao !== void 0;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Release one reference to a texture assigned by `applyTexture`. Shared
|
|
275
|
+
* textures stay alive while another material still samples them.
|
|
276
|
+
*/
|
|
277
|
+
const releaseTexture = (texture) => {
|
|
278
|
+
const ktx2 = ktx2Owners.get(texture);
|
|
279
|
+
if (!ktx2) {
|
|
280
|
+
cache.release(texture);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
ktx2.refs -= 1;
|
|
284
|
+
if (ktx2.refs > 0) return;
|
|
285
|
+
ktx2Owners.delete(texture);
|
|
286
|
+
ktx2Entries.delete(ktx2.key);
|
|
287
|
+
texture.dispose();
|
|
288
|
+
};
|
|
289
|
+
//#endregion
|
|
63
290
|
//#region src/interaction/InteractionController.ts
|
|
64
291
|
const HIGHLIGHT_COLOR = "#ef4444";
|
|
65
292
|
const HIGHLIGHT_THICKNESS = 1.5;
|
|
@@ -503,116 +730,6 @@ const EDGES = "edges";
|
|
|
503
730
|
*/
|
|
504
731
|
const EYE_HEIGHT = "eyeHeight";
|
|
505
732
|
//#endregion
|
|
506
|
-
//#region src/builders/textureCache.ts
|
|
507
|
-
/** Two surfaces can share a texture only at the same tiling and color space. */
|
|
508
|
-
const textureKey = (src, repeat, srgb) => `${src}|${repeat[0]}x${repeat[1]}|${srgb ? "srgb" : "linear"}`;
|
|
509
|
-
/** Tiling and color space of a texture; the image arrives later from the loader. */
|
|
510
|
-
const configureTexture = (texture, repeat, srgb) => {
|
|
511
|
-
texture.wrapS = three.RepeatWrapping;
|
|
512
|
-
texture.wrapT = three.RepeatWrapping;
|
|
513
|
-
texture.repeat.set(repeat[0], repeat[1]);
|
|
514
|
-
texture.colorSpace = srgb ? three.SRGBColorSpace : three.NoColorSpace;
|
|
515
|
-
};
|
|
516
|
-
/**
|
|
517
|
-
* Shares textures between materials: the same source at the same tiling and
|
|
518
|
-
* color space becomes one texture, loaded once and uploaded to the GPU once.
|
|
519
|
-
* Reference counted, so releasing a material keeps the texture alive while
|
|
520
|
-
* another one still samples it.
|
|
521
|
-
*/
|
|
522
|
-
var TextureCache = class {
|
|
523
|
-
source;
|
|
524
|
-
entries = /* @__PURE__ */ new Map();
|
|
525
|
-
owners = /* @__PURE__ */ new Map();
|
|
526
|
-
constructor(source) {
|
|
527
|
-
this.source = source;
|
|
528
|
-
}
|
|
529
|
-
/** The shared texture for a source, created on first use. */
|
|
530
|
-
acquire(src, repeat, srgb) {
|
|
531
|
-
const key = textureKey(src, repeat, srgb);
|
|
532
|
-
const existing = this.entries.get(key);
|
|
533
|
-
if (existing) {
|
|
534
|
-
existing.refs += 1;
|
|
535
|
-
return existing.texture;
|
|
536
|
-
}
|
|
537
|
-
const texture = this.source(src);
|
|
538
|
-
configureTexture(texture, repeat, srgb);
|
|
539
|
-
const entry = {
|
|
540
|
-
key,
|
|
541
|
-
texture,
|
|
542
|
-
refs: 1
|
|
543
|
-
};
|
|
544
|
-
this.entries.set(key, entry);
|
|
545
|
-
this.owners.set(texture, entry);
|
|
546
|
-
return texture;
|
|
547
|
-
}
|
|
548
|
-
/** Drop one reference; the texture is disposed when the last one goes. */
|
|
549
|
-
release(texture) {
|
|
550
|
-
const entry = this.owners.get(texture);
|
|
551
|
-
if (!entry) {
|
|
552
|
-
texture.dispose();
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
entry.refs -= 1;
|
|
556
|
-
if (entry.refs > 0) return;
|
|
557
|
-
this.entries.delete(entry.key);
|
|
558
|
-
this.owners.delete(texture);
|
|
559
|
-
texture.dispose();
|
|
560
|
-
}
|
|
561
|
-
/** Textures currently shared. */
|
|
562
|
-
get size() {
|
|
563
|
-
return this.entries.size;
|
|
564
|
-
}
|
|
565
|
-
};
|
|
566
|
-
//#endregion
|
|
567
|
-
//#region src/builders/texture.ts
|
|
568
|
-
const textureLoader = new three.TextureLoader();
|
|
569
|
-
const cache = new TextureCache((src) => textureLoader.load(src));
|
|
570
|
-
/**
|
|
571
|
-
* Load one map into `material[slot]`. Textures are shared: every material that
|
|
572
|
-
* samples the same source at the same tiling reuses one texture object. `.exr`
|
|
573
|
-
* maps go through EXRLoader, imported on demand, and are not shared because
|
|
574
|
-
* they resolve asynchronously.
|
|
575
|
-
*/
|
|
576
|
-
const loadMap = (material, slot, src, repeat, srgb) => {
|
|
577
|
-
if (src.toLowerCase().endsWith(".exr")) {
|
|
578
|
-
import("three/examples/jsm/loaders/EXRLoader.js").then(({ EXRLoader }) => {
|
|
579
|
-
new EXRLoader().load(src, (texture) => {
|
|
580
|
-
configureTexture(texture, repeat, srgb);
|
|
581
|
-
texture.needsUpdate = true;
|
|
582
|
-
material[slot] = texture;
|
|
583
|
-
material.needsUpdate = true;
|
|
584
|
-
});
|
|
585
|
-
});
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
material[slot] = cache.acquire(src, repeat, srgb);
|
|
589
|
-
};
|
|
590
|
-
/**
|
|
591
|
-
* Apply a `SurfaceTexture` to a standard material. Returns whether a second UV
|
|
592
|
-
* set (`uv1`) is needed — three samples `aoMap` from it, so the geometry must
|
|
593
|
-
* provide one.
|
|
594
|
-
*/
|
|
595
|
-
const applyTexture = (material, texture) => {
|
|
596
|
-
const repeat = texture.repeat ?? [1, 1];
|
|
597
|
-
loadMap(material, "map", texture.src, repeat, true);
|
|
598
|
-
if (texture.normal) {
|
|
599
|
-
loadMap(material, "normalMap", texture.normal, repeat, false);
|
|
600
|
-
const scale = texture.normalScale ?? 1;
|
|
601
|
-
material.normalScale = new three.Vector2(scale, scale);
|
|
602
|
-
}
|
|
603
|
-
if (texture.roughness) loadMap(material, "roughnessMap", texture.roughness, repeat, false);
|
|
604
|
-
if (texture.ao) loadMap(material, "aoMap", texture.ao, repeat, false);
|
|
605
|
-
material.needsUpdate = true;
|
|
606
|
-
return texture.ao !== void 0;
|
|
607
|
-
};
|
|
608
|
-
/**
|
|
609
|
-
* Release one reference to a texture assigned by `applyTexture`. Shared
|
|
610
|
-
* textures stay alive while another material still samples them.
|
|
611
|
-
*/
|
|
612
|
-
const releaseTexture = (texture) => {
|
|
613
|
-
cache.release(texture);
|
|
614
|
-
};
|
|
615
|
-
//#endregion
|
|
616
733
|
//#region src/SceneManager.ts
|
|
617
734
|
const TEXTURE_SLOTS = [
|
|
618
735
|
"map",
|
|
@@ -656,12 +773,24 @@ var SceneManager = class {
|
|
|
656
773
|
root;
|
|
657
774
|
plugins;
|
|
658
775
|
capabilities;
|
|
776
|
+
view;
|
|
659
777
|
/** Mounted plugin elements, per kind, keyed by element id ("" for singletons). */
|
|
660
778
|
pluginElements = /* @__PURE__ */ new Map();
|
|
661
|
-
constructor(root, plugins = [], capabilities = new CapabilityRegistry()
|
|
779
|
+
constructor(root, plugins = [], capabilities = new CapabilityRegistry(), view = {
|
|
780
|
+
camera: new three.PerspectiveCamera(),
|
|
781
|
+
renderer: {}
|
|
782
|
+
}) {
|
|
662
783
|
this.root = root;
|
|
663
784
|
this.plugins = plugins;
|
|
664
785
|
this.capabilities = capabilities;
|
|
786
|
+
this.view = view;
|
|
787
|
+
}
|
|
788
|
+
/** The build context handed to every plugin. */
|
|
789
|
+
context() {
|
|
790
|
+
return {
|
|
791
|
+
capabilities: this.capabilities,
|
|
792
|
+
...this.view
|
|
793
|
+
};
|
|
665
794
|
}
|
|
666
795
|
reconcile(scene) {
|
|
667
796
|
const eye = scene.camera.start.position[1];
|
|
@@ -694,7 +823,7 @@ var SceneManager = class {
|
|
|
694
823
|
const existing = mounted.get(key);
|
|
695
824
|
if (existing?.hash === hash) continue;
|
|
696
825
|
if (existing) this.removePluginElement(mounted, key, existing);
|
|
697
|
-
const built = plugin.build(value,
|
|
826
|
+
const built = plugin.build(value, this.context());
|
|
698
827
|
if (built.object) this.root.add(built.object);
|
|
699
828
|
mounted.set(key, {
|
|
700
829
|
...built,
|
|
@@ -702,7 +831,7 @@ var SceneManager = class {
|
|
|
702
831
|
});
|
|
703
832
|
}
|
|
704
833
|
for (const [key, entry] of mounted) if (!seen.has(key)) this.removePluginElement(mounted, key, entry);
|
|
705
|
-
plugin.provide?.(items.map(([, value]) => value),
|
|
834
|
+
plugin.provide?.(items.map(([, value]) => value), this.context());
|
|
706
835
|
}
|
|
707
836
|
}
|
|
708
837
|
removePluginElement(mounted, key, entry) {
|
|
@@ -793,7 +922,20 @@ function createGallery(scene, options) {
|
|
|
793
922
|
const systemPlugins = allPlugins.filter(isSystemPlugin);
|
|
794
923
|
const elementPlugins = allPlugins.filter((p) => !isSystemPlugin(p));
|
|
795
924
|
const capabilities = new CapabilityRegistry();
|
|
796
|
-
|
|
925
|
+
if (options.ktx2Path) configureKtx2(renderer, options.ktx2Path);
|
|
926
|
+
const assets = /* @__PURE__ */ new Set();
|
|
927
|
+
for (const plugin of elementPlugins) {
|
|
928
|
+
const { kind, cardinality } = plugin.data;
|
|
929
|
+
const raw = scene[kind];
|
|
930
|
+
const values = cardinality === "many" ? Array.isArray(raw) ? raw : [] : raw !== void 0 ? [raw] : [];
|
|
931
|
+
for (const value of values) for (const url of plugin.data.assets?.(value) ?? []) assets.add(url);
|
|
932
|
+
}
|
|
933
|
+
if (scene.environment?.src) assets.add(scene.environment.src);
|
|
934
|
+
startLoading(assets);
|
|
935
|
+
const manager = new SceneManager(threeScene, elementPlugins, capabilities, {
|
|
936
|
+
camera,
|
|
937
|
+
renderer
|
|
938
|
+
});
|
|
797
939
|
manager.reconcile(scene);
|
|
798
940
|
const input = new InputBus();
|
|
799
941
|
const controlSettings = new ControlSettings(loadControlFlags() ?? (options.cardboard ? MODE_PRESETS.cardboard : {}));
|
|
@@ -1012,6 +1154,10 @@ function createGallery(scene, options) {
|
|
|
1012
1154
|
renderer
|
|
1013
1155
|
}
|
|
1014
1156
|
},
|
|
1157
|
+
loading: {
|
|
1158
|
+
get: loadingState,
|
|
1159
|
+
subscribe: onLoading
|
|
1160
|
+
},
|
|
1015
1161
|
setScene(next) {
|
|
1016
1162
|
manager.reconcile(next);
|
|
1017
1163
|
interaction.setRadii(radiiOf(next));
|
|
@@ -1108,7 +1254,9 @@ exports.TERRAIN = TERRAIN;
|
|
|
1108
1254
|
exports.applyMode = applyMode;
|
|
1109
1255
|
exports.applyTexture = applyTexture;
|
|
1110
1256
|
exports.createGallery = createGallery;
|
|
1257
|
+
exports.getKtx2Loader = getKtx2Loader;
|
|
1111
1258
|
exports.isSystemPlugin = isSystemPlugin;
|
|
1112
1259
|
exports.modeOf = modeOf;
|
|
1260
|
+
exports.trackAsset = trackAsset;
|
|
1113
1261
|
|
|
1114
1262
|
//# sourceMappingURL=index.cjs.map
|