minerender 2.1.0-alpha.136 → 2.1.0-alpha.138

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/browser/esm/Materials.mjs +3 -1
  2. package/dist/browser/esm/Materials.mjs.map +1 -1
  3. package/dist/browser/esm/Ticker.mjs +3 -1
  4. package/dist/browser/esm/Ticker.mjs.map +1 -1
  5. package/dist/browser/esm/UVMapper.mjs +9 -9
  6. package/dist/browser/esm/UVMapper.mjs.map +1 -1
  7. package/dist/browser/esm/assets/AssetLoader.mjs +4 -4
  8. package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
  9. package/dist/browser/esm/assets/BlockEntities.mjs +3 -1
  10. package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
  11. package/dist/browser/esm/assets/_fonts/Unihex.mjs +4 -2
  12. package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -1
  13. package/dist/browser/esm/assets/source/HostedAssetSource.mjs +6 -7
  14. package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
  15. package/dist/browser/esm/env/browser/BrowserCache.mjs +3 -3
  16. package/dist/browser/esm/env/browser/BrowserCache.mjs.map +1 -1
  17. package/dist/browser/esm/image/ImageLoader.mjs +3 -3
  18. package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
  19. package/dist/browser/esm/index.browser.d.mts +49 -7
  20. package/dist/browser/esm/inspector/SceneInspector.mjs +3 -3
  21. package/dist/browser/esm/inspector/SceneInspector.mjs.map +1 -1
  22. package/dist/browser/esm/instance/InstanceManager.mjs +4 -4
  23. package/dist/browser/esm/instance/InstanceManager.mjs.map +1 -1
  24. package/dist/browser/esm/model/block/scene/BlockObject.mjs +3 -1
  25. package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
  26. package/dist/browser/esm/model/scene/ModelObject.mjs +4 -4
  27. package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
  28. package/dist/browser/esm/renderer/Renderer.mjs +4 -2
  29. package/dist/browser/esm/renderer/Renderer.mjs.map +1 -1
  30. package/dist/browser/esm/renderer/SceneObject.mjs +0 -6
  31. package/dist/browser/esm/renderer/SceneObject.mjs.map +1 -1
  32. package/dist/browser/esm/request/Requests.mjs +3 -3
  33. package/dist/browser/esm/request/Requests.mjs.map +1 -1
  34. package/dist/browser/esm/skin/Skins.mjs +6 -4
  35. package/dist/browser/esm/skin/Skins.mjs.map +1 -1
  36. package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
  37. package/dist/browser/esm/texture/TextureLoader.mjs.map +1 -1
  38. package/dist/browser/esm/util/log.mjs +75 -0
  39. package/dist/browser/esm/util/log.mjs.map +1 -1
  40. package/dist/browser/esm/util/performance.mjs.map +1 -1
  41. package/dist/browser/esm/world/Chunk.mjs +8 -5
  42. package/dist/browser/esm/world/Chunk.mjs.map +1 -1
  43. package/dist/browser/esm/world/MineRenderWorld.mjs +96 -54
  44. package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
  45. package/dist/browser/esm/world/WorldStreamer.mjs +21 -20
  46. package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
  47. package/dist/browser/esm/world/_entities/WorldEntities.mjs +3 -1
  48. package/dist/browser/esm/world/_entities/WorldEntities.mjs.map +1 -1
  49. package/dist/browser/index.d.ts +49 -7
  50. package/dist/browser/index.js +566 -461
  51. package/dist/browser/index.js.map +1 -1
  52. package/dist/bundle.js +2101 -1994
  53. package/dist/bundle.js.map +1 -1
  54. package/dist/node/index.d.mts +49 -7
  55. package/dist/node/index.d.ts +49 -7
  56. package/dist/node/index.js +566 -459
  57. package/dist/node/index.js.map +1 -1
  58. package/dist/node/index.mjs +537 -431
  59. package/dist/node/index.mjs.map +1 -1
  60. package/package.json +1 -1
@@ -431,12 +431,80 @@ var init_CanvasCompat = __esm({
431
431
  });
432
432
 
433
433
  // src/util/log.ts
434
+ function readSwitch() {
435
+ switchRead = true;
436
+ let value;
437
+ if (typeof runtime.process?.versions?.node === "string") {
438
+ value = runtime.process.env?.MINERENDER_LOG;
439
+ } else {
440
+ try {
441
+ value = runtime.localStorage?.getItem("minerender:log");
442
+ } catch {
443
+ }
444
+ }
445
+ if (value) {
446
+ for (const entry of value.split(",")) {
447
+ const separator = entry.indexOf("=");
448
+ const name = separator < 0 ? void 0 : entry.slice(0, separator).trim();
449
+ const setting = (separator < 0 ? entry : entry.slice(separator + 1)).trim();
450
+ if (!Object.prototype.hasOwnProperty.call(levels, setting) || name === "") continue;
451
+ if (name === void 0) {
452
+ switchThreshold = setting;
453
+ } else {
454
+ switchNamespaces ??= /* @__PURE__ */ new Map();
455
+ switchNamespaces.set(name, setting);
456
+ }
457
+ }
458
+ }
459
+ }
460
+ function logger(namespace) {
461
+ const write = (level, args) => {
462
+ if (!switchRead) readSwitch();
463
+ if (levels[level] < levels[switchNamespaces?.get(namespace) ?? switchThreshold ?? namespaces?.get(namespace) ?? threshold]) return;
464
+ if (logHandler) {
465
+ logHandler(level, namespace, args);
466
+ return;
467
+ }
468
+ if (tagStyle === void 0) {
469
+ tagStyle = typeof runtime.process?.versions?.node === "string" ? runtime.process.stdout?.isTTY === true ? "ansi" : "plain" : "browser";
470
+ }
471
+ if (tagStyle === "browser") {
472
+ console[level](`%cMineRender%c ${namespace}`, "background:#3c8527;color:#fff;border-radius:3px;padding:0 4px", "font-weight:bold", ...args);
473
+ } else {
474
+ const color2 = colors[level];
475
+ const tag = `[minerender:${namespace}]`;
476
+ console[level](tagStyle === "ansi" ? `\x1B[${color2}m${tag}\x1B[0m` : tag, ...args);
477
+ }
478
+ };
479
+ return {
480
+ debug: (...args) => write("debug", args),
481
+ info: (...args) => write("info", args),
482
+ warn: (...args) => write("warn", args),
483
+ error: (...args) => write("error", args)
484
+ };
485
+ }
434
486
  function prefix(prefix2) {
435
487
  return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
436
488
  }
