minerender 2.1.0-alpha.70 → 2.1.0-alpha.74

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.
@@ -800,7 +800,7 @@ var init_TextureLoader = __esm({
800
800
  static createTexture() {
801
801
  return new Texture();
802
802
  }
803
- static loadInBackground(src, format = RGBAFormat, rotation = 0) {
803
+ static loadInBackground(src, format2 = RGBAFormat, rotation = 0) {
804
804
  const texture = this.createTexture();
805
805
  texture.colorSpace = THREE.SRGBColorSpace;
806
806
  const image = ImageLoader.loadElement(src, () => {
@@ -810,11 +810,11 @@ var init_TextureLoader = __esm({
810
810
  console.warn("Failed to load texture", src, error);
811
811
  });
812
812
  texture.image = image;
813
- texture.format = format;
813
+ texture.format = format2;
814
814
  texture.rotation = rotation;
815
815
  return Textures.initTextureProps(texture);
816
816
  }
817
- static load(src, format = RGBAFormat, rotation = 0) {
817
+ static load(src, format2 = RGBAFormat, rotation = 0) {
818
818
  const texture = new Texture();
819
819
  texture.colorSpace = THREE.SRGBColorSpace;
820
820
  ImageLoader.getData(src).then((image) => {
@@ -824,7 +824,7 @@ var init_TextureLoader = __esm({
824
824
  this.failedTextures.add(texture);
825
825
  console.warn("Failed to load texture", src, error);
826
826
  });
827
- texture.format = format;
827
+ texture.format = format2;
828
828
  texture.rotation = rotation;
829
829
  return Textures.initTextureProps(texture);
830
830
  }
@@ -1031,7 +1031,7 @@ var init_Materials = __esm({
1031
1031
  };
1032
1032
  return material;
1033
1033
  }
1034
- static createShadedCanvasMaterial(canvas, transparent = false, shade = false) {
1034
+ static createShadedCanvasMaterial(canvas, transparent = false, shade = false, boundUvs = false) {
1035
1035
  const vertShader = `
1036
1036
  uniform bool SHADE;
1037
1037
 
@@ -1041,6 +1041,10 @@ var init_Materials = __esm({
1041
1041
  #else
1042
1042
  varying vec2 vUv;
1043
1043
  #endif
1044
+ #ifdef BOUND_UVS
1045
+ attribute vec4 uvBounds;
1046
+ flat out vec4 vUvBounds;
1047
+ #endif
1044
1048
  varying vec3 vTint;
1045
1049
  varying float light;
1046
1050
  varying float lift;
@@ -1076,13 +1080,17 @@ var init_Materials = __esm({
1076
1080
  }
1077
1081
 
1078
1082
  vUv = uv;
1083
+ #ifdef BOUND_UVS
1084
+ vUvBounds = uvBounds;
1085
+ #endif
1079
1086
  vTint = color;
1080
1087
 
1088
+ vec4 mvPosition = vec4(position, 1.0);
1081
1089
  #ifdef USE_INSTANCING
1082
- gl_Position = projectionMatrix * viewMatrix * modelMatrix * instanceMatrix * vec4(position, 1.0);
1083
- #else
1084
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
1090
+ mvPosition = instanceMatrix * mvPosition;
1085
1091
  #endif
1092
+ mvPosition = modelViewMatrix * mvPosition;
1093
+ gl_Position = projectionMatrix * mvPosition;
1086
1094
 
1087
1095
  }
1088
1096
  `;
@@ -1102,13 +1110,22 @@ var init_Materials = __esm({
1102
1110
  #else
1103
1111
  varying vec2 vUv;
1104
1112
  #endif
1113
+ #ifdef BOUND_UVS
1114
+ flat in vec4 vUvBounds;
1115
+ #endif
1105
1116
  varying vec3 vTint;
1106
1117
  varying float light;
1107
1118
  varying float lift;
1108
1119
 
1109
1120
  void main(void)
1110
1121
  {
1111
- vec4 color = texture2D(map, vUv);
1122
+ #ifdef BOUND_UVS
1123
+ // Keep edge samples inside their texture even without centroid interpolation.
1124
+ vec2 mapUv = clamp(vUv, vUvBounds.xy, vUvBounds.zw);
1125
+ #else
1126
+ vec2 mapUv = vUv;
1127
+ #endif
1128
+ vec4 color = texture2D(map, mapUv);
1112
1129
  color.rgb *= vTint;
1113
1130
 
1114
1131
  if (color.a < 0.01) discard;
@@ -1129,7 +1146,8 @@ var init_Materials = __esm({
1129
1146
  }
1130
1147
  `;
1131
1148
  try {
1132
- return new ShaderMaterial({
1149
+ const material = new ShaderMaterial({
1150
+ defines: boundUvs ? { BOUND_UVS: true } : {},
1133
1151
  uniforms: {
1134
1152
  SHADE: { value: true },
1135
1153
  BRIGHTNESS: { value: 1 },
@@ -1147,6 +1165,8 @@ var init_Materials = __esm({
1147
1165
  side: transparent ? DoubleSide : FrontSide,
1148
1166
  alphaTest: 0.5
1149
1167
  });
1168
+ Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
1169
+ return material;
1150
1170
  } catch (e) {
1151
1171
  console.warn(e);
1152
1172
  }
@@ -1753,6 +1773,10 @@ var init_AssetSource = __esm({
1753
1773
  AssetSource = class {
1754
1774
  constructor() {
1755
1775
  }
1776
+ /** Whether this source prevents lower-priority sources from supplying the key. Its own assets remain available. */
1777
+ blocks(key) {
1778
+ return false;
1779
+ }
1756
1780
  /**
1757
1781
  * Identifies this source's content across sessions for persistent caching. Sources that
1758
1782
  * cannot tell whether their content changed (an unnamed archive, for example) return
@@ -1932,10 +1956,10 @@ var NBTHelper;
1932
1956
  var init_NBTHelper = __esm({
1933
1957
  "src/nbt/NBTHelper.ts"() {
1934
1958
  NBTHelper = class {
1935
- static async fromBuffer(data, format) {
1959
+ static async fromBuffer(data, format2) {
1936
1960
  const buffer = Buffer3.from(data instanceof Uint8Array ? data : new Uint8Array(data));
1937
1961
  const prismarineNbt = await import("prismarine-nbt");
1938
- const { parsed, type, metadata } = await prismarineNbt.parse(buffer, format);
1962
+ const { parsed, type, metadata } = await prismarineNbt.parse(buffer, format2);
1939
1963
  return Object.assign(parsed, {
1940
1964
  format: type,
1941
1965
  metadata,
@@ -2184,6 +2208,164 @@ var init_BrowserArchiveProxy = __esm({
2184
2208
  }
2185
2209
  });
2186
2210
 
2211
+ // src/assets/source/archive/PackMetadata.ts
2212
+ function object(value, field) {
2213
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
2214
+ throw new Error(`Invalid ${field}: expected an object`);
2215
+ }
2216
+ return value;
2217
+ }
2218
+ function integer(value, field) {
2219
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
2220
+ throw new Error(`Invalid ${field}: expected a nonnegative integer`);
2221
+ }
2222
+ return value;
2223
+ }
2224
+ function format(value, field, upper = false) {
2225
+ const parts = Array.isArray(value) ? value : [value];
2226
+ if (parts.length < 1 || parts.length > 2) {
2227
+ throw new Error(`Invalid ${field}: expected a major version or [major, minor]`);
2228
+ }
2229
+ return [integer(parts[0], field), parts.length === 2 ? integer(parts[1], field) : upper ? Infinity : 0];
2230
+ }
2231
+ function compare(a, b) {
2232
+ return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0];
2233
+ }
2234
+ function overlay(value, field) {
2235
+ const entry = object(value, field);
2236
+ const directory = entry.directory;
2237
+ if (typeof directory !== "string" || !directory || /[^-_a-zA-Z0-9.]/.test(directory) || directory === "." || directory === "..") {
2238
+ throw new Error(`Invalid ${field}.directory: expected a directory name without path separators`);
2239
+ }
2240
+ let min, max;
2241
+ if ("min_format" in entry || "max_format" in entry) {
2242
+ min = format(entry.min_format, `${field}.min_format`);
2243
+ max = format(entry.max_format, `${field}.max_format`, true);
2244
+ } else {
2245
+ const range = entry.formats;
2246
+ let lower, upper;
2247
+ if (typeof range === "number") {
2248
+ lower = upper = range;
2249
+ } else if (Array.isArray(range)) {
2250
+ if (range.length !== 2) throw new Error(`Invalid ${field}.formats: expected [min, max]`);
2251
+ [lower, upper] = range;
2252
+ } else {
2253
+ const bounds = object(range, `${field}.formats`);
2254
+ lower = bounds.min_inclusive;
2255
+ upper = bounds.max_inclusive;
2256
+ }
2257
+ min = [integer(lower, `${field}.formats.min_inclusive`), 0];
2258
+ max = [integer(upper, `${field}.formats.max_inclusive`), Infinity];
2259
+ }
2260
+ if (compare(min, max) > 0) throw new Error(`Invalid ${field}: minimum format exceeds maximum format`);
2261
+ return { directory, min, max };
2262
+ }
2263
+ function pattern(value, field) {
2264
+ if (value === void 0) return void 0;
2265
+ if (typeof value !== "string") throw new Error(`Invalid ${field}: expected a regular expression string`);
2266
+ try {
2267
+ return new RegExp(value);
2268
+ } catch (cause) {
2269
+ throw new Error(`Invalid ${field}: ${String(cause)}`);
2270
+ }
2271
+ }
2272
+ var PackMetadata;
2273
+ var init_PackMetadata = __esm({
2274
+ "src/assets/source/archive/PackMetadata.ts"() {
2275
+ PackMetadata = class _PackMetadata {
2276
+ constructor(overlays, filters) {
2277
+ this.overlays = overlays;
2278
+ this.filters = filters;
2279
+ this.hasOverlays = overlays.length > 0;
2280
+ }
2281
+ static parse(value) {
2282
+ const metadata = object(value, "pack.mcmeta");
2283
+ let overlays = [];
2284
+ if ("overlays" in metadata) {
2285
+ const entries = object(metadata.overlays, "overlays").entries;
2286
+ if (!Array.isArray(entries)) throw new Error("Invalid overlays.entries: expected an array");
2287
+ overlays = entries.map((entry, index) => overlay(entry, `overlays.entries[${index}]`));
2288
+ }
2289
+ let filters = [];
2290
+ if ("filter" in metadata) {
2291
+ const entries = object(metadata.filter, "filter").block;
2292
+ if (!Array.isArray(entries)) throw new Error("Invalid filter.block: expected an array");
2293
+ filters = entries.map((value2, index) => {
2294
+ const field = `filter.block[${index}]`;
2295
+ const entry = object(value2, field);
2296
+ return { namespace: pattern(entry.namespace, `${field}.namespace`), path: pattern(entry.path, `${field}.path`) };
2297
+ });
2298
+ }
2299
+ return new _PackMetadata(overlays, filters);
2300
+ }
2301
+ /** Returns applicable directories in lookup order, with the last declared overlay first. */
2302
+ overlayDirectories(target) {
2303
+ const selected = format(target, "target format");
2304
+ return this.overlays.filter((entry) => compare(selected, entry.min) >= 0 && compare(selected, entry.max) <= 0).map((entry) => entry.directory).reverse();
2305
+ }
2306
+ blocks(namespace, path) {
2307
+ return this.filters.some((entry) => entry.namespace?.test(namespace) ?? true) && this.filters.some((entry) => entry.path?.test(path) ?? true);
2308
+ }
2309
+ };
2310
+ }
2311
+ });
2312
+
2313
+ // src/assets/source/archive/PackFormats.ts
2314
+ var PackFormats;
2315
+ var init_PackFormats = __esm({
2316
+ "src/assets/source/archive/PackFormats.ts"() {
2317
+ init_Requests();
2318
+ PackFormats = class {
2319
+ static {
2320
+ this.versions = /* @__PURE__ */ new Map();
2321
+ }
2322
+ /** Resolves pack formats from Mojang's client metadata hosted on assets.mcasset.cloud. */
2323
+ static async get(version, type) {
2324
+ let pending = this.versions.get(version);
2325
+ if (!pending || pending.expires <= Date.now()) {
2326
+ pending = {
2327
+ formats: this.load(version),
2328
+ expires: ["latest", "release", "snapshot"].includes(version) ? Date.now() + 3e5 : Infinity
2329
+ };
2330
+ this.versions.set(version, pending);
2331
+ }
2332
+ try {
2333
+ return (await pending.formats)[type];
2334
+ } catch (cause) {
2335
+ if (this.versions.get(version) === pending) this.versions.delete(version);
2336
+ const option = type === "assets" ? "resourcePackFormat" : "dataPackFormat";
2337
+ const reason = cause instanceof Error ? cause.message : String(cause);
2338
+ throw new Error(`Could not resolve the pack format for Minecraft ${version}. Set ArchiveAssetSource ${option} explicitly. ${reason}`);
2339
+ }
2340
+ }
2341
+ static async load(version) {
2342
+ const response = await Requests.genericRequest({
2343
+ url: `https://assets.mcasset.cloud/${encodeURIComponent(version)}/game-version.json`,
2344
+ responseType: "json"
2345
+ });
2346
+ const data = response.data;
2347
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
2348
+ throw new Error("Expected version metadata to be an object");
2349
+ }
2350
+ const packs = data.pack_version;
2351
+ if (typeof packs !== "number" && (!packs || typeof packs !== "object" || Array.isArray(packs))) {
2352
+ throw new Error("Expected pack_version to be a number or an object");
2353
+ }
2354
+ const format2 = (type) => {
2355
+ const modern = typeof packs === "object" && ["resource_major", "resource_minor", "data_major", "data_minor"].some((key) => key in packs);
2356
+ const major = typeof packs === "number" ? packs : packs[modern ? `${type}_major` : type];
2357
+ const minor = modern ? packs[`${type}_minor`] : 0;
2358
+ if (typeof major !== "number" || !Number.isSafeInteger(major) || major < 0 || typeof minor !== "number" || !Number.isSafeInteger(minor) || minor < 0) {
2359
+ throw new Error(`Invalid ${type} pack format in version metadata`);
2360
+ }
2361
+ return Object.freeze([major, minor]);
2362
+ };
2363
+ return { assets: format2("resource"), data: format2("data") };
2364
+ }
2365
+ };
2366
+ }
2367
+ });
2368
+
2187
2369
  // src/assets/source/archive/ArchiveAssetSource.ts
2188
2370
  var ArchiveAssetSource;
2189
2371
  var init_ArchiveAssetSource = __esm({
@@ -2192,35 +2374,77 @@ var init_ArchiveAssetSource = __esm({
2192
2374
  init_request();
2193
2375
  init_HostedAssetSource();
2194
2376
  init_BrowserArchiveProxy();
2377
+ init_AssetLoader();
2378
+ init_PackMetadata();
2379
+ init_PackFormats();
2195
2380
  ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
2196
- constructor(archiveProxy) {
2381
+ constructor(archiveProxy, options = {}) {
2197
2382
  super();
2198
- console.log(archiveProxy);
2199
2383
  this._archiveProxy = archiveProxy;
2384
+ const copyFormat = (format2) => typeof format2 === "object" ? [format2[0], format2[1]] : format2;
2385
+ this.options = {
2386
+ resourcePackFormat: copyFormat(options.resourcePackFormat),
2387
+ dataPackFormat: copyFormat(options.dataPackFormat)
2388
+ };
2200
2389
  }
2201
- static blob(blob) {
2202
- return new _ArchiveAssetSource(new BrowserArchiveProxy(blob));
2390
+ static blob(blob, options) {
2391
+ return new _ArchiveAssetSource(new BrowserArchiveProxy(blob), options);
2203
2392
  }
2204
2393
  get cacheId() {
2205
2394
  const id = this._archiveProxy.id;
2206
- return id === void 0 ? void 0 : `archive:${id}`;
2395
+ const formats = [this.options.resourcePackFormat ?? AssetLoader.version, this.options.dataPackFormat ?? AssetLoader.version];
2396
+ return id === void 0 ? void 0 : `archive-metadata:1:${id}:${JSON.stringify(formats)}`;
2207
2397
  }
2208
2398
  async getEntries() {
2209
- return this._archiveProxy.getEntries();
2399
+ return this.entries ??= this._archiveProxy.getEntries().catch((error) => {
2400
+ this.entries = void 0;
2401
+ throw error;
2402
+ });
2210
2403
  }
2211
2404
  async getEntry(path) {
2212
2405
  const entries = await this.getEntries();
2213
2406
  return entries.find((e) => e.filename === path);
2214
2407
  }
2408
+ async getMetadata(key) {
2409
+ try {
2410
+ return await (this.metadata ??= this.getEntry("pack.mcmeta").then(async (entry) => PackMetadata.parse(entry ? JSON.parse(await (await entry.getData()).text()) : {})).catch((error) => {
2411
+ this.metadata = void 0;
2412
+ throw error;
2413
+ }));
2414
+ } catch (cause) {
2415
+ throw new AssetLoadError(this, key, "pack.mcmeta", cause);
2416
+ }
2417
+ }
2418
+ async blocks(key) {
2419
+ if (key.rootType !== "assets" && key.rootType !== "data") return false;
2420
+ const metadata = await this.getMetadata(key);
2421
+ const path = `${key.assetType !== void 0 ? key.assetType + "/" : ""}${key.getFullPath()}${key.extension}`;
2422
+ return metadata.blocks(key.namespace, path);
2423
+ }
2215
2424
  async get(key, parser) {
2216
2425
  const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
2217
2426
  return this.load(key, responseParser);
2218
2427
  }
2219
2428
  async load(key, parser) {
2220
2429
  const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
2430
+ const version = AssetLoader.version;
2431
+ let selectedPath = path;
2221
2432
  let url;
2222
2433
  try {
2223
- const entry = await this.getEntry(path);
2434
+ let directories = [];
2435
+ if (key.rootType === "assets" || key.rootType === "data") {
2436
+ const metadata = await this.getMetadata(key);
2437
+ if (metadata.hasOverlays) {
2438
+ const format2 = (key.rootType === "assets" ? this.options.resourcePackFormat : this.options.dataPackFormat) ?? await PackFormats.get(version, key.rootType);
2439
+ directories = metadata.overlayDirectories(format2);
2440
+ }
2441
+ }
2442
+ let entry;
2443
+ for (const directory of [...directories, ""]) {
2444
+ selectedPath = directory ? `${directory}/${path}` : path;
2445
+ entry = await this.getEntry(selectedPath);
2446
+ if (entry) break;
2447
+ }
2224
2448
  if (!entry) {
2225
2449
  return void 0;
2226
2450
  }
@@ -2233,7 +2457,8 @@ var init_ArchiveAssetSource = __esm({
2233
2457
  }
2234
2458
  return await parser.parse(response);
2235
2459
  } catch (cause) {
2236
- throw new AssetLoadError(this, key, path, cause);
2460
+ if (cause instanceof AssetLoadError) throw cause;
2461
+ throw new AssetLoadError(this, key, selectedPath, cause);
2237
2462
  } finally {
2238
2463
  if (url !== void 0) {
2239
2464
  URL.revokeObjectURL(url);
@@ -2266,6 +2491,8 @@ var init_archive = __esm({
2266
2491
  init_ArchiveEntry();
2267
2492
  init_ArchiveProxy();
2268
2493
  init_BrowserArchiveProxy();
2494
+ init_PackFormats();
2495
+ init_PackMetadata();
2269
2496
  }
2270
2497
  });
2271
2498
 
@@ -2362,13 +2589,14 @@ ${key}` : key;
2362
2589
  this.addSource("mcassets", new HostedAssetSource(this.ROOT, { retryDefaults: false }));
2363
2590
  }
2364
2591
  static async getAll(key, parser) {
2365
- let promises = [];
2366
- for (const source of this._SOURCES) {
2367
- promises.push(source.source.get(key, parser));
2592
+ const sources = [...this._SOURCES];
2593
+ const results = [];
2594
+ for (const { source } of sources) {
2595
+ const asset = await source.get(key, parser);
2596
+ if (asset != void 0) results.push(asset);
2597
+ if (await source.blocks(key)) break;
2368
2598
  }
2369
- return Promise.all(promises).then((results) => {
2370
- return results.filter((r) => r != void 0);
2371
- });
2599
+ return results;
2372
2600
  }
2373
2601
  /** Returns the first defined result in source-priority order, without merging assets. */
2374
2602
  static async get(key, parser) {
@@ -2389,13 +2617,17 @@ ${key}` : key;
2389
2617
  /** Tries each path within a source before considering lower-priority sources. */
2390
2618
  static async getFirst(keys, parser) {
2391
2619
  const sources = [...this._SOURCES];
2620
+ let remaining = [...keys];
2392
2621
  for (const source of sources) {
2393
- for (const key of keys) {
2622
+ for (const key of remaining) {
2394
2623
  const result = await source.source.get(key, parser);
2395
2624
  if (result !== void 0) {
2396
2625
  return { key, asset: result };
2397
2626
  }
2398
2627
  }
2628
+ const blocked = await Promise.all(remaining.map((key) => source.source.blocks(key)));
2629
+ remaining = remaining.filter((_, index) => !blocked[index]);
2630
+ if (!remaining.length) break;
2399
2631
  }
2400
2632
  return void 0;
2401
2633
  }
@@ -2854,6 +3086,37 @@ var init_UVMapper = __esm({
2854
3086
  static facesToUv(faces, originalTextureSize, actualTextureSize) {
2855
3087
  return new Float32BufferAttribute2(this.facesToUvArray(faces, originalTextureSize, actualTextureSize), 2);
2856
3088
  }
3089
+ /** Bounds texture sampling to texel centres without changing cropped face UVs. */
3090
+ static setAtlasUvBounds(geometry, faces, atlas) {
3091
+ const uv = geometry.getAttribute("uv");
3092
+ const bounds = new Float32Array(uv.count * 4);
3093
+ for (const [faceIndex, faceName] of CUBE_FACES.entries()) {
3094
+ const texture = faces[faceName]?.texture?.substring(1);
3095
+ const position = texture && atlas.positions[texture];
3096
+ const size = texture && atlas.sizes[texture];
3097
+ let minU = Infinity, minV = Infinity, maxU = -Infinity, maxV = -Infinity;
3098
+ if (position && size) {
3099
+ minU = position[0] / atlas.image.width;
3100
+ maxU = (position[0] + size[0]) / atlas.image.width;
3101
+ minV = 1 - (position[1] + size[1]) / atlas.image.height;
3102
+ maxV = 1 - position[1] / atlas.image.height;
3103
+ } else {
3104
+ for (let corner = 0; corner < 4; corner++) {
3105
+ const index = faceIndex * 4 + corner;
3106
+ minU = Math.min(minU, uv.getX(index));
3107
+ minV = Math.min(minV, uv.getY(index));
3108
+ maxU = Math.max(maxU, uv.getX(index));
3109
+ maxV = Math.max(maxV, uv.getY(index));
3110
+ }
3111
+ }
3112
+ const insetU = Math.min(0.5 / atlas.image.width, (maxU - minU) / 2);
3113
+ const insetV = Math.min(0.5 / atlas.image.height, (maxV - minV) / 2);
3114
+ for (let corner = 0; corner < 4; corner++) {
3115
+ bounds.set([minU + insetU, minV + insetV, maxU - insetU, maxV - insetV], (faceIndex * 4 + corner) * 4);
3116
+ }
3117
+ }
3118
+ geometry.setAttribute("uvBounds", new Float32BufferAttribute2(bounds, 4));
3119
+ }
2857
3120
  static lockUvs(geometry, faces, atlas, rotation) {
2858
3121
  const uv = geometry.getAttribute("uv");
2859
3122
  for (let faceIndex = 0; faceIndex < CUBE_FACES.length; faceIndex++) {
@@ -3510,27 +3773,27 @@ var init_EntityAnimationPlayer = __esm({
3510
3773
  for (const layer of layers) {
3511
3774
  const objects = [];
3512
3775
  if (poses) {
3513
- layer.traverse((object) => {
3514
- if (poses.has(object)) objects.push(object);
3776
+ layer.traverse((object2) => {
3777
+ if (poses.has(object2)) objects.push(object2);
3515
3778
  });
3516
3779
  } else {
3517
3780
  for (const bone of Object.keys(animation.bones)) {
3518
- const object = layer.getObjectByName(`group:${bone}`);
3519
- if (object) objects.push(object);
3781
+ const object2 = layer.getObjectByName(`group:${bone}`);
3782
+ if (object2) objects.push(object2);
3520
3783
  }
3521
3784
  }
3522
- for (const object of objects) {
3523
- const bone = object.name.slice("group:".length);
3524
- const pose = poses?.get(object);
3785
+ for (const object2 of objects) {
3786
+ const bone = object2.name.slice("group:".length);
3787
+ const pose = poses?.get(object2);
3525
3788
  this.parts.push({
3526
3789
  bone,
3527
- object,
3528
- position: object.position.clone(),
3529
- rotation: object.rotation.clone(),
3530
- scale: object.scale.clone(),
3531
- basePosition: pose ? new Vector35(...pose.offset) : object.position.clone(),
3532
- baseRotation: pose ? new Euler3(...pose.rotation, "ZYX") : object.rotation.clone(),
3533
- baseScale: pose ? new Vector35(...pose.scale ?? [1, 1, 1]) : object.scale.clone()
3790
+ object: object2,
3791
+ position: object2.position.clone(),
3792
+ rotation: object2.rotation.clone(),
3793
+ scale: object2.scale.clone(),
3794
+ basePosition: pose ? new Vector35(...pose.offset) : object2.position.clone(),
3795
+ baseRotation: pose ? new Euler3(...pose.rotation, "ZYX") : object2.rotation.clone(),
3796
+ baseScale: pose ? new Vector35(...pose.scale ?? [1, 1, 1]) : object2.scale.clone()
3534
3797
  });
3535
3798
  }
3536
3799
  }
@@ -4057,15 +4320,15 @@ var init_SceneObject = __esm({
4057
4320
  }
4058
4321
  }
4059
4322
  //</editor-fold>
4060
- toggleObjectVisibility(object, visible) {
4061
- if (object) {
4323
+ toggleObjectVisibility(object2, visible) {
4324
+ if (object2) {
4062
4325
  if (typeof visible !== "undefined") {
4063
- object.visible = visible;
4326
+ object2.visible = visible;
4064
4327
  } else {
4065
- object.visible = !object.visible;
4328
+ object2.visible = !object2.visible;
4066
4329
  }
4067
4330
  this.notifyDirty();
4068
- return object.visible;
4331
+ return object2.visible;
4069
4332
  }
4070
4333
  this.notifyDirty();
4071
4334
  return false;
@@ -4356,8 +4619,8 @@ var init_EntityObject = __esm({
4356
4619
  this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
4357
4620
  }
4358
4621
  }
4359
- this.getLayerGroup(name)?.traverse((object) => {
4360
- if (isMesh(object)) object.material = mat;
4622
+ this.getLayerGroup(name)?.traverse((object2) => {
4623
+ if (isMesh(object2)) object2.material = mat;
4361
4624
  });
4362
4625
  }));
4363
4626
  if (!this.children.length) {
@@ -4696,8 +4959,8 @@ function toTrianglesDrawMode(geometry, drawMode) {
4696
4959
  return geometry;
4697
4960
  }
4698
4961
  }
4699
- function computeMorphedAttributes(object) {
4700
- if (object.geometry.isBufferGeometry !== true) {
4962
+ function computeMorphedAttributes(object2) {
4963
+ if (object2.geometry.isBufferGeometry !== true) {
4701
4964
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
4702
4965
  return null;
4703
4966
  }
@@ -4710,11 +4973,11 @@ function computeMorphedAttributes(object) {
4710
4973
  const _morphA = new Vector310();
4711
4974
  const _morphB = new Vector310();
4712
4975
  const _morphC = new Vector310();
4713
- function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
4976
+ function _calculateMorphedAttributeData(object3, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
4714
4977
  _vA.fromBufferAttribute(attribute, a2);
4715
4978
  _vB.fromBufferAttribute(attribute, b2);
4716
4979
  _vC.fromBufferAttribute(attribute, c2);
4717
- const morphInfluences = object2.morphTargetInfluences;
4980
+ const morphInfluences = object3.morphTargetInfluences;
4718
4981
  if (material2.morphTargets && morphAttribute && morphInfluences) {
4719
4982
  _morphA.set(0, 0, 0);
4720
4983
  _morphB.set(0, 0, 0);
@@ -4740,10 +5003,10 @@ function computeMorphedAttributes(object) {
4740
5003
  _vB.add(_morphB);
4741
5004
  _vC.add(_morphC);
4742
5005
  }
4743
- if (object2.isSkinnedMesh) {
4744
- object2.boneTransform(a2, _vA);
4745
- object2.boneTransform(b2, _vB);
4746
- object2.boneTransform(c2, _vC);
5006
+ if (object3.isSkinnedMesh) {
5007
+ object3.boneTransform(a2, _vA);
5008
+ object3.boneTransform(b2, _vB);
5009
+ object3.boneTransform(c2, _vC);
4747
5010
  }
4748
5011
  modifiedAttributeArray[a2 * 3 + 0] = _vA.x;
4749
5012
  modifiedAttributeArray[a2 * 3 + 1] = _vA.y;
@@ -4755,8 +5018,8 @@ function computeMorphedAttributes(object) {
4755
5018
  modifiedAttributeArray[c2 * 3 + 1] = _vC.y;
4756
5019
  modifiedAttributeArray[c2 * 3 + 2] = _vC.z;
4757
5020
  }
4758
- const geometry = object.geometry;
4759
- const material = object.material;
5021
+ const geometry = object2.geometry;
5022
+ const material = object2.material;
4760
5023
  let a, b, c;
4761
5024
  const index = geometry.index;
4762
5025
  const positionAttribute = geometry.attributes.position;
@@ -4783,7 +5046,7 @@ function computeMorphedAttributes(object) {
4783
5046
  b = index.getX(j + 1);
4784
5047
  c = index.getX(j + 2);
4785
5048
  _calculateMorphedAttributeData(
4786
- object,
5049
+ object2,
4787
5050
  groupMaterial,
4788
5051
  positionAttribute,
4789
5052
  morphPosition,
@@ -4794,7 +5057,7 @@ function computeMorphedAttributes(object) {
4794
5057
  modifiedPosition
4795
5058
  );
4796
5059
  _calculateMorphedAttributeData(
4797
- object,
5060
+ object2,
4798
5061
  groupMaterial,
4799
5062
  normalAttribute,
4800
5063
  morphNormal,
@@ -4814,7 +5077,7 @@ function computeMorphedAttributes(object) {
4814
5077
  b = index.getX(i + 1);
4815
5078
  c = index.getX(i + 2);
4816
5079
  _calculateMorphedAttributeData(
4817
- object,
5080
+ object2,
4818
5081
  material,
4819
5082
  positionAttribute,
4820
5083
  morphPosition,
@@ -4825,7 +5088,7 @@ function computeMorphedAttributes(object) {
4825
5088
  modifiedPosition
4826
5089
  );
4827
5090
  _calculateMorphedAttributeData(
4828
- object,
5091
+ object2,
4829
5092
  material,
4830
5093
  normalAttribute,
4831
5094
  morphNormal,
@@ -4849,7 +5112,7 @@ function computeMorphedAttributes(object) {
4849
5112
  b = j + 1;
4850
5113
  c = j + 2;
4851
5114
  _calculateMorphedAttributeData(
4852
- object,
5115
+ object2,
4853
5116
  groupMaterial,
4854
5117
  positionAttribute,
4855
5118
  morphPosition,
@@ -4860,7 +5123,7 @@ function computeMorphedAttributes(object) {
4860
5123
  modifiedPosition
4861
5124
  );
4862
5125
  _calculateMorphedAttributeData(
4863
- object,
5126
+ object2,
4864
5127
  groupMaterial,
4865
5128
  normalAttribute,
4866
5129
  morphNormal,
@@ -4880,7 +5143,7 @@ function computeMorphedAttributes(object) {
4880
5143
  b = i + 1;
4881
5144
  c = i + 2;
4882
5145
  _calculateMorphedAttributeData(
4883
- object,
5146
+ object2,
4884
5147
  material,
4885
5148
  positionAttribute,
4886
5149
  morphPosition,
@@ -4891,7 +5154,7 @@ function computeMorphedAttributes(object) {
4891
5154
  modifiedPosition
4892
5155
  );
4893
5156
  _calculateMorphedAttributeData(
4894
- object,
5157
+ object2,
4895
5158
  material,
4896
5159
  normalAttribute,
4897
5160
  morphNormal,
@@ -5203,13 +5466,13 @@ var init_ModelObject = __esm({
5203
5466
  transform.multiply(new Matrix49().makeTranslation(-8, -8, -8));
5204
5467
  try {
5205
5468
  for (const part of parts) {
5206
- const object = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5207
- object.matrix.copy(transform).multiply(part.transform);
5208
- object.matrixWorldNeedsUpdate = true;
5209
- object.matrixAutoUpdate = false;
5210
- this.add(object);
5211
- await object.init();
5212
- object.iterateAllMeshes((mesh) => {
5469
+ const object2 = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5470
+ object2.matrix.copy(transform).multiply(part.transform);
5471
+ object2.matrixWorldNeedsUpdate = true;
5472
+ object2.matrixAutoUpdate = false;
5473
+ this.add(object2);
5474
+ await object2.init();
5475
+ object2.iterateAllMeshes((mesh) => {
5213
5476
  const source = mesh.material;
5214
5477
  let material = this.specialMaterials.get(source);
5215
5478
  if (!material) {
@@ -5220,7 +5483,7 @@ var init_ModelObject = __esm({
5220
5483
  mesh.material = material;
5221
5484
  });
5222
5485
  for (const [name, rotation] of Object.entries(part.rotations)) {
5223
- object.getGroupByName(name)?.rotation.set(...rotation, "ZYX");
5486
+ object2.getGroupByName(name)?.rotation.set(...rotation, "ZYX");
5224
5487
  }
5225
5488
  }
5226
5489
  } catch (error) {
@@ -5265,6 +5528,7 @@ var init_ModelObject = __esm({
5265
5528
  if (this.options.uvLockRotation) {
5266
5529
  UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler7(...this.options.uvLockRotation));
5267
5530
  }
5531
+ UVMapper.setAtlasUvBounds(elGeo, el.faces, this.atlas);
5268
5532
  if (this.options.tints) {
5269
5533
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
5270
5534
  for (const [faceIndex, faceName] of CUBE_FACES.entries()) {
@@ -5330,7 +5594,7 @@ var init_ModelObject = __esm({
5330
5594
  }
5331
5595
  applyTextures() {
5332
5596
  if (this.atlas) {
5333
- const mat = Materials.createShadedCanvasMaterial(this.atlas.image.canvas, this.atlas.hasTransparency, false);
5597
+ const mat = Materials.createShadedCanvasMaterial(this.atlas.image.canvas, this.atlas.hasTransparency, false, true);
5334
5598
  this.atlasMaterial = mat;
5335
5599
  this.atlasTexture = mat.uniforms?.map?.value ?? mat.map;
5336
5600
  this.iterateAllMeshes((mesh) => {
@@ -5992,7 +6256,7 @@ var OBJExporter = class {
5992
6256
  * @param {Object3D} object - The 3D object to export.
5993
6257
  * @return {string} The exported OBJ.
5994
6258
  */
5995
- parse(object) {
6259
+ parse(object2) {
5996
6260
  let output = "";
5997
6261
  let indexVertex = 0;
5998
6262
  let indexVertexUvs = 0;
@@ -6111,7 +6375,7 @@ var OBJExporter = class {
6111
6375
  }
6112
6376
  indexVertex += nbVertex;
6113
6377
  }
6114
- object.traverse(function(child) {
6378
+ object2.traverse(function(child) {
6115
6379
  if (child.isMesh === true) {
6116
6380
  parseMesh(child);
6117
6381
  }
@@ -6145,9 +6409,9 @@ var PLYExporter = class {
6145
6409
  * @param {PLYExporter~Options} options - The export options.
6146
6410
  * @return {?(string|ArrayBuffer)} The exported PLY.
6147
6411
  */
6148
- parse(object, onDone, options = {}) {
6412
+ parse(object2, onDone, options = {}) {
6149
6413
  function traverseMeshes(cb) {
6150
- object.traverse(function(child) {
6414
+ object2.traverse(function(child) {
6151
6415
  if (child.isMesh === true || child.isPoints) {
6152
6416
  const mesh = child;
6153
6417
  const geometry = mesh.geometry;
@@ -6180,7 +6444,7 @@ var PLYExporter = class {
6180
6444
  for (const name of customAttributeNames) customTypes[name] = "float";
6181
6445
  let vertexCount = 0;
6182
6446
  let faceCount = 0;
6183
- object.traverse(function(child) {
6447
+ object2.traverse(function(child) {
6184
6448
  if (child.isMesh === true) {
6185
6449
  const mesh = child;
6186
6450
  const geometry = mesh.geometry;
@@ -6996,12 +7260,12 @@ var GLTFWriter = class {
6996
7260
  * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry|THREE.AnimationClip} object
6997
7261
  * @param {Object} objectDef
6998
7262
  */
6999
- serializeUserData(object, objectDef) {
7000
- if (Object.keys(object.userData).length === 0) return;
7263
+ serializeUserData(object2, objectDef) {
7264
+ if (Object.keys(object2.userData).length === 0) return;
7001
7265
  const options = this.options;
7002
7266
  const extensionsUsed = this.extensionsUsed;
7003
7267
  try {
7004
- const json = JSON.parse(JSON.stringify(object.userData));
7268
+ const json = JSON.parse(JSON.stringify(object2.userData));
7005
7269
  if (options.includeCustomExtensions && json.gltfExtensions) {
7006
7270
  if (objectDef.extensions === void 0) objectDef.extensions = {};
7007
7271
  for (const extensionName in json.gltfExtensions) {
@@ -7012,7 +7276,7 @@ var GLTFWriter = class {
7012
7276
  }
7013
7277
  if (Object.keys(json).length > 0) objectDef.extras = json;
7014
7278
  } catch (error) {
7015
- console.warn("THREE.GLTFExporter: userData of '" + object.name + "' won't be serialized because of JSON.stringify error - " + error.message);
7279
+ console.warn("THREE.GLTFExporter: userData of '" + object2.name + "' won't be serialized because of JSON.stringify error - " + error.message);
7016
7280
  }
7017
7281
  }
7018
7282
  /**
@@ -7385,7 +7649,7 @@ var GLTFWriter = class {
7385
7649
  * @param {string} mimeType export format
7386
7650
  * @return {number} Index of the processed texture in the "images" array
7387
7651
  */
7388
- processImage(image, format, flipY, mimeType = "image/png") {
7652
+ processImage(image, format2, flipY, mimeType = "image/png") {
7389
7653
  if (image !== null) {
7390
7654
  const writer = this;
7391
7655
  const cache = writer.cache;
@@ -7409,8 +7673,8 @@ var GLTFWriter = class {
7409
7673
  ctx.scale(1, -1);
7410
7674
  }
7411
7675
  if (image.data !== void 0) {
7412
- if (format !== RGBAFormat2) {
7413
- console.error("GLTFExporter: Only RGBAFormat is supported.", format);
7676
+ if (format2 !== RGBAFormat2) {
7677
+ console.error("GLTFExporter: Only RGBAFormat is supported.", format2);
7414
7678
  }
7415
7679
  if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
7416
7680
  console.warn("GLTFExporter: Image size is bigger than maxTextureSize", image);
@@ -7938,13 +8202,13 @@ var GLTFWriter = class {
7938
8202
  * @param {THREE.Object3D} object
7939
8203
  * @return {?number}
7940
8204
  */
7941
- processSkin(object) {
8205
+ processSkin(object2) {
7942
8206
  const json = this.json;
7943
8207
  const nodeMap = this.nodeMap;
7944
- const node = json.nodes[nodeMap.get(object)];
7945
- const skeleton = object.skeleton;
8208
+ const node = json.nodes[nodeMap.get(object2)];
8209
+ const skeleton = object2.skeleton;
7946
8210
  if (skeleton === void 0) return null;
7947
- const rootJoint = object.skeleton.bones[0];
8211
+ const rootJoint = object2.skeleton.bones[0];
7948
8212
  if (rootJoint === void 0) return null;
7949
8213
  const joints = [];
7950
8214
  const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
@@ -7952,7 +8216,7 @@ var GLTFWriter = class {
7952
8216
  for (let i = 0; i < skeleton.bones.length; ++i) {
7953
8217
  joints.push(nodeMap.get(skeleton.bones[i]));
7954
8218
  temporaryBoneInverse.copy(skeleton.boneInverses[i]);
7955
- temporaryBoneInverse.multiply(object.bindMatrix).toArray(inverseBindMatrices, i * 16);
8219
+ temporaryBoneInverse.multiply(object2.bindMatrix).toArray(inverseBindMatrices, i * 16);
7956
8220
  }
7957
8221
  if (json.skins === void 0) json.skins = [];
7958
8222
  json.skins.push({
@@ -7968,19 +8232,19 @@ var GLTFWriter = class {
7968
8232
  * @param {THREE.Object3D} object Object3D to processNodeAsync
7969
8233
  * @return {Promise<number>} Index of the node in the nodes list
7970
8234
  */
7971
- async processNodeAsync(object) {
8235
+ async processNodeAsync(object2) {
7972
8236
  const json = this.json;
7973
8237
  const options = this.options;
7974
8238
  const nodeMap = this.nodeMap;
7975
8239
  if (!json.nodes) json.nodes = [];
7976
- if (object.pivot !== null) {
7977
- return await this._processNodeWithPivotAsync(object);
8240
+ if (object2.pivot !== null) {
8241
+ return await this._processNodeWithPivotAsync(object2);
7978
8242
  }
7979
8243
  const nodeDef = {};
7980
8244
  if (options.trs) {
7981
- const rotation = object.quaternion.toArray();
7982
- const position = object.position.toArray();
7983
- const scale = object.scale.toArray();
8245
+ const rotation = object2.quaternion.toArray();
8246
+ const position = object2.position.toArray();
8247
+ const scale = object2.scale.toArray();
7984
8248
  if (!equalArray(rotation, [0, 0, 0, 1])) {
7985
8249
  nodeDef.rotation = rotation;
7986
8250
  }
@@ -7991,28 +8255,28 @@ var GLTFWriter = class {
7991
8255
  nodeDef.scale = scale;
7992
8256
  }
7993
8257
  } else {
7994
- if (object.matrixAutoUpdate) {
7995
- object.updateMatrix();
8258
+ if (object2.matrixAutoUpdate) {
8259
+ object2.updateMatrix();
7996
8260
  }
7997
- if (isIdentityMatrix(object.matrix) === false) {
7998
- nodeDef.matrix = object.matrix.elements;
8261
+ if (isIdentityMatrix(object2.matrix) === false) {
8262
+ nodeDef.matrix = object2.matrix.elements;
7999
8263
  }
8000
8264
  }
8001
- if (object.name !== "") nodeDef.name = String(object.name);
8002
- this.serializeUserData(object, nodeDef);
8003
- if (object.isMesh || object.isLine || object.isPoints) {
8004
- const meshIndex = await this.processMeshAsync(object);
8265
+ if (object2.name !== "") nodeDef.name = String(object2.name);
8266
+ this.serializeUserData(object2, nodeDef);
8267
+ if (object2.isMesh || object2.isLine || object2.isPoints) {
8268
+ const meshIndex = await this.processMeshAsync(object2);
8005
8269
  if (meshIndex !== null) nodeDef.mesh = meshIndex;
8006
- } else if (object.isCamera) {
8007
- nodeDef.camera = this.processCamera(object);
8270
+ } else if (object2.isCamera) {
8271
+ nodeDef.camera = this.processCamera(object2);
8008
8272
  }
8009
- if (object.isSkinnedMesh) this.skins.push(object);
8273
+ if (object2.isSkinnedMesh) this.skins.push(object2);
8010
8274
  const nodeIndex = json.nodes.push(nodeDef) - 1;
8011
- nodeMap.set(object, nodeIndex);
8012
- if (object.children.length > 0) {
8275
+ nodeMap.set(object2, nodeIndex);
8276
+ if (object2.children.length > 0) {
8013
8277
  const children = [];
8014
- for (let i = 0, l = object.children.length; i < l; i++) {
8015
- const child = object.children[i];
8278
+ for (let i = 0, l = object2.children.length; i < l; i++) {
8279
+ const child = object2.children[i];
8016
8280
  if (child.visible || options.onlyVisible === false) {
8017
8281
  const childNodeIndex = await this.processNodeAsync(child);
8018
8282
  if (childNodeIndex !== null) children.push(childNodeIndex);
@@ -8021,7 +8285,7 @@ var GLTFWriter = class {
8021
8285
  if (children.length > 0) nodeDef.children = children;
8022
8286
  }
8023
8287
  await this._invokeAllAsync(function(ext) {
8024
- ext.writeNode && ext.writeNode(object, nodeDef);
8288
+ ext.writeNode && ext.writeNode(object2, nodeDef);
8025
8289
  });
8026
8290
  return nodeIndex;
8027
8291
  }
@@ -8030,19 +8294,19 @@ var GLTFWriter = class {
8030
8294
  * @param {THREE.Object3D} object Object3D with pivot
8031
8295
  * @return {Promise<number>} Index of the container node
8032
8296
  */
8033
- async _processNodeWithPivotAsync(object) {
8297
+ async _processNodeWithPivotAsync(object2) {
8034
8298
  const json = this.json;
8035
8299
  const options = this.options;
8036
8300
  const nodeMap = this.nodeMap;
8037
- const pivot = object.pivot;
8301
+ const pivot = object2.pivot;
8038
8302
  const containerDef = {};
8039
- const rotation = object.quaternion.toArray();
8303
+ const rotation = object2.quaternion.toArray();
8040
8304
  const position = [
8041
- object.position.x + pivot.x,
8042
- object.position.y + pivot.y,
8043
- object.position.z + pivot.z
8305
+ object2.position.x + pivot.x,
8306
+ object2.position.y + pivot.y,
8307
+ object2.position.z + pivot.z
8044
8308
  ];
8045
- const scale = object.scale.toArray();
8309
+ const scale = object2.scale.toArray();
8046
8310
  if (!equalArray(rotation, [0, 0, 0, 1])) {
8047
8311
  containerDef.rotation = rotation;
8048
8312
  }
@@ -8053,28 +8317,28 @@ var GLTFWriter = class {
8053
8317
  containerDef.scale = scale;
8054
8318
  }
8055
8319
  containerDef.extras = { pivot: pivot.toArray() };
8056
- if (object.name !== "") containerDef.name = String(object.name);
8057
- this.serializeUserData(object, containerDef);
8320
+ if (object2.name !== "") containerDef.name = String(object2.name);
8321
+ this.serializeUserData(object2, containerDef);
8058
8322
  const containerIndex = json.nodes.push(containerDef) - 1;
8059
- nodeMap.set(object, containerIndex);
8323
+ nodeMap.set(object2, containerIndex);
8060
8324
  const childDef = {};
8061
8325
  const childPosition = [-pivot.x, -pivot.y, -pivot.z];
8062
8326
  if (!equalArray(childPosition, [0, 0, 0])) {
8063
8327
  childDef.translation = childPosition;
8064
8328
  }
8065
- if (object.isMesh || object.isLine || object.isPoints) {
8066
- const meshIndex = await this.processMeshAsync(object);
8329
+ if (object2.isMesh || object2.isLine || object2.isPoints) {
8330
+ const meshIndex = await this.processMeshAsync(object2);
8067
8331
  if (meshIndex !== null) childDef.mesh = meshIndex;
8068
- } else if (object.isCamera) {
8069
- childDef.camera = this.processCamera(object);
8332
+ } else if (object2.isCamera) {
8333
+ childDef.camera = this.processCamera(object2);
8070
8334
  }
8071
- if (object.isSkinnedMesh) this.skins.push(object);
8335
+ if (object2.isSkinnedMesh) this.skins.push(object2);
8072
8336
  const childIndex = json.nodes.push(childDef) - 1;
8073
8337
  const containerChildren = [childIndex];
8074
- if (object.children.length > 0) {
8338
+ if (object2.children.length > 0) {
8075
8339
  const grandchildren = [];
8076
- for (let i = 0, l = object.children.length; i < l; i++) {
8077
- const child = object.children[i];
8340
+ for (let i = 0, l = object2.children.length; i < l; i++) {
8341
+ const child = object2.children[i];
8078
8342
  if (child.visible || options.onlyVisible === false) {
8079
8343
  const childNodeIndex = await this.processNodeAsync(child);
8080
8344
  if (childNodeIndex !== null) grandchildren.push(childNodeIndex);
@@ -8084,7 +8348,7 @@ var GLTFWriter = class {
8084
8348
  }
8085
8349
  containerDef.children = containerChildren;
8086
8350
  await this._invokeAllAsync(function(ext) {
8087
- ext.writeNode && ext.writeNode(object, containerDef);
8351
+ ext.writeNode && ext.writeNode(object2, containerDef);
8088
8352
  });
8089
8353
  return containerIndex;
8090
8354
  }
@@ -8527,10 +8791,10 @@ var GLTFMeshGpuInstancing = class {
8527
8791
  this.writer = writer;
8528
8792
  this.name = "EXT_mesh_gpu_instancing";
8529
8793
  }
8530
- writeNode(object, nodeDef) {
8531
- if (!object.isInstancedMesh) return;
8794
+ writeNode(object2, nodeDef) {
8795
+ if (!object2.isInstancedMesh) return;
8532
8796
  const writer = this.writer;
8533
- const mesh = object;
8797
+ const mesh = object2;
8534
8798
  const translationAttr = new Float32Array(mesh.count * 3);
8535
8799
  const rotationAttr = new Float32Array(mesh.count * 4);
8536
8800
  const scaleAttr = new Float32Array(mesh.count * 3);
@@ -8720,8 +8984,8 @@ var SceneExporter = class {
8720
8984
  }
8721
8985
  }
8722
8986
  };
8723
- function localMatrix(object) {
8724
- return object.matrixAutoUpdate ? new Matrix47().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
8987
+ function localMatrix(object2) {
8988
+ return object2.matrixAutoUpdate ? new Matrix47().compose(object2.position, object2.quaternion, object2.scale) : object2.matrix.clone();
8725
8989
  }
8726
8990
  function createSnapshot(root, gltf, bakeColors = false) {
8727
8991
  const scene = new Scene3();
@@ -8825,10 +9089,10 @@ function createSnapshot(root, gltf, bakeColors = false) {
8825
9089
  scene.add(copy);
8826
9090
  }
8827
9091
  };
8828
- const visit = (object, parentWorld) => {
8829
- if (!object.visible) return;
8830
- const world = parentWorld.clone().multiply(localMatrix(object));
8831
- const mesh = object;
9092
+ const visit = (object2, parentWorld) => {
9093
+ if (!object2.visible) return;
9094
+ const world = parentWorld.clone().multiply(localMatrix(object2));
9095
+ const mesh = object2;
8832
9096
  if (mesh.isMesh) {
8833
9097
  const instanced = mesh;
8834
9098
  if (instanced.isInstancedMesh) {
@@ -8842,7 +9106,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8842
9106
  addMesh(mesh, world);
8843
9107
  }
8844
9108
  }
8845
- for (const child of object.children) visit(child, world);
9109
+ for (const child of object2.children) visit(child, world);
8846
9110
  };
8847
9111
  try {
8848
9112
  const ancestors = [];
@@ -9074,11 +9338,11 @@ var GuiHelper = class {
9074
9338
  switch (recipe.type) {
9075
9339
  case "minecraft:crafting_shaped":
9076
9340
  case "crafting_shaped": {
9077
- const pattern = recipe.pattern;
9078
- if (!pattern.length || pattern.length > 3 || !pattern[0].length || pattern[0].length > 3 || pattern.some((row) => row.length !== pattern[0].length)) {
9341
+ const pattern2 = recipe.pattern;
9342
+ if (!pattern2.length || pattern2.length > 3 || !pattern2[0].length || pattern2[0].length > 3 || pattern2.some((row) => row.length !== pattern2[0].length)) {
9079
9343
  throw new Error("Crafting patterns must be rectangular, with 1\u20133 rows and columns");
9080
9344
  }
9081
- const cells = pattern.flatMap((row, y) => row.split("").map((symbol, x) => ({ symbol, x, y }))).filter((cell) => cell.symbol !== " ");
9345
+ const cells = pattern2.flatMap((row, y) => row.split("").map((symbol, x) => ({ symbol, x, y }))).filter((cell) => cell.symbol !== " ");
9082
9346
  if (!cells.length) throw new Error("Crafting patterns must contain an ingredient");
9083
9347
  const minX = Math.min(...cells.map((cell) => cell.x)), maxX = Math.max(...cells.map((cell) => cell.x));
9084
9348
  const minY = Math.min(...cells.map((cell) => cell.y)), maxY = Math.max(...cells.map((cell) => cell.y));
@@ -9490,29 +9754,29 @@ var SceneInspector = class {
9490
9754
  this.objectControlsContainer.innerHTML = "";
9491
9755
  this.addControls(targetObject, targetIntersection, instance);
9492
9756
  }
9493
- addControls(object, intersection, instance) {
9757
+ addControls(object2, intersection, instance) {
9494
9758
  const container = document.createElement("div");
9495
9759
  container.append(this.separator("Select Parent/Child"));
9496
- if (object.parent) {
9497
- container.append(this.buttonControl("Select Parent " + object.parent.constructor.name + " " + object.parent.name, "P", () => {
9498
- this.selectObject(object.parent, intersection, instance);
9760
+ if (object2.parent) {
9761
+ container.append(this.buttonControl("Select Parent " + object2.parent.constructor.name + " " + object2.parent.name, "P", () => {
9762
+ this.selectObject(object2.parent, intersection, instance);
9499
9763
  }));
9500
9764
  }
9501
- if (object.children.length > 0) {
9765
+ if (object2.children.length > 0) {
9502
9766
  let i = 1;
9503
- for (let child of object.children) {
9767
+ for (let child of object2.children) {
9504
9768
  container.append(this.buttonControl("Select Child " + child.constructor.name + " " + child.name, "C" + i++, () => {
9505
9769
  this.selectObject(child, intersection, instance);
9506
9770
  }));
9507
9771
  }
9508
9772
  }
9509
9773
  container.append(this.separator());
9510
- const selectedInstance = instance && (object === instance.instanceable || object === intersection?.object) ? instance : void 0;
9774
+ const selectedInstance = instance && (object2 === instance.instanceable || object2 === intersection?.object) ? instance : void 0;
9511
9775
  if (!selectedInstance) {
9512
- container.append(this.toggleControl("Visibility", "V", object.visible, (v) => object.visible = v));
9776
+ container.append(this.toggleControl("Visibility", "V", object2.visible, (v) => object2.visible = v));
9513
9777
  }
9514
9778
  container.append(this.separator("Mesh"));
9515
- this.addObjectControls(object, intersection, container, selectedInstance);
9779
+ this.addObjectControls(object2, intersection, container, selectedInstance);
9516
9780
  container.append(this.separator());
9517
9781
  this.objectControlsContainer.append(container);
9518
9782
  }
@@ -10083,8 +10347,8 @@ var BlockObject = class _BlockObject extends SceneObject {
10083
10347
  return false;
10084
10348
  }
10085
10349
  return this._models.some((model) => {
10086
- const object = isInstanceReference(model) ? model.instanceable : model;
10087
- return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
10350
+ const object2 = isInstanceReference(model) ? model.instanceable : model;
10351
+ return object2.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
10088
10352
  });
10089
10353
  }
10090
10354
  getModelMatrix(model) {
@@ -10093,8 +10357,8 @@ var BlockObject = class _BlockObject extends SceneObject {
10093
10357
  return model.matrix.clone();
10094
10358
  }
10095
10359
  getModelCullMask(model, worldMask) {
10096
- const object = isInstanceReference(model) ? model.instanceable : model;
10097
- if (object.options.displayPosition) return 0;
10360
+ const object2 = isInstanceReference(model) ? model.instanceable : model;
10361
+ if (object2.options.displayPosition) return 0;
10098
10362
  const position = new Vector312();
10099
10363
  const rotation = new Quaternion5();
10100
10364
  const scale = new Vector312();
@@ -10111,14 +10375,14 @@ var BlockObject = class _BlockObject extends SceneObject {
10111
10375
  replacements.push(model);
10112
10376
  continue;
10113
10377
  }
10114
- const object = isInstanceReference(model) ? model.instanceable : model;
10378
+ const object2 = isInstanceReference(model) ? model.instanceable : model;
10115
10379
  const cullMask = this.getModelCullMask(model, worldMask);
10116
- if (cullMask === (object.options.cullMask ?? 0)) {
10380
+ if (cullMask === (object2.options.cullMask ?? 0)) {
10117
10381
  replacements.push(model);
10118
10382
  continue;
10119
10383
  }
10120
10384
  const matrix = this.getModelMatrix(model);
10121
- const replacement = await this.scene.addModel(object.originalModel, { ...object.options, cullMask });
10385
+ const replacement = await this.scene.addModel(object2.originalModel, { ...object2.options, cullMask });
10122
10386
  replacements.push(replacement);
10123
10387
  if (isInstanceReference(replacement)) {
10124
10388
  replacement.setMatrix(matrix);
@@ -10126,8 +10390,8 @@ var BlockObject = class _BlockObject extends SceneObject {
10126
10390
  replacement.matrix.copy(matrix);
10127
10391
  replacement.matrixWorldNeedsUpdate = true;
10128
10392
  matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
10129
- replacement.matrixAutoUpdate = object.matrixAutoUpdate;
10130
- replacement.visible = object.visible;
10393
+ replacement.matrixAutoUpdate = object2.matrixAutoUpdate;
10394
+ replacement.visible = object2.visible;
10131
10395
  }
10132
10396
  }
10133
10397
  } catch (error) {
@@ -12045,9 +12309,9 @@ var SchematicParser = class {
12045
12309
  * Parses a legacy schematic using custom mappings before the bundled defaults.
12046
12310
  * Keys are `id:metadata`; values are block states such as `minecraft:oak_log[axis=x]`.
12047
12311
  */
12048
- static async parse(nbt, customMappings = {}) {
12312
+ static async parse(nbt, customMappings = {}, options = {}) {
12049
12313
  const tags = nbt.value;
12050
- if (tags.Materials?.type !== "string" || tags.Materials.value !== "Alpha") {
12314
+ if (!options.lenient && (tags.Materials?.type !== "string" || tags.Materials.value !== "Alpha")) {
12051
12315
  throw new MineRenderError("Schematic Materials must be Alpha");
12052
12316
  }
12053
12317
  const size = ["Width", "Height", "Length"].map((name) => {
@@ -12088,8 +12352,16 @@ var SchematicParser = class {
12088
12352
  const id = high << 8 | ids.value[index] & 255;
12089
12353
  const metadata = data.value[index] & 255;
12090
12354
  const key = `${id}:${metadata}`;
12091
- const mapped = customMappings[key] ?? mapping[key];
12092
- if (!mapped) throw new MineRenderError(`Unsupported legacy block ${id}:${metadata} at schematic index ${index}`);
12355
+ let mapped = customMappings[key] ?? mapping[key];
12356
+ if (!mapped && options.lenient) {
12357
+ mapped = customMappings[`${id}:0`] ?? mapping[`${id}:0`];
12358
+ }
12359
+ if (!mapped) {
12360
+ if (options.lenient) {
12361
+ continue;
12362
+ }
12363
+ throw new MineRenderError(`Unsupported legacy block ${id}:${metadata} at schematic index ${index}`);
12364
+ }
12093
12365
  const [type, state] = mapped.split("[");
12094
12366
  if (type === "minecraft:air") continue;
12095
12367
  const properties = {};
@@ -13250,53 +13522,53 @@ var MineRenderScene = class _MineRenderScene extends Scene4 {
13250
13522
  this.DEFAULT_OPTIONS = (0, import_ts_deepmerge8.default)({}, {});
13251
13523
  }
13252
13524
  add(...objects) {
13253
- for (const object of objects) {
13525
+ for (const object2 of objects) {
13254
13526
  this.dirty = true;
13255
13527
  try {
13256
- super.add(object);
13528
+ super.add(object2);
13257
13529
  } finally {
13258
- if (object?.isObject3D && object !== this) {
13259
- this.updateObjectRegistration(object, object.parent === this);
13530
+ if (object2?.isObject3D && object2 !== this) {
13531
+ this.updateObjectRegistration(object2, object2.parent === this);
13260
13532
  }
13261
13533
  }
13262
13534
  }
13263
13535
  return this;
13264
13536
  }
13265
13537
  remove(...objects) {
13266
- for (const object of objects) {
13267
- if (!this.children.includes(object)) continue;
13538
+ for (const object2 of objects) {
13539
+ if (!this.children.includes(object2)) continue;
13268
13540
  this.dirty = true;
13269
- this.updateObjectRegistration(object, false);
13541
+ this.updateObjectRegistration(object2, false);
13270
13542
  try {
13271
- super.remove(object);
13543
+ super.remove(object2);
13272
13544
  } finally {
13273
- this.updateObjectRegistration(object, object.parent === this);
13545
+ this.updateObjectRegistration(object2, object2.parent === this);
13274
13546
  }
13275
13547
  }
13276
13548
  return this;
13277
13549
  }
13278
- updateObjectRegistration(object, attached) {
13279
- if (this.observedObjects.has(object) === attached) return;
13280
- const observable = object;
13550
+ updateObjectRegistration(object2, attached) {
13551
+ if (this.observedObjects.has(object2) === attached) return;
13552
+ const observable = object2;
13281
13553
  if (attached) {
13282
- this.observedObjects.add(object);
13554
+ this.observedObjects.add(object2);
13283
13555
  observable.addEventListener("change", this.onObjectChange);
13284
13556
  } else {
13285
- this.observedObjects.delete(object);
13557
+ this.observedObjects.delete(object2);
13286
13558
  observable.removeEventListener("change", this.onObjectChange);
13287
13559
  }
13288
13560
  const change = attached ? 1 : -1;
13289
13561
  this.stats.objectCount += change;
13290
- if (isSceneObject(object)) {
13562
+ if (isSceneObject(object2)) {
13291
13563
  this.stats.sceneObjectCount += change;
13292
13564
  }
13293
13565
  }
13294
- async initAndAdd(...object) {
13566
+ async initAndAdd(...object2) {
13295
13567
  this.dirty = true;
13296
- for (let obj of object) {
13568
+ for (let obj of object2) {
13297
13569
  await obj.init();
13298
13570
  }
13299
- return this.add(...object);
13571
+ return this.add(...object2);
13300
13572
  }
13301
13573
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
13302
13574
  this.dirty = true;
@@ -13383,11 +13655,11 @@ var _changeEvent = { type: "change" };
13383
13655
  var _startEvent = { type: "start" };
13384
13656
  var _endEvent = { type: "end" };
13385
13657
  var OrbitControls = class extends EventDispatcher {
13386
- constructor(object, domElement) {
13658
+ constructor(object2, domElement) {
13387
13659
  super();
13388
13660
  if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
13389
13661
  if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
13390
- this.object = object;
13662
+ this.object = object2;
13391
13663
  this.domElement = domElement;
13392
13664
  this.domElement.style.touchAction = "none";
13393
13665
  this.enabled = true;
@@ -13444,7 +13716,7 @@ var OrbitControls = class extends EventDispatcher {
13444
13716
  };
13445
13717
  this.update = function() {
13446
13718
  const offset = new Vector313();
13447
- const quat = new Quaternion6().setFromUnitVectors(object.up, new Vector313(0, 1, 0));
13719
+ const quat = new Quaternion6().setFromUnitVectors(object2.up, new Vector313(0, 1, 0));
13448
13720
  const quatInverse = quat.clone().invert();
13449
13721
  const lastPosition = new Vector313();
13450
13722
  const lastQuaternion = new Quaternion6();
@@ -14009,8 +14281,8 @@ var OrbitControls = class extends EventDispatcher {
14009
14281
  }
14010
14282
  };
14011
14283
  var MapControls = class extends OrbitControls {
14012
- constructor(object, domElement) {
14013
- super(object, domElement);
14284
+ constructor(object2, domElement) {
14285
+ super(object2, domElement);
14014
14286
  this.screenSpacePanning = false;
14015
14287
  this.mouseButtons.LEFT = MOUSE.PAN;
14016
14288
  this.mouseButtons.RIGHT = MOUSE.ROTATE;
@@ -14938,16 +15210,16 @@ var SectionModels = class {
14938
15210
  if (!models) this.models.set(model, models = /* @__PURE__ */ new Map());
14939
15211
  const key = JSON.stringify([rotation.x, rotation.y, rotation.z, variant.uvlock, tints]);
14940
15212
  const template = await cached(models, key, async () => {
14941
- const object = new SectionModel(model, {
15213
+ const object2 = new SectionModel(model, {
14942
15214
  instanceMeshes: false,
14943
15215
  mergeMeshes: false,
14944
15216
  tints,
14945
15217
  uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
14946
15218
  });
14947
- await object.init();
14948
- const geometry = object.children[0].geometry;
15219
+ await object2.init();
15220
+ const geometry = object2.children[0].geometry;
14949
15221
  geometry.applyMatrix4(new Matrix412().makeRotationFromEuler(rotation));
14950
- object.clear();
15222
+ object2.clear();
14951
15223
  const cullFaces = CUBE_FACES.map((face) => {
14952
15224
  const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
14953
15225
  if (local < 0) return 0;
@@ -15135,10 +15407,10 @@ var MineRenderWorld = class {
15135
15407
  await block.object.updateFluid((x, y, z) => {
15136
15408
  const neighbor = pos.clone().add(new Vector316(x, y, z));
15137
15409
  const section = this.getChunkAt(neighbor);
15138
- const object = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
15410
+ const object2 = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
15139
15411
  return {
15140
- fluid: object?.fluidKind,
15141
- level: object?.fluidLevel,
15412
+ fluid: object2?.fluidKind,
15413
+ level: object2?.fluidLevel,
15142
15414
  solid: section?.isOccludingAt(neighbor) ?? false
15143
15415
  };
15144
15416
  });
@@ -15258,14 +15530,17 @@ var SectionMesh = class _SectionMesh extends Group2 {
15258
15530
  for (const { atlas, x, y } of page.placements) {
15259
15531
  context.drawImage(atlas.image.canvas, x, y);
15260
15532
  }
15261
- const positions = [], normals = [], uvs = [], colors = [], indices = [];
15533
+ const positions = [], normals = [], uvs = [], uvBounds = [], colors = [], indices = [];
15262
15534
  for (const { index, template, cullMask } of page.entries) {
15263
15535
  const position = template.geometry.getAttribute("position");
15264
15536
  const normal = template.geometry.getAttribute("normal");
15265
15537
  const uv = template.geometry.getAttribute("uv");
15538
+ const bounds = template.geometry.getAttribute("uvBounds");
15266
15539
  const color = template.geometry.getAttribute("color");
15267
15540
  const sourceIndices = template.geometry.getIndex();
15268
15541
  const placement = locations.get(template.atlas).placement;
15542
+ const mapU = (u) => (placement.x + u * template.atlas.image.width) / page.width;
15543
+ const mapV = (v) => 1 - (placement.y + (1 - v) * template.atlas.image.height) / page.height;
15269
15544
  const offsetX = index % 16 * 16;
15270
15545
  const offsetY = Math.floor(index / 256) * 16;
15271
15546
  const offsetZ = Math.floor(index / 16) % 16 * 16;
@@ -15276,9 +15551,12 @@ var SectionMesh = class _SectionMesh extends Group2 {
15276
15551
  const vertex = face * 4 + corner;
15277
15552
  positions.push(position.getX(vertex) + offsetX, position.getY(vertex) + offsetY, position.getZ(vertex) + offsetZ);
15278
15553
  normals.push(normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex));
15279
- uvs.push(
15280
- (placement.x + uv.getX(vertex) * template.atlas.image.width) / page.width,
15281
- 1 - (placement.y + (1 - uv.getY(vertex)) * template.atlas.image.height) / page.height
15554
+ uvs.push(mapU(uv.getX(vertex)), mapV(uv.getY(vertex)));
15555
+ uvBounds.push(
15556
+ mapU(bounds?.getX(vertex) ?? 0),
15557
+ mapV(bounds?.getY(vertex) ?? 0),
15558
+ mapU(bounds?.getZ(vertex) ?? 1),
15559
+ mapV(bounds?.getW(vertex) ?? 1)
15282
15560
  );
15283
15561
  colors.push(color?.getX(vertex) ?? 1, color?.getY(vertex) ?? 1, color?.getZ(vertex) ?? 1);
15284
15562
  }
@@ -15289,11 +15567,12 @@ var SectionMesh = class _SectionMesh extends Group2 {
15289
15567
  geometry.setAttribute("position", new Float32BufferAttribute8(positions, 3));
15290
15568
  geometry.setAttribute("normal", new Float32BufferAttribute8(normals, 3));
15291
15569
  geometry.setAttribute("uv", new Float32BufferAttribute8(uvs, 2));
15570
+ geometry.setAttribute("uvBounds", new Float32BufferAttribute8(uvBounds, 4));
15292
15571
  geometry.setAttribute("color", new Float32BufferAttribute8(colors, 3));
15293
15572
  geometry.setIndex(indices);
15294
15573
  geometry.computeBoundingBox();
15295
15574
  geometry.computeBoundingSphere();
15296
- const material = Materials.createShadedCanvasMaterial(canvas, false);
15575
+ const material = Materials.createShadedCanvasMaterial(canvas, false, false, true);
15297
15576
  material.vertexColors = true;
15298
15577
  const texture = material.uniforms?.map?.value ?? material.map;
15299
15578
  const mesh = new Mesh9(geometry, material);
@@ -15367,7 +15646,7 @@ var Chunk = class _Chunk {
15367
15646
  this.renderedBlocks.get(index)?.object?.removeFromScene();
15368
15647
  if (this.sectionBlocks.delete(index)) this.meshDirty = true;
15369
15648
  this.renderedBlocks.delete(index);
15370
- let object;
15649
+ let object2;
15371
15650
  try {
15372
15651
  if (!readBlock) return void 0;
15373
15652
  const stored = readBlock();
@@ -15382,22 +15661,22 @@ var Chunk = class _Chunk {
15382
15661
  this.sectionBlocks.set(index, { index, template, cullMask: 0 });
15383
15662
  this.meshDirty = true;
15384
15663
  } else {
15385
- object = await this.scene.addBlock(blockState, {
15664
+ object2 = await this.scene.addBlock(blockState, {
15386
15665
  mergeMeshes: true,
15387
15666
  instanceMeshes: true,
15388
15667
  maxInstanceCount: 2e3,
15389
15668
  initialState: stored.properties
15390
15669
  });
15391
- object.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
15670
+ object2.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
15392
15671
  }
15393
15672
  const info = { get block() {
15394
15673
  return readBlock();
15395
- }, object };
15674
+ }, object: object2 };
15396
15675
  this.renderedBlocks.set(index, info);
15397
15676
  return info;
15398
15677
  } catch (error) {
15399
15678
  this.data.set(index, void 0);
15400
- object?.removeFromScene();
15679
+ object2?.removeFromScene();
15401
15680
  throw error;
15402
15681
  } finally {
15403
15682
  await onBlocksChanged?.([worldPos]);
@@ -15570,6 +15849,8 @@ export {
15570
15849
  NodeCache,
15571
15850
  NodeEnv,
15572
15851
  OrbitControls,
15852
+ PackFormats,
15853
+ PackMetadata,
15573
15854
  PersistentCache,
15574
15855
  Renderer,
15575
15856
  RequestError,