minerender 2.1.0-beta.6 → 2.1.0-beta.7

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 (80) 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/AssetDefaults.mjs +8 -0
  8. package/dist/browser/esm/assets/AssetDefaults.mjs.map +1 -0
  9. package/dist/browser/esm/assets/AssetKey.mjs +1 -1
  10. package/dist/browser/esm/assets/AssetKey.mjs.map +1 -1
  11. package/dist/browser/esm/assets/AssetLoader.mjs +5 -5
  12. package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
  13. package/dist/browser/esm/assets/Assets.mjs +1 -5
  14. package/dist/browser/esm/assets/Assets.mjs.map +1 -1
  15. package/dist/browser/esm/assets/BlockEntities.mjs +3 -1
  16. package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
  17. package/dist/browser/esm/assets/BlockStates.mjs +1 -1
  18. package/dist/browser/esm/assets/BlockStates.mjs.map +1 -1
  19. package/dist/browser/esm/assets/Entities.mjs +1 -1
  20. package/dist/browser/esm/assets/Entities.mjs.map +1 -1
  21. package/dist/browser/esm/assets/Models.mjs +1 -1
  22. package/dist/browser/esm/assets/Models.mjs.map +1 -1
  23. package/dist/browser/esm/assets/_fonts/Unihex.mjs +5 -3
  24. package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -1
  25. package/dist/browser/esm/assets/index.mjs +1 -0
  26. package/dist/browser/esm/assets/index.mjs.map +1 -1
  27. package/dist/browser/esm/assets/source/HostedAssetSource.mjs +7 -8
  28. package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
  29. package/dist/browser/esm/env/browser/BrowserCache.mjs +3 -3
  30. package/dist/browser/esm/env/browser/BrowserCache.mjs.map +1 -1
  31. package/dist/browser/esm/image/ImageLoader.mjs +3 -3
  32. package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
  33. package/dist/browser/esm/index.browser.d.mts +64 -11
  34. package/dist/browser/esm/inspector/SceneInspector.mjs +3 -3
  35. package/dist/browser/esm/inspector/SceneInspector.mjs.map +1 -1
  36. package/dist/browser/esm/instance/InstanceManager.mjs +4 -4
  37. package/dist/browser/esm/instance/InstanceManager.mjs.map +1 -1
  38. package/dist/browser/esm/model/block/scene/BlockObject.mjs +3 -1
  39. package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
  40. package/dist/browser/esm/model/multiblock/StructureParser.mjs +7 -4
  41. package/dist/browser/esm/model/multiblock/StructureParser.mjs.map +1 -1
  42. package/dist/browser/esm/model/scene/ModelObject.mjs +4 -4
  43. package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
  44. package/dist/browser/esm/nbt/NBTHelper.mjs +5 -2
  45. package/dist/browser/esm/nbt/NBTHelper.mjs.map +1 -1
  46. package/dist/browser/esm/renderer/Renderer.mjs +4 -2
  47. package/dist/browser/esm/renderer/Renderer.mjs.map +1 -1
  48. package/dist/browser/esm/renderer/SceneObject.mjs +0 -6
  49. package/dist/browser/esm/renderer/SceneObject.mjs.map +1 -1
  50. package/dist/browser/esm/request/Requests.mjs +3 -3
  51. package/dist/browser/esm/request/Requests.mjs.map +1 -1
  52. package/dist/browser/esm/skin/Skins.mjs +6 -4
  53. package/dist/browser/esm/skin/Skins.mjs.map +1 -1
  54. package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
  55. package/dist/browser/esm/texture/TextureLoader.mjs.map +1 -1
  56. package/dist/browser/esm/util/log.mjs +75 -0
  57. package/dist/browser/esm/util/log.mjs.map +1 -1
  58. package/dist/browser/esm/util/performance.mjs.map +1 -1
  59. package/dist/browser/esm/world/Chunk.mjs +8 -5
  60. package/dist/browser/esm/world/Chunk.mjs.map +1 -1
  61. package/dist/browser/esm/world/MineRenderWorld.mjs +96 -54
  62. package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
  63. package/dist/browser/esm/world/WorldStreamer.mjs +21 -20
  64. package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
  65. package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
  66. package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
  67. package/dist/browser/esm/world/_entities/WorldEntities.mjs +3 -1
  68. package/dist/browser/esm/world/_entities/WorldEntities.mjs.map +1 -1
  69. package/dist/browser/index.d.ts +64 -11
  70. package/dist/browser/index.js +3071 -2956
  71. package/dist/browser/index.js.map +1 -1
  72. package/dist/bundle.js +6095 -5975
  73. package/dist/bundle.js.map +1 -1
  74. package/dist/node/index.d.mts +64 -11
  75. package/dist/node/index.d.ts +64 -11
  76. package/dist/node/index.js +3095 -2978
  77. package/dist/node/index.js.map +1 -1
  78. package/dist/node/index.mjs +3087 -2971
  79. package/dist/node/index.mjs.map +1 -1
  80. package/package.json +1 -1
@@ -3,6 +3,8 @@ import { RGBAFormat, Texture } from "three";
3
3
  import * as THREE from "three";
4
4
  import { ImageLoader } from "../image/ImageLoader.mjs";
5
5
  import { Textures } from "./Textures.mjs";
6
+ import { logger } from "../util/log.mjs";
7
+ var log = logger("TextureLoader");
6
8
  var TextureLoader = class {
7
9
  /** Reports whether image loading failed, so cached textures can be retried. */
8
10
  static hasFailed(texture) {
@@ -18,7 +20,7 @@ var TextureLoader = class {
18
20
  texture.needsUpdate = true;
19
21
  }, (error) => {
20
22
  this.failedTextures.add(texture);
21
- console.warn("Failed to load texture", src, error);
23
+ log.warn("Failed to load texture", src, error);
22
24
  });
23
25
  texture.image = image;
24
26
  texture.format = format;
@@ -34,7 +36,7 @@ var TextureLoader = class {
34
36
  texture.needsUpdate = true;
35
37
  }).catch((error) => {
36
38
  this.failedTextures.add(texture);
37
- console.warn("Failed to load texture", src, error);
39
+ log.warn("Failed to load texture", src, error);
38
40
  });
39
41
  texture.format = format;
40
42
  texture.rotation = rotation;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/texture/TextureLoader.ts"],"sourcesContent":["import { PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Caching } from \"../cache/Caching\";\nimport * as THREE from \"three\";\nimport { ImageLoader } from \"../image/ImageLoader\";\nimport { createCanvas } from \"../canvas/CanvasCompat\";\nimport type { CanvasRenderingContext2D } from \"canvas\";\nimport { Textures } from \"./Textures\";\n\n/** Creates sRGB textures immediately and fills their pixels after asynchronous image loading. */\nexport class TextureLoader {\n\n private static readonly failedTextures = new WeakSet<Texture>();\n\n /** Reports whether image loading failed, so cached textures can be retried. */\n public static hasFailed(texture: Texture): boolean {\n return this.failedTextures.has(texture);\n }\n\n protected static createTexture(): Texture {\n return new Texture();\n }\n\n public static loadInBackground(src: string, format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = this.createTexture();\n texture.colorSpace = THREE.SRGBColorSpace;\n const image = ImageLoader.loadElement(src, () => {\n texture.needsUpdate = true;\n }, error => {\n this.failedTextures.add(texture);\n console.warn(\"Failed to load texture\", src, error);\n });\n texture.image = image;\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n /** Loads image pixels in the background. `rotation` is in radians. Check {@link hasFailed} for load failures. */\n public static load(src: string,format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = new Texture();\n texture.colorSpace = THREE.SRGBColorSpace;\n ImageLoader.getData(src).then(image=>{\n texture.image = image;\n texture.needsUpdate = true;\n }).catch(error => {\n this.failedTextures.add(texture);\n console.warn(\"Failed to load texture\", src, error);\n });\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n\n}\n"],"mappings":";AAAA,SAAsB,YAAY,eAAe;AAEjD,YAAY,WAAW;AACvB,SAAS,mBAAmB;AAG5B,SAAS,gBAAgB;AAGlB,IAAM,gBAAN,MAAoB;AAAA;AAAA,EAKvB,OAAc,UAAU,SAA2B;AAC/C,WAAO,KAAK,eAAe,IAAI,OAAO;AAAA,EAC1C;AAAA,EAEA,OAAiB,gBAAyB;AACtC,WAAO,IAAI,QAAQ;AAAA,EACvB;AAAA,EAEA,OAAc,iBAAiB,KAAa,SAAsB,YAAY,WAAmB,GAAY;AACzG,UAAM,UAAU,KAAK,cAAc;AACnC,YAAQ,aAAmB;AAC3B,UAAM,QAAQ,YAAY,YAAY,KAAK,MAAM;AAC7C,cAAQ,cAAc;AAAA,IAC1B,GAAG,WAAS;AACR,WAAK,eAAe,IAAI,OAAO;AAC/B,cAAQ,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACrD,CAAC;AACD,YAAQ,QAAQ;AAChB,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,OAAc,KAAK,KAAY,SAAsB,YAAY,WAAmB,GAAY;AAC5F,UAAM,UAAU,IAAI,QAAQ;AAC5B,YAAQ,aAAmB;AAC3B,gBAAY,QAAQ,GAAG,EAAE,KAAK,WAAO;AACjC,cAAQ,QAAQ;AAChB,cAAQ,cAAc;AAAA,IAC1B,CAAC,EAAE,MAAM,WAAS;AACd,WAAK,eAAe,IAAI,OAAO;AAC/B,cAAQ,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACrD,CAAC;AACD,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAGJ;AA/Ca,cAEe,iBAAiB,oBAAI,QAAiB;","names":[]}
1
+ {"version":3,"sources":["../../../../src/texture/TextureLoader.ts"],"sourcesContent":["import { PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Caching } from \"../cache/Caching\";\nimport * as THREE from \"three\";\nimport { ImageLoader } from \"../image/ImageLoader\";\nimport { createCanvas } from \"../canvas/CanvasCompat\";\nimport type { CanvasRenderingContext2D } from \"canvas\";\nimport { Textures } from \"./Textures\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"TextureLoader\");\n\n/** Creates sRGB textures immediately and fills their pixels after asynchronous image loading. */\nexport class TextureLoader {\n\n private static readonly failedTextures = new WeakSet<Texture>();\n\n /** Reports whether image loading failed, so cached textures can be retried. */\n public static hasFailed(texture: Texture): boolean {\n return this.failedTextures.has(texture);\n }\n\n protected static createTexture(): Texture {\n return new Texture();\n }\n\n public static loadInBackground(src: string, format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = this.createTexture();\n texture.colorSpace = THREE.SRGBColorSpace;\n const image = ImageLoader.loadElement(src, () => {\n texture.needsUpdate = true;\n }, error => {\n this.failedTextures.add(texture);\n log.warn(\"Failed to load texture\", src, error);\n });\n texture.image = image;\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n /** Loads image pixels in the background. `rotation` is in radians. Check {@link hasFailed} for load failures. */\n public static load(src: string,format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = new Texture();\n texture.colorSpace = THREE.SRGBColorSpace;\n ImageLoader.getData(src).then(image=>{\n texture.image = image;\n texture.needsUpdate = true;\n }).catch(error => {\n this.failedTextures.add(texture);\n log.warn(\"Failed to load texture\", src, error);\n });\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n\n}\n"],"mappings":";AAAA,SAAsB,YAAY,eAAe;AAEjD,YAAY,WAAW;AACvB,SAAS,mBAAmB;AAG5B,SAAS,gBAAgB;AACzB,SAAS,cAAc;AAEvB,IAAM,MAAM,OAAO,eAAe;AAG3B,IAAM,gBAAN,MAAoB;AAAA;AAAA,EAKvB,OAAc,UAAU,SAA2B;AAC/C,WAAO,KAAK,eAAe,IAAI,OAAO;AAAA,EAC1C;AAAA,EAEA,OAAiB,gBAAyB;AACtC,WAAO,IAAI,QAAQ;AAAA,EACvB;AAAA,EAEA,OAAc,iBAAiB,KAAa,SAAsB,YAAY,WAAmB,GAAY;AACzG,UAAM,UAAU,KAAK,cAAc;AACnC,YAAQ,aAAmB;AAC3B,UAAM,QAAQ,YAAY,YAAY,KAAK,MAAM;AAC7C,cAAQ,cAAc;AAAA,IAC1B,GAAG,WAAS;AACR,WAAK,eAAe,IAAI,OAAO;AAC/B,UAAI,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACjD,CAAC;AACD,YAAQ,QAAQ;AAChB,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,OAAc,KAAK,KAAY,SAAsB,YAAY,WAAmB,GAAY;AAC5F,UAAM,UAAU,IAAI,QAAQ;AAC5B,YAAQ,aAAmB;AAC3B,gBAAY,QAAQ,GAAG,EAAE,KAAK,WAAO;AACjC,cAAQ,QAAQ;AAChB,cAAQ,cAAc;AAAA,IAC1B,CAAC,EAAE,MAAM,WAAS;AACd,WAAK,eAAe,IAAI,OAAO;AAC/B,UAAI,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACjD,CAAC;AACD,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAGJ;AA/Ca,cAEe,iBAAiB,oBAAI,QAAiB;","names":[]}
@@ -1,4 +1,77 @@
1
1
  // src/util/log.ts