437
- var Reset, FgGreen, BgBlack;
489
+ var runtime, levels, colors, threshold, namespaces, logHandler, tagStyle, switchRead, switchThreshold, switchNamespaces, Logging, Reset, FgGreen, BgBlack;
438
490
  var init_log = __esm({
439
491
  "src/util/log.ts"() {
492
+ runtime = globalThis;
493
+ levels = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };
494
+ colors = { debug: 90, info: 36, warn: 33, error: 31 };
495
+ threshold = "warn";
496
+ switchRead = false;
497
+ Logging = class {
498
+ /** Updates the given settings and keeps the others. */
499
+ static configure(options) {
500
+ if (options.level !== void 0) threshold = options.level;
501
+ if (options.namespaces !== void 0) namespaces = new Map(Object.entries(options.namespaces));
502
+ }
503
+ /** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */
504
+ static setHandler(handler) {
505
+ logHandler = handler;
506
+ }
507
+ };
440
508
  Reset = "\x1B[0m";
441
509
  FgGreen = "\x1B[32m";
442
510
  BgBlack = "\x1B[40m";
@@ -497,11 +565,11 @@ async function abortable(promise, signal) {
497
565
  signal.removeEventListener("abort", abort);
498
566
  }
499
567
  }
500
- var p, RequestError, RequestQueue, Requests;
568
+ var log, RequestError, RequestQueue, Requests;
501
569
  var init_Requests = __esm({
502
570
  "src/request/Requests.ts"() {
503
571
  init_log();
504
- p = prefix("Requests");
572
+ log = logger("Requests");
505
573
  RequestError = class extends Error {
506
574
  constructor(message, response, cause) {
507
575
  super(message);
@@ -528,7 +596,7 @@ var init_Requests = __esm({
528
596
  try {
529
597
  return await abortable(this.queue.add(request), signal);
530
598
  } catch (error) {
531
- console.debug(p, "Request failed", error);
599
+ log.debug("Request failed", error);
532
600
  const delay = this.retryDelay(error, request, retries);
533
601
  if (delay === void 0) {
534
602
  throw error;
@@ -714,7 +782,7 @@ var init_base64 = __esm({
714
782
  });
715
783
 
716
784
  // src/image/ImageLoader.ts
717
- var p2, ImageLoader;
785
+ var log2, ImageLoader;
718
786
  var init_ImageLoader = __esm({
719
787
  "src/image/ImageLoader.ts"() {
720
788
  init_CanvasCompat();
@@ -725,7 +793,7 @@ var init_ImageLoader = __esm({
725
793
  init_WrappedImage();
726
794
  init_base64();
727
795
  init_log();
728
- p2 = prefix("ImageLoader");
796
+ log2 = logger("ImageLoader");
729
797
  ImageLoader = class _ImageLoader {
730
798
  static _createImage() {
731
799
  return createImage();
@@ -750,7 +818,7 @@ var init_ImageLoader = __esm({
750
818
  return image;
751
819
  }
752
820
  static async loadData(src) {
753
- console.debug(p2, "loadData", src);
821
+ log2.debug("loadData", src);
754
822
  const image = await this.loadCanvasData(src);
755
823
  return image.data.getImageData(0, 0, image.width, image.height);
756
824
  }
@@ -859,11 +927,13 @@ var init_ImageLoader = __esm({
859
927
  // src/texture/TextureLoader.ts
860
928
  import { RGBAFormat, Texture } from "three";
861
929
  import * as THREE from "three";
862
- var TextureLoader;
930
+ var log3, TextureLoader;
863
931
  var init_TextureLoader = __esm({
864
932
  "src/texture/TextureLoader.ts"() {
865
933
  init_ImageLoader();
866
934
  init_Textures();
935
+ init_log();
936
+ log3 = logger("TextureLoader");
867
937
  TextureLoader = class {
868
938
  static {
869
939
  this.failedTextures = /* @__PURE__ */ new WeakSet();
@@ -882,7 +952,7 @@ var init_TextureLoader = __esm({
882
952
  texture.needsUpdate = true;
883
953
  }, (error) => {
884
954
  this.failedTextures.add(texture);
885
- console.warn("Failed to load texture", src, error);
955
+ log3.warn("Failed to load texture", src, error);
886
956
  });
887
957
  texture.image = image;
888
958
  texture.format = format2;
@@ -898,7 +968,7 @@ var init_TextureLoader = __esm({
898
968
  texture.needsUpdate = true;
899
969
  }).catch((error) => {
900
970
  this.failedTextures.add(texture);
901
- console.warn("Failed to load texture", src, error);
971
+ log3.warn("Failed to load texture", src, error);
902
972
  });
903
973
  texture.format = format2;
904
974
  texture.rotation = rotation;
@@ -974,13 +1044,15 @@ var init_Textures = __esm({
974
1044
 
975
1045
  // src/Materials.ts
976
1046
  import { Color, CustomBlending, DoubleSide, OneFactor, OneMinusSrcAlphaFactor, RepeatWrapping, FrontSide, MeshBasicMaterial, MeshStandardMaterial, ShaderChunk, ShaderMaterial } from "three";
977
- var Materials;
1047
+ var log4, Materials;
978
1048
  var init_Materials = __esm({
979
1049
  "src/Materials.ts"() {
980
1050
  init_CacheKey();
981
1051
  init_Textures();
982
1052
  init_TextureLoader();
983
1053
  init_Caching();
1054
+ init_log();
1055
+ log4 = logger("Materials");
984
1056
  Materials = class _Materials {
985
1057
  /** Shared checkerboard material, created on first access. */
986
1058
  static get MISSING_TEXTURE() {
@@ -1251,7 +1323,7 @@ var init_Materials = __esm({
1251
1323
  Object.assign(material.defaultAttributeValues, { shade: [1], uvBounds: [0, 0, 1, 1] });
1252
1324
  return material;
1253
1325
  } catch (e) {
1254
- console.warn(e);
1326
+ log4.warn(e);
1255
1327
  }
1256
1328
  return this.createBasicCanvasMaterial(canvas, transparent, shade);
1257
1329
  }
@@ -1392,12 +1464,12 @@ var init_AssetKey = __esm({
1392
1464
  }
1393
1465
  /** Joins the type subdirectory and path without adding a namespace or file extension. */
1394
1466
  getFullPath() {
1395
- let p10 = [];
1467
+ let p = [];
1396
1468
  if (this.type) {
1397
- p10.push(this.type);
1469
+ p.push(this.type);
1398
1470
  }
1399
- p10.push(this.path);
1400
- return p10.join("/");
1471
+ p.push(this.path);
1472
+ return p.join("/");
1401
1473
  }
1402
1474
  toNamespacedString() {
1403
1475
  return this.namespace + ":" + this.getFullPath();
@@ -1443,182 +1515,6 @@ var init_AssetSource = __esm({
1443
1515
  }
1444
1516
  });
1445
1517
 
1446
- // src/util/BatchedExecutor.ts
1447
- import { JobQueue as JobQueue2 } from "jobqu";
1448
- var BatchedExecutor;
1449
- var init_BatchedExecutor = __esm({
1450
- "src/util/BatchedExecutor.ts"() {
1451
- BatchedExecutor = class {
1452
- /**
1453
- * @param interval - Delay between queue runs, in milliseconds.
1454
- * @param batch - Maximum tasks started per run and maximum tasks active at once.
1455
- */
1456
- constructor(interval = 1, batch = 30) {
1457
- if (!Number.isFinite(interval) || interval < 0) throw new RangeError("Batch interval must be finite and nonnegative");
1458
- if (!Number.isInteger(batch) || batch < 1) throw new RangeError("Batch size must be a positive integer");
1459
- this.interval = interval;
1460
- this.batch = batch;
1461
- this.queue = new JobQueue2(async (task) => task(), { interval, maxPerRun: batch, maxActive: batch });
1462
- }
1463
- /** Queues a task and resolves with its result, or rejects with its error. */
1464
- submit(task) {
1465
- return this.queue.add(() => task());
1466
- }
1467
- /** Rejects queued and future tasks. Tasks already running are allowed to finish. */
1468
- stop() {
1469
- this.queue.end();
1470
- }
1471
- };
1472
- }
1473
- });
1474
-
1475
- // src/util/model.ts
1476
- import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
1477
- function applyElementRotation(rotation, geometry) {
1478
- const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1479
- geometry.translate(-origin.x, -origin.y, -origin.z);
1480
- switch (rotation.axis) {
1481
- case "x" /* X */:
1482
- geometry.rotateX(toRadians(rotation.angle));
1483
- break;
1484
- case "y" /* Y */:
1485
- geometry.rotateY(toRadians(rotation.angle));
1486
- break;
1487
- case "z" /* Z */:
1488
- geometry.rotateZ(toRadians(rotation.angle));
1489
- break;
1490
- }
1491
- if (rotation.rescale) {
1492
- const angle = toRadians(rotation.angle);
1493
- const s = 1 / Math.max(Math.abs(Math.cos(angle)), Math.abs(Math.sin(angle)));
1494
- geometry.scale(
1495
- rotation.axis === "x" /* X */ ? 1 : s,
1496
- rotation.axis === "y" /* Y */ ? 1 : s,
1497
- rotation.axis === "z" /* Z */ ? 1 : s
1498
- );
1499
- }
1500
- geometry.translate(origin.x, origin.y, origin.z);
1501
- }
1502
- function applyGenericRotation(axis, rotation, obj) {
1503
- switch (axis) {
1504
- case "x" /* X */:
1505
- obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
1506
- break;
1507
- case "y" /* Y */:
1508
- obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
1509
- break;
1510
- case "z" /* Z */:
1511
- obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
1512
- break;
1513
- }
1514
- }
1515
- function addBox3WireframeToObject(box, obj, color2 = 16777215, w = 2) {
1516
- let size = new Vector32();
1517
- box.getSize(size);
1518
- let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
1519
- let wireGeo = new EdgesGeometry(boxGeo);
1520
- let wireMat = new LineBasicMaterial({ color: color2, linewidth: w });
1521
- let wireframe = new LineSegments(wireGeo, wireMat);
1522
- obj.add(wireframe);
1523
- let axes = new AxesHelper(1);
1524
- obj.add(axes);
1525
- }
1526
- function addWireframeToObject(obj, color2 = 16777215, w = 2) {
1527
- let boxGeo = new BoxGeometry2(16, 16, 16, 1, 1, 1);
1528
- let wireGeo = new EdgesGeometry(boxGeo);
1529
- let wireMat = new LineBasicMaterial({ color: color2, linewidth: w });
1530
- let wireframe = new LineSegments(wireGeo, wireMat);
1531
- obj.add(wireframe);
1532
- let axes = new AxesHelper(1);
1533
- obj.add(axes);
1534
- }
1535
- function addWireframeToMesh(geo, mesh, color2 = 16777215, w = 2) {
1536
- let wireGeo = new EdgesGeometry(geo);
1537
- let wireMat = new LineBasicMaterial({ color: color2, linewidth: w });
1538
- let wireframe = new LineSegments(wireGeo, wireMat);
1539
- mesh.add(wireframe);
1540
- let axes = new AxesHelper(1);
1541
- mesh.add(axes);
1542
- return () => {
1543
- wireGeo.dispose();
1544
- wireMat.dispose();
1545
- axes.dispose();
1546
- };
1547
- }
1548
- var init_model = __esm({
1549
- "src/util/model.ts"() {
1550
- init_Axis();
1551
- init_util();
1552
- }
1553
- });
1554
-
1555
- // src/util/performance.ts
1556
- function captureException(e, ...extra) {
1557
- console.error(e, extra);
1558
- }
1559
- function timingStart(marker) {
1560
- console.time(marker);
1561
- }
1562
- function timingEnd(marker) {
1563
- console.timeEnd(marker);
1564
- }
1565
- var init_performance = __esm({
1566
- "src/util/performance.ts"() {
1567
- }
1568
- });
1569
-
1570
- // src/util/sha.ts
1571
- import SHA1 from "crypto-js/sha1.js";
1572
- import SHA256 from "crypto-js/sha256.js";
1573
- import SHA512 from "crypto-js/sha512.js";
1574
- function sha1(str) {
1575
- return SHA1(str).toString();
1576
- }
1577
- function sha256(str) {
1578
- return SHA256(str).toString();
1579
- }
1580
- function sha512(str) {
1581
- return SHA512(str).toString();
1582
- }
1583
- var init_sha = __esm({
1584
- "src/util/sha.ts"() {
1585
- }
1586
- });
1587
-
1588
- // src/util/three.ts
1589
- function isObject3D(obj) {
1590
- return obj.isObject3D;
1591
- }
1592
- function isMesh(obj) {
1593
- return obj.isMesh;
1594
- }
1595
- function isInstancedMesh(obj) {
1596
- return obj.isInstancedMesh;
1597
- }
1598
- function isPerspectiveCamera(obj) {
1599
- return obj.isPerspectiveCamera;
1600
- }
1601
- function isOrthographicCamera(obj) {
1602
- return obj.isOrthographicCamera;
1603
- }
1604
- var init_three = __esm({
1605
- "src/util/three.ts"() {
1606
- }
1607
- });
1608
-
1609
- // src/util/index.ts
1610
- var init_util2 = __esm({
1611
- "src/util/index.ts"() {
1612
- init_BatchedExecutor();
1613
- init_log();
1614
- init_model();
1615
- init_performance();
1616
- init_sha();
1617
- init_three();
1618
- init_util();
1619
- }
1620
- });
1621
-
1622
1518
  // src/nbt/NBTHelper.ts
1623
1519
  function commonJsExports(module) {
1624
1520
  return module.default ?? module;
@@ -1704,8 +1600,8 @@ var require_dist = __commonJS({
1704
1600
  __assign = Object.assign || function(t) {
1705
1601
  for (var s, i = 1, n = arguments.length; i < n; i++) {
1706
1602
  s = arguments[i];
1707
- for (var p10 in s) if (Object.prototype.hasOwnProperty.call(s, p10))
1708
- t[p10] = s[p10];
1603
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
1604
+ t[p] = s[p];
1709
1605
  }
1710
1606
  return t;
1711
1607
  };
@@ -1797,11 +1693,11 @@ var init_merge = __esm({
1797
1693
  });
1798
1694
 
1799
1695
  // src/assets/source/HostedAssetSource.ts
1800
- var BINARY_TIMEOUT, p3, DEFAULT_OPTIONS, HostedAssetSource;
1696
+ var BINARY_TIMEOUT, log5, DEFAULT_OPTIONS, HostedAssetSource;
1801
1697
  var init_HostedAssetSource = __esm({
1802
1698
  "src/assets/source/HostedAssetSource.ts"() {
1803
1699
  init_AssetSource();
1804
- init_util2();
1700
+ init_log();
1805
1701
  init_nbt();
1806
1702
  init_image();
1807
1703
  init_AssetKey();
@@ -1811,7 +1707,7 @@ var init_HostedAssetSource = __esm({
1811
1707
  init_parser();
1812
1708
  init_merge();
1813
1709
  BINARY_TIMEOUT = 6e4;
1814
- p3 = prefix("HostedAssetSource");
1710
+ log5 = logger("HostedAssetSource");
1815
1711
  DEFAULT_OPTIONS = {
1816
1712
  retryDefaults: true
1817
1713
  };
@@ -1911,14 +1807,14 @@ var init_HostedAssetSource = __esm({
1911
1807
  return direct;
1912
1808
  }
1913
1809
  if (key.namespace !== DEFAULT_NAMESPACE) {
1914
- console.info(p3, "Retrying", key, "with default namespace");
1810
+ log5.debug("Retrying", key, "with default namespace");
1915
1811
  const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);
1916
1812
  const namespaced = await this.load(namespaceKey, parser);
1917
1813
  if (typeof namespaced !== "undefined") {
1918
1814
  return namespaced;
1919
1815
  }
1920
1816
  if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
1921
- console.info(p3, "Retrying", key, "with default root+namespace");
1817
+ log5.debug("Retrying", key, "with default root+namespace");
1922
1818
  const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
1923
1819
  const namespacedRooted = await this.load(namespacedRootedKey, parser);
1924
1820
  if (typeof namespacedRooted !== "undefined") {
@@ -1926,7 +1822,7 @@ var init_HostedAssetSource = __esm({
1926
1822
  }
1927
1823
  }
1928
1824
  } else if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
1929
- console.info(p3, "Retrying", key, "with default root");
1825
+ log5.debug("Retrying", key, "with default root");
1930
1826
  const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
1931
1827
  const rooted = await this.load(rootKey, parser);
1932
1828
  if (typeof rooted !== "undefined") {
@@ -1936,9 +1832,8 @@ var init_HostedAssetSource = __esm({
1936
1832
  return void 0;
1937
1833
  }
1938
1834
  async load(key, parser) {
1939
- console.info(p3, "Loading", key);
1940
1835
  const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
1941
- console.debug(p3, url);
1836
+ log5.debug("Loading", url);
1942
1837
  const request = { url };
1943
1838
  try {
1944
1839
  parser.config(request);
@@ -2322,7 +2217,7 @@ var init_source = __esm({
2322
2217
  });
2323
2218
 
2324
2219
  // src/assets/AssetLoader.ts
2325
- var p4, AssetLoader;
2220
+ var log6, AssetLoader;
2326
2221
  var init_AssetLoader = __esm({
2327
2222
  "src/assets/AssetLoader.ts"() {
2328
2223
  init_AssetDefaults();
@@ -2330,7 +2225,7 @@ var init_AssetLoader = __esm({
2330
2225
  init_log();
2331
2226
  init_source();
2332
2227
  init_Caching();
2333
- p4 = prefix("AssetLoader");
2228
+ log6 = logger("AssetLoader");
2334
2229
  AssetLoader = class {
2335
2230
  static {
2336
2231
  /** Default asset base URL. Use {@link setVersion} to select a Minecraft version. */
@@ -2393,11 +2288,11 @@ ${key}` : key;
2393
2288
  if (override) {
2394
2289
  const existing = this.removeSource(key);
2395
2290
  if (existing) {
2396
- console.log(p4, "Removed existing AssetSource", key);
2291
+ log6.info("Removed existing AssetSource", key);
2397
2292
  }
2398
2293
  }
2399
2294
  this._SOURCES.unshift({ key, source });
2400
- console.log(p4, "Added AssetSource", key);
2295
+ log6.info("Added AssetSource", key);
2401
2296
  }
2402
2297
  /** Removes and returns the first source with this name. Call {@link Caching.clear} to reload assets. */
2403
2298
  static removeSource(key) {
@@ -2573,9 +2468,11 @@ var init_CanvasImage = __esm({
2573
2468
  });
2574
2469
 
2575
2470
  // src/Ticker.ts
2576
- var Ticker;
2471
+ var log7, Ticker;
2577
2472
  var init_Ticker = __esm({
2578
2473
  "src/Ticker.ts"() {
2474
+ init_log();
2475
+ log7 = logger("Ticker");
2579
2476
  Ticker = class _Ticker {
2580
2477
  static {
2581
2478
  this.TPS = 20;
@@ -2614,7 +2511,7 @@ var init_Ticker = __esm({
2614
2511
  try {
2615
2512
  t();
2616
2513
  } catch (e) {
2617
- console.warn(e);
2514
+ log7.warn(e);
2618
2515
  }
2619
2516
  });
2620
2517
  _Ticker.oneSecondTicks++;
@@ -2853,8 +2750,8 @@ var init_cubeUv = __esm({
2853
2750
  });
2854
2751
 
2855
2752
  // src/UVMapper.ts
2856
- import { Float32BufferAttribute as Float32BufferAttribute2, Vector2, Vector3 as Vector33 } from "three";
2857
- var p5, X, Y, Z, FACE_UV_AXES, UVMapper, MinecraftFaceUV;
2753
+ import { Float32BufferAttribute as Float32BufferAttribute2, Vector2, Vector3 as Vector32 } from "three";
2754
+ var log8, X, Y, Z, FACE_UV_AXES, UVMapper, MinecraftFaceUV;
2858
2755
  var init_UVMapper = __esm({
2859
2756
  "src/UVMapper.ts"() {
2860
2757
  init_CubeFace();
@@ -2868,17 +2765,17 @@ var init_UVMapper = __esm({
2868
2765
  init_ModelGenerator();
2869
2766
  init_log();
2870
2767
  init_cubeUv();
2871
- p5 = prefix("UVMapper");
2768
+ log8 = logger("UVMapper");
2872
2769
  X = 0;
2873
2770
  Y = 1;
2874
2771
  Z = 2;
2875
2772
  FACE_UV_AXES = {
2876
- east: [new Vector33(0, 0, -1), new Vector33(0, -1, 0)],
2877
- west: [new Vector33(0, 0, 1), new Vector33(0, -1, 0)],
2878
- up: [new Vector33(1, 0, 0), new Vector33(0, 0, 1)],
2879
- down: [new Vector33(1, 0, 0), new Vector33(0, 0, -1)],
2880
- south: [new Vector33(1, 0, 0), new Vector33(0, -1, 0)],
2881
- north: [new Vector33(-1, 0, 0), new Vector33(0, -1, 0)]
2773
+ east: [new Vector32(0, 0, -1), new Vector32(0, -1, 0)],
2774
+ west: [new Vector32(0, 0, 1), new Vector32(0, -1, 0)],
2775
+ up: [new Vector32(1, 0, 0), new Vector32(0, 0, 1)],
2776
+ down: [new Vector32(1, 0, 0), new Vector32(0, 0, -1)],
2777
+ south: [new Vector32(1, 0, 0), new Vector32(0, -1, 0)],
2778
+ north: [new Vector32(-1, 0, 0), new Vector32(0, -1, 0)]
2882
2779
  };
2883
2780
  UVMapper = class {
2884
2781
  static makeUv(uvCoord, originalTextureSize, actualTextureSize) {
@@ -3101,7 +2998,7 @@ var init_UVMapper = __esm({
3101
2998
  model.elements = originalModel.elements.map((element) => ({ ...element }));
3102
2999
  }
3103
3000
  const isItemModel = !("elements" in model);
3104
- console.debug(p5, "Creating Atlas for", model.key);
3001
+ log8.debug("Creating Atlas for", model.key);
3105
3002
  if (model.textures) {
3106
3003
  const promises = [];
3107
3004
  const uniqueTextureNames = [];
@@ -3115,7 +3012,7 @@ var init_UVMapper = __esm({
3115
3012
  const assetKey = AssetKey.parse("textures", textureValue, model.key);
3116
3013
  promises.push(ModelTextures.get(assetKey).then((asset2) => {
3117
3014
  if (!asset2) {
3118
- console.warn(p5, "Missing texture", assetKey);
3015
+ log8.warn("Missing texture", assetKey);
3119
3016
  return;
3120
3017
  }
3121
3018
  textureMap[textureKey] = new WrappedImage(asset2);
@@ -3127,7 +3024,7 @@ var init_UVMapper = __esm({
3127
3024
  }
3128
3025
  await Promise.all(promises);
3129
3026
  const textureCount = uniqueTextureNames.length;
3130
- console.debug(p5, "Creating Atlas for", textureCount, "textures");
3027
+ log8.debug("Creating Atlas for", textureCount, "textures");
3131
3028
  this.fillMissingTextureKeys(model.textures, textureMap);
3132
3029
  this.fillMissingTextureKeys(model.textures, metaMap);
3133
3030
  const sizes = {};
@@ -3158,7 +3055,7 @@ var init_UVMapper = __esm({
3158
3055
  this.fillMissingTextureKeys(model.textures, sizes);
3159
3056
  const s = Math.ceil(Math.sqrt(textureCount + 1));
3160
3057
  const size = Math.ceil(s * maxWidth);
3161
- console.debug(p5, "Atlas size:", size);
3058
+ log8.debug("Atlas size:", size);
3162
3059
  const squaredSize = size * size;
3163
3060
  const image = new CanvasImage(size, size);
3164
3061
  const missing = Textures.getMissing().image;
@@ -3237,7 +3134,7 @@ var init_UVMapper = __esm({
3237
3134
  }
3238
3135
  this.fillMissingTextureKeys(model.textures, positions);
3239
3136
  if (isItemModel) {
3240
- console.debug(p5, "Generating item model for", model);
3137
+ log8.debug("Generating item model for", model);
3241
3138
  model.elements = [];
3242
3139
  for (let layerName of ModelGenerator.ITEM_LAYERS) {
3243
3140
  const textureImage = textureMap[layerName];
@@ -3253,7 +3150,7 @@ var init_UVMapper = __esm({
3253
3150
  ), layerName));
3254
3151
  }
3255
3152
  }
3256
- console.debug(p5, "Item model elements", model.elements);
3153
+ log8.debug("Item model elements", model.elements);
3257
3154
  }
3258
3155
  if (!model.elements) {
3259
3156
  }
@@ -3310,7 +3207,7 @@ var init_UVMapper = __esm({
3310
3207
  hasTranslucency
3311
3208
  );
3312
3209
  } else {
3313
- console.warn(p5, "Model does not have any textures", model);
3210
+ log8.warn("Model does not have any textures", model);
3314
3211
  }
3315
3212
  return void 0;
3316
3213
  }
@@ -3635,7 +3532,7 @@ var init_DisplayPosition = __esm({
3635
3532
  });
3636
3533
 
3637
3534
  // src/model/DisplayTransforms.ts
3638
- import { Euler as Euler2, Matrix4 as Matrix42, Quaternion as Quaternion2, Vector3 as Vector34 } from "three";
3535
+ import { Euler as Euler2, Matrix4, Quaternion, Vector3 as Vector33 } from "three";
3639
3536
  var DisplayTransforms;
3640
3537
  var init_DisplayTransforms = __esm({
3641
3538
  "src/model/DisplayTransforms.ts"() {
@@ -3657,7 +3554,7 @@ var init_DisplayTransforms = __esm({
3657
3554
  /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
3658
3555
  static getMatrix(display, position) {
3659
3556
  const transform = this.getTransform(display, position);
3660
- return new Matrix42().compose(transform.position, transform.quaternion, transform.scale);
3557
+ return new Matrix4().compose(transform.position, transform.quaternion, transform.scale);
3661
3558
  }
3662
3559
  /** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
3663
3560
  static getTransform(display, position) {
@@ -3665,10 +3562,10 @@ var init_DisplayTransforms = __esm({
3665
3562
  const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
3666
3563
  const sign = left ? -1 : 1;
3667
3564
  const [x, y, z] = transform.rotation ?? [0, 0, 0];
3668
- const rotation = new Quaternion2().setFromEuler(new Euler2(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
3669
- const translation = new Vector34(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
3565
+ const rotation = new Quaternion().setFromEuler(new Euler2(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
3566
+ const translation = new Vector33(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
3670
3567
  translation.x *= sign;
3671
- const scale = new Vector34(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
3568
+ const scale = new Vector33(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
3672
3569
  return { position: translation, quaternion: rotation, scale };
3673
3570
  }
3674
3571
  /** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
@@ -3712,7 +3609,7 @@ var init_ModelMerger = __esm({
3712
3609
  merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
3713
3610
  }
3714
3611
  }
3715
- merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
3612
+ merged.hierarchy = models.map((m) => m.parent).filter((p) => `${p}`);
3716
3613
  merged.hierarchy.push(`${merged.parent}`);
3717
3614
  if (model.components) merged.components = model.components;
3718
3615
  return merged;
@@ -3791,11 +3688,11 @@ var init_BannerPatterns = __esm({
3791
3688
  static async getLayers(value, target, root) {
3792
3689
  if (value === void 0) return [];
3793
3690
  if (!Array.isArray(value)) throw new Error("banner_patterns must be an array");
3794
- const colors = value.length ? await this.getColors(root) : void 0;
3691
+ const colors2 = value.length ? await this.getColors(root) : void 0;
3795
3692
  return Promise.all(value.slice(0, 16).map(async (layer) => {
3796
3693
  if (!layer || typeof layer !== "object" || Array.isArray(layer)) throw new Error("Each banner pattern requires a pattern and dye color");
3797
- if (typeof layer.color !== "string" || !Object.prototype.hasOwnProperty.call(colors, layer.color)) throw new Error(`Unsupported dye color ${layer.color}`);
3798
- const color2 = colors[layer.color];
3694
+ if (typeof layer.color !== "string" || !Object.prototype.hasOwnProperty.call(colors2, layer.color)) throw new Error(`Unsupported dye color ${layer.color}`);
3695
+ const color2 = colors2[layer.color];
3799
3696
  let pattern2 = layer.pattern;
3800
3697
  if (typeof pattern2 === "string") {
3801
3698
  const id = this.identifier(pattern2);
@@ -3904,49 +3801,49 @@ var init_ItemTints = __esm({
3904
3801
  const sources = model.tints;
3905
3802
  if (!sources?.length) return tints;
3906
3803
  const components = model.components ?? {};
3907
- const colors = { ...tints };
3804
+ const colors2 = { ...tints };
3908
3805
  await Promise.all(sources.map(async (source, index) => {
3909
- if (colors[index] !== void 0) return;
3806
+ if (colors2[index] !== void 0) return;
3910
3807
  switch (source.type) {
3911
3808
  case "constant":
3912
3809
  case "minecraft:constant":
3913
- colors[index] = this.rgb(source.value);
3810
+ colors2[index] = this.rgb(source.value);
3914
3811
  break;
3915
3812
  case "grass":
3916
3813
  case "minecraft:grass":
3917
- colors[index] = await Colormaps.grassColor(model.key, source.temperature, source.downfall);
3814
+ colors2[index] = await Colormaps.grassColor(model.key, source.temperature, source.downfall);
3918
3815
  break;
3919
3816
  case "dye":
3920
3817
  case "minecraft:dye":
3921
- colors[index] = this.colorOrDefault(components["minecraft:dyed_color"], source.default, true);
3818
+ colors2[index] = this.colorOrDefault(components["minecraft:dyed_color"], source.default, true);
3922
3819
  break;
3923
3820
  case "potion":
3924
3821
  case "minecraft:potion": {
3925
- colors[index] = await this.potionColor(components["minecraft:potion_contents"], source.default, model.key?.root);
3822
+ colors2[index] = await this.potionColor(components["minecraft:potion_contents"], source.default, model.key?.root);
3926
3823
  break;
3927
3824
  }
3928
3825
  case "map_color":
3929
3826
  case "minecraft:map_color":
3930
- colors[index] = this.colorOrDefault(components["minecraft:map_color"], source.default);
3827
+ colors2[index] = this.colorOrDefault(components["minecraft:map_color"], source.default);
3931
3828
  break;
3932
3829
  case "firework":
3933
3830
  case "minecraft:firework": {
3934
3831
  const values = this.componentField(components, "firework_explosion", "colors");
3935
3832
  if (values !== void 0 && !Array.isArray(values)) throw new MineRenderError("Item tint firework_explosion.colors must be an array");
3936
3833
  if (!values?.length) {
3937
- colors[index] = this.rgb(source.default);
3834
+ colors2[index] = this.rgb(source.default);
3938
3835
  break;
3939
3836
  }
3940
3837
  const rgb = values.map((value) => this.componentColor(value));
3941
3838
  const red = Math.floor(rgb.reduce((sum, color2) => sum + (color2 >> 16 & 255), 0) / rgb.length);
3942
3839
  const green = Math.floor(rgb.reduce((sum, color2) => sum + (color2 >> 8 & 255), 0) / rgb.length);
3943
3840
  const blue = Math.floor(rgb.reduce((sum, color2) => sum + (color2 & 255), 0) / rgb.length);
3944
- colors[index] = red << 16 | green << 8 | blue;
3841
+ colors2[index] = red << 16 | green << 8 | blue;
3945
3842
  break;
3946
3843
  }
3947
3844
  case "team":
3948
3845
  case "minecraft:team":
3949
- colors[index] = this.rgb(source.default);
3846
+ colors2[index] = this.rgb(source.default);
3950
3847
  break;
3951
3848
  case "custom_model_data":
3952
3849
  case "minecraft:custom_model_data": {
@@ -3954,14 +3851,14 @@ var init_ItemTints = __esm({
3954
3851
  if (!Number.isSafeInteger(colorIndex) || colorIndex < 0) throw new MineRenderError("Item tint custom_model_data index must be a nonnegative integer");
3955
3852
  const values = this.componentField(components, "custom_model_data", "colors");
3956
3853
  if (values !== void 0 && !Array.isArray(values)) throw new MineRenderError("Item tint custom_model_data.colors must be an array");
3957
- colors[index] = this.colorOrDefault(values?.[colorIndex], source.default, true);
3854
+ colors2[index] = this.colorOrDefault(values?.[colorIndex], source.default, true);
3958
3855
  break;
3959
3856
  }
3960
3857
  default:
3961
3858
  throw new MineRenderError(`Unsupported item tint source ${source.type}`);
3962
3859
  }
3963
3860
  }));
3964
- return colors;
3861
+ return colors2;
3965
3862
  }
3966
3863
  /** Whether a potion component contains a known effect, including effects with hidden particles. */
3967
3864
  static async hasPotionEffects(value, root) {
@@ -4535,7 +4432,7 @@ function createPermutation() {
4535
4432
  return values;
4536
4433
  }
4537
4434
  function swampGrassColor(x, z) {
4538
- const p10 = permutation ??= createPermutation();
4435
+ const p = permutation ??= createPermutation();
4539
4436
  x *= 0.0225;
4540
4437
  z *= 0.0225;
4541
4438
  const s = (x + z) * skew;
@@ -4546,7 +4443,7 @@ function swampGrassColor(x, z) {
4546
4443
  const corner = (gx, gz, a, b) => {
4547
4444
  let falloff = 0.5 - a * a - b * b;
4548
4445
  if (falloff < 0) return 0;
4549
- const gradient = gradients[p10[gx + p10[gz & 255] & 255] % 12];
4446
+ const gradient = gradients[p[gx + p[gz & 255] & 255] % 12];
4550
4447
  falloff *= falloff;
4551
4448
  return falloff * falloff * (gradient[0] * a + gradient[1] * b);
4552
4449
  };
@@ -4624,14 +4521,16 @@ var init_Biomes = __esm({
4624
4521
  });
4625
4522
 
4626
4523
  // src/assets/BlockEntities.ts
4627
- import { Matrix4 as Matrix43 } from "three";
4628
- var BlockEntities;
4524
+ import { Matrix4 as Matrix42 } from "three";
4525
+ var log9, BlockEntities;
4629
4526
  var init_BlockEntities = __esm({
4630
4527
  "src/assets/BlockEntities.ts"() {
4631
4528
  init_AssetKey();
4632
4529
  init_AssetLoader();
4633
4530
  init_source();
4634
4531
  init_Caching();
4532
+ init_log();
4533
+ log9 = logger("BlockEntities");
4635
4534
  BlockEntities = class {
4636
4535
  /**
4637
4536
  * Loads the block index of a version. Versions and sources without one yield an empty index, and so does
@@ -4645,7 +4544,7 @@ var init_BlockEntities = __esm({
4645
4544
  try {
4646
4545
  return await AssetLoader.get(key, "json" /* JSON */) ?? {};
4647
4546
  } catch (error) {
4648
- console.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
4547
+ log9.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
4649
4548
  return {};
4650
4549
  }
4651
4550
  });
@@ -4672,8 +4571,8 @@ var init_BlockEntities = __esm({
4672
4571
  return { parts, rotation, translation: entry.translation ?? [0, 0, 0] };
4673
4572
  }
4674
4573
  /** Placement in block space (0..16 per axis), applied on top of the model's own transform. */
4675
- static matrix(resolved, matrix = new Matrix43()) {
4676
- return matrix.makeTranslation(8, 0, 8).multiply(new Matrix43().makeRotationY(resolved.rotation * Math.PI / 180)).multiply(new Matrix43().makeTranslation(resolved.translation[0] - 8, resolved.translation[1], resolved.translation[2] - 8));
4574
+ static matrix(resolved, matrix = new Matrix42()) {
4575
+ return matrix.makeTranslation(8, 0, 8).multiply(new Matrix42().makeRotationY(resolved.rotation * Math.PI / 180)).multiply(new Matrix42().makeTranslation(resolved.translation[0] - 8, resolved.translation[1], resolved.translation[2] - 8));
4677
4576
  }
4678
4577
  };
4679
4578
  }
@@ -4917,7 +4816,7 @@ async function parseUnihex(key) {
4917
4816
  }
4918
4817
  return { indices, rows, metrics };
4919
4818
  } catch (error) {
4920
- console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
4819
+ log10.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
4921
4820
  return void 0;
4922
4821
  }
4923
4822
  }
@@ -4936,7 +4835,7 @@ async function loadUnihex(provider, fontKey, characters) {
4936
4835
  return { ...override, from, to };
4937
4836
  });
4938
4837
  } catch (error) {
4939
- console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
4838
+ log10.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
4940
4839
  return glyphs;
4941
4840
  }
4942
4841
  const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
@@ -4984,7 +4883,7 @@ async function loadUnihex(provider, fontKey, characters) {
4984
4883
  }
4985
4884
  return glyphs;
4986
4885
  }
4987
- var ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
4886
+ var log10, ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
4988
4887
  var init_Unihex = __esm({
4989
4888
  "src/assets/_fonts/Unihex.ts"() {
4990
4889
  init_AssetKey();
@@ -4993,6 +4892,8 @@ var init_Unihex = __esm({
4993
4892
  init_Caching();
4994
4893
  init_AssetParsers();
4995
4894
  init_CanvasCompat();
4895
+ init_log();
4896
+ log10 = logger("Unihex");
4996
4897
  ATLAS_SIZE = 512;
4997
4898
  GLYPH_HEIGHT = 16;
4998
4899
  UnihexAtlas = class {
@@ -5157,8 +5058,8 @@ var init_Fonts = __esm({
5157
5058
  });
5158
5059
 
5159
5060
  // src/entity/EntityAnimation.ts
5160
- function catmullRom(delta, p0, p1, p22, p32) {
5161
- return 0.5 * (2 * p1 + (p22 - p0) * delta + (2 * p0 - 5 * p1 + 4 * p22 - p32) * delta * delta + (3 * p1 - p0 - 3 * p22 + p32) * delta * delta * delta);
5061
+ function catmullRom(delta, p0, p1, p2, p3) {
5062
+ return 0.5 * (2 * p1 + (p2 - p0) * delta + (2 * p0 - 5 * p1 + 4 * p2 - p3) * delta * delta + (3 * p1 - p0 - 3 * p2 + p3) * delta * delta * delta);
5162
5063
  }
5163
5064
  function sampleEntityKeyframes(keyframes, time) {
5164
5065
  if (keyframes.length === 0) return [0, 0, 0];
@@ -5204,7 +5105,7 @@ var init_EntityAnimation = __esm({
5204
5105
  });
5205
5106
 
5206
5107
  // src/entity/scene/EntityAnimationPlayer.ts
5207
- import { Euler as Euler3, Vector3 as Vector35 } from "three";
5108
+ import { Euler as Euler3, Vector3 as Vector34 } from "three";
5208
5109
  function validateAnimationWeights(weights, count) {
5209
5110
  const values = Array.from(weights);
5210
5111
  if (values.length !== count || values.some((weight) => !Number.isFinite(weight) || weight < 0)) {
@@ -5280,9 +5181,9 @@ var init_EntityAnimationPlayer = __esm({
5280
5181
  position: object4.position.clone(),
5281
5182
  rotation: object4.rotation.clone(),
5282
5183
  scale: object4.scale.clone(),
5283
- basePosition: pose ? new Vector35(...pose.offset) : object4.position.clone(),
5184
+ basePosition: pose ? new Vector34(...pose.offset) : object4.position.clone(),
5284
5185
  baseRotation: pose ? new Euler3(...pose.rotation, "ZYX") : object4.rotation.clone(),
5285
- baseScale: pose ? new Vector35(...pose.scale ?? [1, 1, 1]) : object4.scale.clone()
5186
+ baseScale: pose ? new Vector34(...pose.scale ?? [1, 1, 1]) : object4.scale.clone()
5286
5187
  });
5287
5188
  }
5288
5189
  }
@@ -5418,12 +5319,33 @@ var init_InstanceReference = __esm({
5418
5319
  }
5419
5320
  });
5420
5321
 
5322
+ // src/util/three.ts
5323
+ function isObject3D(obj) {
5324
+ return obj.isObject3D;
5325
+ }
5326
+ function isMesh(obj) {
5327
+ return obj.isMesh;
5328
+ }
5329
+ function isInstancedMesh(obj) {
5330
+ return obj.isInstancedMesh;
5331
+ }
5332
+ function isPerspectiveCamera(obj) {
5333
+ return obj.isPerspectiveCamera;
5334
+ }
5335
+ function isOrthographicCamera(obj) {
5336
+ return obj.isOrthographicCamera;
5337
+ }
5338
+ var init_three = __esm({
5339
+ "src/util/three.ts"() {
5340
+ }
5341
+ });
5342
+
5421
5343
  // src/renderer/SceneObject.ts
5422
- import { Color as Color2, Euler as Euler4, InstancedBufferAttribute, InstancedMesh, Matrix4 as Matrix44, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion3, Vector3 as Vector36 } from "three";
5344
+ import { Color as Color2, Euler as Euler4, InstancedBufferAttribute, InstancedMesh, Matrix4 as Matrix43, Mesh as Mesh2, Object3D, Quaternion as Quaternion2, Vector3 as Vector35 } from "three";
5423
5345
  function isSceneObject(obj) {
5424
5346
  return obj.isSceneObject;
5425
5347
  }
5426
- var p6, SceneObject;
5348
+ var SceneObject;
5427
5349
  var init_SceneObject = __esm({
5428
5350
  "src/renderer/SceneObject.ts"() {
5429
5351
  init_Geometries();
@@ -5435,9 +5357,7 @@ var init_SceneObject = __esm({
5435
5357
  init_three();
5436
5358
  init_Disposable();
5437
5359
  init_merge();
5438
- init_log();
5439
- p6 = prefix("SceneObject");
5440
- SceneObject = class _SceneObject extends Object3D2 {
5360
+ SceneObject = class _SceneObject extends Object3D {
5441
5361
  constructor(options) {
5442
5362
  super();
5443
5363
  this.isSceneObject = true;
@@ -5448,7 +5368,6 @@ var init_SceneObject = __esm({
5448
5368
  this.freeInstanceIndices = [];
5449
5369
  this.hiddenInstanceMatrices = /* @__PURE__ */ new Map();
5450
5370
  this.options = (0, import_ts_deepmerge.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
5451
- console.log("SceneObject options", this.options);
5452
5371
  }
5453
5372
  static {
5454
5373
  this.DEFAULT_OPTIONS = (0, import_ts_deepmerge.default)({}, {
@@ -5485,13 +5404,12 @@ var init_SceneObject = __esm({
5485
5404
  this.remove(existing);
5486
5405
  }
5487
5406
  }
5488
- console.log("add", group, group.name);
5489
5407
  this.add(group);
5490
5408
  this.notifyDirty();
5491
5409
  return group;
5492
5410
  }
5493
5411
  createGroup(name, x = 0, y = 0, z = 0, offsetAxis, offset = 0) {
5494
- const obj = new Object3D2();
5412
+ const obj = new Object3D();
5495
5413
  if (name) {
5496
5414
  obj.name = `group:${name}`;
5497
5415
  }
@@ -5525,11 +5443,9 @@ var init_SceneObject = __esm({
5525
5443
  if (name) {
5526
5444
  const existing = parent.getObjectByName(mesh.name);
5527
5445
  if (existing) {
5528
- console.log("remove", existing.name, existing);
5529
5446
  parent.remove(existing);
5530
5447
  }
5531
5448
  }
5532
- console.log("add", mesh, mesh.name);
5533
5449
  parent.add(mesh);
5534
5450
  }
5535
5451
  createAndAddMesh(name, group, geometry, material, offsetAxis, offset = 0) {
@@ -5543,7 +5459,7 @@ var init_SceneObject = __esm({
5543
5459
  return mesh;
5544
5460
  }
5545
5461
  createMesh(name, geometry, material, offsetAxis, offset = 0) {
5546
- const mesh = new Mesh3(geometry, material);
5462
+ const mesh = new Mesh2(geometry, material);
5547
5463
  if (name) {
5548
5464
  mesh.name = `mesh:${name}`;
5549
5465
  }
@@ -5642,7 +5558,7 @@ var init_SceneObject = __esm({
5642
5558
  mesh.instanceColor.needsUpdate = true;
5643
5559
  }
5644
5560
  if (this._scene) this._scene.stats.instanceCount++;
5645
- this.setMatrixAt(index, new Matrix44());
5561
+ this.setMatrixAt(index, new Matrix43());
5646
5562
  return reference;
5647
5563
  }
5648
5564
  /** Returns the live reference for a raycast hit on this object's instance mesh. */
@@ -5656,7 +5572,7 @@ var init_SceneObject = __esm({
5656
5572
  if (!this.instanceReferences.has(index)) return;
5657
5573
  const mesh = this.instanceMesh;
5658
5574
  this.hiddenInstanceMatrices.delete(index);
5659
- this.setMatrixAt(index, new Matrix44().makeScale(0, 0, 0));
5575
+ this.setMatrixAt(index, new Matrix43().makeScale(0, 0, 0));
5660
5576
  this.instanceReferences.delete(index);
5661
5577
  this.freeInstanceIndices.push(index);
5662
5578
  this._instanceCounter = this.instanceReferences.size;
@@ -5686,7 +5602,7 @@ var init_SceneObject = __esm({
5686
5602
  }
5687
5603
  //</editor-fold>
5688
5604
  //<editor-fold desc="TRANSFORMATION">
5689
- getMatrixAt(index, matrix = new Matrix44()) {
5605
+ getMatrixAt(index, matrix = new Matrix43()) {
5690
5606
  if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
5691
5607
  const hidden = this.hiddenInstanceMatrices.get(index);
5692
5608
  if (hidden) {
@@ -5702,7 +5618,7 @@ var init_SceneObject = __esm({
5702
5618
  if (hidden) {
5703
5619
  hidden.copy(matrix);
5704
5620
  }
5705
- mesh.setMatrixAt(index, hidden ? new Matrix44().makeScale(0, 0, 0) : matrix);
5621
+ mesh.setMatrixAt(index, hidden ? new Matrix43().makeScale(0, 0, 0) : matrix);
5706
5622
  mesh.instanceMatrix.needsUpdate = true;
5707
5623
  mesh.boundingBox = null;
5708
5624
  mesh.boundingSphere = null;
@@ -5730,16 +5646,16 @@ var init_SceneObject = __esm({
5730
5646
  }
5731
5647
  setPositionRotationScaleAt(index, position, rotation, scale) {
5732
5648
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
5733
- const oldPosition = new Vector36();
5734
- const oldRotation = new Quaternion3();
5735
- const oldScale = new Vector36();
5736
- const matrix = new Matrix44();
5649
+ const oldPosition = new Vector35();
5650
+ const oldRotation = new Quaternion2();
5651
+ const oldScale = new Vector35();
5652
+ const matrix = new Matrix43();
5737
5653
  if (!scale || !rotation || !position) {
5738
5654
  this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
5739
5655
  }
5740
5656
  matrix.compose(
5741
5657
  position ? position : oldPosition,
5742
- rotation ? new Quaternion3().setFromEuler(rotation) : oldRotation,
5658
+ rotation ? new Quaternion2().setFromEuler(rotation) : oldRotation,
5743
5659
  scale ? scale : oldScale
5744
5660
  );
5745
5661
  this.setMatrixAt(index, matrix);
@@ -5748,7 +5664,7 @@ var init_SceneObject = __esm({
5748
5664
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
5749
5665
  this.setPositionRotationScaleAt(index, position);
5750
5666
  }
5751
- getPositionAt(index, vector = new Vector36()) {
5667
+ getPositionAt(index, vector = new Vector35()) {
5752
5668
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
5753
5669
  const matrix = this.getMatrixAt(index);
5754
5670
  vector.setFromMatrixPosition(matrix);
@@ -5760,15 +5676,15 @@ var init_SceneObject = __esm({
5760
5676
  }
5761
5677
  getRotationAt(index, euler = new Euler4()) {
5762
5678
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
5763
- const rotation = new Quaternion3();
5764
- this.getMatrixAt(index).decompose(new Vector36(), rotation, new Vector36());
5679
+ const rotation = new Quaternion2();
5680
+ this.getMatrixAt(index).decompose(new Vector35(), rotation, new Vector35());
5765
5681
  return euler.setFromQuaternion(rotation);
5766
5682
  }
5767
5683
  setScaleAt(index, scale) {
5768
5684
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
5769
5685
  this.setPositionRotationScaleAt(index, void 0, void 0, scale);
5770
5686
  }
5771
- getScaleAt(index, vector = new Vector36()) {
5687
+ getScaleAt(index, vector = new Vector35()) {
5772
5688
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
5773
5689
  const matrix = this.getMatrixAt(index);
5774
5690
  vector.setFromMatrixScale(matrix);
@@ -5900,6 +5816,86 @@ var init_SceneObject = __esm({
5900
5816
  }
5901
5817
  });
5902
5818
 
5819
+ // src/util/model.ts
5820
+ import { AxesHelper, BoxGeometry as BoxGeometry4, EdgesGeometry as EdgesGeometry2, LineBasicMaterial as LineBasicMaterial2, LineSegments as LineSegments2, Vector3 as Vector36 } from "three";
5821
+ function applyElementRotation(rotation, geometry) {
5822
+ const origin = new Vector36(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
5823
+ geometry.translate(-origin.x, -origin.y, -origin.z);
5824
+ switch (rotation.axis) {
5825
+ case "x" /* X */:
5826
+ geometry.rotateX(toRadians(rotation.angle));
5827
+ break;
5828
+ case "y" /* Y */:
5829
+ geometry.rotateY(toRadians(rotation.angle));
5830
+ break;
5831
+ case "z" /* Z */:
5832
+ geometry.rotateZ(toRadians(rotation.angle));
5833
+ break;
5834
+ }
5835
+ if (rotation.rescale) {
5836
+ const angle = toRadians(rotation.angle);
5837
+ const s = 1 / Math.max(Math.abs(Math.cos(angle)), Math.abs(Math.sin(angle)));
5838
+ geometry.scale(
5839
+ rotation.axis === "x" /* X */ ? 1 : s,
5840
+ rotation.axis === "y" /* Y */ ? 1 : s,
5841
+ rotation.axis === "z" /* Z */ ? 1 : s
5842
+ );
5843
+ }
5844
+ geometry.translate(origin.x, origin.y, origin.z);
5845
+ }
5846
+ function applyGenericRotation(axis, rotation, obj) {
5847
+ switch (axis) {
5848
+ case "x" /* X */:
5849
+ obj.rotateOnAxis(new Vector36(1, 0, 0), toRadians(rotation));
5850
+ break;
5851
+ case "y" /* Y */:
5852
+ obj.rotateOnAxis(new Vector36(0, 1, 0), toRadians(rotation));
5853
+ break;
5854
+ case "z" /* Z */:
5855
+ obj.rotateOnAxis(new Vector36(0, 0, 1), toRadians(rotation));
5856
+ break;
5857
+ }
5858
+ }
5859
+ function addBox3WireframeToObject(box, obj, color2 = 16777215, w = 2) {
5860
+ let size = new Vector36();
5861
+ box.getSize(size);
5862
+ let boxGeo = new BoxGeometry4(size.x, size.y, size.z, 1, 1, 1);
5863
+ let wireGeo = new EdgesGeometry2(boxGeo);
5864
+ let wireMat = new LineBasicMaterial2({ color: color2, linewidth: w });
5865
+ let wireframe = new LineSegments2(wireGeo, wireMat);
5866
+ obj.add(wireframe);
5867
+ let axes = new AxesHelper(1);
5868
+ obj.add(axes);
5869
+ }
5870
+ function addWireframeToObject(obj, color2 = 16777215, w = 2) {
5871
+ let boxGeo = new BoxGeometry4(16, 16, 16, 1, 1, 1);
5872
+ let wireGeo = new EdgesGeometry2(boxGeo);
5873
+ let wireMat = new LineBasicMaterial2({ color: color2, linewidth: w });
5874
+ let wireframe = new LineSegments2(wireGeo, wireMat);
5875
+ obj.add(wireframe);
5876
+ let axes = new AxesHelper(1);
5877
+ obj.add(axes);
5878
+ }
5879
+ function addWireframeToMesh(geo, mesh, color2 = 16777215, w = 2) {
5880
+ let wireGeo = new EdgesGeometry2(geo);
5881
+ let wireMat = new LineBasicMaterial2({ color: color2, linewidth: w });
5882
+ let wireframe = new LineSegments2(wireGeo, wireMat);
5883
+ mesh.add(wireframe);
5884
+ let axes = new AxesHelper(1);
5885
+ mesh.add(axes);
5886
+ return () => {
5887
+ wireGeo.dispose();
5888
+ wireMat.dispose();
5889
+ axes.dispose();
5890
+ };
5891
+ }
5892
+ var init_model = __esm({
5893
+ "src/util/model.ts"() {
5894
+ init_Axis();
5895
+ init_util();
5896
+ }
5897
+ });
5898
+
5903
5899
  // src/entity/scene/EntityObject.ts
5904
5900
  var EntityObject_exports = {};
5905
5901
  __export(EntityObject_exports, {
@@ -8445,7 +8441,7 @@ function createGuiTextGeometry(layout, shadow = true) {
8445
8441
  }
8446
8442
  }
8447
8443
  }
8448
- return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry2().setAttribute("position", new Float32BufferAttribute4(positions, 3)).setAttribute("uv", new Float32BufferAttribute4(uvs, 2)).setAttribute("color", new Float32BufferAttribute4(colors, 3)).setIndex(indices) }));
8444
+ return batches.map(({ image, positions, uvs, colors: colors2, indices }) => ({ image, geometry: new BufferGeometry2().setAttribute("position", new Float32BufferAttribute4(positions, 3)).setAttribute("uv", new Float32BufferAttribute4(uvs, 2)).setAttribute("color", new Float32BufferAttribute4(colors2, 3)).setIndex(indices) }));
8449
8445
  }
8450
8446
  var init_GuiText = __esm({
8451
8447
  "src/gui/GuiText.ts"() {
@@ -9127,11 +9123,13 @@ var init_ModelCulling = __esm({
9127
9123
  });
9128
9124
 
9129
9125
  // src/skin/Skins.ts
9130
- var Skins;
9126
+ var log11, Skins;
9131
9127
  var init_Skins = __esm({
9132
9128
  "src/skin/Skins.ts"() {
9133
9129
  init_Requests();
9134
9130
  init_Caching();
9131
+ init_log();
9132
+ log11 = logger("Skins");
9135
9133
  Skins = class {
9136
9134
  //<editor-fold desc="Skins">
9137
9135
  /** Returns a skin URL for {@link MineRenderScene.addSkin}, or `undefined` if name lookup fails. */
@@ -9203,7 +9201,7 @@ var init_Skins = __esm({
9203
9201
  }
9204
9202
  return void 0;
9205
9203
  }).catch((err) => {
9206
- console.warn(err);
9204
+ log11.warn(err);
9207
9205
  return void 0;
9208
9206
  });
9209
9207
  }
@@ -9218,7 +9216,7 @@ var init_Skins = __esm({
9218
9216
  }
9219
9217
  return void 0;
9220
9218
  }).catch((err) => {
9221
- console.warn(err);
9219
+ log11.warn(err);
9222
9220
  return void 0;
9223
9221
  });
9224
9222
  }
@@ -9232,7 +9230,7 @@ var init_Skins = __esm({
9232
9230
  }
9233
9231
  return void 0;
9234
9232
  }).catch((err) => {
9235
- console.warn(err);
9233
+ log11.warn(err);
9236
9234
  return void 0;
9237
9235
  });
9238
9236
  }
@@ -9256,7 +9254,7 @@ var init_Skins = __esm({
9256
9254
  }
9257
9255
  return void 0;
9258
9256
  }).catch((err) => {
9259
- console.warn(err);
9257
+ log11.warn(err);
9260
9258
  return void 0;
9261
9259
  });
9262
9260
  }
@@ -9700,10 +9698,10 @@ var init_SpecialItems = __esm({
9700
9698
  case "minecraft:shield":
9701
9699
  case "shield": {
9702
9700
  const banner = special.type === "banner" || special.type === "minecraft:banner";
9703
- const colors = await BannerPatterns.getColors(root);
9701
+ const colors2 = await BannerPatterns.getColors(root);
9704
9702
  const dye = banner ? special.color : components["minecraft:base_color"];
9705
- if (dye !== void 0 && (typeof dye !== "string" || !Object.prototype.hasOwnProperty.call(colors, dye))) throw new Error(`Unsupported dye color ${dye}`);
9706
- const color2 = dye === void 0 ? void 0 : colors[dye];
9703
+ if (dye !== void 0 && (typeof dye !== "string" || !Object.prototype.hasOwnProperty.call(colors2, dye))) throw new Error(`Unsupported dye color ${dye}`);
9704
+ const color2 = dye === void 0 ? void 0 : colors2[dye];
9707
9705
  const patterns = await BannerPatterns.getLayers(components["minecraft:banner_patterns"], banner ? "banner" : "shield", root);
9708
9706
  const patterned = banner || color2 !== void 0 || patterns.length > 0;
9709
9707
  const baseTexture = texture(banner ? "banner_base" : patterned ? "shield_base" : "shield_base_nopattern", "");
@@ -9728,7 +9726,7 @@ var init_SpecialItems = __esm({
9728
9726
  }
9729
9727
  const tints = {};
9730
9728
  if (patterned) {
9731
- const draws = [{ texture: texture(`${banner ? "banner" : "shield"}/base`, ""), color: color2 ?? colors.white }, ...patterns];
9729
+ const draws = [{ texture: texture(`${banner ? "banner" : "shield"}/base`, ""), color: color2 ?? colors2.white }, ...patterns];
9732
9730
  draws.forEach((draw, index) => {
9733
9731
  const name = index === 0 ? "pattern_base" : `pattern_${index - 1}`;
9734
9732
  layers[name] = { key: draw.texture, texture: draw.texture, layer: overlay2, render: "no_outline", tint: name };
@@ -10059,7 +10057,7 @@ import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color
10059
10057
  function isModelObject(obj) {
10060
10058
  return obj.isModelObject;
10061
10059
  }
10062
- var p7, ModelObject;
10060
+ var log12, ModelObject;
10063
10061
  var init_ModelObject = __esm({
10064
10062
  "src/model/scene/ModelObject.ts"() {
10065
10063
  init_SceneObject();
@@ -10078,7 +10076,7 @@ var init_ModelObject = __esm({
10078
10076
  init_GuiLight();
10079
10077
  init_ItemTints();
10080
10078
  init_ItemGlint();
10081
- p7 = prefix("ModelObject");
10079
+ log12 = logger("ModelObject");
10082
10080
  ModelObject = class _ModelObject extends SceneObject {
10083
10081
  constructor(originalModel, options) {
10084
10082
  super(options);
@@ -10232,7 +10230,7 @@ var init_ModelObject = __esm({
10232
10230
  }
10233
10231
  UVMapper.setAtlasUvBounds(elGeo, el.faces, this.atlas);
10234
10232
  if (this.options.tints) {
10235
- const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
10233
+ const colors2 = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
10236
10234
  for (const [faceIndex, faceName] of CUBE_FACES.entries()) {
10237
10235
  const tintIndex = el.faces[faceName]?.tintindex;
10238
10236
  if (tintIndex === void 0 || tintIndex < 0) continue;
@@ -10240,10 +10238,10 @@ var init_ModelObject = __esm({
10240
10238
  if (tint === void 0) continue;
10241
10239
  const color2 = new Color9(tint);
10242
10240
  for (let vertex = 0; vertex < 4; vertex++) {
10243
- color2.toArray(colors, (faceIndex * 4 + vertex) * 3);
10241
+ color2.toArray(colors2, (faceIndex * 4 + vertex) * 3);
10244
10242
  }
10245
10243
  }
10246
- elGeo.setAttribute("color", new BufferAttribute5(colors, 3));
10244
+ elGeo.setAttribute("color", new BufferAttribute5(colors2, 3));
10247
10245
  }
10248
10246
  elGeo.applyMatrix4(new Matrix48().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
10249
10247
  elGeo.applyMatrix4(new Matrix48().makeTranslation(el.from[0], el.from[1], el.from[2]));
@@ -10263,10 +10261,10 @@ var init_ModelObject = __esm({
10263
10261
  }
10264
10262
  });
10265
10263
  } else {
10266
- console.debug(p7, this.atlas.model, "has no elements");
10264
+ log12.debug(this.atlas.model, "has no elements");
10267
10265
  }
10268
10266
  } else {
10269
- console.debug(p7, "Missing atlas for", this);
10267
+ log12.debug("Missing atlas for", this);
10270
10268
  }
10271
10269
  if (this.options.mergeMeshes) {
10272
10270
  let combinedGeo;
@@ -11037,9 +11035,9 @@ var init_FluidModelObject = __esm({
11037
11035
  }
11038
11036
  geometry.clearGroups();
11039
11037
  const color2 = new Color11(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
11040
- const colors = new Float32Array(geometry.getAttribute("position").count * 3);
11041
- for (let i = 0; i < colors.length; i += 3) color2.toArray(colors, i);
11042
- geometry.setAttribute("color", new BufferAttribute6(colors, 3));
11038
+ const colors2 = new Float32Array(geometry.getAttribute("position").count * 3);
11039
+ for (let i = 0; i < colors2.length; i += 3) color2.toArray(colors2, i);
11040
+ geometry.setAttribute("color", new BufferAttribute6(colors2, 3));
11043
11041
  geometry.computeBoundingBox();
11044
11042
  geometry.computeBoundingSphere();
11045
11043
  if (this.options.instanceMeshes) {
@@ -11077,7 +11075,7 @@ import { Euler as Euler9, Matrix4 as Matrix410, Quaternion as Quaternion5, Vecto
11077
11075
  function isBlockObject(obj) {
11078
11076
  return obj.isBlockObject;
11079
11077
  }
11080
- var BlockObject;
11078
+ var log15, BlockObject;
11081
11079
  var init_BlockObject = __esm({
11082
11080
  "src/model/block/scene/BlockObject.ts"() {
11083
11081
  init_SceneObject();
@@ -11095,6 +11093,8 @@ var init_BlockObject = __esm({
11095
11093
  init_BlockEntities();
11096
11094
  init_Entities();
11097
11095
  init_Biomes();
11096
+ init_log();
11097
+ log15 = logger("BlockObject");
11098
11098
  BlockObject = class _BlockObject extends SceneObject {
11099
11099
  constructor(blockState3, options) {
11100
11100
  super(options);
@@ -11204,7 +11204,7 @@ var init_BlockObject = __esm({
11204
11204
  created.push(await this.scene.addEntity(entity, { wireframe: this.options.wireframe }));
11205
11205
  }
11206
11206
  } catch (error) {
11207
- console.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
11207
+ log15.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
11208
11208
  this.removeEntities(created);
11209
11209
  return false;
11210
11210
  }
@@ -11858,15 +11858,15 @@ var OBJExporter = class {
11858
11858
  let nbVertex = 0;
11859
11859
  const geometry = points.geometry;
11860
11860
  const vertices = geometry.getAttribute("position");
11861
- const colors = geometry.getAttribute("color");
11861
+ const colors2 = geometry.getAttribute("color");
11862
11862
  output += "o " + points.name + "\n";
11863
11863
  if (vertices !== void 0) {
11864
11864
  for (let i = 0, l = vertices.count; i < l; i++, nbVertex++) {
11865
11865
  vertex.fromBufferAttribute(vertices, i);
11866
11866
  vertex.applyMatrix4(points.matrixWorld);
11867
11867
  output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
11868
- if (colors !== void 0) {
11869
- color2.fromBufferAttribute(colors, i);
11868
+ if (colors2 !== void 0) {
11869
+ color2.fromBufferAttribute(colors2, i);
11870
11870
  ColorManagement.workingToColorSpace(color2, SRGBColorSpace3);
11871
11871
  output += " " + color2.r + " " + color2.g + " " + color2.b;
11872
11872
  }
@@ -11956,7 +11956,7 @@ var PLYExporter = class {
11956
11956
  const vertices = geometry.getAttribute("position");
11957
11957
  const normals = geometry.getAttribute("normal");
11958
11958
  const uvs = geometry.getAttribute("uv");
11959
- const colors = geometry.getAttribute("color");
11959
+ const colors2 = geometry.getAttribute("color");
11960
11960
  const indices = geometry.getIndex();
11961
11961
  if (vertices === void 0) {
11962
11962
  return;
@@ -11972,9 +11972,9 @@ var PLYExporter = class {
11972
11972
  includeUVs = true;
11973
11973
  uvType = getPlyType(uvs.array);
11974
11974
  }
11975
- if (colors !== void 0) {
11975
+ if (colors2 !== void 0) {
11976
11976
  includeColors = true;
11977
- colorType = getPlyType(colors.array);
11977
+ colorType = getPlyType(colors2.array);
11978
11978
  }
11979
11979
  for (const name of customAttributeNames) {
11980
11980
  const attr = geometry.getAttribute(name);
@@ -11985,16 +11985,16 @@ var PLYExporter = class {
11985
11985
  const geometry = mesh.geometry;
11986
11986
  const vertices = geometry.getAttribute("position");
11987
11987
  const normals = geometry.getAttribute("normal");
11988
- const colors = geometry.getAttribute("color");
11988
+ const colors2 = geometry.getAttribute("color");
11989
11989
  vertexCount += vertices.count;
11990
11990
  positionType = getPlyType(vertices.array);
11991
11991
  if (normals !== void 0) {
11992
11992
  includeNormals = true;
11993
11993
  normalType = getPlyType(normals.array);
11994
11994
  }
11995
- if (colors !== void 0) {
11995
+ if (colors2 !== void 0) {
11996
11996
  includeColors = true;
11997
- colorType = getPlyType(colors.array);
11997
+ colorType = getPlyType(colors2.array);
11998
11998
  }
11999
11999
  for (const name of customAttributeNames) {
12000
12000
  const attr = geometry.getAttribute(name);
@@ -12084,7 +12084,7 @@ property list uchar int vertex_index
12084
12084
  const vertices = geometry.getAttribute("position");
12085
12085
  const normals = geometry.getAttribute("normal");
12086
12086
  const uvs = geometry.getAttribute("uv");
12087
- const colors = geometry.getAttribute("color");
12087
+ const colors2 = geometry.getAttribute("color");
12088
12088
  const indices = geometry.getIndex();
12089
12089
  normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
12090
12090
  for (let i = 0, l = vertices.count; i < l; i++) {
@@ -12129,8 +12129,8 @@ property list uchar int vertex_index
12129
12129
  }
12130
12130
  }
12131
12131
  if (includeColors === true) {
12132
- if (colors != null) {
12133
- tempColor.fromBufferAttribute(colors, i);
12132
+ if (colors2 != null) {
12133
+ tempColor.fromBufferAttribute(colors2, i);
12134
12134
  ColorManagement2.workingToColorSpace(tempColor, SRGBColorSpace4);
12135
12135
  const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
12136
12136
  const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
@@ -12207,7 +12207,7 @@ property list uchar int vertex_index
12207
12207
  const vertices = geometry.getAttribute("position");
12208
12208
  const normals = geometry.getAttribute("normal");
12209
12209
  const uvs = geometry.getAttribute("uv");
12210
- const colors = geometry.getAttribute("color");
12210
+ const colors2 = geometry.getAttribute("color");
12211
12211
  const indices = geometry.getIndex();
12212
12212
  normalMatrixWorld.getNormalMatrix(mesh.matrixWorld);
12213
12213
  for (let i = 0, l = vertices.count; i < l; i++) {
@@ -12231,8 +12231,8 @@ property list uchar int vertex_index
12231
12231
  }
12232
12232
  }
12233
12233
  if (includeColors === true) {
12234
- if (colors != null) {
12235
- tempColor.fromBufferAttribute(colors, i);
12234
+ if (colors2 != null) {
12235
+ tempColor.fromBufferAttribute(colors2, i);
12236
12236
  ColorManagement2.workingToColorSpace(tempColor, SRGBColorSpace4);
12237
12237
  const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
12238
12238
  const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
@@ -12474,11 +12474,11 @@ function createSnapshot(root, gltf, bakeColors = false) {
12474
12474
  if (instanceColor) tint.multiply(instanceColor);
12475
12475
  if (bakeColors) {
12476
12476
  const original = geometry.getAttribute("color");
12477
- const colors = new Float32BufferAttribute3(new Float32Array(geometry.getAttribute("position").count * 3), 3);
12478
- for (let i = 0; i < colors.count; i++) {
12479
- colors.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
12477
+ const colors2 = new Float32BufferAttribute3(new Float32Array(geometry.getAttribute("position").count * 3), 3);
12478
+ for (let i = 0; i < colors2.count; i++) {
12479
+ colors2.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
12480
12480
  }
12481
- geometry.setAttribute("color", colors);
12481
+ geometry.setAttribute("color", colors2);
12482
12482
  } else if (material.color) {
12483
12483
  material.color.copy(tint);
12484
12484
  }
@@ -12527,8 +12527,8 @@ function selectAlphaMode(material, geometry) {
12527
12527
  const texture = material.map;
12528
12528
  if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !== RGBAFormat3 || texture.type !== UnsignedByteType || texture.wrapS !== ClampToEdgeWrapping2 || texture.wrapT !== ClampToEdgeWrapping2 || texture.magFilter !== NearestFilter3 || texture.minFilter !== NearestFilter3 || texture.anisotropy > 1 || texture.offset.x !== 0 || texture.offset.y !== 0 || texture.repeat.x !== 1 || texture.repeat.y !== 1 || texture.rotation !== 0 || !texture.matrixAutoUpdate && !texture.matrix.elements.every((value, i) => value === (i % 4 === 0 ? 1 : 0))) return;
12529
12529
  const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
12530
- const colors = geometry.getAttribute("color");
12531
- if (!uv || material.vertexColors && colors?.itemSize === 4) return;
12530
+ const colors2 = geometry.getAttribute("color");
12531
+ if (!uv || material.vertexColors && colors2?.itemSize === 4) return;
12532
12532
  const { data, width, height } = texture.image;
12533
12533
  if (!data || width < 1 || height < 1 || data.length < width * height * 4) return;
12534
12534
  const count = geometry.index?.count ?? uv.count;
@@ -12937,7 +12937,7 @@ init_util();
12937
12937
  import { Raycaster, Vector2 as Vector25 } from "three";
12938
12938
  init_log();
12939
12939
  init_three();
12940
- var p8 = prefix("SceneInspector");
12940
+ var log13 = logger("SceneInspector");
12941
12941
  var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
12942
12942
  var SceneInspector = class {
12943
12943
  constructor(renderer) {
@@ -13031,7 +13031,7 @@ var SceneInspector = class {
13031
13031
  }
13032
13032
  selectObject(targetObject, targetIntersection, instance = this.getIntersectionInstance(targetIntersection)) {
13033
13033
  this.selectedObject = targetObject;
13034
- console.log(p8, "selected", targetObject);
13034
+ log13.debug("selected", targetObject);
13035
13035
  this.redraw(targetObject, targetIntersection, instance);
13036
13036
  }
13037
13037
  redraw(targetObject, targetIntersection, instance) {
@@ -13291,7 +13291,7 @@ var SceneStatsDisplay = class {
13291
13291
 
13292
13292
  // src/instance/InstanceManager.ts
13293
13293
  init_log();
13294
- var p9 = prefix("InstanceManager");
13294
+ var log14 = logger("InstanceManager");
13295
13295
  var InstanceManager = class {
13296
13296
  constructor() {
13297
13297
  this.isInstanceManager = true;
@@ -13300,7 +13300,7 @@ var InstanceManager = class {
13300
13300
  /** Allocates a new placement of a cached model, or returns `undefined` if the key is unknown. */
13301
13301
  async get(key) {
13302
13302
  if (key in this.instanceCache) {
13303
- console.debug(p9, "key in cache", key);
13303
+ log14.debug("key in cache", key);
13304
13304
  return (await this.instanceCache[key]).nextInstance();
13305
13305
  }
13306
13306
  return void 0;
@@ -13310,7 +13310,7 @@ var InstanceManager = class {
13310
13310
  if (key in this.instanceCache) {
13311
13311
  return await this.get(key);
13312
13312
  }
13313
- console.debug(p9, "key not in cache", key);
13313
+ log14.debug("key not in cache", key);
13314
13314
  const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
13315
13315
  this.instanceCache[key] = pending;
13316
13316
  try {
@@ -15921,6 +15921,8 @@ var MapControls = class extends OrbitControls {
15921
15921
  };
15922
15922
 
15923
15923
  // src/renderer/Renderer.ts
15924
+ init_log();
15925
+ var log16 = logger("Renderer");
15924
15926
  var Renderer = class _Renderer {
15925
15927
  constructor(options, surface) {
15926
15928
  this._width = 0;
@@ -16206,10 +16208,10 @@ var Renderer = class _Renderer {
16206
16208
  this._element = element;
16207
16209
  this._element.appendChild(this.renderer.domElement);
16208
16210
  if (this.viewWidth == 0) {
16209
- console.warn("0 element width");
16211
+ log16.warn("0 element width");
16210
16212
  }
16211
16213
  if (this.viewHeight == 0) {
16212
- console.warn("0 element height");
16214
+ log16.warn("0 element height");
16213
16215
  }
16214
16216
  this.resize(this.viewWidth, this.viewHeight);
16215
16217
  }
@@ -17023,8 +17025,62 @@ init_Textures();
17023
17025
  // src/three/index.ts
17024
17026
  init_BufferGeometryUtils();
17025
17027
 
17026
- // src/index.ts
17027
- init_util2();
17028
+ // src/util/BatchedExecutor.ts
17029
+ import { JobQueue as JobQueue2 } from "jobqu";
17030
+ var BatchedExecutor = class {
17031
+ /**
17032
+ * @param interval - Delay between queue runs, in milliseconds.
17033
+ * @param batch - Maximum tasks started per run and maximum tasks active at once.
17034
+ */
17035
+ constructor(interval = 1, batch = 30) {
17036
+ if (!Number.isFinite(interval) || interval < 0) throw new RangeError("Batch interval must be finite and nonnegative");
17037
+ if (!Number.isInteger(batch) || batch < 1) throw new RangeError("Batch size must be a positive integer");
17038
+ this.interval = interval;
17039
+ this.batch = batch;
17040
+ this.queue = new JobQueue2(async (task) => task(), { interval, maxPerRun: batch, maxActive: batch });
17041
+ }
17042
+ /** Queues a task and resolves with its result, or rejects with its error. */
17043
+ submit(task) {
17044
+ return this.queue.add(() => task());
17045
+ }
17046
+ /** Rejects queued and future tasks. Tasks already running are allowed to finish. */
17047
+ stop() {
17048
+ this.queue.end();
17049
+ }
17050
+ };
17051
+
17052
+ // src/util/index.ts
17053
+ init_log();
17054
+ init_model();
17055
+
17056
+ // src/util/performance.ts
17057
+ function captureException(e, ...extra) {
17058
+ console.error(e, extra);
17059
+ }
17060
+ function timingStart(marker) {
17061
+ console.time(marker);
17062
+ }
17063
+ function timingEnd(marker) {
17064
+ console.timeEnd(marker);
17065
+ }
17066
+
17067
+ // src/util/sha.ts
17068
+ import SHA1 from "crypto-js/sha1.js";
17069
+ import SHA256 from "crypto-js/sha256.js";
17070
+ import SHA512 from "crypto-js/sha512.js";
17071
+ function sha1(str) {
17072
+ return SHA1(str).toString();
17073
+ }
17074
+ function sha256(str) {
17075
+ return SHA256(str).toString();
17076
+ }
17077
+ function sha512(str) {
17078
+ return SHA512(str).toString();
17079
+ }
17080
+
17081
+ // src/util/index.ts
17082
+ init_three();
17083
+ init_util();
17028
17084
 
17029
17085
  // src/world/AnvilParser.ts
17030
17086
  init_MineRenderError();
@@ -18114,6 +18170,8 @@ function hitNormal(hit) {
18114
18170
  }
18115
18171
 
18116
18172
  // src/world/_entities/WorldEntities.ts
18173
+ init_log();
18174
+ var log17 = logger("WorldEntities");
18117
18175
  var WorldEntities = class {
18118
18176
  constructor(scene) {
18119
18177
  this.scene = scene;
@@ -18182,7 +18240,7 @@ var WorldEntities = class {
18182
18240
  placement.owner.set(object4, { type: key.toNamespacedString(), position: placement.position });
18183
18241
  this.scene.add(object4);
18184
18242
  } catch (error) {
18185
- console.warn(`Could not draw saved entity ${placement.key.toNamespacedString()}, skipping it`, error);
18243
+ log17.warn(`Could not draw saved entity ${placement.key.toNamespacedString()}, skipping it`, error);
18186
18244
  } finally {
18187
18245
  if (object4 && !placement.owner.has(object4)) object4.dispose();
18188
18246
  }
@@ -18259,14 +18317,14 @@ var BiomeBlend = class {
18259
18317
  this.tiles.set(key, tile);
18260
18318
  } else {
18261
18319
  const snapshot = new AssetKey("minecraft", "", void 0, void 0, "assets", ".json", root);
18262
- const colors = this.buildTile(kind, snapshot, tileX, quartY, tileZ, this._radius).then((result2) => {
18263
- if (!result2.complete && this.tiles.get(key)?.colors === colors) this.tiles.delete(key);
18320
+ const colors2 = this.buildTile(kind, snapshot, tileX, quartY, tileZ, this._radius).then((result2) => {
18321
+ if (!result2.complete && this.tiles.get(key)?.colors === colors2) this.tiles.delete(key);
18264
18322
  return result2;
18265
18323
  }, (error) => {
18266
- if (this.tiles.get(key)?.colors === colors) this.tiles.delete(key);
18324
+ if (this.tiles.get(key)?.colors === colors2) this.tiles.delete(key);
18267
18325
  throw error;
18268
18326
  });
18269
- tile = { x: tileX, z: tileZ, colors };
18327
+ tile = { x: tileX, z: tileZ, colors: colors2 };
18270
18328
  this.tiles.set(key, tile);
18271
18329
  if (this.tiles.size > MAX_TILES) this.tiles.delete(this.tiles.keys().next().value);
18272
18330
  }
@@ -18324,7 +18382,7 @@ var BiomeBlend = class {
18324
18382
  }
18325
18383
  }
18326
18384
  }
18327
- const colors = new Int32Array(256).fill(-1), width = radius * 2 + 1;
18385
+ const colors2 = new Int32Array(256).fill(-1), width = radius * 2 + 1;
18328
18386
  for (let z = 0; z < 16; z++) {
18329
18387
  for (let x = 0; x < 16; x++) {
18330
18388
  if (samples[(z + radius) * size + x + radius] === -1) continue;
@@ -18332,10 +18390,10 @@ var BiomeBlend = class {
18332
18390
  const bottomLeft = (z + width) * stride + x, bottomRight = bottomLeft + width;
18333
18391
  const sum = (values) => values[bottomRight] - values[bottomLeft] - values[topRight] + values[topLeft];
18334
18392
  const count = sum(sums[3]);
18335
- if (count) colors[z * 16 + x] = Math.floor(sum(sums[0]) / count) << 16 | Math.floor(sum(sums[1]) / count) << 8 | Math.floor(sum(sums[2]) / count);
18393
+ if (count) colors2[z * 16 + x] = Math.floor(sum(sums[0]) / count) << 16 | Math.floor(sum(sums[1]) / count) << 8 | Math.floor(sum(sums[2]) / count);
18336
18394
  }
18337
18395
  }
18338
- return { colors, complete, failures };
18396
+ return { colors: colors2, complete, failures };
18339
18397
  }
18340
18398
  };
18341
18399
 
@@ -18394,6 +18452,8 @@ function skipsBlockFace(data, rule, block, neighbor, face) {
18394
18452
  }
18395
18453
 
18396
18454
  // src/world/MineRenderWorld.ts
18455
+ init_log();
18456
+ var log18 = logger("MineRenderWorld");
18397
18457
  var MineRenderWorld = class {
18398
18458
  constructor(scene, options = {}) {
18399
18459
  this._chunks = /* @__PURE__ */ new Map();
@@ -18483,8 +18543,14 @@ var MineRenderWorld = class {
18483
18543
  }
18484
18544
  return queued;
18485
18545
  }
18486
- async refreshBiomes() {
18487
- if (this.biomeRefreshing) await this.biomeRefreshing;
18546
+ async refreshBiomes(deferCulling = false) {
18547
+ if (this.biomeRefreshing) {
18548
+ await this.biomeRefreshing;
18549
+ if (!deferCulling) {
18550
+ if (this.pendingCulling.size) await this.updateCulling([]);
18551
+ else await this.culling;
18552
+ }
18553
+ }
18488
18554
  if (!this.pendingBiomes.size) return /* @__PURE__ */ new Map();
18489
18555
  return this.biomeRefreshing ??= Promise.resolve().then(async () => {
18490
18556
  const failures = /* @__PURE__ */ new Map();
@@ -18496,7 +18562,7 @@ var MineRenderWorld = class {
18496
18562
  this.pendingBiomes.delete(chunk);
18497
18563
  if (this._chunks.get(`${chunk.x}_${chunk.y}_${chunk.z}`) !== chunk) continue;
18498
18564
  try {
18499
- await chunk.refreshBiomes(columns);
18565
+ await chunk.refreshBiomes(columns, deferCulling);
18500
18566
  } catch (error) {
18501
18567
  failures.set(chunk, error);
18502
18568
  if (this._chunks.get(`${chunk.x}_${chunk.y}_${chunk.z}`) === chunk) this.pendingBiomes.set(chunk, void 0);
@@ -18749,7 +18815,7 @@ var MineRenderWorld = class {
18749
18815
  } finally {
18750
18816
  this.markBiomesChanged(chunk.x, chunk.z, void 0, false);
18751
18817
  const failures = await this.refreshBiomes();
18752
- if (failures.size) console.warn("Failed to refresh biome colors", failures.values().next().value);
18818
+ if (failures.size) log18.warn("Failed to refresh biome colors", failures.values().next().value);
18753
18819
  await this.updateCulling([...changes.values()]);
18754
18820
  }
18755
18821
  }
@@ -18758,16 +18824,36 @@ var MineRenderWorld = class {
18758
18824
  * Coordinates match AnvilChunk.x/z, not block positions. Missing columns are ignored.
18759
18825
  */
18760
18826
  async unloadChunkColumn(x, z) {
18761
- if (!Number.isInteger(x) || !Number.isInteger(z)) {
18762
- throw new RangeError("Chunk column coordinates must be integers");
18827
+ return this.unloadChunkColumns([{ x, z }]);
18828
+ }
18829
+ /**
18830
+ * Removes chunk columns together and refreshes surviving neighbors once.
18831
+ * Coordinates are absolute chunk columns. Duplicate and missing columns are ignored.
18832
+ */
18833
+ async unloadChunkColumns(positions) {
18834
+ const columns = /* @__PURE__ */ new Map();
18835
+ for (const position of positions) {
18836
+ const { x, z } = position ?? {};
18837
+ if (!Number.isInteger(x) || !Number.isInteger(z)) {
18838
+ throw new RangeError("Chunk column coordinates must be integers");
18839
+ }
18840
+ columns.set(`${x}_${z}`, { x, z });
18763
18841
  }
18764
- this.entities?.clearColumn(x, z);
18842
+ if (!columns.size) return;
18765
18843
  await this.culling;
18844
+ let sliceStart = performance.now();
18766
18845
  try {
18767
- await this.clearChunkColumn(x, z);
18846
+ for (const { x, z } of columns.values()) {
18847
+ this.entities?.clearColumn(x, z);
18848
+ await this.clearChunkColumn(x, z);
18849
+ if (performance.now() - sliceStart > 8) {
18850
+ await yieldToEventLoop();
18851
+ sliceStart = performance.now();
18852
+ }
18853
+ }
18768
18854
  } finally {
18769
- const failures = await this.refreshBiomes();
18770
- if (failures.size) console.warn("Failed to refresh biome colors", failures.values().next().value);
18855
+ const failures = await this.refreshBiomes(true);
18856
+ if (failures.size) log18.warn("Failed to refresh biome colors", failures.values().next().value);
18771
18857
  await this.updateCulling([]);
18772
18858
  }
18773
18859
  }
@@ -18829,7 +18915,7 @@ var MineRenderWorld = class {
18829
18915
  }
18830
18916
  this.sectionModels?.clear();
18831
18917
  }
18832
- updateCulling(positions) {
18918
+ updateCulling(positions, defer = false) {
18833
18919
  const neighbor = new Vector319();
18834
18920
  for (const pos of positions) {
18835
18921
  const cx = Math.floor(pos.x / 16), cy = Math.floor(pos.y / 16), cz = Math.floor(pos.z / 16);
@@ -18851,58 +18937,72 @@ var MineRenderWorld = class {
18851
18937
  }
18852
18938
  }
18853
18939
  }
18940
+ if (defer) return Promise.resolve();
18854
18941
  return this.culling ??= Promise.resolve().then(async () => {
18855
18942
  let sliceStart = performance.now();
18856
18943
  try {
18857
18944
  const culling = await loadBlockCulling();
18858
18945
  while (this.pendingCulling.size) {
18859
- const batch = [...this.pendingCulling];
18946
+ const batch = new Map(this.pendingCulling);
18860
18947
  this.pendingCulling.clear();
18861
- for (const [chunk, indices] of batch) {
18862
- const neighbors = CUBE_FACE_OFFSETS.map(([x, y, z]) => this._chunks.get(`${chunk.x + x}_${chunk.y + y}_${chunk.z + z}`));
18863
- const neighborAt = (x, y, z) => {
18864
- const lx = x - chunk.x * 16, ly = y - chunk.y * 16, lz = z - chunk.z * 16;
18865
- const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
18866
- return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
18867
- };
18868
- const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18869
- const [section, i] = neighborAt(x, y, z);
18870
- return section?.isOccludingIndex(i) ?? false;
18871
- }, culling, (x, y, z) => {
18872
- const [section, i] = neighborAt(x, y, z);
18873
- return section?.visibleBlockIndex(i);
18874
- });
18875
- const fluidIndices = indices === "all" ? function* () {
18876
- for (let index = 0; index < 4096; index++) yield index;
18877
- }() : indices;
18878
- for (const index of fluidIndices) {
18879
- if (!chunk.fluidByteIndex(index) || !chunk.isBlockVisibleIndex(index)) continue;
18880
- const lx = index % 16, ly = Math.floor(index / 256), lz = Math.floor(index / 16) % 16;
18881
- const wx = chunk.x * 16 + lx, wy = chunk.y * 16 + ly, wz = chunk.z * 16 + lz;
18882
- const block = chunk.getBlockAt(neighbor.set(wx, wy, wz));
18883
- if (block.object?.fluidKind) {
18884
- await block.object.updateFluid((x, y, z) => {
18885
- const nx = lx + x, ny = ly + y, nz = lz + z;
18886
- const section = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16 ? chunk : this._chunks.get(`${chunk.x + Math.floor(nx / 16)}_${chunk.y + Math.floor(ny / 16)}_${chunk.z + Math.floor(nz / 16)}`);
18887
- const neighborIndex = (ny & 15) * 256 + (nz & 15) * 16 + (nx & 15);
18888
- const byte = section?.fluidByteIndex(neighborIndex) ?? 0;
18889
- return {
18890
- fluid: fluidKindOf(byte),
18891
- level: byte & 15,
18892
- solid: section?.isOccludingIndex(neighborIndex) ?? false
18893
- };
18894
- });
18948
+ try {
18949
+ for (const [chunk, indices] of batch) {
18950
+ const neighbors = CUBE_FACE_OFFSETS.map(([x, y, z]) => this._chunks.get(`${chunk.x + x}_${chunk.y + y}_${chunk.z + z}`));
18951
+ const neighborAt = (x, y, z) => {
18952
+ const lx = x - chunk.x * 16, ly = y - chunk.y * 16, lz = z - chunk.z * 16;
18953
+ const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
18954
+ return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
18955
+ };
18956
+ const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
18957
+ const [section, i] = neighborAt(x, y, z);
18958
+ return section?.isOccludingIndex(i) ?? false;
18959
+ }, culling, (x, y, z) => {
18960
+ const [section, i] = neighborAt(x, y, z);
18961
+ return section?.visibleBlockIndex(i);
18962
+ });
18963
+ const fluidIndices = indices === "all" ? function* () {
18964
+ for (let index = 0; index < 4096; index++) yield index;
18965
+ }() : indices;
18966
+ for (const index of fluidIndices) {
18967
+ if (!chunk.fluidByteIndex(index) || !chunk.isBlockVisibleIndex(index)) continue;
18968
+ const lx = index % 16, ly = Math.floor(index / 256), lz = Math.floor(index / 16) % 16;
18969
+ const wx = chunk.x * 16 + lx, wy = chunk.y * 16 + ly, wz = chunk.z * 16 + lz;
18970
+ const block = chunk.getBlockAt(neighbor.set(wx, wy, wz));
18971
+ if (block.object?.fluidKind) {
18972
+ await block.object.updateFluid((x, y, z) => {
18973
+ const nx = lx + x, ny = ly + y, nz = lz + z;
18974
+ const section = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16 ? chunk : this._chunks.get(`${chunk.x + Math.floor(nx / 16)}_${chunk.y + Math.floor(ny / 16)}_${chunk.z + Math.floor(nz / 16)}`);
18975
+ const neighborIndex = (ny & 15) * 256 + (nz & 15) * 16 + (nx & 15);
18976
+ const byte = section?.fluidByteIndex(neighborIndex) ?? 0;
18977
+ return {
18978
+ fluid: fluidKindOf(byte),
18979
+ level: byte & 15,
18980
+ solid: section?.isOccludingIndex(neighborIndex) ?? false
18981
+ };
18982
+ });
18983
+ }
18984
+ }
18985
+ for (const [index, mask] of masks) await chunk.setCullMaskIndex(index, mask);
18986
+ await chunk.refreshLight(indices === "all" ? void 0 : indices);
18987
+ chunk.refreshAmbientOcclusion(this._ambientOcclusion);
18988
+ if ((this._ambientOcclusion || this.ambientOcclusionPending) && performance.now() - sliceStart > 8) {
18989
+ await yieldToEventLoop();
18990
+ sliceStart = performance.now();
18895
18991
  }
18896
18992
  }
18897
- for (const [index, mask] of masks) await chunk.setCullMaskIndex(index, mask);
18898
- await chunk.refreshLight(indices === "all" ? void 0 : indices);
18899
- chunk.refreshAmbientOcclusion(this._ambientOcclusion);
18900
- if ((this._ambientOcclusion || this.ambientOcclusionPending) && performance.now() - sliceStart > 8) {
18901
- await yieldToEventLoop();
18902
- sliceStart = performance.now();
18993
+ const builds = await Promise.allSettled([...batch.keys()].map(async (chunk) => {
18994
+ await chunk.rebuildSectionMesh();
18995
+ batch.delete(chunk);
18996
+ }));
18997
+ const failure = builds.find((result) => result.status === "rejected");
18998
+ if (failure?.status === "rejected") throw failure.reason;
18999
+ } catch (error) {
19000
+ for (const [chunk, indices] of batch) {
19001
+ const pending = this.pendingCulling.get(chunk);
19002
+ this.pendingCulling.set(chunk, indices === "all" || pending === "all" ? "all" : /* @__PURE__ */ new Set([...indices, ...pending ?? []]));
18903
19003
  }
19004
+ throw error;
18904
19005
  }
18905
- await Promise.all(batch.map(([chunk]) => chunk.rebuildSectionMesh()));
18906
19006
  }
18907
19007
  } finally {
18908
19008
  this.culling = void 0;
@@ -18919,7 +19019,7 @@ var MineRenderWorld = class {
18919
19019
  x,
18920
19020
  y,
18921
19021
  z,
18922
- (positions) => this.updateCulling(positions),
19022
+ (positions, defer) => this.updateCulling(positions, defer),
18923
19023
  this.sectionModels,
18924
19024
  (x2, y2, z2) => {
18925
19025
  const cx = Math.floor(x2 / 16), cy = Math.floor(y2 / 16), cz = Math.floor(z2 / 16);
@@ -19192,7 +19292,7 @@ function buildSectionGeometry(input) {
19192
19292
  }
19193
19293
  }
19194
19294
  const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
19195
- const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
19295
+ const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors2 = new Float32Array(faces * 12);
19196
19296
  const shade = new Float32Array(faces * 4).fill(1);
19197
19297
  const outputIndices = new Uint32Array(faces * 6);
19198
19298
  const blockIndices = new Uint16Array(faces);
@@ -19231,9 +19331,9 @@ function buildSectionGeometry(input) {
19231
19331
  uvBounds[vertex * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);
19232
19332
  uvBounds[vertex * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);
19233
19333
  const factor = brightness * (ambientMask ? cornerBrightness2[corner] : 1);
19234
- colors[vertex * 3] = (tint === void 0 ? template.colors[source * 3] : biomeTints[tint]) * factor;
19235
- colors[vertex * 3 + 1] = (tint === void 0 ? template.colors[source * 3 + 1] : biomeTints[tint + 1]) * factor;
19236
- colors[vertex * 3 + 2] = (tint === void 0 ? template.colors[source * 3 + 2] : biomeTints[tint + 2]) * factor;
19334
+ colors2[vertex * 3] = (tint === void 0 ? template.colors[source * 3] : biomeTints[tint]) * factor;
19335
+ colors2[vertex * 3 + 1] = (tint === void 0 ? template.colors[source * 3 + 1] : biomeTints[tint + 1]) * factor;
19336
+ colors2[vertex * 3 + 2] = (tint === void 0 ? template.colors[source * 3 + 2] : biomeTints[tint + 2]) * factor;
19237
19337
  }
19238
19338
  for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];
19239
19339
  }
@@ -19268,15 +19368,15 @@ function buildSectionGeometry(input) {
19268
19368
  mapU((rect[0] + rect[2]) / atlas.width),
19269
19369
  mapV(1 - rect[1] / atlas.height)
19270
19370
  ], vertex * 4);
19271
- colors[vertex * 3] = tint[0] * brightness;
19272
- colors[vertex * 3 + 1] = tint[1] * brightness;
19273
- colors[vertex * 3 + 2] = tint[2] * brightness;
19371
+ colors2[vertex * 3] = tint[0] * brightness;
19372
+ colors2[vertex * 3 + 1] = tint[1] * brightness;
19373
+ colors2[vertex * 3 + 2] = tint[2] * brightness;
19274
19374
  }
19275
19375
  outputIndices.set([start, start + 1, start + 2, start, start + 2, start + 3], indexOffset);
19276
19376
  indexOffset += 6;
19277
19377
  }
19278
19378
  }
19279
- return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, shade, indices: outputIndices, blockIndices };
19379
+ return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors: colors2, shade, indices: outputIndices, blockIndices };
19280
19380
  });
19281
19381
  }
19282
19382
  function sectionGeometryTransferables(pages) {
@@ -19654,11 +19754,14 @@ var Chunk = class _Chunk {
19654
19754
  this.biomes = copy;
19655
19755
  return this.refreshBiomes();
19656
19756
  }
19657
- /** Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects. */
19658
- refreshBiomes(columns) {
19659
- return this.changeBlocks(() => this.refreshBiomeBlocks(columns), true);
19757
+ /**
19758
+ * Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects.
19759
+ * The owning world can defer neighbor culling until all affected chunks are refreshed.
19760
+ */
19761
+ refreshBiomes(columns, deferCulling = false) {
19762
+ return this.changeBlocks(() => this.refreshBiomeBlocks(columns, deferCulling), true);
19660
19763
  }
19661
- async refreshBiomeBlocks(columns) {
19764
+ async refreshBiomeBlocks(columns, deferCulling = false) {
19662
19765
  const blend = columns && this.biomeBlend?.();
19663
19766
  const ownColumn = columns?.some((column) => column.x === this.x && column.z === this.z);
19664
19767
  const affected = /* @__PURE__ */ new Map();
@@ -19715,7 +19818,7 @@ var Chunk = class _Chunk {
19715
19818
  this.renderedBlocks.get(index)?.object?.setVisible(false);
19716
19819
  }
19717
19820
  const positions = blocks.map(({ index }) => new Vector320(...this.positionAt(index)));
19718
- if (this.onBlocksChanged) await this.onBlocksChanged(positions);
19821
+ if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);
19719
19822
  else await this.rebuildSectionMesh();
19720
19823
  }
19721
19824
  }
@@ -20369,19 +20472,12 @@ var WorldStreamer = class {
20369
20472
  this.loading?.controller.abort();
20370
20473
  return this.disposal ??= Promise.resolve().then(async () => {
20371
20474
  await this.running?.catch(() => void 0);
20372
- let failure;
20373
- let failed = false;
20374
- for (const position of this.owned.values()) {
20375
- try {
20376
- await this.unload(position);
20377
- } catch (error) {
20378
- failed = true;
20379
- failure ??= error;
20380
- }
20475
+ try {
20476
+ await this.unloadMany([...this.owned.values()]);
20477
+ } finally {
20478
+ this.missing.clear();
20479
+ this.failed.clear();
20381
20480
  }
20382
- this.missing.clear();
20383
- this.failed.clear();
20384
- if (failed) throw failure;
20385
20481
  }).catch((error) => {
20386
20482
  this.disposal = void 0;
20387
20483
  throw error;
@@ -20396,9 +20492,9 @@ var WorldStreamer = class {
20396
20492
  for (const [key, position2] of this.failed) {
20397
20493
  if (!this.within(position2, this.unloadRadius)) this.failed.delete(key);
20398
20494
  }
20399
- const obsolete = [...this.owned.values()].find((position2) => !this.loaded.has(this.key(position2)) || !this.within(position2, this.unloadRadius));
20400
- if (obsolete) {
20401
- await this.unload(obsolete);
20495
+ const obsolete = [...this.owned.values()].filter((position2) => !this.loaded.has(this.key(position2)) || !this.within(position2, this.unloadRadius));
20496
+ if (obsolete.length) {
20497
+ await this.unloadMany(obsolete);
20402
20498
  continue;
20403
20499
  }
20404
20500
  const position = this.desired.find((position2) => this.needsLoad(position2));
@@ -20428,7 +20524,7 @@ var WorldStreamer = class {
20428
20524
  this.loaded.set(this.key(position), position);
20429
20525
  } catch (error) {
20430
20526
  try {
20431
- await this.unload(position);
20527
+ await this.unloadMany([position]);
20432
20528
  } catch (cleanupError) {
20433
20529
  const failure = error instanceof Error ? error : new Error(String(error));
20434
20530
  try {
@@ -20449,10 +20545,18 @@ var WorldStreamer = class {
20449
20545
  const key = this.key(position);
20450
20546
  return !this.loaded.has(key) && !this.missing.has(key) && !this.failed.has(key);
20451
20547
  }
20452
- async unload(position) {
20453
- await this.world.unloadChunkColumn(position.x, position.z);
20454
- this.owned.delete(this.key(position));
20455
- this.loaded.delete(this.key(position));
20548
+ async unloadMany(positions) {
20549
+ if (!positions.length) return;
20550
+ try {
20551
+ await this.world.unloadChunkColumns(positions.map(({ x, z }) => ({ x, z })));
20552
+ } catch (error) {
20553
+ for (const position of positions) this.loaded.delete(this.key(position));
20554
+ throw error;
20555
+ }
20556
+ for (const position of positions) {
20557
+ this.owned.delete(this.key(position));
20558
+ this.loaded.delete(this.key(position));
20559
+ }
20456
20560
  }
20457
20561
  validateChunk(chunk, position) {
20458
20562
  if (chunk.x !== position.x || chunk.z !== position.z) {
@@ -20695,6 +20799,7 @@ export {
20695
20799
  ItemGlint,
20696
20800
  ItemTints,
20697
20801
  LitematicaParser,
20802
+ Logging,
20698
20803
  MapControls,
20699
20804
  Materials,
20700
20805
  Meshes,
@@ -20809,6 +20914,7 @@ export {
20809
20914
  isTripleArray,
20810
20915
  isVector3,
20811
20916
  layoutGuiText,
20917
+ logger,
20812
20918
  md5,
20813
20919
  mergeBufferAttributes,
20814
20920
  mergeBufferGeometries,