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.
@@ -749,7 +749,7 @@ var init_TextureLoader = __esm({
749
749
  static createTexture() {
750
750
  return new Texture();
751
751
  }
752
- static loadInBackground(src, format = RGBAFormat, rotation = 0) {
752
+ static loadInBackground(src, format2 = RGBAFormat, rotation = 0) {
753
753
  const texture = this.createTexture();
754
754
  texture.colorSpace = THREE.SRGBColorSpace;
755
755
  const image = ImageLoader.loadElement(src, () => {
@@ -759,11 +759,11 @@ var init_TextureLoader = __esm({
759
759
  console.warn("Failed to load texture", src, error);
760
760
  });
761
761
  texture.image = image;
762
- texture.format = format;
762
+ texture.format = format2;
763
763
  texture.rotation = rotation;
764
764
  return Textures.initTextureProps(texture);
765
765
  }
766
- static load(src, format = RGBAFormat, rotation = 0) {
766
+ static load(src, format2 = RGBAFormat, rotation = 0) {
767
767
  const texture = new Texture();
768
768
  texture.colorSpace = THREE.SRGBColorSpace;
769
769
  ImageLoader.getData(src).then((image) => {
@@ -773,7 +773,7 @@ var init_TextureLoader = __esm({
773
773
  this.failedTextures.add(texture);
774
774
  console.warn("Failed to load texture", src, error);
775
775
  });
776
- texture.format = format;
776
+ texture.format = format2;
777
777
  texture.rotation = rotation;
778
778
  return Textures.initTextureProps(texture);
779
779
  }
@@ -981,7 +981,7 @@ var init_Materials = __esm({
981
981
  };
982
982
  return material;
983
983
  }
984
- static createShadedCanvasMaterial(canvas, transparent = false, shade = false) {
984
+ static createShadedCanvasMaterial(canvas, transparent = false, shade = false, boundUvs = false) {
985
985
  const vertShader = `
986
986
  uniform bool SHADE;
987
987
 
@@ -991,6 +991,10 @@ var init_Materials = __esm({
991
991
  #else
992
992
  varying vec2 vUv;
993
993
  #endif
994
+ #ifdef BOUND_UVS
995
+ attribute vec4 uvBounds;
996
+ flat out vec4 vUvBounds;
997
+ #endif
994
998
  varying vec3 vTint;
995
999
  varying float light;
996
1000
  varying float lift;
@@ -1026,13 +1030,17 @@ var init_Materials = __esm({
1026
1030
  }
1027
1031
 
1028
1032
  vUv = uv;
1033
+ #ifdef BOUND_UVS
1034
+ vUvBounds = uvBounds;
1035
+ #endif
1029
1036
  vTint = color;
1030
1037
 
1038
+ vec4 mvPosition = vec4(position, 1.0);
1031
1039
  #ifdef USE_INSTANCING
1032
- gl_Position = projectionMatrix * viewMatrix * modelMatrix * instanceMatrix * vec4(position, 1.0);
1033
- #else
1034
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
1040
+ mvPosition = instanceMatrix * mvPosition;
1035
1041
  #endif
1042
+ mvPosition = modelViewMatrix * mvPosition;
1043
+ gl_Position = projectionMatrix * mvPosition;
1036
1044
 
1037
1045
  }
1038
1046
  `;
@@ -1052,13 +1060,22 @@ var init_Materials = __esm({
1052
1060
  #else
1053
1061
  varying vec2 vUv;
1054
1062
  #endif
1063
+ #ifdef BOUND_UVS
1064
+ flat in vec4 vUvBounds;
1065
+ #endif
1055
1066
  varying vec3 vTint;
1056
1067
  varying float light;
1057
1068
  varying float lift;
1058
1069
 
1059
1070
  void main(void)
1060
1071
  {
1061
- vec4 color = texture2D(map, vUv);
1072
+ #ifdef BOUND_UVS
1073
+ // Keep edge samples inside their texture even without centroid interpolation.
1074
+ vec2 mapUv = clamp(vUv, vUvBounds.xy, vUvBounds.zw);
1075
+ #else
1076
+ vec2 mapUv = vUv;
1077
+ #endif
1078
+ vec4 color = texture2D(map, mapUv);
1062
1079
  color.rgb *= vTint;
1063
1080
 
1064
1081
  if (color.a < 0.01) discard;
@@ -1079,7 +1096,8 @@ var init_Materials = __esm({
1079
1096
  }
1080
1097
  `;
1081
1098
  try {
1082
- return new ShaderMaterial({
1099
+ const material = new ShaderMaterial({
1100
+ defines: boundUvs ? { BOUND_UVS: true } : {},
1083
1101
  uniforms: {
1084
1102
  SHADE: { value: true },
1085
1103
  BRIGHTNESS: { value: 1 },
@@ -1097,6 +1115,8 @@ var init_Materials = __esm({
1097
1115
  side: transparent ? DoubleSide : FrontSide,
1098
1116
  alphaTest: 0.5
1099
1117
  });
1118
+ Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
1119
+ return material;
1100
1120
  } catch (e) {
1101
1121
  console.warn(e);
1102
1122
  }
@@ -1703,6 +1723,10 @@ var init_AssetSource = __esm({
1703
1723
  AssetSource = class {
1704
1724
  constructor() {
1705
1725
  }
1726
+ /** Whether this source prevents lower-priority sources from supplying the key. Its own assets remain available. */
1727
+ blocks(key) {
1728
+ return false;
1729
+ }
1706
1730
  /**
1707
1731
  * Identifies this source's content across sessions for persistent caching. Sources that
1708
1732
  * cannot tell whether their content changed (an unnamed archive, for example) return
@@ -1882,10 +1906,10 @@ var NBTHelper;
1882
1906
  var init_NBTHelper = __esm({
1883
1907
  "src/nbt/NBTHelper.ts"() {
1884
1908
  NBTHelper = class {
1885
- static async fromBuffer(data, format) {
1909
+ static async fromBuffer(data, format2) {
1886
1910
  const buffer = Buffer3.from(data instanceof Uint8Array ? data : new Uint8Array(data));
1887
1911
  const prismarineNbt = await import("prismarine-nbt");
1888
- const { parsed, type, metadata } = await prismarineNbt.parse(buffer, format);
1912
+ const { parsed, type, metadata } = await prismarineNbt.parse(buffer, format2);
1889
1913
  return Object.assign(parsed, {
1890
1914
  format: type,
1891
1915
  metadata,
@@ -2119,6 +2143,162 @@ var init_BrowserArchiveProxy = __esm({
2119
2143
  }
2120
2144
  });
2121
2145
 
2146
+ // src/assets/source/archive/PackMetadata.ts
2147
+ function object(value, field) {
2148
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
2149
+ throw new Error(`Invalid ${field}: expected an object`);
2150
+ }
2151
+ return value;
2152
+ }
2153
+ function integer(value, field) {
2154
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
2155
+ throw new Error(`Invalid ${field}: expected a nonnegative integer`);
2156
+ }
2157
+ return value;
2158
+ }
2159
+ function format(value, field, upper = false) {
2160
+ const parts = Array.isArray(value) ? value : [value];
2161
+ if (parts.length < 1 || parts.length > 2) {
2162
+ throw new Error(`Invalid ${field}: expected a major version or [major, minor]`);
2163
+ }
2164
+ return [integer(parts[0], field), parts.length === 2 ? integer(parts[1], field) : upper ? Infinity : 0];
2165
+ }
2166
+ function compare(a, b) {
2167
+ return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0];
2168
+ }
2169
+ function overlay(value, field) {
2170
+ const entry = object(value, field);
2171
+ const directory = entry.directory;
2172
+ if (typeof directory !== "string" || !directory || /[^-_a-zA-Z0-9.]/.test(directory) || directory === "." || directory === "..") {
2173
+ throw new Error(`Invalid ${field}.directory: expected a directory name without path separators`);
2174
+ }
2175
+ let min, max;
2176
+ if ("min_format" in entry || "max_format" in entry) {
2177
+ min = format(entry.min_format, `${field}.min_format`);
2178
+ max = format(entry.max_format, `${field}.max_format`, true);
2179
+ } else {
2180
+ const range = entry.formats;
2181
+ let lower, upper;
2182
+ if (typeof range === "number") {
2183
+ lower = upper = range;
2184
+ } else if (Array.isArray(range)) {
2185
+ if (range.length !== 2) throw new Error(`Invalid ${field}.formats: expected [min, max]`);
2186
+ [lower, upper] = range;
2187
+ } else {
2188
+ const bounds = object(range, `${field}.formats`);
2189
+ lower = bounds.min_inclusive;
2190
+ upper = bounds.max_inclusive;
2191
+ }
2192
+ min = [integer(lower, `${field}.formats.min_inclusive`), 0];
2193
+ max = [integer(upper, `${field}.formats.max_inclusive`), Infinity];
2194
+ }
2195
+ if (compare(min, max) > 0) throw new Error(`Invalid ${field}: minimum format exceeds maximum format`);
2196
+ return { directory, min, max };
2197
+ }
2198
+ function pattern(value, field) {
2199
+ if (value === void 0) return void 0;
2200
+ if (typeof value !== "string") throw new Error(`Invalid ${field}: expected a regular expression string`);
2201
+ try {
2202
+ return new RegExp(value);
2203
+ } catch (cause) {
2204
+ throw new Error(`Invalid ${field}: ${String(cause)}`);
2205
+ }
2206
+ }
2207
+ var PackMetadata;
2208
+ var init_PackMetadata = __esm({
2209
+ "src/assets/source/archive/PackMetadata.ts"() {
2210
+ PackMetadata = class _PackMetadata {
2211
+ constructor(overlays, filters) {
2212
+ this.overlays = overlays;
2213
+ this.filters = filters;
2214
+ this.hasOverlays = overlays.length > 0;
2215
+ }
2216
+ static parse(value) {
2217
+ const metadata = object(value, "pack.mcmeta");
2218
+ let overlays = [];
2219
+ if ("overlays" in metadata) {
2220
+ const entries = object(metadata.overlays, "overlays").entries;
2221
+ if (!Array.isArray(entries)) throw new Error("Invalid overlays.entries: expected an array");
2222
+ overlays = entries.map((entry, index) => overlay(entry, `overlays.entries[${index}]`));
2223
+ }
2224
+ let filters = [];
2225
+ if ("filter" in metadata) {
2226
+ const entries = object(metadata.filter, "filter").block;
2227
+ if (!Array.isArray(entries)) throw new Error("Invalid filter.block: expected an array");
2228
+ filters = entries.map((value2, index) => {
2229
+ const field = `filter.block[${index}]`;
2230
+ const entry = object(value2, field);
2231
+ return { namespace: pattern(entry.namespace, `${field}.namespace`), path: pattern(entry.path, `${field}.path`) };
2232
+ });
2233
+ }
2234
+ return new _PackMetadata(overlays, filters);
2235
+ }
2236
+ /** Returns applicable directories in lookup order, with the last declared overlay first. */
2237
+ overlayDirectories(target) {
2238
+ const selected = format(target, "target format");
2239
+ return this.overlays.filter((entry) => compare(selected, entry.min) >= 0 && compare(selected, entry.max) <= 0).map((entry) => entry.directory).reverse();
2240
+ }
2241
+ blocks(namespace, path) {
2242
+ return this.filters.some((entry) => entry.namespace?.test(namespace) ?? true) && this.filters.some((entry) => entry.path?.test(path) ?? true);
2243
+ }
2244
+ };
2245
+ }
2246
+ });
2247
+
2248
+ // src/assets/source/archive/PackFormats.ts
2249
+ var PackFormats;
2250
+ var init_PackFormats = __esm({
2251
+ "src/assets/source/archive/PackFormats.ts"() {
2252
+ init_Requests();
2253
+ PackFormats = class {
2254
+ /** Resolves pack formats from Mojang's client metadata hosted on assets.mcasset.cloud. */
2255
+ static async get(version, type) {
2256
+ let pending = this.versions.get(version);
2257
+ if (!pending || pending.expires <= Date.now()) {
2258
+ pending = {
2259
+ formats: this.load(version),
2260
+ expires: ["latest", "release", "snapshot"].includes(version) ? Date.now() + 3e5 : Infinity
2261
+ };
2262
+ this.versions.set(version, pending);
2263
+ }
2264
+ try {
2265
+ return (await pending.formats)[type];
2266
+ } catch (cause) {
2267
+ if (this.versions.get(version) === pending) this.versions.delete(version);
2268
+ const option = type === "assets" ? "resourcePackFormat" : "dataPackFormat";
2269
+ const reason = cause instanceof Error ? cause.message : String(cause);
2270
+ throw new Error(`Could not resolve the pack format for Minecraft ${version}. Set ArchiveAssetSource ${option} explicitly. ${reason}`);
2271
+ }
2272
+ }
2273
+ static async load(version) {
2274
+ const response = await Requests.genericRequest({
2275
+ url: `https://assets.mcasset.cloud/${encodeURIComponent(version)}/game-version.json`,
2276
+ responseType: "json"
2277
+ });
2278
+ const data = response.data;
2279
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
2280
+ throw new Error("Expected version metadata to be an object");
2281
+ }
2282
+ const packs = data.pack_version;
2283
+ if (typeof packs !== "number" && (!packs || typeof packs !== "object" || Array.isArray(packs))) {
2284
+ throw new Error("Expected pack_version to be a number or an object");
2285
+ }
2286
+ const format2 = (type) => {
2287
+ const modern = typeof packs === "object" && ["resource_major", "resource_minor", "data_major", "data_minor"].some((key) => key in packs);
2288
+ const major = typeof packs === "number" ? packs : packs[modern ? `${type}_major` : type];
2289
+ const minor = modern ? packs[`${type}_minor`] : 0;
2290
+ if (typeof major !== "number" || !Number.isSafeInteger(major) || major < 0 || typeof minor !== "number" || !Number.isSafeInteger(minor) || minor < 0) {
2291
+ throw new Error(`Invalid ${type} pack format in version metadata`);
2292
+ }
2293
+ return Object.freeze([major, minor]);
2294
+ };
2295
+ return { assets: format2("resource"), data: format2("data") };
2296
+ }
2297
+ };
2298
+ PackFormats.versions = /* @__PURE__ */ new Map();
2299
+ }
2300
+ });
2301
+
2122
2302
  // src/assets/source/archive/ArchiveAssetSource.ts
2123
2303
  var ArchiveAssetSource;
2124
2304
  var init_ArchiveAssetSource = __esm({
@@ -2127,35 +2307,77 @@ var init_ArchiveAssetSource = __esm({
2127
2307
  init_request();
2128
2308
  init_HostedAssetSource();
2129
2309
  init_BrowserArchiveProxy();
2310
+ init_AssetLoader();
2311
+ init_PackMetadata();
2312
+ init_PackFormats();
2130
2313
  ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
2131
- constructor(archiveProxy) {
2314
+ constructor(archiveProxy, options = {}) {
2132
2315
  super();
2133
- console.log(archiveProxy);
2134
2316
  this._archiveProxy = archiveProxy;
2317
+ const copyFormat = (format2) => typeof format2 === "object" ? [format2[0], format2[1]] : format2;
2318
+ this.options = {
2319
+ resourcePackFormat: copyFormat(options.resourcePackFormat),
2320
+ dataPackFormat: copyFormat(options.dataPackFormat)
2321
+ };
2135
2322
  }
2136
- static blob(blob) {
2137
- return new _ArchiveAssetSource(new BrowserArchiveProxy(blob));
2323
+ static blob(blob, options) {
2324
+ return new _ArchiveAssetSource(new BrowserArchiveProxy(blob), options);
2138
2325
  }
2139
2326
  get cacheId() {
2140
2327
  const id = this._archiveProxy.id;
2141
- return id === void 0 ? void 0 : `archive:${id}`;
2328
+ const formats = [this.options.resourcePackFormat ?? AssetLoader.version, this.options.dataPackFormat ?? AssetLoader.version];
2329
+ return id === void 0 ? void 0 : `archive-metadata:1:${id}:${JSON.stringify(formats)}`;
2142
2330
  }
2143
2331
  async getEntries() {
2144
- return this._archiveProxy.getEntries();
2332
+ return this.entries ?? (this.entries = this._archiveProxy.getEntries().catch((error) => {
2333
+ this.entries = void 0;
2334
+ throw error;
2335
+ }));
2145
2336
  }
2146
2337
  async getEntry(path) {
2147
2338
  const entries = await this.getEntries();
2148
2339
  return entries.find((e) => e.filename === path);
2149
2340
  }
2341
+ async getMetadata(key) {
2342
+ try {
2343
+ return await (this.metadata ?? (this.metadata = this.getEntry("pack.mcmeta").then(async (entry) => PackMetadata.parse(entry ? JSON.parse(await (await entry.getData()).text()) : {})).catch((error) => {
2344
+ this.metadata = void 0;
2345
+ throw error;
2346
+ })));
2347
+ } catch (cause) {
2348
+ throw new AssetLoadError(this, key, "pack.mcmeta", cause);
2349
+ }
2350
+ }
2351
+ async blocks(key) {
2352
+ if (key.rootType !== "assets" && key.rootType !== "data") return false;
2353
+ const metadata = await this.getMetadata(key);
2354
+ const path = `${key.assetType !== void 0 ? key.assetType + "/" : ""}${key.getFullPath()}${key.extension}`;
2355
+ return metadata.blocks(key.namespace, path);
2356
+ }
2150
2357
  async get(key, parser) {
2151
2358
  const responseParser = HostedAssetSource.PARSER_MAP.get(parser);
2152
2359
  return this.load(key, responseParser);
2153
2360
  }
2154
2361
  async load(key, parser) {
2155
2362
  const path = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
2363
+ const version = AssetLoader.version;
2364
+ let selectedPath = path;
2156
2365
  let url;
2157
2366
  try {
2158
- const entry = await this.getEntry(path);
2367
+ let directories = [];
2368
+ if (key.rootType === "assets" || key.rootType === "data") {
2369
+ const metadata = await this.getMetadata(key);
2370
+ if (metadata.hasOverlays) {
2371
+ const format2 = (key.rootType === "assets" ? this.options.resourcePackFormat : this.options.dataPackFormat) ?? await PackFormats.get(version, key.rootType);
2372
+ directories = metadata.overlayDirectories(format2);
2373
+ }
2374
+ }
2375
+ let entry;
2376
+ for (const directory of [...directories, ""]) {
2377
+ selectedPath = directory ? `${directory}/${path}` : path;
2378
+ entry = await this.getEntry(selectedPath);
2379
+ if (entry) break;
2380
+ }
2159
2381
  if (!entry) {
2160
2382
  return void 0;
2161
2383
  }
@@ -2168,7 +2390,8 @@ var init_ArchiveAssetSource = __esm({
2168
2390
  }
2169
2391
  return await parser.parse(response);
2170
2392
  } catch (cause) {
2171
- throw new AssetLoadError(this, key, path, cause);
2393
+ if (cause instanceof AssetLoadError) throw cause;
2394
+ throw new AssetLoadError(this, key, selectedPath, cause);
2172
2395
  } finally {
2173
2396
  if (url !== void 0) {
2174
2397
  URL.revokeObjectURL(url);
@@ -2201,6 +2424,8 @@ var init_archive = __esm({
2201
2424
  init_ArchiveEntry();
2202
2425
  init_ArchiveProxy();
2203
2426
  init_BrowserArchiveProxy();
2427
+ init_PackFormats();
2428
+ init_PackMetadata();
2204
2429
  }
2205
2430
  });
2206
2431
 
@@ -2283,13 +2508,14 @@ ${key}` : key;
2283
2508
  return void 0;
2284
2509
  }
2285
2510
  static async getAll(key, parser) {
2286
- let promises = [];
2287
- for (const source of this._SOURCES) {
2288
- promises.push(source.source.get(key, parser));
2511
+ const sources = [...this._SOURCES];
2512
+ const results = [];
2513
+ for (const { source } of sources) {
2514
+ const asset = await source.get(key, parser);
2515
+ if (asset != void 0) results.push(asset);
2516
+ if (await source.blocks(key)) break;
2289
2517
  }
2290
- return Promise.all(promises).then((results) => {
2291
- return results.filter((r) => r != void 0);
2292
- });
2518
+ return results;
2293
2519
  }
2294
2520
  /** Returns the first defined result in source-priority order, without merging assets. */
2295
2521
  static async get(key, parser) {
@@ -2310,13 +2536,17 @@ ${key}` : key;
2310
2536
  /** Tries each path within a source before considering lower-priority sources. */
2311
2537
  static async getFirst(keys, parser) {
2312
2538
  const sources = [...this._SOURCES];
2539
+ let remaining = [...keys];
2313
2540
  for (const source of sources) {
2314
- for (const key of keys) {
2541
+ for (const key of remaining) {
2315
2542
  const result = await source.source.get(key, parser);
2316
2543
  if (result !== void 0) {
2317
2544
  return { key, asset: result };
2318
2545
  }
2319
2546
  }
2547
+ const blocked = await Promise.all(remaining.map((key) => source.source.blocks(key)));
2548
+ remaining = remaining.filter((_, index) => !blocked[index]);
2549
+ if (!remaining.length) break;
2320
2550
  }
2321
2551
  return void 0;
2322
2552
  }
@@ -2767,6 +2997,37 @@ var init_UVMapper = __esm({
2767
2997
  static facesToUv(faces, originalTextureSize, actualTextureSize) {
2768
2998
  return new Float32BufferAttribute2(this.facesToUvArray(faces, originalTextureSize, actualTextureSize), 2);
2769
2999
  }
3000
+ /** Bounds texture sampling to texel centres without changing cropped face UVs. */
3001
+ static setAtlasUvBounds(geometry, faces, atlas) {
3002
+ const uv = geometry.getAttribute("uv");
3003
+ const bounds = new Float32Array(uv.count * 4);
3004
+ for (const [faceIndex, faceName] of CUBE_FACES.entries()) {
3005
+ const texture = faces[faceName]?.texture?.substring(1);
3006
+ const position = texture && atlas.positions[texture];
3007
+ const size = texture && atlas.sizes[texture];
3008
+ let minU = Infinity, minV = Infinity, maxU = -Infinity, maxV = -Infinity;
3009
+ if (position && size) {
3010
+ minU = position[0] / atlas.image.width;
3011
+ maxU = (position[0] + size[0]) / atlas.image.width;
3012
+ minV = 1 - (position[1] + size[1]) / atlas.image.height;
3013
+ maxV = 1 - position[1] / atlas.image.height;
3014
+ } else {
3015
+ for (let corner = 0; corner < 4; corner++) {
3016
+ const index = faceIndex * 4 + corner;
3017
+ minU = Math.min(minU, uv.getX(index));
3018
+ minV = Math.min(minV, uv.getY(index));
3019
+ maxU = Math.max(maxU, uv.getX(index));
3020
+ maxV = Math.max(maxV, uv.getY(index));
3021
+ }
3022
+ }
3023
+ const insetU = Math.min(0.5 / atlas.image.width, (maxU - minU) / 2);
3024
+ const insetV = Math.min(0.5 / atlas.image.height, (maxV - minV) / 2);
3025
+ for (let corner = 0; corner < 4; corner++) {
3026
+ bounds.set([minU + insetU, minV + insetV, maxU - insetU, maxV - insetV], (faceIndex * 4 + corner) * 4);
3027
+ }
3028
+ }
3029
+ geometry.setAttribute("uvBounds", new Float32BufferAttribute2(bounds, 4));
3030
+ }
2770
3031
  static lockUvs(geometry, faces, atlas, rotation) {
2771
3032
  const uv = geometry.getAttribute("uv");
2772
3033
  for (let faceIndex = 0; faceIndex < CUBE_FACES.length; faceIndex++) {
@@ -3423,27 +3684,27 @@ var init_EntityAnimationPlayer = __esm({
3423
3684
  for (const layer of layers) {
3424
3685
  const objects = [];
3425
3686
  if (poses) {
3426
- layer.traverse((object) => {
3427
- if (poses.has(object)) objects.push(object);
3687
+ layer.traverse((object2) => {
3688
+ if (poses.has(object2)) objects.push(object2);
3428
3689
  });
3429
3690
  } else {
3430
3691
  for (const bone of Object.keys(animation.bones)) {
3431
- const object = layer.getObjectByName(`group:${bone}`);
3432
- if (object) objects.push(object);
3692
+ const object2 = layer.getObjectByName(`group:${bone}`);
3693
+ if (object2) objects.push(object2);
3433
3694
  }
3434
3695
  }
3435
- for (const object of objects) {
3436
- const bone = object.name.slice("group:".length);
3437
- const pose = poses?.get(object);
3696
+ for (const object2 of objects) {
3697
+ const bone = object2.name.slice("group:".length);
3698
+ const pose = poses?.get(object2);
3438
3699
  this.parts.push({
3439
3700
  bone,
3440
- object,
3441
- position: object.position.clone(),
3442
- rotation: object.rotation.clone(),
3443
- scale: object.scale.clone(),
3444
- basePosition: pose ? new Vector35(...pose.offset) : object.position.clone(),
3445
- baseRotation: pose ? new Euler3(...pose.rotation, "ZYX") : object.rotation.clone(),
3446
- baseScale: pose ? new Vector35(...pose.scale ?? [1, 1, 1]) : object.scale.clone()
3701
+ object: object2,
3702
+ position: object2.position.clone(),
3703
+ rotation: object2.rotation.clone(),
3704
+ scale: object2.scale.clone(),
3705
+ basePosition: pose ? new Vector35(...pose.offset) : object2.position.clone(),
3706
+ baseRotation: pose ? new Euler3(...pose.rotation, "ZYX") : object2.rotation.clone(),
3707
+ baseScale: pose ? new Vector35(...pose.scale ?? [1, 1, 1]) : object2.scale.clone()
3447
3708
  });
3448
3709
  }
3449
3710
  }
@@ -3962,15 +4223,15 @@ var init_SceneObject = __esm({
3962
4223
  }
3963
4224
  }
3964
4225
  //</editor-fold>
3965
- toggleObjectVisibility(object, visible) {
3966
- if (object) {
4226
+ toggleObjectVisibility(object2, visible) {
4227
+ if (object2) {
3967
4228
  if (typeof visible !== "undefined") {
3968
- object.visible = visible;
4229
+ object2.visible = visible;
3969
4230
  } else {
3970
- object.visible = !object.visible;
4231
+ object2.visible = !object2.visible;
3971
4232
  }
3972
4233
  this.notifyDirty();
3973
- return object.visible;
4234
+ return object2.visible;
3974
4235
  }
3975
4236
  this.notifyDirty();
3976
4237
  return false;
@@ -4265,8 +4526,8 @@ var init_EntityObject = __esm({
4265
4526
  this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
4266
4527
  }
4267
4528
  }
4268
- this.getLayerGroup(name)?.traverse((object) => {
4269
- if (isMesh(object)) object.material = mat;
4529
+ this.getLayerGroup(name)?.traverse((object2) => {
4530
+ if (isMesh(object2)) object2.material = mat;
4270
4531
  });
4271
4532
  }));
4272
4533
  if (!this.children.length) {
@@ -4607,8 +4868,8 @@ function toTrianglesDrawMode(geometry, drawMode) {
4607
4868
  return geometry;
4608
4869
  }
4609
4870
  }
4610
- function computeMorphedAttributes(object) {
4611
- if (object.geometry.isBufferGeometry !== true) {
4871
+ function computeMorphedAttributes(object2) {
4872
+ if (object2.geometry.isBufferGeometry !== true) {
4612
4873
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
4613
4874
  return null;
4614
4875
  }
@@ -4621,11 +4882,11 @@ function computeMorphedAttributes(object) {
4621
4882
  const _morphA = new Vector310();
4622
4883
  const _morphB = new Vector310();
4623
4884
  const _morphC = new Vector310();
4624
- function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
4885
+ function _calculateMorphedAttributeData(object3, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
4625
4886
  _vA.fromBufferAttribute(attribute, a2);
4626
4887
  _vB.fromBufferAttribute(attribute, b2);
4627
4888
  _vC.fromBufferAttribute(attribute, c2);
4628
- const morphInfluences = object2.morphTargetInfluences;
4889
+ const morphInfluences = object3.morphTargetInfluences;
4629
4890
  if (material2.morphTargets && morphAttribute && morphInfluences) {
4630
4891
  _morphA.set(0, 0, 0);
4631
4892
  _morphB.set(0, 0, 0);
@@ -4651,10 +4912,10 @@ function computeMorphedAttributes(object) {
4651
4912
  _vB.add(_morphB);
4652
4913
  _vC.add(_morphC);
4653
4914
  }
4654
- if (object2.isSkinnedMesh) {
4655
- object2.boneTransform(a2, _vA);
4656
- object2.boneTransform(b2, _vB);
4657
- object2.boneTransform(c2, _vC);
4915
+ if (object3.isSkinnedMesh) {
4916
+ object3.boneTransform(a2, _vA);
4917
+ object3.boneTransform(b2, _vB);
4918
+ object3.boneTransform(c2, _vC);
4658
4919
  }
4659
4920
  modifiedAttributeArray[a2 * 3 + 0] = _vA.x;
4660
4921
  modifiedAttributeArray[a2 * 3 + 1] = _vA.y;
@@ -4666,8 +4927,8 @@ function computeMorphedAttributes(object) {
4666
4927
  modifiedAttributeArray[c2 * 3 + 1] = _vC.y;
4667
4928
  modifiedAttributeArray[c2 * 3 + 2] = _vC.z;
4668
4929
  }
4669
- const geometry = object.geometry;
4670
- const material = object.material;
4930
+ const geometry = object2.geometry;
4931
+ const material = object2.material;
4671
4932
  let a, b, c;
4672
4933
  const index = geometry.index;
4673
4934
  const positionAttribute = geometry.attributes.position;
@@ -4694,7 +4955,7 @@ function computeMorphedAttributes(object) {
4694
4955
  b = index.getX(j + 1);
4695
4956
  c = index.getX(j + 2);
4696
4957
  _calculateMorphedAttributeData(
4697
- object,
4958
+ object2,
4698
4959
  groupMaterial,
4699
4960
  positionAttribute,
4700
4961
  morphPosition,
@@ -4705,7 +4966,7 @@ function computeMorphedAttributes(object) {
4705
4966
  modifiedPosition
4706
4967
  );
4707
4968
  _calculateMorphedAttributeData(
4708
- object,
4969
+ object2,
4709
4970
  groupMaterial,
4710
4971
  normalAttribute,
4711
4972
  morphNormal,
@@ -4725,7 +4986,7 @@ function computeMorphedAttributes(object) {
4725
4986
  b = index.getX(i + 1);
4726
4987
  c = index.getX(i + 2);
4727
4988
  _calculateMorphedAttributeData(
4728
- object,
4989
+ object2,
4729
4990
  material,
4730
4991
  positionAttribute,
4731
4992
  morphPosition,
@@ -4736,7 +4997,7 @@ function computeMorphedAttributes(object) {
4736
4997
  modifiedPosition
4737
4998
  );
4738
4999
  _calculateMorphedAttributeData(
4739
- object,
5000
+ object2,
4740
5001
  material,
4741
5002
  normalAttribute,
4742
5003
  morphNormal,
@@ -4760,7 +5021,7 @@ function computeMorphedAttributes(object) {
4760
5021
  b = j + 1;
4761
5022
  c = j + 2;
4762
5023
  _calculateMorphedAttributeData(
4763
- object,
5024
+ object2,
4764
5025
  groupMaterial,
4765
5026
  positionAttribute,
4766
5027
  morphPosition,
@@ -4771,7 +5032,7 @@ function computeMorphedAttributes(object) {
4771
5032
  modifiedPosition
4772
5033
  );
4773
5034
  _calculateMorphedAttributeData(
4774
- object,
5035
+ object2,
4775
5036
  groupMaterial,
4776
5037
  normalAttribute,
4777
5038
  morphNormal,
@@ -4791,7 +5052,7 @@ function computeMorphedAttributes(object) {
4791
5052
  b = i + 1;
4792
5053
  c = i + 2;
4793
5054
  _calculateMorphedAttributeData(
4794
- object,
5055
+ object2,
4795
5056
  material,
4796
5057
  positionAttribute,
4797
5058
  morphPosition,
@@ -4802,7 +5063,7 @@ function computeMorphedAttributes(object) {
4802
5063
  modifiedPosition
4803
5064
  );
4804
5065
  _calculateMorphedAttributeData(
4805
- object,
5066
+ object2,
4806
5067
  material,
4807
5068
  normalAttribute,
4808
5069
  morphNormal,
@@ -5111,13 +5372,13 @@ var init_ModelObject = __esm({
5111
5372
  transform.multiply(new Matrix49().makeTranslation(-8, -8, -8));
5112
5373
  try {
5113
5374
  for (const part of parts) {
5114
- const object = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5115
- object.matrix.copy(transform).multiply(part.transform);
5116
- object.matrixWorldNeedsUpdate = true;
5117
- object.matrixAutoUpdate = false;
5118
- this.add(object);
5119
- await object.init();
5120
- object.iterateAllMeshes((mesh) => {
5375
+ const object2 = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5376
+ object2.matrix.copy(transform).multiply(part.transform);
5377
+ object2.matrixWorldNeedsUpdate = true;
5378
+ object2.matrixAutoUpdate = false;
5379
+ this.add(object2);
5380
+ await object2.init();
5381
+ object2.iterateAllMeshes((mesh) => {
5121
5382
  const source = mesh.material;
5122
5383
  let material = this.specialMaterials.get(source);
5123
5384
  if (!material) {
@@ -5128,7 +5389,7 @@ var init_ModelObject = __esm({
5128
5389
  mesh.material = material;
5129
5390
  });
5130
5391
  for (const [name, rotation] of Object.entries(part.rotations)) {
5131
- object.getGroupByName(name)?.rotation.set(...rotation, "ZYX");
5392
+ object2.getGroupByName(name)?.rotation.set(...rotation, "ZYX");
5132
5393
  }
5133
5394
  }
5134
5395
  } catch (error) {
@@ -5173,6 +5434,7 @@ var init_ModelObject = __esm({
5173
5434
  if (this.options.uvLockRotation) {
5174
5435
  UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler7(...this.options.uvLockRotation));
5175
5436
  }
5437
+ UVMapper.setAtlasUvBounds(elGeo, el.faces, this.atlas);
5176
5438
  if (this.options.tints) {
5177
5439
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
5178
5440
  for (const [faceIndex, faceName] of CUBE_FACES.entries()) {
@@ -5238,7 +5500,7 @@ var init_ModelObject = __esm({
5238
5500
  }
5239
5501
  applyTextures() {
5240
5502
  if (this.atlas) {
5241
- const mat = Materials.createShadedCanvasMaterial(this.atlas.image.canvas, this.atlas.hasTransparency, false);
5503
+ const mat = Materials.createShadedCanvasMaterial(this.atlas.image.canvas, this.atlas.hasTransparency, false, true);
5242
5504
  this.atlasMaterial = mat;
5243
5505
  this.atlasTexture = mat.uniforms?.map?.value ?? mat.map;
5244
5506
  this.iterateAllMeshes((mesh) => {
@@ -5940,7 +6202,7 @@ var OBJExporter = class {
5940
6202
  * @param {Object3D} object - The 3D object to export.
5941
6203
  * @return {string} The exported OBJ.
5942
6204
  */
5943
- parse(object) {
6205
+ parse(object2) {
5944
6206
  let output = "";
5945
6207
  let indexVertex = 0;
5946
6208
  let indexVertexUvs = 0;
@@ -6059,7 +6321,7 @@ var OBJExporter = class {
6059
6321
  }
6060
6322
  indexVertex += nbVertex;
6061
6323
  }
6062
- object.traverse(function(child) {
6324
+ object2.traverse(function(child) {
6063
6325
  if (child.isMesh === true) {
6064
6326
  parseMesh(child);
6065
6327
  }
@@ -6093,9 +6355,9 @@ var PLYExporter = class {
6093
6355
  * @param {PLYExporter~Options} options - The export options.
6094
6356
  * @return {?(string|ArrayBuffer)} The exported PLY.
6095
6357
  */
6096
- parse(object, onDone, options = {}) {
6358
+ parse(object2, onDone, options = {}) {
6097
6359
  function traverseMeshes(cb) {
6098
- object.traverse(function(child) {
6360
+ object2.traverse(function(child) {
6099
6361
  if (child.isMesh === true || child.isPoints) {
6100
6362
  const mesh = child;
6101
6363
  const geometry = mesh.geometry;
@@ -6128,7 +6390,7 @@ var PLYExporter = class {
6128
6390
  for (const name of customAttributeNames) customTypes[name] = "float";
6129
6391
  let vertexCount = 0;
6130
6392
  let faceCount = 0;
6131
- object.traverse(function(child) {
6393
+ object2.traverse(function(child) {
6132
6394
  if (child.isMesh === true) {
6133
6395
  const mesh = child;
6134
6396
  const geometry = mesh.geometry;
@@ -6944,12 +7206,12 @@ var GLTFWriter = class {
6944
7206
  * @param {THREE.Object3D|THREE.Material|THREE.BufferGeometry|THREE.AnimationClip} object
6945
7207
  * @param {Object} objectDef
6946
7208
  */
6947
- serializeUserData(object, objectDef) {
6948
- if (Object.keys(object.userData).length === 0) return;
7209
+ serializeUserData(object2, objectDef) {
7210
+ if (Object.keys(object2.userData).length === 0) return;
6949
7211
  const options = this.options;
6950
7212
  const extensionsUsed = this.extensionsUsed;
6951
7213
  try {
6952
- const json = JSON.parse(JSON.stringify(object.userData));
7214
+ const json = JSON.parse(JSON.stringify(object2.userData));
6953
7215
  if (options.includeCustomExtensions && json.gltfExtensions) {
6954
7216
  if (objectDef.extensions === void 0) objectDef.extensions = {};
6955
7217
  for (const extensionName in json.gltfExtensions) {
@@ -6960,7 +7222,7 @@ var GLTFWriter = class {
6960
7222
  }
6961
7223
  if (Object.keys(json).length > 0) objectDef.extras = json;
6962
7224
  } catch (error) {
6963
- console.warn("THREE.GLTFExporter: userData of '" + object.name + "' won't be serialized because of JSON.stringify error - " + error.message);
7225
+ console.warn("THREE.GLTFExporter: userData of '" + object2.name + "' won't be serialized because of JSON.stringify error - " + error.message);
6964
7226
  }
6965
7227
  }
6966
7228
  /**
@@ -7333,7 +7595,7 @@ var GLTFWriter = class {
7333
7595
  * @param {string} mimeType export format
7334
7596
  * @return {number} Index of the processed texture in the "images" array
7335
7597
  */
7336
- processImage(image, format, flipY, mimeType = "image/png") {
7598
+ processImage(image, format2, flipY, mimeType = "image/png") {
7337
7599
  if (image !== null) {
7338
7600
  const writer = this;
7339
7601
  const cache = writer.cache;
@@ -7357,8 +7619,8 @@ var GLTFWriter = class {
7357
7619
  ctx.scale(1, -1);
7358
7620
  }
7359
7621
  if (image.data !== void 0) {
7360
- if (format !== RGBAFormat2) {
7361
- console.error("GLTFExporter: Only RGBAFormat is supported.", format);
7622
+ if (format2 !== RGBAFormat2) {
7623
+ console.error("GLTFExporter: Only RGBAFormat is supported.", format2);
7362
7624
  }
7363
7625
  if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
7364
7626
  console.warn("GLTFExporter: Image size is bigger than maxTextureSize", image);
@@ -7886,13 +8148,13 @@ var GLTFWriter = class {
7886
8148
  * @param {THREE.Object3D} object
7887
8149
  * @return {?number}
7888
8150
  */
7889
- processSkin(object) {
8151
+ processSkin(object2) {
7890
8152
  const json = this.json;
7891
8153
  const nodeMap = this.nodeMap;
7892
- const node = json.nodes[nodeMap.get(object)];
7893
- const skeleton = object.skeleton;
8154
+ const node = json.nodes[nodeMap.get(object2)];
8155
+ const skeleton = object2.skeleton;
7894
8156
  if (skeleton === void 0) return null;
7895
- const rootJoint = object.skeleton.bones[0];
8157
+ const rootJoint = object2.skeleton.bones[0];
7896
8158
  if (rootJoint === void 0) return null;
7897
8159
  const joints = [];
7898
8160
  const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
@@ -7900,7 +8162,7 @@ var GLTFWriter = class {
7900
8162
  for (let i = 0; i < skeleton.bones.length; ++i) {
7901
8163
  joints.push(nodeMap.get(skeleton.bones[i]));
7902
8164
  temporaryBoneInverse.copy(skeleton.boneInverses[i]);
7903
- temporaryBoneInverse.multiply(object.bindMatrix).toArray(inverseBindMatrices, i * 16);
8165
+ temporaryBoneInverse.multiply(object2.bindMatrix).toArray(inverseBindMatrices, i * 16);
7904
8166
  }
7905
8167
  if (json.skins === void 0) json.skins = [];
7906
8168
  json.skins.push({
@@ -7916,19 +8178,19 @@ var GLTFWriter = class {
7916
8178
  * @param {THREE.Object3D} object Object3D to processNodeAsync
7917
8179
  * @return {Promise<number>} Index of the node in the nodes list
7918
8180
  */
7919
- async processNodeAsync(object) {
8181
+ async processNodeAsync(object2) {
7920
8182
  const json = this.json;
7921
8183
  const options = this.options;
7922
8184
  const nodeMap = this.nodeMap;
7923
8185
  if (!json.nodes) json.nodes = [];
7924
- if (object.pivot !== null) {
7925
- return await this._processNodeWithPivotAsync(object);
8186
+ if (object2.pivot !== null) {
8187
+ return await this._processNodeWithPivotAsync(object2);
7926
8188
  }
7927
8189
  const nodeDef = {};
7928
8190
  if (options.trs) {
7929
- const rotation = object.quaternion.toArray();
7930
- const position = object.position.toArray();
7931
- const scale = object.scale.toArray();
8191
+ const rotation = object2.quaternion.toArray();
8192
+ const position = object2.position.toArray();
8193
+ const scale = object2.scale.toArray();
7932
8194
  if (!equalArray(rotation, [0, 0, 0, 1])) {
7933
8195
  nodeDef.rotation = rotation;
7934
8196
  }
@@ -7939,28 +8201,28 @@ var GLTFWriter = class {
7939
8201
  nodeDef.scale = scale;
7940
8202
  }
7941
8203
  } else {
7942
- if (object.matrixAutoUpdate) {
7943
- object.updateMatrix();
8204
+ if (object2.matrixAutoUpdate) {
8205
+ object2.updateMatrix();
7944
8206
  }
7945
- if (isIdentityMatrix(object.matrix) === false) {
7946
- nodeDef.matrix = object.matrix.elements;
8207
+ if (isIdentityMatrix(object2.matrix) === false) {
8208
+ nodeDef.matrix = object2.matrix.elements;
7947
8209
  }
7948
8210
  }
7949
- if (object.name !== "") nodeDef.name = String(object.name);
7950
- this.serializeUserData(object, nodeDef);
7951
- if (object.isMesh || object.isLine || object.isPoints) {
7952
- const meshIndex = await this.processMeshAsync(object);
8211
+ if (object2.name !== "") nodeDef.name = String(object2.name);
8212
+ this.serializeUserData(object2, nodeDef);
8213
+ if (object2.isMesh || object2.isLine || object2.isPoints) {
8214
+ const meshIndex = await this.processMeshAsync(object2);
7953
8215
  if (meshIndex !== null) nodeDef.mesh = meshIndex;
7954
- } else if (object.isCamera) {
7955
- nodeDef.camera = this.processCamera(object);
8216
+ } else if (object2.isCamera) {
8217
+ nodeDef.camera = this.processCamera(object2);
7956
8218
  }
7957
- if (object.isSkinnedMesh) this.skins.push(object);
8219
+ if (object2.isSkinnedMesh) this.skins.push(object2);
7958
8220
  const nodeIndex = json.nodes.push(nodeDef) - 1;
7959
- nodeMap.set(object, nodeIndex);
7960
- if (object.children.length > 0) {
8221
+ nodeMap.set(object2, nodeIndex);
8222
+ if (object2.children.length > 0) {
7961
8223
  const children = [];
7962
- for (let i = 0, l = object.children.length; i < l; i++) {
7963
- const child = object.children[i];
8224
+ for (let i = 0, l = object2.children.length; i < l; i++) {
8225
+ const child = object2.children[i];
7964
8226
  if (child.visible || options.onlyVisible === false) {
7965
8227
  const childNodeIndex = await this.processNodeAsync(child);
7966
8228
  if (childNodeIndex !== null) children.push(childNodeIndex);
@@ -7969,7 +8231,7 @@ var GLTFWriter = class {
7969
8231
  if (children.length > 0) nodeDef.children = children;
7970
8232
  }
7971
8233
  await this._invokeAllAsync(function(ext) {
7972
- ext.writeNode && ext.writeNode(object, nodeDef);
8234
+ ext.writeNode && ext.writeNode(object2, nodeDef);
7973
8235
  });
7974
8236
  return nodeIndex;
7975
8237
  }
@@ -7978,19 +8240,19 @@ var GLTFWriter = class {
7978
8240
  * @param {THREE.Object3D} object Object3D with pivot
7979
8241
  * @return {Promise<number>} Index of the container node
7980
8242
  */
7981
- async _processNodeWithPivotAsync(object) {
8243
+ async _processNodeWithPivotAsync(object2) {
7982
8244
  const json = this.json;
7983
8245
  const options = this.options;
7984
8246
  const nodeMap = this.nodeMap;
7985
- const pivot = object.pivot;
8247
+ const pivot = object2.pivot;
7986
8248
  const containerDef = {};
7987
- const rotation = object.quaternion.toArray();
8249
+ const rotation = object2.quaternion.toArray();
7988
8250
  const position = [
7989
- object.position.x + pivot.x,
7990
- object.position.y + pivot.y,
7991
- object.position.z + pivot.z
8251
+ object2.position.x + pivot.x,
8252
+ object2.position.y + pivot.y,
8253
+ object2.position.z + pivot.z
7992
8254
  ];
7993
- const scale = object.scale.toArray();
8255
+ const scale = object2.scale.toArray();
7994
8256
  if (!equalArray(rotation, [0, 0, 0, 1])) {
7995
8257
  containerDef.rotation = rotation;
7996
8258
  }
@@ -8001,28 +8263,28 @@ var GLTFWriter = class {
8001
8263
  containerDef.scale = scale;
8002
8264
  }
8003
8265
  containerDef.extras = { pivot: pivot.toArray() };
8004
- if (object.name !== "") containerDef.name = String(object.name);
8005
- this.serializeUserData(object, containerDef);
8266
+ if (object2.name !== "") containerDef.name = String(object2.name);
8267
+ this.serializeUserData(object2, containerDef);
8006
8268
  const containerIndex = json.nodes.push(containerDef) - 1;
8007
- nodeMap.set(object, containerIndex);
8269
+ nodeMap.set(object2, containerIndex);
8008
8270
  const childDef = {};
8009
8271
  const childPosition = [-pivot.x, -pivot.y, -pivot.z];
8010
8272
  if (!equalArray(childPosition, [0, 0, 0])) {
8011
8273
  childDef.translation = childPosition;
8012
8274
  }
8013
- if (object.isMesh || object.isLine || object.isPoints) {
8014
- const meshIndex = await this.processMeshAsync(object);
8275
+ if (object2.isMesh || object2.isLine || object2.isPoints) {
8276
+ const meshIndex = await this.processMeshAsync(object2);
8015
8277
  if (meshIndex !== null) childDef.mesh = meshIndex;
8016
- } else if (object.isCamera) {
8017
- childDef.camera = this.processCamera(object);
8278
+ } else if (object2.isCamera) {
8279
+ childDef.camera = this.processCamera(object2);
8018
8280
  }
8019
- if (object.isSkinnedMesh) this.skins.push(object);
8281
+ if (object2.isSkinnedMesh) this.skins.push(object2);
8020
8282
  const childIndex = json.nodes.push(childDef) - 1;
8021
8283
  const containerChildren = [childIndex];
8022
- if (object.children.length > 0) {
8284
+ if (object2.children.length > 0) {
8023
8285
  const grandchildren = [];
8024
- for (let i = 0, l = object.children.length; i < l; i++) {
8025
- const child = object.children[i];
8286
+ for (let i = 0, l = object2.children.length; i < l; i++) {
8287
+ const child = object2.children[i];
8026
8288
  if (child.visible || options.onlyVisible === false) {
8027
8289
  const childNodeIndex = await this.processNodeAsync(child);
8028
8290
  if (childNodeIndex !== null) grandchildren.push(childNodeIndex);
@@ -8032,7 +8294,7 @@ var GLTFWriter = class {
8032
8294
  }
8033
8295
  containerDef.children = containerChildren;
8034
8296
  await this._invokeAllAsync(function(ext) {
8035
- ext.writeNode && ext.writeNode(object, containerDef);
8297
+ ext.writeNode && ext.writeNode(object2, containerDef);
8036
8298
  });
8037
8299
  return containerIndex;
8038
8300
  }
@@ -8475,10 +8737,10 @@ var GLTFMeshGpuInstancing = class {
8475
8737
  this.writer = writer;
8476
8738
  this.name = "EXT_mesh_gpu_instancing";
8477
8739
  }
8478
- writeNode(object, nodeDef) {
8479
- if (!object.isInstancedMesh) return;
8740
+ writeNode(object2, nodeDef) {
8741
+ if (!object2.isInstancedMesh) return;
8480
8742
  const writer = this.writer;
8481
- const mesh = object;
8743
+ const mesh = object2;
8482
8744
  const translationAttr = new Float32Array(mesh.count * 3);
8483
8745
  const rotationAttr = new Float32Array(mesh.count * 4);
8484
8746
  const scaleAttr = new Float32Array(mesh.count * 3);
@@ -8668,8 +8930,8 @@ var SceneExporter = class {
8668
8930
  }
8669
8931
  }
8670
8932
  };
8671
- function localMatrix(object) {
8672
- return object.matrixAutoUpdate ? new Matrix47().compose(object.position, object.quaternion, object.scale) : object.matrix.clone();
8933
+ function localMatrix(object2) {
8934
+ return object2.matrixAutoUpdate ? new Matrix47().compose(object2.position, object2.quaternion, object2.scale) : object2.matrix.clone();
8673
8935
  }
8674
8936
  function createSnapshot(root, gltf, bakeColors = false) {
8675
8937
  const scene = new Scene3();
@@ -8773,10 +9035,10 @@ function createSnapshot(root, gltf, bakeColors = false) {
8773
9035
  scene.add(copy);
8774
9036
  }
8775
9037
  };
8776
- const visit = (object, parentWorld) => {
8777
- if (!object.visible) return;
8778
- const world = parentWorld.clone().multiply(localMatrix(object));
8779
- const mesh = object;
9038
+ const visit = (object2, parentWorld) => {
9039
+ if (!object2.visible) return;
9040
+ const world = parentWorld.clone().multiply(localMatrix(object2));
9041
+ const mesh = object2;
8780
9042
  if (mesh.isMesh) {
8781
9043
  const instanced = mesh;
8782
9044
  if (instanced.isInstancedMesh) {
@@ -8790,7 +9052,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
8790
9052
  addMesh(mesh, world);
8791
9053
  }
8792
9054
  }
8793
- for (const child of object.children) visit(child, world);
9055
+ for (const child of object2.children) visit(child, world);
8794
9056
  };
8795
9057
  try {
8796
9058
  const ancestors = [];
@@ -9022,11 +9284,11 @@ var GuiHelper = class {
9022
9284
  switch (recipe.type) {
9023
9285
  case "minecraft:crafting_shaped":
9024
9286
  case "crafting_shaped": {
9025
- const pattern = recipe.pattern;
9026
- if (!pattern.length || pattern.length > 3 || !pattern[0].length || pattern[0].length > 3 || pattern.some((row) => row.length !== pattern[0].length)) {
9287
+ const pattern2 = recipe.pattern;
9288
+ if (!pattern2.length || pattern2.length > 3 || !pattern2[0].length || pattern2[0].length > 3 || pattern2.some((row) => row.length !== pattern2[0].length)) {
9027
9289
  throw new Error("Crafting patterns must be rectangular, with 1\u20133 rows and columns");
9028
9290
  }
9029
- const cells = pattern.flatMap((row, y) => row.split("").map((symbol, x) => ({ symbol, x, y }))).filter((cell) => cell.symbol !== " ");
9291
+ const cells = pattern2.flatMap((row, y) => row.split("").map((symbol, x) => ({ symbol, x, y }))).filter((cell) => cell.symbol !== " ");
9030
9292
  if (!cells.length) throw new Error("Crafting patterns must contain an ingredient");
9031
9293
  const minX = Math.min(...cells.map((cell) => cell.x)), maxX = Math.max(...cells.map((cell) => cell.x));
9032
9294
  const minY = Math.min(...cells.map((cell) => cell.y)), maxY = Math.max(...cells.map((cell) => cell.y));
@@ -9438,29 +9700,29 @@ var SceneInspector = class {
9438
9700
  this.objectControlsContainer.innerHTML = "";
9439
9701
  this.addControls(targetObject, targetIntersection, instance);
9440
9702
  }
9441
- addControls(object, intersection, instance) {
9703
+ addControls(object2, intersection, instance) {
9442
9704
  const container = document.createElement("div");
9443
9705
  container.append(this.separator("Select Parent/Child"));
9444
- if (object.parent) {
9445
- container.append(this.buttonControl("Select Parent " + object.parent.constructor.name + " " + object.parent.name, "P", () => {
9446
- this.selectObject(object.parent, intersection, instance);
9706
+ if (object2.parent) {
9707
+ container.append(this.buttonControl("Select Parent " + object2.parent.constructor.name + " " + object2.parent.name, "P", () => {
9708
+ this.selectObject(object2.parent, intersection, instance);
9447
9709
  }));
9448
9710
  }
9449
- if (object.children.length > 0) {
9711
+ if (object2.children.length > 0) {
9450
9712
  let i = 1;
9451
- for (let child of object.children) {
9713
+ for (let child of object2.children) {
9452
9714
  container.append(this.buttonControl("Select Child " + child.constructor.name + " " + child.name, "C" + i++, () => {
9453
9715
  this.selectObject(child, intersection, instance);
9454
9716
  }));
9455
9717
  }
9456
9718
  }
9457
9719
  container.append(this.separator());
9458
- const selectedInstance = instance && (object === instance.instanceable || object === intersection?.object) ? instance : void 0;
9720
+ const selectedInstance = instance && (object2 === instance.instanceable || object2 === intersection?.object) ? instance : void 0;
9459
9721
  if (!selectedInstance) {
9460
- container.append(this.toggleControl("Visibility", "V", object.visible, (v) => object.visible = v));
9722
+ container.append(this.toggleControl("Visibility", "V", object2.visible, (v) => object2.visible = v));
9461
9723
  }
9462
9724
  container.append(this.separator("Mesh"));
9463
- this.addObjectControls(object, intersection, container, selectedInstance);
9725
+ this.addObjectControls(object2, intersection, container, selectedInstance);
9464
9726
  container.append(this.separator());
9465
9727
  this.objectControlsContainer.append(container);
9466
9728
  }
@@ -10026,8 +10288,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
10026
10288
  return false;
10027
10289
  }
10028
10290
  return this._models.some((model) => {
10029
- const object = isInstanceReference(model) ? model.instanceable : model;
10030
- return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
10291
+ const object2 = isInstanceReference(model) ? model.instanceable : model;
10292
+ return object2.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
10031
10293
  });
10032
10294
  }
10033
10295
  getModelMatrix(model) {
@@ -10036,8 +10298,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
10036
10298
  return model.matrix.clone();
10037
10299
  }
10038
10300
  getModelCullMask(model, worldMask) {
10039
- const object = isInstanceReference(model) ? model.instanceable : model;
10040
- if (object.options.displayPosition) return 0;
10301
+ const object2 = isInstanceReference(model) ? model.instanceable : model;
10302
+ if (object2.options.displayPosition) return 0;
10041
10303
  const position = new Vector312();
10042
10304
  const rotation = new Quaternion5();
10043
10305
  const scale = new Vector312();
@@ -10054,14 +10316,14 @@ var _BlockObject = class _BlockObject extends SceneObject {
10054
10316
  replacements.push(model);
10055
10317
  continue;
10056
10318
  }
10057
- const object = isInstanceReference(model) ? model.instanceable : model;
10319
+ const object2 = isInstanceReference(model) ? model.instanceable : model;
10058
10320
  const cullMask = this.getModelCullMask(model, worldMask);
10059
- if (cullMask === (object.options.cullMask ?? 0)) {
10321
+ if (cullMask === (object2.options.cullMask ?? 0)) {
10060
10322
  replacements.push(model);
10061
10323
  continue;
10062
10324
  }
10063
10325
  const matrix = this.getModelMatrix(model);
10064
- const replacement = await this.scene.addModel(object.originalModel, { ...object.options, cullMask });
10326
+ const replacement = await this.scene.addModel(object2.originalModel, { ...object2.options, cullMask });
10065
10327
  replacements.push(replacement);
10066
10328
  if (isInstanceReference(replacement)) {
10067
10329
  replacement.setMatrix(matrix);
@@ -10069,8 +10331,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
10069
10331
  replacement.matrix.copy(matrix);
10070
10332
  replacement.matrixWorldNeedsUpdate = true;
10071
10333
  matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
10072
- replacement.matrixAutoUpdate = object.matrixAutoUpdate;
10073
- replacement.visible = object.visible;
10334
+ replacement.matrixAutoUpdate = object2.matrixAutoUpdate;
10335
+ replacement.visible = object2.visible;
10074
10336
  }
10075
10337
  }
10076
10338
  } catch (error) {
@@ -11992,9 +12254,9 @@ var SchematicParser = class {
11992
12254
  * Parses a legacy schematic using custom mappings before the bundled defaults.
11993
12255
  * Keys are `id:metadata`; values are block states such as `minecraft:oak_log[axis=x]`.
11994
12256
  */
11995
- static async parse(nbt, customMappings = {}) {
12257
+ static async parse(nbt, customMappings = {}, options = {}) {
11996
12258
  const tags = nbt.value;
11997
- if (tags.Materials?.type !== "string" || tags.Materials.value !== "Alpha") {
12259
+ if (!options.lenient && (tags.Materials?.type !== "string" || tags.Materials.value !== "Alpha")) {
11998
12260
  throw new MineRenderError("Schematic Materials must be Alpha");
11999
12261
  }
12000
12262
  const size = ["Width", "Height", "Length"].map((name) => {
@@ -12035,8 +12297,16 @@ var SchematicParser = class {
12035
12297
  const id = high << 8 | ids.value[index] & 255;
12036
12298
  const metadata = data.value[index] & 255;
12037
12299
  const key = `${id}:${metadata}`;
12038
- const mapped = customMappings[key] ?? mapping[key];
12039
- if (!mapped) throw new MineRenderError(`Unsupported legacy block ${id}:${metadata} at schematic index ${index}`);
12300
+ let mapped = customMappings[key] ?? mapping[key];
12301
+ if (!mapped && options.lenient) {
12302
+ mapped = customMappings[`${id}:0`] ?? mapping[`${id}:0`];
12303
+ }
12304
+ if (!mapped) {
12305
+ if (options.lenient) {
12306
+ continue;
12307
+ }
12308
+ throw new MineRenderError(`Unsupported legacy block ${id}:${metadata} at schematic index ${index}`);
12309
+ }
12040
12310
  const [type, state] = mapped.split("[");
12041
12311
  if (type === "minecraft:air") continue;
12042
12312
  const properties = {};
@@ -13194,53 +13464,53 @@ var _MineRenderScene = class _MineRenderScene extends Scene4 {
13194
13464
  this.options = (0, import_ts_deepmerge8.default)({}, _MineRenderScene.DEFAULT_OPTIONS, options ?? {});
13195
13465
  }
13196
13466
  add(...objects) {
13197
- for (const object of objects) {
13467
+ for (const object2 of objects) {
13198
13468
  this.dirty = true;
13199
13469
  try {
13200
- super.add(object);
13470
+ super.add(object2);
13201
13471
  } finally {
13202
- if (object?.isObject3D && object !== this) {
13203
- this.updateObjectRegistration(object, object.parent === this);
13472
+ if (object2?.isObject3D && object2 !== this) {
13473
+ this.updateObjectRegistration(object2, object2.parent === this);
13204
13474
  }
13205
13475
  }
13206
13476
  }
13207
13477
  return this;
13208
13478
  }
13209
13479
  remove(...objects) {
13210
- for (const object of objects) {
13211
- if (!this.children.includes(object)) continue;
13480
+ for (const object2 of objects) {
13481
+ if (!this.children.includes(object2)) continue;
13212
13482
  this.dirty = true;
13213
- this.updateObjectRegistration(object, false);
13483
+ this.updateObjectRegistration(object2, false);
13214
13484
  try {
13215
- super.remove(object);
13485
+ super.remove(object2);
13216
13486
  } finally {
13217
- this.updateObjectRegistration(object, object.parent === this);
13487
+ this.updateObjectRegistration(object2, object2.parent === this);
13218
13488
  }
13219
13489
  }
13220
13490
  return this;
13221
13491
  }
13222
- updateObjectRegistration(object, attached) {
13223
- if (this.observedObjects.has(object) === attached) return;
13224
- const observable = object;
13492
+ updateObjectRegistration(object2, attached) {
13493
+ if (this.observedObjects.has(object2) === attached) return;
13494
+ const observable = object2;
13225
13495
  if (attached) {
13226
- this.observedObjects.add(object);
13496
+ this.observedObjects.add(object2);
13227
13497
  observable.addEventListener("change", this.onObjectChange);
13228
13498
  } else {
13229
- this.observedObjects.delete(object);
13499
+ this.observedObjects.delete(object2);
13230
13500
  observable.removeEventListener("change", this.onObjectChange);
13231
13501
  }
13232
13502
  const change = attached ? 1 : -1;
13233
13503
  this.stats.objectCount += change;
13234
- if (isSceneObject(object)) {
13504
+ if (isSceneObject(object2)) {
13235
13505
  this.stats.sceneObjectCount += change;
13236
13506
  }
13237
13507
  }
13238
- async initAndAdd(...object) {
13508
+ async initAndAdd(...object2) {
13239
13509
  this.dirty = true;
13240
- for (let obj of object) {
13510
+ for (let obj of object2) {
13241
13511
  await obj.init();
13242
13512
  }
13243
- return this.add(...object);
13513
+ return this.add(...object2);
13244
13514
  }
13245
13515
  async addSceneObject(asset, objectSupplier, _options, parent = this) {
13246
13516
  this.dirty = true;
@@ -13329,11 +13599,11 @@ var _changeEvent = { type: "change" };
13329
13599
  var _startEvent = { type: "start" };
13330
13600
  var _endEvent = { type: "end" };
13331
13601
  var OrbitControls = class extends EventDispatcher {
13332
- constructor(object, domElement) {
13602
+ constructor(object2, domElement) {
13333
13603
  super();
13334
13604
  if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
13335
13605
  if (domElement === document) console.error('THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.');
13336
- this.object = object;
13606
+ this.object = object2;
13337
13607
  this.domElement = domElement;
13338
13608
  this.domElement.style.touchAction = "none";
13339
13609
  this.enabled = true;
@@ -13390,7 +13660,7 @@ var OrbitControls = class extends EventDispatcher {
13390
13660
  };
13391
13661
  this.update = function() {
13392
13662
  const offset = new Vector313();
13393
- const quat = new Quaternion6().setFromUnitVectors(object.up, new Vector313(0, 1, 0));
13663
+ const quat = new Quaternion6().setFromUnitVectors(object2.up, new Vector313(0, 1, 0));
13394
13664
  const quatInverse = quat.clone().invert();
13395
13665
  const lastPosition = new Vector313();
13396
13666
  const lastQuaternion = new Quaternion6();
@@ -13955,8 +14225,8 @@ var OrbitControls = class extends EventDispatcher {
13955
14225
  }
13956
14226
  };
13957
14227
  var MapControls = class extends OrbitControls {
13958
- constructor(object, domElement) {
13959
- super(object, domElement);
14228
+ constructor(object2, domElement) {
14229
+ super(object2, domElement);
13960
14230
  this.screenSpacePanning = false;
13961
14231
  this.mouseButtons.LEFT = MOUSE.PAN;
13962
14232
  this.mouseButtons.RIGHT = MOUSE.ROTATE;
@@ -14883,16 +15153,16 @@ var SectionModels = class {
14883
15153
  if (!models) this.models.set(model, models = /* @__PURE__ */ new Map());
14884
15154
  const key = JSON.stringify([rotation.x, rotation.y, rotation.z, variant.uvlock, tints]);
14885
15155
  const template = await cached(models, key, async () => {
14886
- const object = new SectionModel(model, {
15156
+ const object2 = new SectionModel(model, {
14887
15157
  instanceMeshes: false,
14888
15158
  mergeMeshes: false,
14889
15159
  tints,
14890
15160
  uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
14891
15161
  });
14892
- await object.init();
14893
- const geometry = object.children[0].geometry;
15162
+ await object2.init();
15163
+ const geometry = object2.children[0].geometry;
14894
15164
  geometry.applyMatrix4(new Matrix412().makeRotationFromEuler(rotation));
14895
- object.clear();
15165
+ object2.clear();
14896
15166
  const cullFaces = CUBE_FACES.map((face) => {
14897
15167
  const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
14898
15168
  if (local < 0) return 0;
@@ -15080,10 +15350,10 @@ var MineRenderWorld = class {
15080
15350
  await block.object.updateFluid((x, y, z) => {
15081
15351
  const neighbor = pos.clone().add(new Vector316(x, y, z));
15082
15352
  const section = this.getChunkAt(neighbor);
15083
- const object = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
15353
+ const object2 = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
15084
15354
  return {
15085
- fluid: object?.fluidKind,
15086
- level: object?.fluidLevel,
15355
+ fluid: object2?.fluidKind,
15356
+ level: object2?.fluidLevel,
15087
15357
  solid: section?.isOccludingAt(neighbor) ?? false
15088
15358
  };
15089
15359
  });
@@ -15203,14 +15473,17 @@ var SectionMesh = class _SectionMesh extends Group2 {
15203
15473
  for (const { atlas, x, y } of page.placements) {
15204
15474
  context.drawImage(atlas.image.canvas, x, y);
15205
15475
  }
15206
- const positions = [], normals = [], uvs = [], colors = [], indices = [];
15476
+ const positions = [], normals = [], uvs = [], uvBounds = [], colors = [], indices = [];
15207
15477
  for (const { index, template, cullMask } of page.entries) {
15208
15478
  const position = template.geometry.getAttribute("position");
15209
15479
  const normal = template.geometry.getAttribute("normal");
15210
15480
  const uv = template.geometry.getAttribute("uv");
15481
+ const bounds = template.geometry.getAttribute("uvBounds");
15211
15482
  const color = template.geometry.getAttribute("color");
15212
15483
  const sourceIndices = template.geometry.getIndex();
15213
15484
  const placement = locations.get(template.atlas).placement;
15485
+ const mapU = (u) => (placement.x + u * template.atlas.image.width) / page.width;
15486
+ const mapV = (v) => 1 - (placement.y + (1 - v) * template.atlas.image.height) / page.height;
15214
15487
  const offsetX = index % 16 * 16;
15215
15488
  const offsetY = Math.floor(index / 256) * 16;
15216
15489
  const offsetZ = Math.floor(index / 16) % 16 * 16;
@@ -15221,9 +15494,12 @@ var SectionMesh = class _SectionMesh extends Group2 {
15221
15494
  const vertex = face * 4 + corner;
15222
15495
  positions.push(position.getX(vertex) + offsetX, position.getY(vertex) + offsetY, position.getZ(vertex) + offsetZ);
15223
15496
  normals.push(normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex));
15224
- uvs.push(
15225
- (placement.x + uv.getX(vertex) * template.atlas.image.width) / page.width,
15226
- 1 - (placement.y + (1 - uv.getY(vertex)) * template.atlas.image.height) / page.height
15497
+ uvs.push(mapU(uv.getX(vertex)), mapV(uv.getY(vertex)));
15498
+ uvBounds.push(
15499
+ mapU(bounds?.getX(vertex) ?? 0),
15500
+ mapV(bounds?.getY(vertex) ?? 0),
15501
+ mapU(bounds?.getZ(vertex) ?? 1),
15502
+ mapV(bounds?.getW(vertex) ?? 1)
15227
15503
  );
15228
15504
  colors.push(color?.getX(vertex) ?? 1, color?.getY(vertex) ?? 1, color?.getZ(vertex) ?? 1);
15229
15505
  }
@@ -15234,11 +15510,12 @@ var SectionMesh = class _SectionMesh extends Group2 {
15234
15510
  geometry.setAttribute("position", new Float32BufferAttribute8(positions, 3));
15235
15511
  geometry.setAttribute("normal", new Float32BufferAttribute8(normals, 3));
15236
15512
  geometry.setAttribute("uv", new Float32BufferAttribute8(uvs, 2));
15513
+ geometry.setAttribute("uvBounds", new Float32BufferAttribute8(uvBounds, 4));
15237
15514
  geometry.setAttribute("color", new Float32BufferAttribute8(colors, 3));
15238
15515
  geometry.setIndex(indices);
15239
15516
  geometry.computeBoundingBox();
15240
15517
  geometry.computeBoundingSphere();
15241
- const material = Materials.createShadedCanvasMaterial(canvas, false);
15518
+ const material = Materials.createShadedCanvasMaterial(canvas, false, false, true);
15242
15519
  material.vertexColors = true;
15243
15520
  const texture = material.uniforms?.map?.value ?? material.map;
15244
15521
  const mesh = new Mesh9(geometry, material);
@@ -15312,7 +15589,7 @@ var Chunk = class _Chunk {
15312
15589
  this.renderedBlocks.get(index)?.object?.removeFromScene();
15313
15590
  if (this.sectionBlocks.delete(index)) this.meshDirty = true;
15314
15591
  this.renderedBlocks.delete(index);
15315
- let object;
15592
+ let object2;
15316
15593
  try {
15317
15594
  if (!readBlock) return void 0;
15318
15595
  const stored = readBlock();
@@ -15327,22 +15604,22 @@ var Chunk = class _Chunk {
15327
15604
  this.sectionBlocks.set(index, { index, template, cullMask: 0 });
15328
15605
  this.meshDirty = true;
15329
15606
  } else {
15330
- object = await this.scene.addBlock(blockState, {
15607
+ object2 = await this.scene.addBlock(blockState, {
15331
15608
  mergeMeshes: true,
15332
15609
  instanceMeshes: true,
15333
15610
  maxInstanceCount: 2e3,
15334
15611
  initialState: stored.properties
15335
15612
  });
15336
- object.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
15613
+ object2.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
15337
15614
  }
15338
15615
  const info = { get block() {
15339
15616
  return readBlock();
15340
- }, object };
15617
+ }, object: object2 };
15341
15618
  this.renderedBlocks.set(index, info);
15342
15619
  return info;
15343
15620
  } catch (error) {
15344
15621
  this.data.set(index, void 0);
15345
- object?.removeFromScene();
15622
+ object2?.removeFromScene();
15346
15623
  throw error;
15347
15624
  } finally {
15348
15625
  await onBlocksChanged?.([worldPos]);
@@ -15515,6 +15792,8 @@ export {
15515
15792
  Models,
15516
15793
  NBTHelper,
15517
15794
  OrbitControls,
15795
+ PackFormats,
15796
+ PackMetadata,
15518
15797
  PersistentCache,
15519
15798
  Renderer,
15520
15799
  RequestError,