2
+ var runtime = globalThis;
3
+ var levels = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };
4
+ var colors = { debug: 90, info: 36, warn: 33, error: 31 };
5
+ var threshold = "warn";
6
+ var namespaces;
7
+ var logHandler;
8
+ var tagStyle;
9
+ var switchRead = false;
10
+ var switchThreshold;
11
+ var switchNamespaces;
12
+ function readSwitch() {
13
+ switchRead = true;
14
+ let value;
15
+ if (typeof runtime.process?.versions?.node === "string") {
16
+ value = runtime.process.env?.MINERENDER_LOG;
17
+ } else {
18
+ try {
19
+ value = runtime.localStorage?.getItem("minerender:log");
20
+ } catch {
21
+ }
22
+ }
23
+ if (value) {
24
+ for (const entry of value.split(",")) {
25
+ const separator = entry.indexOf("=");
26
+ const name = separator < 0 ? void 0 : entry.slice(0, separator).trim();
27
+ const setting = (separator < 0 ? entry : entry.slice(separator + 1)).trim();
28
+ if (!Object.prototype.hasOwnProperty.call(levels, setting) || name === "") continue;
29
+ if (name === void 0) {
30
+ switchThreshold = setting;
31
+ } else {
32
+ switchNamespaces ?? (switchNamespaces = /* @__PURE__ */ new Map());
33
+ switchNamespaces.set(name, setting);
34
+ }
35
+ }
36
+ }
37
+ }
38
+ var Logging = class {
39
+ /** Updates the given settings and keeps the others. */
40
+ static configure(options) {
41
+ if (options.level !== void 0) threshold = options.level;
42
+ if (options.namespaces !== void 0) namespaces = new Map(Object.entries(options.namespaces));
43
+ }
44
+ /** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */
45
+ static setHandler(handler) {
46
+ logHandler = handler;
47
+ }
48
+ };
49
+ function logger(namespace) {
50
+ const write = (level, args) => {
51
+ if (!switchRead) readSwitch();
52
+ if (levels[level] < levels[switchNamespaces?.get(namespace) ?? switchThreshold ?? namespaces?.get(namespace) ?? threshold]) return;
53
+ if (logHandler) {
54
+ logHandler(level, namespace, args);
55
+ return;
56
+ }
57
+ if (tagStyle === void 0) {
58
+ tagStyle = typeof runtime.process?.versions?.node === "string" ? runtime.process.stdout?.isTTY === true ? "ansi" : "plain" : "browser";
59
+ }
60
+ if (tagStyle === "browser") {
61
+ console[level](`%cMineRender%c ${namespace}`, "background:#3c8527;color:#fff;border-radius:3px;padding:0 4px", "font-weight:bold", ...args);
62
+ } else {
63
+ const color = colors[level];
64
+ const tag = `[minerender:${namespace}]`;
65
+ console[level](tagStyle === "ansi" ? `\x1B[${color}m${tag}\x1B[0m` : tag, ...args);
66
+ }
67
+ };
68
+ return {
69
+ debug: (...args) => write("debug", args),
70
+ info: (...args) => write("info", args),
71
+ warn: (...args) => write("warn", args),
72
+ error: (...args) => write("error", args)
73
+ };
74
+ }
2
75
  var Reset = "\x1B[0m";
3
76
  var FgGreen = "\x1B[32m";
4
77
  var BgBlack = "\x1B[40m";
@@ -6,6 +79,8 @@ function prefix(prefix2) {
6
79
  return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
7
80
  }
8
81
  export {
82
+ Logging,
83
+ logger,
9
84
  prefix
10
85
  };
11
86
  //# sourceMappingURL=log.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/util/log.ts"],"sourcesContent":["// https://stackoverflow.com/a/41407246/6257838\nconst Reset = \"\\x1b[0m\"\nconst Bright = \"\\x1b[1m\"\nconst Dim = \"\\x1b[2m\"\nconst Underscore = \"\\x1b[4m\"\nconst Blink = \"\\x1b[5m\"\nconst Reverse = \"\\x1b[7m\"\nconst Hidden = \"\\x1b[8m\"\n\nconst FgBlack = \"\\x1b[30m\"\nconst FgRed = \"\\x1b[31m\"\nconst FgGreen = \"\\x1b[32m\"\nconst FgYellow = \"\\x1b[33m\"\nconst FgBlue = \"\\x1b[34m\"\nconst FgMagenta = \"\\x1b[35m\"\nconst FgCyan = \"\\x1b[36m\"\nconst FgWhite = \"\\x1b[37m\"\n\nconst BgBlack = \"\\x1b[40m\"\nconst BgRed = \"\\x1b[41m\"\nconst BgGreen = \"\\x1b[42m\"\nconst BgYellow = \"\\x1b[43m\"\nconst BgBlue = \"\\x1b[44m\"\nconst BgMagenta = \"\\x1b[45m\"\nconst BgCyan = \"\\x1b[46m\"\nconst BgWhite = \"\\x1b[47m\"\n\nexport function prefix(prefix?: string): string {\n return `${ FgGreen }MR${ BgBlack }${ prefix ?? '' }${ Reset }`\n}\n"],"mappings":";AACA,IAAM,QAAQ;AAUd,IAAM,UAAU;AAOhB,IAAM,UAAU;AAST,SAAS,OAAOA,SAAyB;AAC5C,SAAO,GAAI,OAAQ,KAAM,OAAQ,GAAIA,WAAU,EAAG,GAAI,KAAM;AAChE;","names":["prefix"]}
1
+ {"version":3,"sources":["../../../../src/util/log.ts"],"sourcesContent":["/** Severity of a log message, from most to least verbose. */\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/** The lowest level that is printed, or `\"silent\"` to print nothing. */\nexport type LogThreshold = LogLevel | \"silent\";\n\n/** Receives each message that passes the threshold. `args` are the logger call's arguments, without a tag. */\nexport type LogHandler = (level: LogLevel, namespace: string, args: unknown[]) => void;\n\nexport interface LoggingOptions {\n /** Threshold for namespaces without an override. Starts at `\"warn\"`. */\n level?: LogThreshold;\n /** Thresholds by logger name, such as `{ UVMapper: \"debug\" }`. Replaces earlier overrides. */\n namespaces?: Record<string, LogThreshold>;\n}\n\nexport interface Logger {\n debug(...args: unknown[]): void;\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\ntype Runtime = {\n process?: { versions?: { node?: string }; stdout?: { isTTY?: boolean }; env?: Record<string, string | undefined> };\n localStorage?: { getItem(key: string): string | null };\n};\n\nconst runtime = globalThis as Runtime;\nconst levels: Record<LogThreshold, number> = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };\nconst colors: Record<LogLevel, number> = { debug: 90, info: 36, warn: 33, error: 31 };\n\nlet threshold: LogThreshold = \"warn\";\nlet namespaces: Map<string, LogThreshold> | undefined;\nlet logHandler: LogHandler | undefined;\nlet tagStyle: \"plain\" | \"ansi\" | \"browser\" | undefined;\nlet switchRead = false;\nlet switchThreshold: LogThreshold | undefined;\nlet switchNamespaces: Map<string, LogThreshold> | undefined;\n\nfunction readSwitch(): void {\n switchRead = true;\n let value: string | null | undefined;\n if (typeof runtime.process?.versions?.node === \"string\") {\n value = runtime.process.env?.MINERENDER_LOG;\n } else {\n try {\n value = runtime.localStorage?.getItem(\"minerender:log\");\n } catch {\n // Sandboxed pages can deny access to storage.\n }\n }\n if (value) {\n for (const entry of value.split(\",\")) {\n const separator = entry.indexOf(\"=\");\n const name = separator < 0 ? undefined : entry.slice(0, separator).trim();\n const setting = (separator < 0 ? entry : entry.slice(separator + 1)).trim();\n if (!Object.prototype.hasOwnProperty.call(levels, setting) || name === \"\") continue;\n if (name === undefined) {\n switchThreshold = setting as LogThreshold;\n } else {\n switchNamespaces ??= new Map();\n switchNamespaces.set(name, setting as LogThreshold);\n }\n }\n }\n}\n\n/** Global log settings for every MineRender logger. */\nexport class Logging {\n /** Updates the given settings and keeps the others. */\n static configure(options: LoggingOptions): void {\n if (options.level !== undefined) threshold = options.level;\n if (options.namespaces !== undefined) namespaces = new Map(Object.entries(options.namespaces));\n }\n\n /** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */\n static setHandler(handler?: LogHandler): void {\n logHandler = handler;\n }\n}\n\n/** Creates a logger whose messages are tagged and filtered as `namespace`. */\nexport function logger(namespace: string): Logger {\n const write = (level: LogLevel, args: unknown[]): void => {\n if (!switchRead) readSwitch();\n if (levels[level] < levels[switchNamespaces?.get(namespace) ?? switchThreshold ?? namespaces?.get(namespace) ?? threshold]) return;\n if (logHandler) {\n logHandler(level, namespace, args);\n return;\n }\n if (tagStyle === undefined) {\n tagStyle = typeof runtime.process?.versions?.node === \"string\"\n ? runtime.process.stdout?.isTTY === true ? \"ansi\" : \"plain\"\n : \"browser\";\n }\n if (tagStyle === \"browser\") {\n console[level](`%cMineRender%c ${namespace}`, \"background:#3c8527;color:#fff;border-radius:3px;padding:0 4px\", \"font-weight:bold\", ...args);\n } else {\n const color = colors[level];\n const tag = `[minerender:${namespace}]`;\n console[level](tagStyle === \"ansi\" ? `\\x1b[${color}m${tag}\\x1b[0m` : tag, ...args);\n }\n };\n return {\n debug: (...args) => write(\"debug\", args),\n info: (...args) => write(\"info\", args),\n warn: (...args) => write(\"warn\", args),\n error: (...args) => write(\"error\", args),\n };\n}\n\nconst Reset = \"\\x1b[0m\"\nconst FgGreen = \"\\x1b[32m\"\nconst BgBlack = \"\\x1b[40m\"\n\n/** @deprecated Use {@link logger}. */\nexport function prefix(prefix?: string): string {\n return `${ FgGreen }MR${ BgBlack }${ prefix ?? '' }${ Reset }`\n}\n"],"mappings":";AA4BA,IAAM,UAAU;AAChB,IAAM,SAAuC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,EAAE;AAC/F,IAAM,SAAmC,EAAE,OAAO,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,GAAG;AAEpF,IAAI,YAA0B;AAC9B,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI,aAAa;AACjB,IAAI;AACJ,IAAI;AAEJ,SAAS,aAAmB;AACxB,eAAa;AACb,MAAI;AACJ,MAAI,OAAO,QAAQ,SAAS,UAAU,SAAS,UAAU;AACrD,YAAQ,QAAQ,QAAQ,KAAK;AAAA,EACjC,OAAO;AACH,QAAI;AACA,cAAQ,QAAQ,cAAc,QAAQ,gBAAgB;AAAA,IAC1D,QAAQ;AAAA,IAER;AAAA,EACJ;AACA,MAAI,OAAO;AACP,eAAW,SAAS,MAAM,MAAM,GAAG,GAAG;AAClC,YAAM,YAAY,MAAM,QAAQ,GAAG;AACnC,YAAM,OAAO,YAAY,IAAI,SAAY,MAAM,MAAM,GAAG,SAAS,EAAE,KAAK;AACxE,YAAM,WAAW,YAAY,IAAI,QAAQ,MAAM,MAAM,YAAY,CAAC,GAAG,KAAK;AAC1E,UAAI,CAAC,OAAO,UAAU,eAAe,KAAK,QAAQ,OAAO,KAAK,SAAS,GAAI;AAC3E,UAAI,SAAS,QAAW;AACpB,0BAAkB;AAAA,MACtB,OAAO;AACH,gDAAqB,oBAAI,IAAI;AAC7B,yBAAiB,IAAI,MAAM,OAAuB;AAAA,MACtD;AAAA,IACJ;AAAA,EACJ;AACJ;AAGO,IAAM,UAAN,MAAc;AAAA;AAAA,EAEjB,OAAO,UAAU,SAA+B;AAC5C,QAAI,QAAQ,UAAU,OAAW,aAAY,QAAQ;AACrD,QAAI,QAAQ,eAAe,OAAW,cAAa,IAAI,IAAI,OAAO,QAAQ,QAAQ,UAAU,CAAC;AAAA,EACjG;AAAA;AAAA,EAGA,OAAO,WAAW,SAA4B;AAC1C,iBAAa;AAAA,EACjB;AACJ;AAGO,SAAS,OAAO,WAA2B;AAC9C,QAAM,QAAQ,CAAC,OAAiB,SAA0B;AACtD,QAAI,CAAC,WAAY,YAAW;AAC5B,QAAI,OAAO,KAAK,IAAI,OAAO,kBAAkB,IAAI,SAAS,KAAK,mBAAmB,YAAY,IAAI,SAAS,KAAK,SAAS,EAAG;AAC5H,QAAI,YAAY;AACZ,iBAAW,OAAO,WAAW,IAAI;AACjC;AAAA,IACJ;AACA,QAAI,aAAa,QAAW;AACxB,iBAAW,OAAO,QAAQ,SAAS,UAAU,SAAS,WAChD,QAAQ,QAAQ,QAAQ,UAAU,OAAO,SAAS,UAClD;AAAA,IACV;AACA,QAAI,aAAa,WAAW;AACxB,cAAQ,KAAK,EAAE,kBAAkB,SAAS,IAAI,iEAAiE,oBAAoB,GAAG,IAAI;AAAA,IAC9I,OAAO;AACH,YAAM,QAAQ,OAAO,KAAK;AAC1B,YAAM,MAAM,eAAe,SAAS;AACpC,cAAQ,KAAK,EAAE,aAAa,SAAS,QAAQ,KAAK,IAAI,GAAG,YAAY,KAAK,GAAG,IAAI;AAAA,IACrF;AAAA,EACJ;AACA,SAAO;AAAA,IACH,OAAO,IAAI,SAAS,MAAM,SAAS,IAAI;AAAA,IACvC,MAAM,IAAI,SAAS,MAAM,QAAQ,IAAI;AAAA,IACrC,MAAM,IAAI,SAAS,MAAM,QAAQ,IAAI;AAAA,IACrC,OAAO,IAAI,SAAS,MAAM,SAAS,IAAI;AAAA,EAC3C;AACJ;AAEA,IAAM,QAAQ;AACd,IAAM,UAAU;AAChB,IAAM,UAAU;AAGT,SAAS,OAAOA,SAAyB;AAC5C,SAAO,GAAI,OAAQ,KAAM,OAAQ,GAAIA,WAAU,EAAG,GAAI,KAAM;AAChE;","names":["prefix"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/util/performance.ts"],"sourcesContent":["export function captureException(e: any, ...extra: any[]) {\n console.error(e, extra);\n //TODO\n}\n\nexport function timingStart(marker: string) {\n console.time(marker);\n //TODO\n}\n\nexport function timingEnd(marker: string) {\n console.timeEnd(marker);\n //TODO\n}\n"],"mappings":";AAAO,SAAS,iBAAiB,MAAW,OAAc;AACtD,UAAQ,MAAM,GAAG,KAAK;AAE1B;AAEO,SAAS,YAAY,QAAgB;AACxC,UAAQ,KAAK,MAAM;AAEvB;AAEO,SAAS,UAAU,QAAgB;AACtC,UAAQ,QAAQ,MAAM;AAE1B;","names":[]}
1
+ {"version":3,"sources":["../../../../src/util/performance.ts"],"sourcesContent":["/** @deprecated Unused by MineRender. */\nexport function captureException(e: any, ...extra: any[]) {\n console.error(e, extra);\n //TODO\n}\n\n/** @deprecated Unused by MineRender. */\nexport function timingStart(marker: string) {\n console.time(marker);\n //TODO\n}\n\n/** @deprecated Unused by MineRender. */\nexport function timingEnd(marker: string) {\n console.timeEnd(marker);\n //TODO\n}\n"],"mappings":";AACO,SAAS,iBAAiB,MAAW,OAAc;AACtD,UAAQ,MAAM,GAAG,KAAK;AAE1B;AAGO,SAAS,YAAY,QAAgB;AACxC,UAAQ,KAAK,MAAM;AAEvB;AAGO,SAAS,UAAU,QAAgB;AACtC,UAAQ,QAAQ,MAAM;AAE1B;","names":[]}
@@ -134,11 +134,14 @@ var Chunk = class _Chunk {
134
134
  this.biomes = copy;
135
135
  return this.refreshBiomes();
136
136
  }
137
- /** Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects. */
138
- refreshBiomes(columns) {
139
- return this.changeBlocks(() => this.refreshBiomeBlocks(columns), true);
137
+ /**
138
+ * Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects.
139
+ * The owning world can defer neighbor culling until all affected chunks are refreshed.
140
+ */
141
+ refreshBiomes(columns, deferCulling = false) {
142
+ return this.changeBlocks(() => this.refreshBiomeBlocks(columns, deferCulling), true);
140
143
  }
141
- async refreshBiomeBlocks(columns) {
144
+ async refreshBiomeBlocks(columns, deferCulling = false) {
142
145
  const blend = columns && this.biomeBlend?.();
143
146
  const ownColumn = columns?.some((column) => column.x === this.x && column.z === this.z);
144
147
  const affected = /* @__PURE__ */ new Map();
@@ -195,7 +198,7 @@ var Chunk = class _Chunk {
195
198
  this.renderedBlocks.get(index)?.object?.setVisible(false);
196
199
  }
197
200
  const positions = blocks.map(({ index }) => new Vector3(...this.positionAt(index)));
198
- if (this.onBlocksChanged) await this.onBlocksChanged(positions);
201
+ if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);
199
202
  else await this.rebuildSectionMesh();
200
203
  }
201
204
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/world/Chunk.ts"],"sourcesContent":["import { Block } from \"../model/block/Block\";\nimport { BlockObject } from \"../model/block/scene/BlockObject\";\nimport { Color, Mesh, Object3D, Raycaster, Vector3 } from \"three\";\nimport { Maybe } from \"../util/util\";\nimport { BlockInfo } from \"./BlockInfo\";\nimport { ChunkData } from \"./ChunkData\";\nimport { MineRenderScene } from \"../renderer/MineRenderScene\";\nimport { BlockStates } from \"../assets/BlockStates\";\nimport { AssetKey } from \"../assets/AssetKey\";\nimport { MineRenderWorld } from \"./MineRenderWorld\";\nimport { isTripleArray, TripleArray } from \"../model/Model\";\nimport { SectionModels } from \"./SectionModels\";\nimport { BlockEntities } from \"../assets/BlockEntities\";\nimport { SectionFluids, SectionMesh, SectionMeshEntry } from \"./SectionMesh\";\nimport { FluidKind, getBlockFluidState } from \"../model/fluid/FluidGeometry\";\nimport { fluidKindOf } from \"../model/fluid/FluidQuads\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { CUBE_FACE_OFFSETS } from \"../CubeFace\";\nimport { BlockTints } from \"../model/block/BlockTints\";\nimport { Biomes, BiomeColorKind } from \"../assets/Biomes\";\nimport { BiomeBlend } from \"./_biomes/BiomeBlend\";\nimport { isInstanceReference } from \"../instance/InstanceReference\";\nimport type { InstanceReference } from \"../instance/InstanceReference\";\nimport type { ModelObject } from \"../model/scene/ModelObject\";\nimport type { WorldBlockIntersection } from \"./WorldBlockIntersection\";\nimport { hitNormal, pickableMeshes, visibleHits } from \"./_picking/Picking\";\nimport { BlockCullingData, BlockCullingRule, blockCullingRule, skipsBlockFace } from \"./_culling/BlockCulling\";\n\nconst WATER_TINT = new Color(0x3f76e4).toArray() as TripleArray;\n\n/**\n * A 16×16×16 block section and its render objects.\n * Constructor coordinates identify the section. Block accessors use world block coordinates\n * unless their name explicitly refers to positions within the chunk.\n */\nexport class Chunk<SectionMeshing extends boolean = false> {\n\n public readonly scene: MineRenderScene; //TODO: should probably be the world\n\n public readonly x: number;\n public readonly y: number;\n public readonly z: number;\n\n private readonly data = new ChunkData();\n private readonly renderedBlocks = new Map<number, BlockInfo<SectionMeshing>>();\n private readonly objectBlocks = new Set<number>();\n private readonly sectionBlocks = new Map<number, SectionMeshEntry[]>();\n private readonly hiddenBlocks = new Set<number>();\n private readonly fluidCells = new Uint8Array(4096);\n private readonly blockPosition = new Vector3();\n private waterTints?: Float32Array;\n private biomes?: readonly string[];\n private sectionMesh?: SectionMesh;\n private meshDirty = false;\n private meshGeneration = 0;\n private ambientOcclusionCells?: Uint8Array;\n private readonly blockChanges = new Set<Promise<unknown>>();\n private biomeChange?: Promise<unknown>;\n\n constructor(scene: MineRenderScene, x: number, y: number, z: number,\n private readonly onBlocksChanged?: (positions: Vector3[]) => Promise<void>,\n private readonly sectionModels?: SectionModels,\n private readonly neighborCell?: (x: number, y: number, z: number) => number,\n private readonly biomeAt?: (x: number, y: number, z: number) => Maybe<string>,\n private readonly onBiomesChanged?: (biomes?: readonly string[]) => Promise<void>,\n private readonly lightAt?: (x: number, y: number, z: number) => number,\n private readonly onLightCleared?: () => Promise<void>,\n private readonly ambientLight = 0,\n private readonly biomeBlend?: () => BiomeBlend | undefined) {\n this.scene = scene;\n this.x = x;\n this.y = y;\n this.z = z;\n }\n\n /** Finds the nearest owned block hit across sections, testing each shared mesh once. */\n public static raycast<SectionMeshing extends boolean>(chunks: Iterable<Chunk<SectionMeshing>>, raycaster: Raycaster): WorldBlockIntersection | undefined {\n type Owner = { chunk: Chunk<SectionMeshing>; index: number };\n const roots = new Map<Object3D, Mesh[]>();\n const targets = new Map<Mesh, {\n owners: Map<number | undefined, Owner>;\n section?: { chunk: Chunk<SectionMeshing>; mesh: SectionMesh };\n }>();\n const meshes = (root: Object3D, scene: MineRenderScene): Mesh[] => {\n const cached = roots.get(root);\n if (cached) return cached;\n const result = pickableMeshes(root, scene, raycaster);\n roots.set(root, result);\n return result;\n };\n const add = (root: Object3D, owner: Owner, reference?: InstanceReference<ModelObject>) => {\n for (const mesh of meshes(root, owner.chunk.scene)) {\n if (reference && reference.instanceable.getInstanceReference(mesh, reference.index) !== reference) continue;\n let entry = targets.get(mesh);\n if (!entry) targets.set(mesh, entry = { owners: new Map() });\n entry.owners.set(reference?.index, owner);\n }\n };\n for (const chunk of chunks) {\n for (const index of chunk.objectBlocks) {\n const block = chunk.renderedBlocks.get(index)!.object;\n if (!block || !block.visible || chunk.hiddenBlocks.has(index)) continue;\n const owner = { chunk, index };\n for (const model of block.models) {\n if (isInstanceReference(model)) {\n if (model.instanceable.isInstanceActive(model.index, model)) add(model.instanceable, owner, model);\n } else {\n add(model, owner);\n }\n }\n for (const entity of block.blockEntities) add(entity, owner);\n }\n if (chunk.sectionMesh) {\n for (const mesh of meshes(chunk.sectionMesh, chunk.scene)) {\n targets.set(mesh, { owners: new Map(), section: { chunk, mesh: chunk.sectionMesh } });\n }\n }\n }\n for (const hit of visibleHits(raycaster, [...targets.keys()])) {\n const mesh = hit.object as Mesh;\n const entry = targets.get(mesh)!;\n let owner = entry.owners.get(hit.instanceId) ?? entry.owners.get(undefined);\n if (entry.section) {\n const index = entry.section.mesh.getBlockIndex(hit);\n if (index !== undefined) owner = { chunk: entry.section.chunk, index };\n }\n if (!owner || owner.chunk.hiddenBlocks.has(owner.index)) continue;\n const info = owner.chunk.renderedBlocks.get(owner.index);\n if (!info) continue;\n return {\n position: new Vector3(owner.chunk.x * 16 + owner.index % 16,\n owner.chunk.y * 16 + Math.floor(owner.index / 256), owner.chunk.z * 16 + Math.floor(owner.index / 16) % 16),\n block: info.block,\n point: hit.point.clone(),\n normal: hitNormal(hit),\n distance: hit.distance\n };\n }\n return undefined;\n }\n\n public getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo<SectionMeshing>>;\n public getBlockAt(pos: Vector3): Maybe<BlockInfo<SectionMeshing>>;\n public getBlockAt(pos: TripleArray): Maybe<BlockInfo<SectionMeshing>>;\n public getBlockAt(posOrX: number | Vector3 | TripleArray, y?: number, z?: number): Maybe<BlockInfo<SectionMeshing>> {\n if (typeof posOrX == \"number\") {\n return this.getBlockAt(new Vector3(posOrX, y, z));\n }\n if (isTripleArray(posOrX)) {\n return this.getBlockAt(new Vector3(posOrX[0], posOrX[1], posOrX[2]))\n }\n const pos = this.blockPosition.set(posOrX.x - this.x * 16, posOrX.y - this.y * 16, posOrX.z - this.z * 16);\n const index = Chunk.chunkPosToBlockIndex(pos);\n return this.renderedBlocks.get(index);\n }\n\n /** Returns the saved 4-block biome sample at integer world block coordinates, or `undefined` if absent. */\n public getBiomeAt(x: number, y: number, z: number): Maybe<string>;\n public getBiomeAt(pos: Vector3): Maybe<string>;\n public getBiomeAt(pos: TripleArray): Maybe<string>;\n public getBiomeAt(posOrX: number | Vector3 | TripleArray, y?: number, z?: number): Maybe<string> {\n if (typeof posOrX === \"number\") return this.getBiomeAt(new Vector3(posOrX, y, z));\n if (isTripleArray(posOrX)) return this.getBiomeAt(new Vector3(...posOrX));\n const pos = this.worldPosToChunkPos(posOrX);\n Chunk.chunkPosToBlockIndex(pos);\n return this.biomeAt ? this.biomeAt(posOrX.x, posOrX.y, posOrX.z)\n : this.biomes?.[Math.floor(pos.x / 4) + Math.floor(pos.z / 4) * 4 + Math.floor(pos.y / 4) * 16];\n }\n\n /** Copies 64 biome IDs in x + z * 4 + y * 16 order and refreshes placed blocks. Omit the array to clear biome data. */\n public setBiomes(biomes?: readonly string[]): Promise<void> {\n const copy = biomes ? [...biomes] : undefined;\n if (copy && (copy.length !== 64 || !copy.every(id => typeof id === \"string\" && id.length > 0))) {\n throw new RangeError(\"Section biomes must contain 64 nonempty biome IDs\");\n }\n if (this.onBiomesChanged) return this.onBiomesChanged(copy);\n this.biomes = copy;\n return this.refreshBiomes();\n }\n\n /** Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects. */\n public refreshBiomes(columns?: readonly { x: number; z: number }[]): Promise<void> {\n return this.changeBlocks(() => this.refreshBiomeBlocks(columns), true);\n }\n\n private async refreshBiomeBlocks(columns?: readonly { x: number; z: number }[]): Promise<void> {\n const blend = columns && this.biomeBlend?.();\n // Individual objects keep their own biome's unblended color, so only a change to their own column affects them.\n const ownColumn = columns?.some(column => column.x === this.x && column.z === this.z);\n const affected = new Map<string, Promise<boolean>>();\n const blocks: { index: number; block: Block }[] = [];\n for (const index of this.renderedBlocks.keys()) {\n if (blend) {\n if (this.objectBlocks.has(index) && !ownColumn) continue;\n const [x, , z] = this.positionAt(index), radius = blend.radius;\n if (!columns!.some(column => x >= column.x * 16 - radius && x <= column.x * 16 + 15 + radius\n && z >= column.z * 16 - radius && z <= column.z * 16 + 15 + radius)) continue;\n }\n const block = this.data.get(index)!;\n const stateKey = ChunkData.paletteKey(block);\n let matches = affected.get(stateKey);\n if (!matches) {\n const key = AssetKey.parse(\"blockstates\", block.type);\n matches = BlockStates.get(key).then(async state => {\n const origin = state?.key ?? key;\n const [source, fluid] = await Promise.all([BlockTints.biomeSource(origin), getBlockFluidState(origin, block.properties)]);\n return !!source || fluid?.kind === \"water\";\n });\n affected.set(stateKey, matches);\n }\n if (await matches) blocks.push({ index, block });\n }\n if (blend) {\n const groups = new Map<string, typeof blocks>();\n for (const entry of blocks) {\n const key = ChunkData.paletteKey(entry.block);\n let group = groups.get(key);\n if (!group) groups.set(key, group = []);\n group.push(entry);\n }\n blocks.length = 0;\n const biomes = new Map<string, Promise<boolean>>();\n for (const group of groups.values()) {\n const { contexts, fluid } = await this.resolveState(group[0].block, group.map(entry => entry.index), biomes);\n for (const entry of group) {\n const context = contexts.get(entry.index);\n const current = this.sectionBlocks.get(entry.index)?.[0]?.biomeTint;\n const tint = context?.tint;\n const tintChanged = !!current !== !!tint || tint?.some((value, channel) => value !== current?.[channel]);\n const waterChanged = fluid?.kind === \"water\" && (context?.waterTint ?? WATER_TINT).some((value, channel) =>\n Math.fround(value) !== (this.waterTints?.[entry.index * 3 + channel] ?? Math.fround(WATER_TINT[channel])));\n if (this.objectBlocks.has(entry.index) || tintChanged || waterChanged) blocks.push(entry);\n }\n }\n }\n if (!blocks.length) return;\n const hidden = new Set(this.hiddenBlocks);\n try {\n await this.replaceBlocks(blocks, true);\n } finally {\n for (const index of hidden) {\n this.hiddenBlocks.add(index);\n this.renderedBlocks.get(index)?.object?.setVisible(false);\n }\n const positions = blocks.map(({ index }) => new Vector3(...this.positionAt(index)));\n if (this.onBlocksChanged) await this.onBlocksChanged(positions);\n else await this.rebuildSectionMesh();\n }\n }\n\n /**\n * Places a block at integer world block coordinates. Pass `undefined` to remove it.\n */\n public async setBlockAt(x: number, y: number, z: number, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;\n public async setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;\n public async setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;\n public async setBlockAt(posOrX: number | Vector3 | TripleArray, yOrBlock?: number | Block, z?: number, block?: Block): Promise<Maybe<BlockInfo<SectionMeshing>>> {\n if (typeof posOrX == \"number\") {\n return this.setBlockAt(new Vector3(posOrX, yOrBlock as number, z), block as Block);\n }\n if (isTripleArray(posOrX)) {\n return this.setBlockAt(new Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock as Block);\n }\n const worldPos: Vector3 = posOrX;\n const pos: Vector3 = this.worldPosToChunkPos(worldPos);\n block = yOrBlock as Block;\n\n return this.setBlockInChunkAt(pos, block, worldPos);\n }\n\n /**\n * Places a block at integer chunk-local coordinates from 0 to 15.\n */\n public async setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3,\n onBlocksChanged = this.onBlocksChanged): Promise<Maybe<BlockInfo<SectionMeshing>>> {\n if (typeof worldPos === \"undefined\") {\n worldPos = this.chunkPosToWorldPos(pos);\n }\n\n const index = Chunk.chunkPosToBlockIndex(pos);\n try {\n await this.placeBlocks([{ index, block }]);\n return this.renderedBlocks.get(index);\n } finally {\n await onBlocksChanged?.([worldPos]);\n }\n }\n\n /** Places cells in input order and returns changed world positions without refreshing neighbors. */\n public async placeBlocks(blocks: readonly { index: number; block: Maybe<Block> }[]): Promise<Vector3[]> {\n return this.changeBlocks(() => this.replaceBlocks(blocks));\n }\n\n private changeBlocks<T>(change: () => Promise<T>, refreshBiomes = false): Promise<T> {\n // Color refreshes snapshot existing blocks; edits on either side of that snapshot must retain their order.\n const before = refreshBiomes ? Promise.allSettled(this.blockChanges) : this.biomeChange;\n const result = before ? before.catch(() => undefined).then(change) : change();\n const pending = result.finally(() => {\n this.blockChanges.delete(pending);\n if (this.biomeChange === pending) this.biomeChange = undefined;\n });\n this.blockChanges.add(pending);\n if (refreshBiomes) this.biomeChange = pending;\n return pending;\n }\n\n private async replaceBlocks(blocks: readonly { index: number; block: Maybe<Block> }[], preserveDataOnFailure = false): Promise<Vector3[]> {\n const placements = blocks.map(({ index, block }) => ({\n index,\n key: block && !ChunkData.isAir(block) ? ChunkData.paletteKey(block) : undefined,\n block: block ? {\n type: block.type,\n properties: block.properties ? { ...block.properties } : undefined,\n nbt: block.nbt === undefined ? undefined : structuredClone(block.nbt)\n } : undefined\n }));\n const states = new Map<string, { stored: Block; indices: number[] }>();\n for (const { index, key, block } of placements) {\n if (key === undefined) continue;\n let state = states.get(key);\n if (!state) states.set(key, state = { stored: block!, indices: [] });\n state.indices.push(index);\n }\n const biomes = new Map<string, Promise<boolean>>();\n const settled = await Promise.allSettled([...states.values()].map(({ stored, indices }) =>\n this.resolveState(stored, indices, biomes)));\n const resolutions = new Map([...states.keys()].map((key, i) => [key, settled[i]]));\n if (preserveDataOnFailure) {\n const rejected = settled.find(result => result.status === \"rejected\");\n if (rejected?.status === \"rejected\") throw rejected.reason;\n }\n const positions: Vector3[] = [];\n let failed = false, failure: unknown;\n for (const { index, key, block } of placements) {\n this.hiddenBlocks.delete(index);\n this.data.assign(index, this.data.intern(block), block?.nbt);\n const readBlock = this.data.snapshot(index);\n this.renderedBlocks.get(index)?.object?.removeFromScene();\n if (this.sectionBlocks.delete(index)) this.meshDirty = true;\n if (this.fluidCells[index]) this.meshDirty = true;\n this.fluidCells[index] = 0;\n this.renderedBlocks.delete(index);\n this.objectBlocks.delete(index);\n const worldPos = new Vector3(this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256),\n this.z * 16 + Math.floor(index / 16) % 16);\n positions.push(worldPos);\n let object: BlockObject | undefined;\n try {\n if (!readBlock) continue;\n const resolved = resolutions.get(key!)!;\n if (resolved.status === \"rejected\") throw resolved.reason;\n const { blockState, perBlock, fluid, prepared, contexts, stored } = resolved.value;\n const context = contexts.get(index);\n if (!blockState) {\n this.data.assign(index, 0);\n continue;\n }\n const variantPosition = worldPos.toArray();\n if (fluid) {\n this.fluidCells[index] = (fluid.kind === \"water\" ? 16 : 32) | Math.min(fluid.level, 8);\n if (fluid.kind === \"water\") this.setWaterTint(index, context?.waterTint);\n this.meshDirty = true;\n }\n const templates = perBlock ? undefined : fluid?.renderModel === false ? [] : (context?.prepared ?? prepared)?.pick(variantPosition);\n if (templates) {\n this.sectionBlocks.set(index, templates.map(template => ({ index, template, cullMask: 0, biomeTint: context?.tint })));\n this.meshDirty = true;\n } else {\n object = await this.scene.addBlock(blockState, {\n mergeMeshes: true,\n instanceMeshes: true,\n maxInstanceCount: 2000,\n initialState: stored.properties,\n variantPosition, biome: context?.biome,\n biomePosition: this.biomePosition(index, blockState, stored)\n }) as BlockObject;\n object.setPosition(MineRenderWorld.worldToScenePosition(worldPos));\n }\n this.renderedBlocks.set(index, { get block() { return readBlock(); }, object } as BlockInfo<SectionMeshing>);\n if (object) this.objectBlocks.add(index);\n } catch (error) {\n if (preserveDataOnFailure && readBlock) {\n // Keep saved block data available for a failed color refresh to retry.\n this.renderedBlocks.set(index, { get block() { return readBlock(); }, object: undefined } as BlockInfo<SectionMeshing>);\n } else this.data.assign(index, 0);\n this.fluidCells[index] = 0;\n object?.removeFromScene();\n if (!failed) failure = error;\n failed = true;\n }\n }\n if (failed) throw failure;\n return positions;\n }\n\n /** Replaces every cell from parsed section data. The caller refreshes neighbor culling. */\n public placeSection(data: ChunkData): Promise<void> {\n return this.changeBlocks(() => this.replaceSection(data));\n }\n\n private async replaceSection(data: ChunkData): Promise<void> {\n for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();\n this.sectionBlocks.clear();\n this.fluidCells.fill(0);\n this.waterTints = undefined;\n this.renderedBlocks.clear();\n this.objectBlocks.clear();\n this.hiddenBlocks.clear();\n this.meshDirty = true;\n this.data.copyFrom(data);\n\n const ids = new Map<number, number[]>();\n for (let index = 0; index < 4096; index++) {\n const id = this.data.idAt(index);\n if (!id) continue;\n let indices = ids.get(id);\n if (!indices) ids.set(id, indices = []);\n indices.push(index);\n }\n const palette = [...ids.keys()], biomes = new Map<string, Promise<boolean>>();\n const settled = await Promise.allSettled(palette.map(id =>\n this.resolveState(this.data.stateAt(id)!, ids.get(id)!, biomes)));\n const resolutions = new Map(palette.map((id, i) => [id, settled[i]]));\n const perBlocks: { index: number; blockState: BlockState; biome?: string }[] = [];\n let failed = false, failure: unknown;\n for (let index = 0; index < 4096; index++) {\n const id = this.data.idAt(index);\n if (!id) continue;\n try {\n const resolved = resolutions.get(id)!;\n if (resolved.status === \"rejected\") throw resolved.reason;\n const { blockState, perBlock, fluid, prepared, contexts } = resolved.value;\n const context = contexts.get(index);\n if (!blockState) {\n this.data.assign(index, 0);\n this.fluidCells[index] = 0;\n continue;\n }\n if (fluid) {\n this.fluidCells[index] = (fluid.kind === \"water\" ? 16 : 32) | Math.min(fluid.level, 8);\n if (fluid.kind === \"water\") this.setWaterTint(index, context?.waterTint);\n }\n const variantPosition: TripleArray = [this.x * 16 + index % 16,\n this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];\n const templates = perBlock ? undefined : fluid?.renderModel === false ? [] : (context?.prepared ?? prepared)?.pick(variantPosition);\n if (templates) {\n this.sectionBlocks.set(index, templates.map(template => ({ index, template, cullMask: 0, biomeTint: context?.tint })));\n this.meshDirty = true;\n } else {\n perBlocks.push({ index, blockState, biome: context?.biome });\n }\n const readBlock = this.data.snapshot(index)!;\n this.renderedBlocks.set(index, { get block() { return readBlock(); }, object: undefined } as BlockInfo<SectionMeshing>);\n this.objectBlocks.delete(index);\n } catch (error) {\n this.data.assign(index, 0);\n this.fluidCells[index] = 0;\n if (!failed) failure = error;\n failed = true;\n }\n }\n for (const { index, blockState, biome } of perBlocks) {\n let object: BlockObject | undefined;\n try {\n object = await this.scene.addBlock(blockState, {\n mergeMeshes: true,\n instanceMeshes: true,\n maxInstanceCount: 2000,\n initialState: this.data.stateAt(this.data.idAt(index))!.properties,\n variantPosition: this.positionAt(index), biome,\n biomePosition: this.biomePosition(index, blockState, this.data.stateAt(this.data.idAt(index))!)\n }) as BlockObject;\n object.setPosition(new Vector3(this.x * 256 + index % 16 * 16,\n this.y * 256 + Math.floor(index / 256) * 16, this.z * 256 + Math.floor(index / 16) % 16 * 16));\n this.renderedBlocks.get(index)!.object = object;\n this.objectBlocks.add(index);\n } catch (error) {\n this.data.assign(index, 0);\n this.fluidCells[index] = 0;\n this.renderedBlocks.delete(index);\n this.objectBlocks.delete(index);\n object?.removeFromScene();\n if (!failed) failure = error;\n failed = true;\n }\n }\n if (failed) throw failure;\n }\n\n private positionAt(index: number): TripleArray {\n return [this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];\n }\n\n /** Refreshes saved lighting after adjacent columns load or unload, including columns with only light data. */\n public async refreshLight(indices?: Iterable<number>): Promise<void> {\n if (!this.lightAt) return;\n for (const index of indices ?? this.renderedBlocks.keys()) {\n if (this.renderedBlocks.has(index)) this.meshDirty = true;\n }\n }\n\n /** Refreshes baked corner shading after edits or a world setting change. Disabled chunks keep no AO neighborhood. */\n public refreshAmbientOcclusion(enabled: boolean): void {\n if (!enabled && !this.ambientOcclusionCells) return;\n const cells = enabled ? this.buildAmbientOcclusionCells() : undefined;\n if (cells?.some((value, index) => value !== this.ambientOcclusionCells?.[index])\n || !!cells !== !!this.ambientOcclusionCells) this.meshDirty = true;\n this.ambientOcclusionCells = cells;\n }\n\n private buildAmbientOcclusionCells(): Uint8Array {\n const cells = new Uint8Array(18 * 18 * 18);\n for (let y = -1; y <= 16; y++) {\n for (let z = -1; z <= 16; z++) {\n for (let x = -1; x <= 16; x++) {\n const inner = x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 16;\n cells[(y + 1) * 324 + (z + 1) * 18 + x + 1] = inner\n ? Number(this.isOccludingIndex(y * 256 + z * 16 + x))\n : Number(!!((this.neighborCell?.(this.x * 16 + x, this.y * 16 + y, this.z * 16 + z) ?? 0) & 64));\n }\n }\n }\n return cells;\n }\n\n private biomePosition(index: number, blockState: BlockState, stored: Block): TripleArray {\n const position = this.positionAt(index), name = blockState.key?.toNamespacedString();\n if (stored.properties?.half === \"upper\" && (name === \"minecraft:tall_grass\" || name === \"minecraft:large_fern\")) position[1]--;\n return position;\n }\n\n private async resolveState(stored: Block, indices: readonly number[], biomes: Map<string, Promise<boolean>>) {\n const blockState = await BlockStates.get(AssetKey.parse(\"blockstates\", stored.type));\n let perBlock = !blockState || !this.sectionModels\n || !!(blockState.key && BlockEntities.entry(await BlockEntities.getIndex(blockState.key.root), blockState.key.toNamespacedString()));\n const fluid = await getBlockFluidState(blockState?.key, stored.properties);\n const hasBiomes = this.getBiomeAt(this.x * 16, this.y * 16, this.z * 16) !== undefined\n || this.biomeAt?.(this.x * 16, this.y * 16 - 1, this.z * 16) !== undefined;\n const source = hasBiomes && blockState ? await BlockTints.biomeSource(blockState.key) : undefined;\n const prepare = (color?: () => Promise<number | undefined>) => perBlock || fluid?.renderModel === false ? undefined\n : this.sectionModels!.prepareState(blockState!, stored.properties, color);\n type Context = {\n biome?: string;\n prepared?: Awaited<ReturnType<SectionModels[\"prepareState\"]>>;\n tint?: TripleArray;\n waterTint?: TripleArray;\n };\n const contexts = new Map<number, Context>();\n const blend = this.biomeBlend?.();\n if (blend && !perBlock && blockState && (source || fluid?.kind === \"water\")) {\n const prepared = fluid?.renderModel === false ? undefined\n : await this.sectionModels!.prepareState(blockState, stored.properties, undefined, true);\n if (!prepared && fluid?.renderModel !== false) {\n // A model that cannot join the section mesh becomes an individual object with its own biome's color.\n perBlock = true;\n } else {\n await Promise.all(indices.map(async index => {\n const position = this.biomePosition(index, blockState, stored);\n const biomeColor = (kind: BiomeColorKind) => blend.getColor(kind, blockState.key, position);\n const context: Context = {};\n if (source && prepared?.biomeTint) {\n const color = await biomeColor(source);\n if (color !== undefined) context.tint = new Color(color).toArray() as TripleArray;\n }\n if (fluid?.kind === \"water\") {\n const color = await biomeColor(\"water\");\n if (color !== undefined && color !== 0x3f76e4) context.waterTint = new Color(color).toArray() as TripleArray;\n }\n contexts.set(index, context);\n }));\n return { blockState, perBlock, fluid, prepared, contexts, stored };\n }\n }\n const groups = new Map<string, { biome: string; position: TripleArray; indices: number[] }>();\n if (blockState && (source || fluid?.kind === \"water\")) {\n for (const index of indices) {\n const position = this.biomePosition(index, blockState, stored);\n const biome = this.biomeAt ? this.biomeAt(...position)\n : position[1] >= this.y * 16 ? this.getBiomeAt(position) : undefined;\n if (!biome) continue;\n const key = JSON.stringify(source === \"grass\" ? [biome, position[0], position[2]] : [biome]);\n let group = groups.get(key);\n if (!group) groups.set(key, group = { biome, position, indices: [] });\n group.indices.push(index);\n }\n }\n const groupedCount = [...groups.values()].reduce((sum, group) => sum + group.indices.length, 0);\n const prepared = groupedCount < indices.length ? await prepare() : undefined;\n await Promise.all([...groups.values()].map(async ({ biome, position, indices }) => {\n const available = () => {\n const key = JSON.stringify([biome, blockState?.key?.root]);\n let found = biomes.get(key);\n if (!found) {\n found = Biomes.get(biome, blockState?.key).then(value => value !== undefined);\n biomes.set(key, found);\n }\n return found;\n };\n const context: Context = { biome };\n if (perBlock) {\n if (!await available()) context.biome = undefined;\n } else {\n context.prepared = await prepare(async () => await available()\n ? BlockTints.getBiomeColor(blockState?.key, biome, position) : undefined);\n if (fluid?.kind === \"water\" && await available()) {\n const color = await Biomes.getColor(biome, \"water\", blockState?.key);\n if (color !== undefined && color !== 0x3f76e4) context.waterTint = new Color(color).toArray() as TripleArray;\n }\n }\n for (const index of indices) contexts.set(index, context);\n }));\n return { blockState, perBlock, fluid, prepared, contexts, stored };\n }\n\n private setWaterTint(index: number, tint?: TripleArray): void {\n if (!this.sectionModels || (!this.waterTints && tint === undefined)) return;\n if (!this.waterTints) {\n this.waterTints = new Float32Array(4096 * 3);\n for (let cell = 0; cell < 4096; cell++) this.waterTints.set(WATER_TINT, cell * 3);\n }\n this.waterTints.set(tint ?? WATER_TINT, index * 3);\n }\n\n /** Changes visibility at world block coordinates while preserving the block's data. */\n public setBlockVisibleAt(pos: Vector3, visible: boolean): Promise<void> {\n const position = pos.clone();\n return this.changeBlocks(() => this.setBlockVisibility(position, visible));\n }\n\n private async setBlockVisibility(pos: Vector3, visible: boolean): Promise<void> {\n const index = Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));\n const block = this.renderedBlocks.get(index);\n if (!block || visible === !this.hiddenBlocks.has(index)) {\n return;\n }\n if (visible) {\n this.hiddenBlocks.delete(index);\n } else {\n this.hiddenBlocks.add(index);\n }\n block.object?.setVisible(visible);\n if (this.sectionBlocks.has(index) || this.fluidCells[index]) {\n this.meshDirty = true;\n }\n this.scene.dirty = true;\n await this.onBlocksChanged?.([pos]);\n }\n\n public isBlockVisibleAt(pos: Vector3): boolean {\n return this.isBlockVisibleIndex(Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)));\n }\n\n /** Reports whether a cell has a visible render object or section entry. */\n public isBlockVisibleIndex(index: number): boolean {\n return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);\n }\n\n /** Stored state of a rendered, visible cell, or `undefined`. */\n public visibleBlockIndex(index: number): Maybe<Pick<Block, \"type\" | \"properties\">> {\n return this.isBlockVisibleIndex(index) ? this.data.stateAt(this.data.idAt(index)) : undefined;\n }\n\n /** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */\n public fluidByteIndex(index: number): number {\n return this.hiddenBlocks.has(index) ? 0 : this.fluidCells[index];\n }\n\n /** Whether the cell holds a fluid, merged or per-block. */\n public isFluidIndex(index: number): boolean {\n return this.fluidCells[index] !== 0;\n }\n\n public isOccludingAt(pos: Vector3): boolean {\n return this.isOccludingIndex(Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)));\n }\n\n /** Reports whether a visible cell hides neighboring cube faces. */\n public isOccludingIndex(index: number): boolean {\n return !this.hiddenBlocks.has(index)\n && (this.sectionBlocks.get(index)?.some(entry => entry.template.occludes)\n ?? this.renderedBlocks.get(index)?.object?.isOccluding ?? false);\n }\n\n public async setCullMaskAt(pos: Vector3, mask: number): Promise<void> {\n await this.setCullMaskIndex(Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)), mask);\n }\n\n /**\n * Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.\n * `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.\n */\n public updateCullMasks(indices: Iterable<number> | undefined, occludes: (x: number, y: number, z: number) => boolean,\n culling?: BlockCullingData, blockAt?: (x: number, y: number, z: number) => Maybe<Pick<Block, \"type\" | \"properties\">>): [number, number][] {\n const changed: [number, number][] = [];\n const rules: (BlockCullingRule | null | undefined)[] = [];\n for (const index of indices ?? this.fluidCells.keys()) {\n if (!this.isBlockVisibleIndex(index)) continue;\n const x = index % 16, y = Math.floor(index / 256), z = Math.floor(index / 16) % 16;\n const id = this.data.idAt(index);\n let rule = rules[id];\n if (culling && rule === undefined) rules[id] = rule = blockCullingRule(culling, this.data.stateAt(id)!.type) ?? null;\n const block = rule ? this.data.stateAt(id)! : undefined;\n let mask = 0;\n for (let face = 0; face < CUBE_FACE_OFFSETS.length; face++) {\n const [dx, dy, dz] = CUBE_FACE_OFFSETS[face];\n const nx = x + dx, ny = y + dy, nz = z + dz;\n const inner = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16;\n if (inner ? this.isOccludingIndex(ny * 256 + nz * 16 + nx)\n : occludes(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz)) mask |= 1 << face;\n else if (rule) {\n const neighbor = inner ? this.visibleBlockIndex(ny * 256 + nz * 16 + nx)\n : blockAt?.(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz);\n if (neighbor && skipsBlockFace(culling!, rule, block!, neighbor, face)) mask |= 1 << face;\n }\n }\n if (this.fluidCells[index]) this.meshDirty = true;\n const entries = this.sectionBlocks.get(index);\n if (entries) {\n for (const entry of entries) {\n if (entry.cullMask !== mask) {\n entry.cullMask = mask;\n this.meshDirty = true;\n }\n }\n } else {\n const object = this.renderedBlocks.get(index)?.object;\n if (object && object.cullMask !== mask) changed.push([index, mask]);\n }\n }\n return changed;\n }\n\n /** Updates hidden faces for a cell's section entry or individual render object. */\n public async setCullMaskIndex(index: number, mask: number): Promise<void> {\n if (this.fluidCells[index]) this.meshDirty = true;\n const entries = this.sectionBlocks.get(index);\n if (entries) {\n for (const entry of entries) {\n if (entry.cullMask !== mask) {\n entry.cullMask = mask;\n this.meshDirty = true;\n }\n }\n } else {\n await this.renderedBlocks.get(index)?.object?.setCullMask(mask);\n }\n }\n\n /** Rebuilds visible section geometry and discards results superseded by another rebuild or clear. */\n public async rebuildSectionMesh(): Promise<void> {\n if (!this.sectionModels || !this.meshDirty) return;\n this.meshDirty = false;\n const generation = ++this.meshGeneration;\n const entries = [...this.sectionBlocks.entries()].flatMap(([index, entries]) => this.hiddenBlocks.has(index) ? [] : entries);\n let fluids: SectionFluids | undefined;\n const origins = new Map<FluidKind, string>();\n for (let index = 0; index < this.fluidCells.length; index++) {\n const kind = fluidKindOf(this.fluidCells[index]);\n if (!kind || origins.has(kind) || this.hiddenBlocks.has(index)) continue;\n const block = this.renderedBlocks.get(index);\n if (block && !block.object) origins.set(kind, block.block.type);\n }\n if (origins.size) {\n fluids = { cells: new Uint8Array(18 * 18 * 18), waterTints: this.waterTints?.slice() };\n for (let y = -1; y <= 16; y++) {\n for (let z = -1; z <= 16; z++) {\n for (let x = -1; x <= 16; x++) {\n const index = y * 256 + z * 16 + x;\n const inner = x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 16;\n fluids.cells[(y + 1) * 324 + (z + 1) * 18 + x + 1] = inner\n ? this.fluidByteIndex(index) | (this.renderedBlocks.get(index)?.object ? 128 : 0)\n | (this.isOccludingIndex(index) ? 64 : 0)\n : this.neighborCell?.(this.x * 16 + x, this.y * 16 + y, this.z * 16 + z) ?? 0;\n }\n }\n }\n for (const [kind, type] of origins) {\n const state = await BlockStates.get(AssetKey.parse(\"blockstates\", type));\n fluids[kind] = await this.sectionModels.fluidAtlas(kind, state?.key?.root);\n }\n }\n let light: Uint8Array | undefined;\n if (this.lightAt) {\n light = new Uint8Array(18 * 18 * 18);\n for (let y = -1; y <= 16; y++) {\n for (let z = -1; z <= 16; z++) {\n for (let x = -1; x <= 16; x++) {\n light[(y + 1) * 324 + (z + 1) * 18 + x + 1] = this.lightAt(this.x * 16 + x, this.y * 16 + y, this.z * 16 + z);\n }\n }\n }\n }\n let next: SectionMesh | undefined;\n try {\n next = entries.length || fluids ? await SectionMesh.buildAsync(entries, this.sectionModels.maxAtlasSize, fluids,\n { light, ambientLight: this.ambientLight, ambientOcclusion: this.ambientOcclusionCells }) : undefined;\n } catch (error) {\n if (generation === this.meshGeneration) this.meshDirty = true;\n throw error;\n }\n if (generation !== this.meshGeneration) {\n next?.dispose();\n return;\n }\n this.sectionMesh?.dispose();\n this.sectionMesh = next;\n if (next) {\n next.position.set(this.x * 256, this.y * 256, this.z * 256);\n this.scene.add(next);\n }\n this.scene.dirty = true;\n }\n\n /** Removes stored blocks and render objects. Set `notify` to false to skip the owning world's update. */\n public async clear(notify = true): Promise<void> {\n if (this.blockChanges.size) await Promise.allSettled(this.blockChanges);\n const positions = notify && this.onBlocksChanged ? [...this.renderedBlocks.keys()].map(index => this.chunkPosToWorldPos(\n new Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)\n )) : [];\n for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();\n this.sectionBlocks.clear();\n this.meshGeneration++;\n this.sectionMesh?.dispose();\n this.sectionMesh = undefined;\n this.meshDirty = false;\n this.renderedBlocks.clear();\n this.objectBlocks.clear();\n this.hiddenBlocks.clear();\n this.fluidCells.fill(0);\n this.waterTints = undefined;\n this.ambientOcclusionCells = undefined;\n this.data.clear();\n this.biomes = undefined;\n if (notify) {\n await this.onBiomesChanged?.(undefined);\n await this.onLightCleared?.();\n await this.onBlocksChanged?.(positions);\n }\n }\n\n public async dispose(): Promise<void> {\n await this.clear();\n }\n\n static isAir(block: Maybe<Block>): boolean {\n return ChunkData.isAir(block);\n }\n\n /** Maps chunk-local coordinates from 0 to 15 to a storage index, with x varying fastest, then z, then y. */\n static chunkPosToBlockIndex(pos: Vector3): number {\n if ([pos.x, pos.y, pos.z].some(value => !Number.isInteger(value) || value < 0 || value >= 16)) {\n throw new RangeError(\"Block coordinates must be integers from 0 to 15 within a chunk\");\n }\n return (pos.y * 16 * 16) + (pos.z * 16) + pos.x;\n }\n\n worldPosToChunkPos(pos: Vector3): Vector3 {\n return new Vector3(\n pos.x - (this.x * 16),\n pos.y - (this.y * 16),\n pos.z - (this.z * 16)\n )\n }\n\n chunkPosToWorldPos(pos: Vector3): Vector3 {\n return new Vector3(\n (this.x * 16) + pos.x,\n (this.y * 16) + pos.y,\n (this.z * 16) + pos.z\n );\n }\n\n}\n"],"mappings":"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","names":["prepared","indices","entries"]}
1
+ {"version":3,"sources":["../../../../src/world/Chunk.ts"],"sourcesContent":["import { Block } from \"../model/block/Block\";\nimport { BlockObject } from \"../model/block/scene/BlockObject\";\nimport { Color, Mesh, Object3D, Raycaster, Vector3 } from \"three\";\nimport { Maybe } from \"../util/util\";\nimport { BlockInfo } from \"./BlockInfo\";\nimport { ChunkData } from \"./ChunkData\";\nimport { MineRenderScene } from \"../renderer/MineRenderScene\";\nimport { BlockStates } from \"../assets/BlockStates\";\nimport { AssetKey } from \"../assets/AssetKey\";\nimport { MineRenderWorld } from \"./MineRenderWorld\";\nimport { isTripleArray, TripleArray } from \"../model/Model\";\nimport { SectionModels } from \"./SectionModels\";\nimport { BlockEntities } from \"../assets/BlockEntities\";\nimport { SectionFluids, SectionMesh, SectionMeshEntry } from \"./SectionMesh\";\nimport { FluidKind, getBlockFluidState } from \"../model/fluid/FluidGeometry\";\nimport { fluidKindOf } from \"../model/fluid/FluidQuads\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { CUBE_FACE_OFFSETS } from \"../CubeFace\";\nimport { BlockTints } from \"../model/block/BlockTints\";\nimport { Biomes, BiomeColorKind } from \"../assets/Biomes\";\nimport { BiomeBlend } from \"./_biomes/BiomeBlend\";\nimport { isInstanceReference } from \"../instance/InstanceReference\";\nimport type { InstanceReference } from \"../instance/InstanceReference\";\nimport type { ModelObject } from \"../model/scene/ModelObject\";\nimport type { WorldBlockIntersection } from \"./WorldBlockIntersection\";\nimport { hitNormal, pickableMeshes, visibleHits } from \"./_picking/Picking\";\nimport { BlockCullingData, BlockCullingRule, blockCullingRule, skipsBlockFace } from \"./_culling/BlockCulling\";\n\nconst WATER_TINT = new Color(0x3f76e4).toArray() as TripleArray;\n\n/**\n * A 16×16×16 block section and its render objects.\n * Constructor coordinates identify the section. Block accessors use world block coordinates\n * unless their name explicitly refers to positions within the chunk.\n */\nexport class Chunk<SectionMeshing extends boolean = false> {\n\n public readonly scene: MineRenderScene; //TODO: should probably be the world\n\n public readonly x: number;\n public readonly y: number;\n public readonly z: number;\n\n private readonly data = new ChunkData();\n private readonly renderedBlocks = new Map<number, BlockInfo<SectionMeshing>>();\n private readonly objectBlocks = new Set<number>();\n private readonly sectionBlocks = new Map<number, SectionMeshEntry[]>();\n private readonly hiddenBlocks = new Set<number>();\n private readonly fluidCells = new Uint8Array(4096);\n private readonly blockPosition = new Vector3();\n private waterTints?: Float32Array;\n private biomes?: readonly string[];\n private sectionMesh?: SectionMesh;\n private meshDirty = false;\n private meshGeneration = 0;\n private ambientOcclusionCells?: Uint8Array;\n private readonly blockChanges = new Set<Promise<unknown>>();\n private biomeChange?: Promise<unknown>;\n\n constructor(scene: MineRenderScene, x: number, y: number, z: number,\n private readonly onBlocksChanged?: (positions: Vector3[], deferCulling?: boolean) => Promise<void>,\n private readonly sectionModels?: SectionModels,\n private readonly neighborCell?: (x: number, y: number, z: number) => number,\n private readonly biomeAt?: (x: number, y: number, z: number) => Maybe<string>,\n private readonly onBiomesChanged?: (biomes?: readonly string[]) => Promise<void>,\n private readonly lightAt?: (x: number, y: number, z: number) => number,\n private readonly onLightCleared?: () => Promise<void>,\n private readonly ambientLight = 0,\n private readonly biomeBlend?: () => BiomeBlend | undefined) {\n this.scene = scene;\n this.x = x;\n this.y = y;\n this.z = z;\n }\n\n /** Finds the nearest owned block hit across sections, testing each shared mesh once. */\n public static raycast<SectionMeshing extends boolean>(chunks: Iterable<Chunk<SectionMeshing>>, raycaster: Raycaster): WorldBlockIntersection | undefined {\n type Owner = { chunk: Chunk<SectionMeshing>; index: number };\n const roots = new Map<Object3D, Mesh[]>();\n const targets = new Map<Mesh, {\n owners: Map<number | undefined, Owner>;\n section?: { chunk: Chunk<SectionMeshing>; mesh: SectionMesh };\n }>();\n const meshes = (root: Object3D, scene: MineRenderScene): Mesh[] => {\n const cached = roots.get(root);\n if (cached) return cached;\n const result = pickableMeshes(root, scene, raycaster);\n roots.set(root, result);\n return result;\n };\n const add = (root: Object3D, owner: Owner, reference?: InstanceReference<ModelObject>) => {\n for (const mesh of meshes(root, owner.chunk.scene)) {\n if (reference && reference.instanceable.getInstanceReference(mesh, reference.index) !== reference) continue;\n let entry = targets.get(mesh);\n if (!entry) targets.set(mesh, entry = { owners: new Map() });\n entry.owners.set(reference?.index, owner);\n }\n };\n for (const chunk of chunks) {\n for (const index of chunk.objectBlocks) {\n const block = chunk.renderedBlocks.get(index)!.object;\n if (!block || !block.visible || chunk.hiddenBlocks.has(index)) continue;\n const owner = { chunk, index };\n for (const model of block.models) {\n if (isInstanceReference(model)) {\n if (model.instanceable.isInstanceActive(model.index, model)) add(model.instanceable, owner, model);\n } else {\n add(model, owner);\n }\n }\n for (const entity of block.blockEntities) add(entity, owner);\n }\n if (chunk.sectionMesh) {\n for (const mesh of meshes(chunk.sectionMesh, chunk.scene)) {\n targets.set(mesh, { owners: new Map(), section: { chunk, mesh: chunk.sectionMesh } });\n }\n }\n }\n for (const hit of visibleHits(raycaster, [...targets.keys()])) {\n const mesh = hit.object as Mesh;\n const entry = targets.get(mesh)!;\n let owner = entry.owners.get(hit.instanceId) ?? entry.owners.get(undefined);\n if (entry.section) {\n const index = entry.section.mesh.getBlockIndex(hit);\n if (index !== undefined) owner = { chunk: entry.section.chunk, index };\n }\n if (!owner || owner.chunk.hiddenBlocks.has(owner.index)) continue;\n const info = owner.chunk.renderedBlocks.get(owner.index);\n if (!info) continue;\n return {\n position: new Vector3(owner.chunk.x * 16 + owner.index % 16,\n owner.chunk.y * 16 + Math.floor(owner.index / 256), owner.chunk.z * 16 + Math.floor(owner.index / 16) % 16),\n block: info.block,\n point: hit.point.clone(),\n normal: hitNormal(hit),\n distance: hit.distance\n };\n }\n return undefined;\n }\n\n public getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo<SectionMeshing>>;\n public getBlockAt(pos: Vector3): Maybe<BlockInfo<SectionMeshing>>;\n public getBlockAt(pos: TripleArray): Maybe<BlockInfo<SectionMeshing>>;\n public getBlockAt(posOrX: number | Vector3 | TripleArray, y?: number, z?: number): Maybe<BlockInfo<SectionMeshing>> {\n if (typeof posOrX == \"number\") {\n return this.getBlockAt(new Vector3(posOrX, y, z));\n }\n if (isTripleArray(posOrX)) {\n return this.getBlockAt(new Vector3(posOrX[0], posOrX[1], posOrX[2]))\n }\n const pos = this.blockPosition.set(posOrX.x - this.x * 16, posOrX.y - this.y * 16, posOrX.z - this.z * 16);\n const index = Chunk.chunkPosToBlockIndex(pos);\n return this.renderedBlocks.get(index);\n }\n\n /** Returns the saved 4-block biome sample at integer world block coordinates, or `undefined` if absent. */\n public getBiomeAt(x: number, y: number, z: number): Maybe<string>;\n public getBiomeAt(pos: Vector3): Maybe<string>;\n public getBiomeAt(pos: TripleArray): Maybe<string>;\n public getBiomeAt(posOrX: number | Vector3 | TripleArray, y?: number, z?: number): Maybe<string> {\n if (typeof posOrX === \"number\") return this.getBiomeAt(new Vector3(posOrX, y, z));\n if (isTripleArray(posOrX)) return this.getBiomeAt(new Vector3(...posOrX));\n const pos = this.worldPosToChunkPos(posOrX);\n Chunk.chunkPosToBlockIndex(pos);\n return this.biomeAt ? this.biomeAt(posOrX.x, posOrX.y, posOrX.z)\n : this.biomes?.[Math.floor(pos.x / 4) + Math.floor(pos.z / 4) * 4 + Math.floor(pos.y / 4) * 16];\n }\n\n /** Copies 64 biome IDs in x + z * 4 + y * 16 order and refreshes placed blocks. Omit the array to clear biome data. */\n public setBiomes(biomes?: readonly string[]): Promise<void> {\n const copy = biomes ? [...biomes] : undefined;\n if (copy && (copy.length !== 64 || !copy.every(id => typeof id === \"string\" && id.length > 0))) {\n throw new RangeError(\"Section biomes must contain 64 nonempty biome IDs\");\n }\n if (this.onBiomesChanged) return this.onBiomesChanged(copy);\n this.biomes = copy;\n return this.refreshBiomes();\n }\n\n /**\n * Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects.\n * The owning world can defer neighbor culling until all affected chunks are refreshed.\n */\n public refreshBiomes(columns?: readonly { x: number; z: number }[], deferCulling = false): Promise<void> {\n return this.changeBlocks(() => this.refreshBiomeBlocks(columns, deferCulling), true);\n }\n\n private async refreshBiomeBlocks(columns?: readonly { x: number; z: number }[], deferCulling = false): Promise<void> {\n const blend = columns && this.biomeBlend?.();\n // Individual objects keep their own biome's unblended color, so only a change to their own column affects them.\n const ownColumn = columns?.some(column => column.x === this.x && column.z === this.z);\n const affected = new Map<string, Promise<boolean>>();\n const blocks: { index: number; block: Block }[] = [];\n for (const index of this.renderedBlocks.keys()) {\n if (blend) {\n if (this.objectBlocks.has(index) && !ownColumn) continue;\n const [x, , z] = this.positionAt(index), radius = blend.radius;\n if (!columns!.some(column => x >= column.x * 16 - radius && x <= column.x * 16 + 15 + radius\n && z >= column.z * 16 - radius && z <= column.z * 16 + 15 + radius)) continue;\n }\n const block = this.data.get(index)!;\n const stateKey = ChunkData.paletteKey(block);\n let matches = affected.get(stateKey);\n if (!matches) {\n const key = AssetKey.parse(\"blockstates\", block.type);\n matches = BlockStates.get(key).then(async state => {\n const origin = state?.key ?? key;\n const [source, fluid] = await Promise.all([BlockTints.biomeSource(origin), getBlockFluidState(origin, block.properties)]);\n return !!source || fluid?.kind === \"water\";\n });\n affected.set(stateKey, matches);\n }\n if (await matches) blocks.push({ index, block });\n }\n if (blend) {\n const groups = new Map<string, typeof blocks>();\n for (const entry of blocks) {\n const key = ChunkData.paletteKey(entry.block);\n let group = groups.get(key);\n if (!group) groups.set(key, group = []);\n group.push(entry);\n }\n blocks.length = 0;\n const biomes = new Map<string, Promise<boolean>>();\n for (const group of groups.values()) {\n const { contexts, fluid } = await this.resolveState(group[0].block, group.map(entry => entry.index), biomes);\n for (const entry of group) {\n const context = contexts.get(entry.index);\n const current = this.sectionBlocks.get(entry.index)?.[0]?.biomeTint;\n const tint = context?.tint;\n const tintChanged = !!current !== !!tint || tint?.some((value, channel) => value !== current?.[channel]);\n const waterChanged = fluid?.kind === \"water\" && (context?.waterTint ?? WATER_TINT).some((value, channel) =>\n Math.fround(value) !== (this.waterTints?.[entry.index * 3 + channel] ?? Math.fround(WATER_TINT[channel])));\n if (this.objectBlocks.has(entry.index) || tintChanged || waterChanged) blocks.push(entry);\n }\n }\n }\n if (!blocks.length) return;\n const hidden = new Set(this.hiddenBlocks);\n try {\n await this.replaceBlocks(blocks, true);\n } finally {\n for (const index of hidden) {\n this.hiddenBlocks.add(index);\n this.renderedBlocks.get(index)?.object?.setVisible(false);\n }\n const positions = blocks.map(({ index }) => new Vector3(...this.positionAt(index)));\n if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);\n else await this.rebuildSectionMesh();\n }\n }\n\n /**\n * Places a block at integer world block coordinates. Pass `undefined` to remove it.\n */\n public async setBlockAt(x: number, y: number, z: number, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;\n public async setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;\n public async setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;\n public async setBlockAt(posOrX: number | Vector3 | TripleArray, yOrBlock?: number | Block, z?: number, block?: Block): Promise<Maybe<BlockInfo<SectionMeshing>>> {\n if (typeof posOrX == \"number\") {\n return this.setBlockAt(new Vector3(posOrX, yOrBlock as number, z), block as Block);\n }\n if (isTripleArray(posOrX)) {\n return this.setBlockAt(new Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock as Block);\n }\n const worldPos: Vector3 = posOrX;\n const pos: Vector3 = this.worldPosToChunkPos(worldPos);\n block = yOrBlock as Block;\n\n return this.setBlockInChunkAt(pos, block, worldPos);\n }\n\n /**\n * Places a block at integer chunk-local coordinates from 0 to 15.\n */\n public async setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3,\n onBlocksChanged = this.onBlocksChanged): Promise<Maybe<BlockInfo<SectionMeshing>>> {\n if (typeof worldPos === \"undefined\") {\n worldPos = this.chunkPosToWorldPos(pos);\n }\n\n const index = Chunk.chunkPosToBlockIndex(pos);\n try {\n await this.placeBlocks([{ index, block }]);\n return this.renderedBlocks.get(index);\n } finally {\n await onBlocksChanged?.([worldPos]);\n }\n }\n\n /** Places cells in input order and returns changed world positions without refreshing neighbors. */\n public async placeBlocks(blocks: readonly { index: number; block: Maybe<Block> }[]): Promise<Vector3[]> {\n return this.changeBlocks(() => this.replaceBlocks(blocks));\n }\n\n private changeBlocks<T>(change: () => Promise<T>, refreshBiomes = false): Promise<T> {\n // Color refreshes snapshot existing blocks; edits on either side of that snapshot must retain their order.\n const before = refreshBiomes ? Promise.allSettled(this.blockChanges) : this.biomeChange;\n const result = before ? before.catch(() => undefined).then(change) : change();\n const pending = result.finally(() => {\n this.blockChanges.delete(pending);\n if (this.biomeChange === pending) this.biomeChange = undefined;\n });\n this.blockChanges.add(pending);\n if (refreshBiomes) this.biomeChange = pending;\n return pending;\n }\n\n private async replaceBlocks(blocks: readonly { index: number; block: Maybe<Block> }[], preserveDataOnFailure = false): Promise<Vector3[]> {\n const placements = blocks.map(({ index, block }) => ({\n index,\n key: block && !ChunkData.isAir(block) ? ChunkData.paletteKey(block) : undefined,\n block: block ? {\n type: block.type,\n properties: block.properties ? { ...block.properties } : undefined,\n nbt: block.nbt === undefined ? undefined : structuredClone(block.nbt)\n } : undefined\n }));\n const states = new Map<string, { stored: Block; indices: number[] }>();\n for (const { index, key, block } of placements) {\n if (key === undefined) continue;\n let state = states.get(key);\n if (!state) states.set(key, state = { stored: block!, indices: [] });\n state.indices.push(index);\n }\n const biomes = new Map<string, Promise<boolean>>();\n const settled = await Promise.allSettled([...states.values()].map(({ stored, indices }) =>\n this.resolveState(stored, indices, biomes)));\n const resolutions = new Map([...states.keys()].map((key, i) => [key, settled[i]]));\n if (preserveDataOnFailure) {\n const rejected = settled.find(result => result.status === \"rejected\");\n if (rejected?.status === \"rejected\") throw rejected.reason;\n }\n const positions: Vector3[] = [];\n let failed = false, failure: unknown;\n for (const { index, key, block } of placements) {\n this.hiddenBlocks.delete(index);\n this.data.assign(index, this.data.intern(block), block?.nbt);\n const readBlock = this.data.snapshot(index);\n this.renderedBlocks.get(index)?.object?.removeFromScene();\n if (this.sectionBlocks.delete(index)) this.meshDirty = true;\n if (this.fluidCells[index]) this.meshDirty = true;\n this.fluidCells[index] = 0;\n this.renderedBlocks.delete(index);\n this.objectBlocks.delete(index);\n const worldPos = new Vector3(this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256),\n this.z * 16 + Math.floor(index / 16) % 16);\n positions.push(worldPos);\n let object: BlockObject | undefined;\n try {\n if (!readBlock) continue;\n const resolved = resolutions.get(key!)!;\n if (resolved.status === \"rejected\") throw resolved.reason;\n const { blockState, perBlock, fluid, prepared, contexts, stored } = resolved.value;\n const context = contexts.get(index);\n if (!blockState) {\n this.data.assign(index, 0);\n continue;\n }\n const variantPosition = worldPos.toArray();\n if (fluid) {\n this.fluidCells[index] = (fluid.kind === \"water\" ? 16 : 32) | Math.min(fluid.level, 8);\n if (fluid.kind === \"water\") this.setWaterTint(index, context?.waterTint);\n this.meshDirty = true;\n }\n const templates = perBlock ? undefined : fluid?.renderModel === false ? [] : (context?.prepared ?? prepared)?.pick(variantPosition);\n if (templates) {\n this.sectionBlocks.set(index, templates.map(template => ({ index, template, cullMask: 0, biomeTint: context?.tint })));\n this.meshDirty = true;\n } else {\n object = await this.scene.addBlock(blockState, {\n mergeMeshes: true,\n instanceMeshes: true,\n maxInstanceCount: 2000,\n initialState: stored.properties,\n variantPosition, biome: context?.biome,\n biomePosition: this.biomePosition(index, blockState, stored)\n }) as BlockObject;\n object.setPosition(MineRenderWorld.worldToScenePosition(worldPos));\n }\n this.renderedBlocks.set(index, { get block() { return readBlock(); }, object } as BlockInfo<SectionMeshing>);\n if (object) this.objectBlocks.add(index);\n } catch (error) {\n if (preserveDataOnFailure && readBlock) {\n // Keep saved block data available for a failed color refresh to retry.\n this.renderedBlocks.set(index, { get block() { return readBlock(); }, object: undefined } as BlockInfo<SectionMeshing>);\n } else this.data.assign(index, 0);\n this.fluidCells[index] = 0;\n object?.removeFromScene();\n if (!failed) failure = error;\n failed = true;\n }\n }\n if (failed) throw failure;\n return positions;\n }\n\n /** Replaces every cell from parsed section data. The caller refreshes neighbor culling. */\n public placeSection(data: ChunkData): Promise<void> {\n return this.changeBlocks(() => this.replaceSection(data));\n }\n\n private async replaceSection(data: ChunkData): Promise<void> {\n for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();\n this.sectionBlocks.clear();\n this.fluidCells.fill(0);\n this.waterTints = undefined;\n this.renderedBlocks.clear();\n this.objectBlocks.clear();\n this.hiddenBlocks.clear();\n this.meshDirty = true;\n this.data.copyFrom(data);\n\n const ids = new Map<number, number[]>();\n for (let index = 0; index < 4096; index++) {\n const id = this.data.idAt(index);\n if (!id) continue;\n let indices = ids.get(id);\n if (!indices) ids.set(id, indices = []);\n indices.push(index);\n }\n const palette = [...ids.keys()], biomes = new Map<string, Promise<boolean>>();\n const settled = await Promise.allSettled(palette.map(id =>\n this.resolveState(this.data.stateAt(id)!, ids.get(id)!, biomes)));\n const resolutions = new Map(palette.map((id, i) => [id, settled[i]]));\n const perBlocks: { index: number; blockState: BlockState; biome?: string }[] = [];\n let failed = false, failure: unknown;\n for (let index = 0; index < 4096; index++) {\n const id = this.data.idAt(index);\n if (!id) continue;\n try {\n const resolved = resolutions.get(id)!;\n if (resolved.status === \"rejected\") throw resolved.reason;\n const { blockState, perBlock, fluid, prepared, contexts } = resolved.value;\n const context = contexts.get(index);\n if (!blockState) {\n this.data.assign(index, 0);\n this.fluidCells[index] = 0;\n continue;\n }\n if (fluid) {\n this.fluidCells[index] = (fluid.kind === \"water\" ? 16 : 32) | Math.min(fluid.level, 8);\n if (fluid.kind === \"water\") this.setWaterTint(index, context?.waterTint);\n }\n const variantPosition: TripleArray = [this.x * 16 + index % 16,\n this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];\n const templates = perBlock ? undefined : fluid?.renderModel === false ? [] : (context?.prepared ?? prepared)?.pick(variantPosition);\n if (templates) {\n this.sectionBlocks.set(index, templates.map(template => ({ index, template, cullMask: 0, biomeTint: context?.tint })));\n this.meshDirty = true;\n } else {\n perBlocks.push({ index, blockState, biome: context?.biome });\n }\n const readBlock = this.data.snapshot(index)!;\n this.renderedBlocks.set(index, { get block() { return readBlock(); }, object: undefined } as BlockInfo<SectionMeshing>);\n this.objectBlocks.delete(index);\n } catch (error) {\n this.data.assign(index, 0);\n this.fluidCells[index] = 0;\n if (!failed) failure = error;\n failed = true;\n }\n }\n for (const { index, blockState, biome } of perBlocks) {\n let object: BlockObject | undefined;\n try {\n object = await this.scene.addBlock(blockState, {\n mergeMeshes: true,\n instanceMeshes: true,\n maxInstanceCount: 2000,\n initialState: this.data.stateAt(this.data.idAt(index))!.properties,\n variantPosition: this.positionAt(index), biome,\n biomePosition: this.biomePosition(index, blockState, this.data.stateAt(this.data.idAt(index))!)\n }) as BlockObject;\n object.setPosition(new Vector3(this.x * 256 + index % 16 * 16,\n this.y * 256 + Math.floor(index / 256) * 16, this.z * 256 + Math.floor(index / 16) % 16 * 16));\n this.renderedBlocks.get(index)!.object = object;\n this.objectBlocks.add(index);\n } catch (error) {\n this.data.assign(index, 0);\n this.fluidCells[index] = 0;\n this.renderedBlocks.delete(index);\n this.objectBlocks.delete(index);\n object?.removeFromScene();\n if (!failed) failure = error;\n failed = true;\n }\n }\n if (failed) throw failure;\n }\n\n private positionAt(index: number): TripleArray {\n return [this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];\n }\n\n /** Refreshes saved lighting after adjacent columns load or unload, including columns with only light data. */\n public async refreshLight(indices?: Iterable<number>): Promise<void> {\n if (!this.lightAt) return;\n for (const index of indices ?? this.renderedBlocks.keys()) {\n if (this.renderedBlocks.has(index)) this.meshDirty = true;\n }\n }\n\n /** Refreshes baked corner shading after edits or a world setting change. Disabled chunks keep no AO neighborhood. */\n public refreshAmbientOcclusion(enabled: boolean): void {\n if (!enabled && !this.ambientOcclusionCells) return;\n const cells = enabled ? this.buildAmbientOcclusionCells() : undefined;\n if (cells?.some((value, index) => value !== this.ambientOcclusionCells?.[index])\n || !!cells !== !!this.ambientOcclusionCells) this.meshDirty = true;\n this.ambientOcclusionCells = cells;\n }\n\n private buildAmbientOcclusionCells(): Uint8Array {\n const cells = new Uint8Array(18 * 18 * 18);\n for (let y = -1; y <= 16; y++) {\n for (let z = -1; z <= 16; z++) {\n for (let x = -1; x <= 16; x++) {\n const inner = x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 16;\n cells[(y + 1) * 324 + (z + 1) * 18 + x + 1] = inner\n ? Number(this.isOccludingIndex(y * 256 + z * 16 + x))\n : Number(!!((this.neighborCell?.(this.x * 16 + x, this.y * 16 + y, this.z * 16 + z) ?? 0) & 64));\n }\n }\n }\n return cells;\n }\n\n private biomePosition(index: number, blockState: BlockState, stored: Block): TripleArray {\n const position = this.positionAt(index), name = blockState.key?.toNamespacedString();\n if (stored.properties?.half === \"upper\" && (name === \"minecraft:tall_grass\" || name === \"minecraft:large_fern\")) position[1]--;\n return position;\n }\n\n private async resolveState(stored: Block, indices: readonly number[], biomes: Map<string, Promise<boolean>>) {\n const blockState = await BlockStates.get(AssetKey.parse(\"blockstates\", stored.type));\n let perBlock = !blockState || !this.sectionModels\n || !!(blockState.key && BlockEntities.entry(await BlockEntities.getIndex(blockState.key.root), blockState.key.toNamespacedString()));\n const fluid = await getBlockFluidState(blockState?.key, stored.properties);\n const hasBiomes = this.getBiomeAt(this.x * 16, this.y * 16, this.z * 16) !== undefined\n || this.biomeAt?.(this.x * 16, this.y * 16 - 1, this.z * 16) !== undefined;\n const source = hasBiomes && blockState ? await BlockTints.biomeSource(blockState.key) : undefined;\n const prepare = (color?: () => Promise<number | undefined>) => perBlock || fluid?.renderModel === false ? undefined\n : this.sectionModels!.prepareState(blockState!, stored.properties, color);\n type Context = {\n biome?: string;\n prepared?: Awaited<ReturnType<SectionModels[\"prepareState\"]>>;\n tint?: TripleArray;\n waterTint?: TripleArray;\n };\n const contexts = new Map<number, Context>();\n const blend = this.biomeBlend?.();\n if (blend && !perBlock && blockState && (source || fluid?.kind === \"water\")) {\n const prepared = fluid?.renderModel === false ? undefined\n : await this.sectionModels!.prepareState(blockState, stored.properties, undefined, true);\n if (!prepared && fluid?.renderModel !== false) {\n // A model that cannot join the section mesh becomes an individual object with its own biome's color.\n perBlock = true;\n } else {\n await Promise.all(indices.map(async index => {\n const position = this.biomePosition(index, blockState, stored);\n const biomeColor = (kind: BiomeColorKind) => blend.getColor(kind, blockState.key, position);\n const context: Context = {};\n if (source && prepared?.biomeTint) {\n const color = await biomeColor(source);\n if (color !== undefined) context.tint = new Color(color).toArray() as TripleArray;\n }\n if (fluid?.kind === \"water\") {\n const color = await biomeColor(\"water\");\n if (color !== undefined && color !== 0x3f76e4) context.waterTint = new Color(color).toArray() as TripleArray;\n }\n contexts.set(index, context);\n }));\n return { blockState, perBlock, fluid, prepared, contexts, stored };\n }\n }\n const groups = new Map<string, { biome: string; position: TripleArray; indices: number[] }>();\n if (blockState && (source || fluid?.kind === \"water\")) {\n for (const index of indices) {\n const position = this.biomePosition(index, blockState, stored);\n const biome = this.biomeAt ? this.biomeAt(...position)\n : position[1] >= this.y * 16 ? this.getBiomeAt(position) : undefined;\n if (!biome) continue;\n const key = JSON.stringify(source === \"grass\" ? [biome, position[0], position[2]] : [biome]);\n let group = groups.get(key);\n if (!group) groups.set(key, group = { biome, position, indices: [] });\n group.indices.push(index);\n }\n }\n const groupedCount = [...groups.values()].reduce((sum, group) => sum + group.indices.length, 0);\n const prepared = groupedCount < indices.length ? await prepare() : undefined;\n await Promise.all([...groups.values()].map(async ({ biome, position, indices }) => {\n const available = () => {\n const key = JSON.stringify([biome, blockState?.key?.root]);\n let found = biomes.get(key);\n if (!found) {\n found = Biomes.get(biome, blockState?.key).then(value => value !== undefined);\n biomes.set(key, found);\n }\n return found;\n };\n const context: Context = { biome };\n if (perBlock) {\n if (!await available()) context.biome = undefined;\n } else {\n context.prepared = await prepare(async () => await available()\n ? BlockTints.getBiomeColor(blockState?.key, biome, position) : undefined);\n if (fluid?.kind === \"water\" && await available()) {\n const color = await Biomes.getColor(biome, \"water\", blockState?.key);\n if (color !== undefined && color !== 0x3f76e4) context.waterTint = new Color(color).toArray() as TripleArray;\n }\n }\n for (const index of indices) contexts.set(index, context);\n }));\n return { blockState, perBlock, fluid, prepared, contexts, stored };\n }\n\n private setWaterTint(index: number, tint?: TripleArray): void {\n if (!this.sectionModels || (!this.waterTints && tint === undefined)) return;\n if (!this.waterTints) {\n this.waterTints = new Float32Array(4096 * 3);\n for (let cell = 0; cell < 4096; cell++) this.waterTints.set(WATER_TINT, cell * 3);\n }\n this.waterTints.set(tint ?? WATER_TINT, index * 3);\n }\n\n /** Changes visibility at world block coordinates while preserving the block's data. */\n public setBlockVisibleAt(pos: Vector3, visible: boolean): Promise<void> {\n const position = pos.clone();\n return this.changeBlocks(() => this.setBlockVisibility(position, visible));\n }\n\n private async setBlockVisibility(pos: Vector3, visible: boolean): Promise<void> {\n const index = Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));\n const block = this.renderedBlocks.get(index);\n if (!block || visible === !this.hiddenBlocks.has(index)) {\n return;\n }\n if (visible) {\n this.hiddenBlocks.delete(index);\n } else {\n this.hiddenBlocks.add(index);\n }\n block.object?.setVisible(visible);\n if (this.sectionBlocks.has(index) || this.fluidCells[index]) {\n this.meshDirty = true;\n }\n this.scene.dirty = true;\n await this.onBlocksChanged?.([pos]);\n }\n\n public isBlockVisibleAt(pos: Vector3): boolean {\n return this.isBlockVisibleIndex(Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)));\n }\n\n /** Reports whether a cell has a visible render object or section entry. */\n public isBlockVisibleIndex(index: number): boolean {\n return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);\n }\n\n /** Stored state of a rendered, visible cell, or `undefined`. */\n public visibleBlockIndex(index: number): Maybe<Pick<Block, \"type\" | \"properties\">> {\n return this.isBlockVisibleIndex(index) ? this.data.stateAt(this.data.idAt(index)) : undefined;\n }\n\n /** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */\n public fluidByteIndex(index: number): number {\n return this.hiddenBlocks.has(index) ? 0 : this.fluidCells[index];\n }\n\n /** Whether the cell holds a fluid, merged or per-block. */\n public isFluidIndex(index: number): boolean {\n return this.fluidCells[index] !== 0;\n }\n\n public isOccludingAt(pos: Vector3): boolean {\n return this.isOccludingIndex(Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)));\n }\n\n /** Reports whether a visible cell hides neighboring cube faces. */\n public isOccludingIndex(index: number): boolean {\n return !this.hiddenBlocks.has(index)\n && (this.sectionBlocks.get(index)?.some(entry => entry.template.occludes)\n ?? this.renderedBlocks.get(index)?.object?.isOccluding ?? false);\n }\n\n public async setCullMaskAt(pos: Vector3, mask: number): Promise<void> {\n await this.setCullMaskIndex(Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)), mask);\n }\n\n /**\n * Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.\n * `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.\n */\n public updateCullMasks(indices: Iterable<number> | undefined, occludes: (x: number, y: number, z: number) => boolean,\n culling?: BlockCullingData, blockAt?: (x: number, y: number, z: number) => Maybe<Pick<Block, \"type\" | \"properties\">>): [number, number][] {\n const changed: [number, number][] = [];\n const rules: (BlockCullingRule | null | undefined)[] = [];\n for (const index of indices ?? this.fluidCells.keys()) {\n if (!this.isBlockVisibleIndex(index)) continue;\n const x = index % 16, y = Math.floor(index / 256), z = Math.floor(index / 16) % 16;\n const id = this.data.idAt(index);\n let rule = rules[id];\n if (culling && rule === undefined) rules[id] = rule = blockCullingRule(culling, this.data.stateAt(id)!.type) ?? null;\n const block = rule ? this.data.stateAt(id)! : undefined;\n let mask = 0;\n for (let face = 0; face < CUBE_FACE_OFFSETS.length; face++) {\n const [dx, dy, dz] = CUBE_FACE_OFFSETS[face];\n const nx = x + dx, ny = y + dy, nz = z + dz;\n const inner = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16;\n if (inner ? this.isOccludingIndex(ny * 256 + nz * 16 + nx)\n : occludes(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz)) mask |= 1 << face;\n else if (rule) {\n const neighbor = inner ? this.visibleBlockIndex(ny * 256 + nz * 16 + nx)\n : blockAt?.(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz);\n if (neighbor && skipsBlockFace(culling!, rule, block!, neighbor, face)) mask |= 1 << face;\n }\n }\n if (this.fluidCells[index]) this.meshDirty = true;\n const entries = this.sectionBlocks.get(index);\n if (entries) {\n for (const entry of entries) {\n if (entry.cullMask !== mask) {\n entry.cullMask = mask;\n this.meshDirty = true;\n }\n }\n } else {\n const object = this.renderedBlocks.get(index)?.object;\n if (object && object.cullMask !== mask) changed.push([index, mask]);\n }\n }\n return changed;\n }\n\n /** Updates hidden faces for a cell's section entry or individual render object. */\n public async setCullMaskIndex(index: number, mask: number): Promise<void> {\n if (this.fluidCells[index]) this.meshDirty = true;\n const entries = this.sectionBlocks.get(index);\n if (entries) {\n for (const entry of entries) {\n if (entry.cullMask !== mask) {\n entry.cullMask = mask;\n this.meshDirty = true;\n }\n }\n } else {\n await this.renderedBlocks.get(index)?.object?.setCullMask(mask);\n }\n }\n\n /** Rebuilds visible section geometry and discards results superseded by another rebuild or clear. */\n public async rebuildSectionMesh(): Promise<void> {\n if (!this.sectionModels || !this.meshDirty) return;\n this.meshDirty = false;\n const generation = ++this.meshGeneration;\n const entries = [...this.sectionBlocks.entries()].flatMap(([index, entries]) => this.hiddenBlocks.has(index) ? [] : entries);\n let fluids: SectionFluids | undefined;\n const origins = new Map<FluidKind, string>();\n for (let index = 0; index < this.fluidCells.length; index++) {\n const kind = fluidKindOf(this.fluidCells[index]);\n if (!kind || origins.has(kind) || this.hiddenBlocks.has(index)) continue;\n const block = this.renderedBlocks.get(index);\n if (block && !block.object) origins.set(kind, block.block.type);\n }\n if (origins.size) {\n fluids = { cells: new Uint8Array(18 * 18 * 18), waterTints: this.waterTints?.slice() };\n for (let y = -1; y <= 16; y++) {\n for (let z = -1; z <= 16; z++) {\n for (let x = -1; x <= 16; x++) {\n const index = y * 256 + z * 16 + x;\n const inner = x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 16;\n fluids.cells[(y + 1) * 324 + (z + 1) * 18 + x + 1] = inner\n ? this.fluidByteIndex(index) | (this.renderedBlocks.get(index)?.object ? 128 : 0)\n | (this.isOccludingIndex(index) ? 64 : 0)\n : this.neighborCell?.(this.x * 16 + x, this.y * 16 + y, this.z * 16 + z) ?? 0;\n }\n }\n }\n for (const [kind, type] of origins) {\n const state = await BlockStates.get(AssetKey.parse(\"blockstates\", type));\n fluids[kind] = await this.sectionModels.fluidAtlas(kind, state?.key?.root);\n }\n }\n let light: Uint8Array | undefined;\n if (this.lightAt) {\n light = new Uint8Array(18 * 18 * 18);\n for (let y = -1; y <= 16; y++) {\n for (let z = -1; z <= 16; z++) {\n for (let x = -1; x <= 16; x++) {\n light[(y + 1) * 324 + (z + 1) * 18 + x + 1] = this.lightAt(this.x * 16 + x, this.y * 16 + y, this.z * 16 + z);\n }\n }\n }\n }\n let next: SectionMesh | undefined;\n try {\n next = entries.length || fluids ? await SectionMesh.buildAsync(entries, this.sectionModels.maxAtlasSize, fluids,\n { light, ambientLight: this.ambientLight, ambientOcclusion: this.ambientOcclusionCells }) : undefined;\n } catch (error) {\n if (generation === this.meshGeneration) this.meshDirty = true;\n throw error;\n }\n if (generation !== this.meshGeneration) {\n next?.dispose();\n return;\n }\n this.sectionMesh?.dispose();\n this.sectionMesh = next;\n if (next) {\n next.position.set(this.x * 256, this.y * 256, this.z * 256);\n this.scene.add(next);\n }\n this.scene.dirty = true;\n }\n\n /** Removes stored blocks and render objects. Set `notify` to false to skip the owning world's update. */\n public async clear(notify = true): Promise<void> {\n if (this.blockChanges.size) await Promise.allSettled(this.blockChanges);\n const positions = notify && this.onBlocksChanged ? [...this.renderedBlocks.keys()].map(index => this.chunkPosToWorldPos(\n new Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)\n )) : [];\n for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();\n this.sectionBlocks.clear();\n this.meshGeneration++;\n this.sectionMesh?.dispose();\n this.sectionMesh = undefined;\n this.meshDirty = false;\n this.renderedBlocks.clear();\n this.objectBlocks.clear();\n this.hiddenBlocks.clear();\n this.fluidCells.fill(0);\n this.waterTints = undefined;\n this.ambientOcclusionCells = undefined;\n this.data.clear();\n this.biomes = undefined;\n if (notify) {\n await this.onBiomesChanged?.(undefined);\n await this.onLightCleared?.();\n await this.onBlocksChanged?.(positions);\n }\n }\n\n public async dispose(): Promise<void> {\n await this.clear();\n }\n\n static isAir(block: Maybe<Block>): boolean {\n return ChunkData.isAir(block);\n }\n\n /** Maps chunk-local coordinates from 0 to 15 to a storage index, with x varying fastest, then z, then y. */\n static chunkPosToBlockIndex(pos: Vector3): number {\n if ([pos.x, pos.y, pos.z].some(value => !Number.isInteger(value) || value < 0 || value >= 16)) {\n throw new RangeError(\"Block coordinates must be integers from 0 to 15 within a chunk\");\n }\n return (pos.y * 16 * 16) + (pos.z * 16) + pos.x;\n }\n\n worldPosToChunkPos(pos: Vector3): Vector3 {\n return new Vector3(\n pos.x - (this.x * 16),\n pos.y - (this.y * 16),\n pos.z - (this.z * 16)\n )\n }\n\n chunkPosToWorldPos(pos: Vector3): Vector3 {\n return new Vector3(\n (this.x * 16) + pos.x,\n (this.y * 16) + pos.y,\n (this.z * 16) + pos.z\n );\n }\n\n}\n"],"mappings":"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","names":["prepared","indices","entries"]}