minerender 2.1.0-beta.5 → 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 (102) hide show
  1. package/dist/browser/esm/Materials.mjs +6 -3
  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/Fonts.mjs +31 -4
  22. package/dist/browser/esm/assets/Fonts.mjs.map +1 -1
  23. package/dist/browser/esm/assets/Models.mjs +1 -1
  24. package/dist/browser/esm/assets/Models.mjs.map +1 -1
  25. package/dist/browser/esm/assets/_fonts/Unihex.mjs +168 -0
  26. package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -0
  27. package/dist/browser/esm/assets/index.mjs +1 -0
  28. package/dist/browser/esm/assets/index.mjs.map +1 -1
  29. package/dist/browser/esm/assets/source/HostedAssetSource.mjs +19 -9
  30. package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
  31. package/dist/browser/esm/assets/source/parser/AssetParsers.mjs +1 -0
  32. package/dist/browser/esm/assets/source/parser/AssetParsers.mjs.map +1 -1
  33. package/dist/browser/esm/cache/Caching.mjs +2 -0
  34. package/dist/browser/esm/cache/Caching.mjs.map +1 -1
  35. package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs +62 -11
  36. package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs.map +1 -1
  37. package/dist/browser/esm/entity/scene/EntityObject.mjs +53 -20
  38. package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
  39. package/dist/browser/esm/env/browser/BrowserCache.mjs +3 -3
  40. package/dist/browser/esm/env/browser/BrowserCache.mjs.map +1 -1
  41. package/dist/browser/esm/env/browser/section.worker.mjs +5 -3
  42. package/dist/browser/esm/env/browser/section.worker.mjs.map +1 -1
  43. package/dist/browser/esm/gui/GuiText.mjs +4 -3
  44. package/dist/browser/esm/gui/GuiText.mjs.map +1 -1
  45. package/dist/browser/esm/image/ImageLoader.mjs +3 -3
  46. package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
  47. package/dist/browser/esm/index.browser.d.mts +115 -20
  48. package/dist/browser/esm/inspector/SceneInspector.mjs +3 -3
  49. package/dist/browser/esm/inspector/SceneInspector.mjs.map +1 -1
  50. package/dist/browser/esm/instance/InstanceManager.mjs +4 -4
  51. package/dist/browser/esm/instance/InstanceManager.mjs.map +1 -1
  52. package/dist/browser/esm/model/block/scene/BlockObject.mjs +3 -1
  53. package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
  54. package/dist/browser/esm/model/multiblock/StructureParser.mjs +7 -4
  55. package/dist/browser/esm/model/multiblock/StructureParser.mjs.map +1 -1
  56. package/dist/browser/esm/model/scene/ModelObject.mjs +8 -4
  57. package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
  58. package/dist/browser/esm/nbt/NBTHelper.mjs +5 -2
  59. package/dist/browser/esm/nbt/NBTHelper.mjs.map +1 -1
  60. package/dist/browser/esm/renderer/Renderer.mjs +4 -2
  61. package/dist/browser/esm/renderer/Renderer.mjs.map +1 -1
  62. package/dist/browser/esm/renderer/SceneObject.mjs +0 -6
  63. package/dist/browser/esm/renderer/SceneObject.mjs.map +1 -1
  64. package/dist/browser/esm/request/Requests.mjs +3 -3
  65. package/dist/browser/esm/request/Requests.mjs.map +1 -1
  66. package/dist/browser/esm/skin/Skins.mjs +6 -4
  67. package/dist/browser/esm/skin/Skins.mjs.map +1 -1
  68. package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
  69. package/dist/browser/esm/texture/TextureLoader.mjs.map +1 -1
  70. package/dist/browser/esm/util/log.mjs +75 -0
  71. package/dist/browser/esm/util/log.mjs.map +1 -1
  72. package/dist/browser/esm/util/model.mjs +7 -7
  73. package/dist/browser/esm/util/model.mjs.map +1 -1
  74. package/dist/browser/esm/util/performance.mjs.map +1 -1
  75. package/dist/browser/esm/world/Chunk.mjs +8 -5
  76. package/dist/browser/esm/world/Chunk.mjs.map +1 -1
  77. package/dist/browser/esm/world/MineRenderWorld.mjs +96 -54
  78. package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
  79. package/dist/browser/esm/world/SectionGeometry.mjs +5 -3
  80. package/dist/browser/esm/world/SectionGeometry.mjs.map +1 -1
  81. package/dist/browser/esm/world/SectionMesh.mjs +4 -0
  82. package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
  83. package/dist/browser/esm/world/SectionModels.mjs +2 -2
  84. package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
  85. package/dist/browser/esm/world/WorldStreamer.mjs +21 -20
  86. package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
  87. package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
  88. package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
  89. package/dist/browser/esm/world/_entities/WorldEntities.mjs +3 -1
  90. package/dist/browser/esm/world/_entities/WorldEntities.mjs.map +1 -1
  91. package/dist/browser/index.d.ts +115 -20
  92. package/dist/browser/index.js +3449 -3025
  93. package/dist/browser/index.js.map +1 -1
  94. package/dist/bundle.js +13217 -12745
  95. package/dist/bundle.js.map +1 -1
  96. package/dist/node/index.d.mts +115 -20
  97. package/dist/node/index.d.ts +115 -20
  98. package/dist/node/index.js +3477 -3046
  99. package/dist/node/index.js.map +1 -1
  100. package/dist/node/index.mjs +3456 -3027
  101. package/dist/node/index.mjs.map +1 -1
  102. package/package.json +1 -1
@@ -8,6 +8,7 @@ async function layoutGuiText(text, options = {}) {
8
8
  }
9
9
  const font = await Fonts.get(options.font);
10
10
  const runs = typeof text === "string" ? [{ text }] : text;
11
+ await font.resolve?.(runs.map((run) => run.text).join(""));
11
12
  const glyphs = [], lineWidths = [];
12
13
  let line = [], width = 0;
13
14
  let trailingNewline = false;
@@ -34,7 +35,7 @@ async function layoutGuiText(text, options = {}) {
34
35
  continue;
35
36
  }
36
37
  const glyph = font.glyphs.get(character);
37
- const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
38
+ const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
38
39
  line.push({ character, glyph, advance, style, x: 0, y: 0 });
39
40
  width += advance;
40
41
  while (width > maxWidth && line.length > 1) {
@@ -62,7 +63,7 @@ function createGuiTextGeometry(layout, shadow = true) {
62
63
  batches.push(batch);
63
64
  }
64
65
  const color = new Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
65
- const offset = isShadow ? 1 : 0;
66
+ const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
66
67
  const top = glyph ? 7 - glyph.ascent : 0;
67
68
  const height = glyph ? glyph.height * glyph.scale : 8;
68
69
  const width = glyph ? glyph.width * glyph.scale : 5;
@@ -92,7 +93,7 @@ function createGuiTextGeometry(layout, shadow = true) {
92
93
  for (let i = 0; i < 4; i++) batch.colors.push(color.r, color.g, color.b);
93
94
  batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
94
95
  };
95
- for (const boldOffset of style.bold ? [0, 1] : [0]) {
96
+ for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
96
97
  if (glyph) quad(0, top, width, top + height, boldOffset);
97
98
  else {
98
99
  quad(0, 0, 5, 1, boldOffset);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/gui/GuiText.ts"],"sourcesContent":["import { BufferGeometry, Color, Float32BufferAttribute } from \"three\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport { Fonts, type BitmapGlyph } from \"../assets/Fonts\";\nimport type { CompatCanvas } from \"../canvas/CanvasCompat\";\n\n/** Text appearance set on a GUI text layer or overridden by an individual text run. */\nexport interface GuiTextStyle {\n /** sRGB 0xRRGGBB; defaults to white. */\n color?: number;\n bold?: boolean;\n italic?: boolean;\n}\n\n/** A text segment with optional style overrides within {@link GuiText}. */\nexport interface GuiTextRun extends GuiTextStyle {\n text: string;\n}\n\n/** Literal text, or styled runs. Newlines are preserved. */\nexport type GuiText = string | readonly GuiTextRun[];\n\n/** Text layout settings set on a GUI text layer or passed to {@link layoutGuiText}. */\nexport interface GuiTextOptions extends GuiTextStyle {\n /** Font resource ID; defaults to minecraft:default. */\n font?: AssetKey | string;\n /** Draws a one-pixel shadow; defaults to true. */\n shadow?: boolean;\n /** Wrap width in GUI pixels. Long words break at glyph boundaries. */\n maxWidth?: number;\n /** Distance between line origins; defaults to 9 GUI pixels. */\n lineHeight?: number;\n}\n\n/** One measured glyph and its position in GUI pixels, produced by {@link layoutGuiText}. */\nexport interface PositionedGuiGlyph {\n character: string;\n glyph?: BitmapGlyph;\n x: number;\n y: number;\n advance: number;\n style: Required<GuiTextStyle>;\n}\n\n/** Measured glyphs, line widths, and overall dimensions in GUI pixels. */\nexport interface GuiTextLayout {\n glyphs: PositionedGuiGlyph[];\n lineWidths: number[];\n width: number;\n height: number;\n}\n\n/** Measures and wraps text using the same glyph advances used for rendering. */\nexport async function layoutGuiText(text: GuiText, options: GuiTextOptions = {}): Promise<GuiTextLayout> {\n const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;\n if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {\n throw new Error(\"Text wrap width and line height must be positive\");\n }\n const font = await Fonts.get(options.font);\n const runs = typeof text === \"string\" ? [{ text }] : text;\n const glyphs: PositionedGuiGlyph[] = [], lineWidths: number[] = [];\n let line: PositionedGuiGlyph[] = [], width = 0;\n let trailingNewline = false;\n const finishLine = (entries: PositionedGuiGlyph[]) => {\n let x = 0;\n for (const entry of entries) {\n glyphs.push({ ...entry, x, y: lineWidths.length * lineHeight });\n x += entry.advance;\n }\n lineWidths.push(x);\n };\n for (const run of runs) {\n const style = { color: run.color ?? options.color ?? 0xffffff,\n bold: run.bold ?? options.bold ?? false, italic: run.italic ?? options.italic ?? false };\n for (const character of run.text.replace(/\\r\\n?/g, \"\\n\")) {\n trailingNewline = character === \"\\n\";\n if (character === \"\\n\") {\n finishLine(line); line = []; width = 0;\n continue;\n }\n const glyph = font.glyphs.get(character);\n const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);\n line.push({ character, glyph, advance, style, x: 0, y: 0 });\n width += advance;\n while (width > maxWidth && line.length > 1) {\n let space = -1;\n for (let i = 0; i < line.length; i++) if (line[i].character === \" \") space = i;\n const split = space >= 0 ? space : line.length - 1;\n if (split > 0) finishLine(line.slice(0, split));\n line = line.slice(split + (space >= 0 ? 1 : 0));\n width = line.reduce((sum, entry) => sum + entry.advance, 0);\n }\n }\n }\n if (line.length || !lineWidths.length || trailingNewline) finishLine(line);\n return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };\n}\n\n/** Creates glyph batches in painter order. Unsupported characters use an outlined missing glyph. */\nexport function createGuiTextGeometry(layout: GuiTextLayout, shadow = true): { image?: CompatCanvas; geometry: BufferGeometry }[] {\n interface Batch { image?: CompatCanvas; positions: number[]; uvs: number[]; colors: number[]; indices: number[]; }\n const batches: Batch[] = [];\n for (const isShadow of shadow ? [true, false] : [false]) {\n let batch: Batch | undefined;\n for (const entry of layout.glyphs) {\n const { glyph, style } = entry;\n if (glyph && !glyph.image) continue;\n if (!batch || batch.image !== glyph?.image) {\n batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };\n batches.push(batch);\n }\n const color = new Color(isShadow ? (style.color & 0xfcfcfc) >> 2 : style.color);\n const offset = isShadow ? 1 : 0;\n const top = glyph ? 7 - glyph.ascent : 0;\n const height = glyph ? glyph.height * glyph.scale : 8;\n const width = glyph ? glyph.width * glyph.scale : 5;\n const shear = (y: number) => style.italic ? 1 - 0.25 * y : 0;\n const quad = (left: number, upper: number, right: number, lower: number, boldOffset: number) => {\n const base = batch!.positions.length / 3;\n const x = entry.x + offset + boldOffset, y = entry.y + offset;\n batch!.positions.push(x + left + shear(upper), -y - upper, 0, x + right + shear(upper), -y - upper, 0,\n x + left + shear(lower), -y - lower, 0, x + right + shear(lower), -y - lower, 0);\n const u0 = glyph ? glyph.x / glyph.image!.width : 0;\n const u1 = glyph ? (glyph.x + glyph.width) / glyph.image!.width : 1;\n const v0 = glyph ? 1 - glyph.y / glyph.image!.height : 1;\n const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image!.height : 0;\n batch!.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);\n for (let i = 0; i < 4; i++) batch!.colors.push(color.r, color.g, color.b);\n batch!.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);\n };\n for (const boldOffset of style.bold ? [0, 1] : [0]) {\n if (glyph) quad(0, top, width, top + height, boldOffset);\n else {\n quad(0, 0, 5, 1, boldOffset); quad(0, 7, 5, 8, boldOffset);\n quad(0, 1, 1, 7, boldOffset); quad(4, 1, 5, 7, boldOffset);\n }\n }\n }\n }\n return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry()\n .setAttribute(\"position\", new Float32BufferAttribute(positions, 3))\n .setAttribute(\"uv\", new Float32BufferAttribute(uvs, 2))\n .setAttribute(\"color\", new Float32BufferAttribute(colors, 3))\n .setIndex(indices) }));\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/gui/GuiText.ts"],"sourcesContent":["import { BufferGeometry, Color, Float32BufferAttribute } from \"three\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport { Fonts, type BitmapGlyph } from \"../assets/Fonts\";\nimport type { CompatCanvas } from \"../canvas/CanvasCompat\";\n\n/** Text appearance set on a GUI text layer or overridden by an individual text run. */\nexport interface GuiTextStyle {\n /** sRGB 0xRRGGBB; defaults to white. */\n color?: number;\n bold?: boolean;\n italic?: boolean;\n}\n\n/** A text segment with optional style overrides within {@link GuiText}. */\nexport interface GuiTextRun extends GuiTextStyle {\n text: string;\n}\n\n/** Literal text, or styled runs. Newlines are preserved. */\nexport type GuiText = string | readonly GuiTextRun[];\n\n/** Text layout settings set on a GUI text layer or passed to {@link layoutGuiText}. */\nexport interface GuiTextOptions extends GuiTextStyle {\n /** Font resource ID; defaults to minecraft:default. */\n font?: AssetKey | string;\n /** Draws a one-pixel shadow; defaults to true. */\n shadow?: boolean;\n /** Wrap width in GUI pixels. Long words break at glyph boundaries. */\n maxWidth?: number;\n /** Distance between line origins; defaults to 9 GUI pixels. */\n lineHeight?: number;\n}\n\n/** One measured glyph and its position in GUI pixels, produced by {@link layoutGuiText}. */\nexport interface PositionedGuiGlyph {\n character: string;\n glyph?: BitmapGlyph;\n x: number;\n y: number;\n advance: number;\n style: Required<GuiTextStyle>;\n}\n\n/** Measured glyphs, line widths, and overall dimensions in GUI pixels. */\nexport interface GuiTextLayout {\n glyphs: PositionedGuiGlyph[];\n lineWidths: number[];\n width: number;\n height: number;\n}\n\n/** Measures and wraps text using the same glyph advances used for rendering. */\nexport async function layoutGuiText(text: GuiText, options: GuiTextOptions = {}): Promise<GuiTextLayout> {\n const maxWidth = options.maxWidth ?? Infinity, lineHeight = options.lineHeight ?? 9;\n if (!(maxWidth > 0) || !Number.isFinite(lineHeight) || lineHeight <= 0) {\n throw new Error(\"Text wrap width and line height must be positive\");\n }\n const font = await Fonts.get(options.font);\n const runs = typeof text === \"string\" ? [{ text }] : text;\n await font.resolve?.(runs.map(run => run.text).join(\"\"));\n const glyphs: PositionedGuiGlyph[] = [], lineWidths: number[] = [];\n let line: PositionedGuiGlyph[] = [], width = 0;\n let trailingNewline = false;\n const finishLine = (entries: PositionedGuiGlyph[]) => {\n let x = 0;\n for (const entry of entries) {\n glyphs.push({ ...entry, x, y: lineWidths.length * lineHeight });\n x += entry.advance;\n }\n lineWidths.push(x);\n };\n for (const run of runs) {\n const style = { color: run.color ?? options.color ?? 0xffffff,\n bold: run.bold ?? options.bold ?? false, italic: run.italic ?? options.italic ?? false };\n for (const character of run.text.replace(/\\r\\n?/g, \"\\n\")) {\n trailingNewline = character === \"\\n\";\n if (character === \"\\n\") {\n finishLine(line); line = []; width = 0;\n continue;\n }\n const glyph = font.glyphs.get(character);\n const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);\n line.push({ character, glyph, advance, style, x: 0, y: 0 });\n width += advance;\n while (width > maxWidth && line.length > 1) {\n let space = -1;\n for (let i = 0; i < line.length; i++) if (line[i].character === \" \") space = i;\n const split = space >= 0 ? space : line.length - 1;\n if (split > 0) finishLine(line.slice(0, split));\n line = line.slice(split + (space >= 0 ? 1 : 0));\n width = line.reduce((sum, entry) => sum + entry.advance, 0);\n }\n }\n }\n if (line.length || !lineWidths.length || trailingNewline) finishLine(line);\n return { glyphs, lineWidths, width: Math.max(0, ...lineWidths), height: lineWidths.length * lineHeight };\n}\n\n/** Creates glyph batches in painter order. Unsupported characters use an outlined missing glyph. */\nexport function createGuiTextGeometry(layout: GuiTextLayout, shadow = true): { image?: CompatCanvas; geometry: BufferGeometry }[] {\n interface Batch { image?: CompatCanvas; positions: number[]; uvs: number[]; colors: number[]; indices: number[]; }\n const batches: Batch[] = [];\n for (const isShadow of shadow ? [true, false] : [false]) {\n let batch: Batch | undefined;\n for (const entry of layout.glyphs) {\n const { glyph, style } = entry;\n if (glyph && !glyph.image) continue;\n if (!batch || batch.image !== glyph?.image) {\n batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };\n batches.push(batch);\n }\n const color = new Color(isShadow ? (style.color & 0xfcfcfc) >> 2 : style.color);\n const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;\n const top = glyph ? 7 - glyph.ascent : 0;\n const height = glyph ? glyph.height * glyph.scale : 8;\n const width = glyph ? glyph.width * glyph.scale : 5;\n const shear = (y: number) => style.italic ? 1 - 0.25 * y : 0;\n const quad = (left: number, upper: number, right: number, lower: number, boldOffset: number) => {\n const base = batch!.positions.length / 3;\n const x = entry.x + offset + boldOffset, y = entry.y + offset;\n batch!.positions.push(x + left + shear(upper), -y - upper, 0, x + right + shear(upper), -y - upper, 0,\n x + left + shear(lower), -y - lower, 0, x + right + shear(lower), -y - lower, 0);\n const u0 = glyph ? glyph.x / glyph.image!.width : 0;\n const u1 = glyph ? (glyph.x + glyph.width) / glyph.image!.width : 1;\n const v0 = glyph ? 1 - glyph.y / glyph.image!.height : 1;\n const v1 = glyph ? 1 - (glyph.y + glyph.height) / glyph.image!.height : 0;\n batch!.uvs.push(u0, v0, u1, v0, u0, v1, u1, v1);\n for (let i = 0; i < 4; i++) batch!.colors.push(color.r, color.g, color.b);\n batch!.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);\n };\n for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {\n if (glyph) quad(0, top, width, top + height, boldOffset);\n else {\n quad(0, 0, 5, 1, boldOffset); quad(0, 7, 5, 8, boldOffset);\n quad(0, 1, 1, 7, boldOffset); quad(4, 1, 5, 7, boldOffset);\n }\n }\n }\n }\n return batches.map(({ image, positions, uvs, colors, indices }) => ({ image, geometry: new BufferGeometry()\n .setAttribute(\"position\", new Float32BufferAttribute(positions, 3))\n .setAttribute(\"uv\", new Float32BufferAttribute(uvs, 2))\n .setAttribute(\"color\", new Float32BufferAttribute(colors, 3))\n .setIndex(indices) }));\n}\n"],"mappings":"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","names":[]}
@@ -6,8 +6,8 @@ import { Env } from "../Env.mjs";
6
6
  import { Requests } from "../request/Requests.mjs";
7
7
  import { WrappedImage } from "../WrappedImage.mjs";
8
8
  import { base64ToBytes, bytesToBase64 } from "../util/_internal/base64.mjs";
9
- import { prefix } from "../util/log.mjs";
10
- var p = prefix("ImageLoader");
9
+ import { logger } from "../util/log.mjs";
10
+ var log = logger("ImageLoader");
11
11
  var ImageLoader = class _ImageLoader {
12
12
  static _createImage() {
13
13
  return createImage();
@@ -32,7 +32,7 @@ var ImageLoader = class _ImageLoader {
32
32
  return image;
33
33
  }
34
34
  static async loadData(src) {
35
- console.debug(p, "loadData", src);
35
+ log.debug("loadData", src);
36
36
  const image = await this.loadCanvasData(src);
37
37
  return image.data.getImageData(0, 0, image.width, image.height);
38
38
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/image/ImageLoader.ts"],"sourcesContent":["import { CompatImage, createCanvas, createImage } from \"../canvas/CanvasCompat\";\nimport { serializeImageKey } from \"../cache/CacheKey\";\nimport { Caching } from \"../cache/Caching\";\nimport type { RequestResponse } from \"../request/Requests\";\nimport { Env } from \"../Env\";\nimport { Requests } from \"../request/Requests\";\nimport { WrappedImage } from \"../WrappedImage\";\nimport { ExtractableImageData } from \"../ExtractableImageData\";\nimport { base64ToBytes, bytesToBase64 } from \"../util/_internal/base64\";\nimport { prefix } from \"../util/log\";\n\nconst p = prefix(\"ImageLoader\");\n\n/** Encoded image bytes with dimensions and format detected from the file header. */\nexport interface ImageInfo {\n src?: string;\n width: number;\n height: number;\n type?: string;\n data: Uint8Array;\n}\n\n/** Fetches and decodes images through the active browser or Node environment provider. */\nexport class ImageLoader {\n\n protected static _createImage(): CompatImage {\n return createImage();\n }\n\n /** Resolves when an image URL has decoded, or rejects if decoding fails. */\n public static async loadAsync(src: string): Promise<CompatImage> {\n return new Promise<CompatImage>((resolve, reject) => {\n const image = this._createImage();\n image.onload = () => resolve(image);\n image.onerror = (err: Error) => reject(err instanceof Error ? err : new Error(\"Failed to decode image\"));\n // Node images can finish decoding synchronously when src is assigned.\n image.src = src;\n });\n }\n\n /** Returns an image immediately. Use the callbacks to observe loading, or await {@link loadAsync}. */\n public static loadElement(src: string, onload?: () => void, onerr?: (err: Error) => void): CompatImage {\n const image = this._createImage();\n if (onload)\n image.onload = onload;\n if (onerr)\n image.onerror = onerr;\n image.src = src;\n return image;\n }\n\n public static async loadData(src: string): Promise<ImageData> {\n console.debug(p, \"loadData\", src);\n const image = await this.loadCanvasData(src);\n return image.data.getImageData(0, 0, image.width, image.height);\n }\n\n public static async loadCanvasData(src: string): Promise<ExtractableImageData> {\n const keyStr = serializeImageKey({ src });\n const info = this.getInfo(src);\n const cached = Caching.rawImageCache.getIfPresent(keyStr);\n try {\n return await this.infoToCanvasData(await info);\n } catch (err) {\n // A valid header can still contain corrupt pixels. Retry the fetch after a decode\n // failure, without evicting a replacement inserted while this load was pending.\n if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {\n Caching.rawImageCache.invalidate(keyStr);\n }\n throw err;\n }\n }\n\n /** Decodes the supplied bytes into a canvas without fetching the source URL again. */\n public static async infoToCanvasData(info: ImageInfo): Promise<ExtractableImageData> {\n const type = info.type === \"jpg\" ? \"jpeg\" : info.type ?? \"png\";\n // Both browser and Node images accept data URLs; src remains provenance, not a second fetch.\n const image = await ImageLoader.loadAsync(`data:image/${type};base64,${bytesToBase64(info.data)}`);\n const canvas = createCanvas(info.width, info.height);\n const context = canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n context.drawImage(image as CanvasImageSource, 0, 0);\n return {\n data: context,\n width: info.width,\n height: info.height\n }\n }\n\n\n public static async infoToData(info: ImageInfo): Promise<ImageData> {\n const image = await this.infoToCanvasData(info);\n return image.data.getImageData(0, 0, image.width, image.height);\n }\n\n /** Returns cached RGBA pixels for an image URL or data URL. Failed loads can be retried. */\n public static async getData(src: string): Promise<ImageData> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.imageDataCache.get(keyStr, k => {\n return ImageLoader.loadData(src);\n }))!;\n }\n\n /** Returns a cached canvas context and dimensions for an image URL or data URL. */\n public static async getCanvasData(src: string): Promise<ExtractableImageData> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.canvasImageDataCache.get(keyStr, k => {\n return ImageLoader.loadCanvasData(src);\n }))!;\n }\n\n public static async processResponse(response: Pick<RequestResponse<ArrayBuffer>, \"data\" | \"url\">): Promise<ImageInfo> {\n const src = response.url;\n const data = new Uint8Array(response.data);\n const { width, height, type } = Env.provider.imageSize(data);\n if (!width || !height) {\n throw new Error(\"Invalid or unsupported image dimensions\");\n }\n return {\n src,\n width,\n height,\n type,\n data: data\n }\n }\n\n\n public static async loadInfo(src: string): Promise<ImageInfo> {\n if (/^data:/i.test(src.trimStart())) {\n const url = new URL(src);\n url.hash = \"\";\n const comma = url.href.indexOf(\",\");\n if (comma < 0) {\n throw new Error(\"Invalid image data URL\");\n }\n // Percent escapes represent image bytes, which need not be valid UTF-8.\n const bytes = url.href.slice(comma + 1).replace(/%([\\da-f]{2})/gi,\n (_, hex: string) => String.fromCharCode(parseInt(hex, 16)));\n const data = /; *base64 *$/i.test(url.href.slice(5, comma))\n ? base64ToBytes(bytes)\n : Uint8Array.from(bytes, char => char.charCodeAt(0));\n return this.processResponse({\n url: src,\n data: data.buffer\n });\n }\n\n return Requests.genericRequest({\n url: src,\n responseType: \"arraybuffer\"\n })\n .then(this.processResponse);\n }\n\n public static async getInfo(src: string): Promise<ImageInfo> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.rawImageCache.get(keyStr, k => {\n return ImageLoader.loadInfo(src);\n }))!;\n }\n\n public static async loadWrapped(src: string): Promise<WrappedImage> {\n const data = await this.getCanvasData(src);\n return new WrappedImage(data);\n }\n\n public static async getWrapped(src: string): Promise<WrappedImage> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.wrappedImageCache.get(keyStr, k => {\n return ImageLoader.loadWrapped(src);\n }))!;\n }\n\n\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/image/ImageLoader.ts"],"sourcesContent":["import { CompatImage, createCanvas, createImage } from \"../canvas/CanvasCompat\";\nimport { serializeImageKey } from \"../cache/CacheKey\";\nimport { Caching } from \"../cache/Caching\";\nimport type { RequestResponse } from \"../request/Requests\";\nimport { Env } from \"../Env\";\nimport { Requests } from \"../request/Requests\";\nimport { WrappedImage } from \"../WrappedImage\";\nimport { ExtractableImageData } from \"../ExtractableImageData\";\nimport { base64ToBytes, bytesToBase64 } from \"../util/_internal/base64\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"ImageLoader\");\n\n/** Encoded image bytes with dimensions and format detected from the file header. */\nexport interface ImageInfo {\n src?: string;\n width: number;\n height: number;\n type?: string;\n data: Uint8Array;\n}\n\n/** Fetches and decodes images through the active browser or Node environment provider. */\nexport class ImageLoader {\n\n protected static _createImage(): CompatImage {\n return createImage();\n }\n\n /** Resolves when an image URL has decoded, or rejects if decoding fails. */\n public static async loadAsync(src: string): Promise<CompatImage> {\n return new Promise<CompatImage>((resolve, reject) => {\n const image = this._createImage();\n image.onload = () => resolve(image);\n image.onerror = (err: Error) => reject(err instanceof Error ? err : new Error(\"Failed to decode image\"));\n // Node images can finish decoding synchronously when src is assigned.\n image.src = src;\n });\n }\n\n /** Returns an image immediately. Use the callbacks to observe loading, or await {@link loadAsync}. */\n public static loadElement(src: string, onload?: () => void, onerr?: (err: Error) => void): CompatImage {\n const image = this._createImage();\n if (onload)\n image.onload = onload;\n if (onerr)\n image.onerror = onerr;\n image.src = src;\n return image;\n }\n\n public static async loadData(src: string): Promise<ImageData> {\n log.debug(\"loadData\", src);\n const image = await this.loadCanvasData(src);\n return image.data.getImageData(0, 0, image.width, image.height);\n }\n\n public static async loadCanvasData(src: string): Promise<ExtractableImageData> {\n const keyStr = serializeImageKey({ src });\n const info = this.getInfo(src);\n const cached = Caching.rawImageCache.getIfPresent(keyStr);\n try {\n return await this.infoToCanvasData(await info);\n } catch (err) {\n // A valid header can still contain corrupt pixels. Retry the fetch after a decode\n // failure, without evicting a replacement inserted while this load was pending.\n if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {\n Caching.rawImageCache.invalidate(keyStr);\n }\n throw err;\n }\n }\n\n /** Decodes the supplied bytes into a canvas without fetching the source URL again. */\n public static async infoToCanvasData(info: ImageInfo): Promise<ExtractableImageData> {\n const type = info.type === \"jpg\" ? \"jpeg\" : info.type ?? \"png\";\n // Both browser and Node images accept data URLs; src remains provenance, not a second fetch.\n const image = await ImageLoader.loadAsync(`data:image/${type};base64,${bytesToBase64(info.data)}`);\n const canvas = createCanvas(info.width, info.height);\n const context = canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n context.drawImage(image as CanvasImageSource, 0, 0);\n return {\n data: context,\n width: info.width,\n height: info.height\n }\n }\n\n\n public static async infoToData(info: ImageInfo): Promise<ImageData> {\n const image = await this.infoToCanvasData(info);\n return image.data.getImageData(0, 0, image.width, image.height);\n }\n\n /** Returns cached RGBA pixels for an image URL or data URL. Failed loads can be retried. */\n public static async getData(src: string): Promise<ImageData> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.imageDataCache.get(keyStr, k => {\n return ImageLoader.loadData(src);\n }))!;\n }\n\n /** Returns a cached canvas context and dimensions for an image URL or data URL. */\n public static async getCanvasData(src: string): Promise<ExtractableImageData> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.canvasImageDataCache.get(keyStr, k => {\n return ImageLoader.loadCanvasData(src);\n }))!;\n }\n\n public static async processResponse(response: Pick<RequestResponse<ArrayBuffer>, \"data\" | \"url\">): Promise<ImageInfo> {\n const src = response.url;\n const data = new Uint8Array(response.data);\n const { width, height, type } = Env.provider.imageSize(data);\n if (!width || !height) {\n throw new Error(\"Invalid or unsupported image dimensions\");\n }\n return {\n src,\n width,\n height,\n type,\n data: data\n }\n }\n\n\n public static async loadInfo(src: string): Promise<ImageInfo> {\n if (/^data:/i.test(src.trimStart())) {\n const url = new URL(src);\n url.hash = \"\";\n const comma = url.href.indexOf(\",\");\n if (comma < 0) {\n throw new Error(\"Invalid image data URL\");\n }\n // Percent escapes represent image bytes, which need not be valid UTF-8.\n const bytes = url.href.slice(comma + 1).replace(/%([\\da-f]{2})/gi,\n (_, hex: string) => String.fromCharCode(parseInt(hex, 16)));\n const data = /; *base64 *$/i.test(url.href.slice(5, comma))\n ? base64ToBytes(bytes)\n : Uint8Array.from(bytes, char => char.charCodeAt(0));\n return this.processResponse({\n url: src,\n data: data.buffer\n });\n }\n\n return Requests.genericRequest({\n url: src,\n responseType: \"arraybuffer\"\n })\n .then(this.processResponse);\n }\n\n public static async getInfo(src: string): Promise<ImageInfo> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.rawImageCache.get(keyStr, k => {\n return ImageLoader.loadInfo(src);\n }))!;\n }\n\n public static async loadWrapped(src: string): Promise<WrappedImage> {\n const data = await this.getCanvasData(src);\n return new WrappedImage(data);\n }\n\n public static async getWrapped(src: string): Promise<WrappedImage> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.wrappedImageCache.get(keyStr, k => {\n return ImageLoader.loadWrapped(src);\n }))!;\n }\n\n\n}\n"],"mappings":"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","names":[]}
@@ -913,6 +913,9 @@ declare class MinecraftFaceUV {
913
913
  */
914
914
  declare function shutdown(): void;
915
915
 
916
+ declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
917
+ declare const DEFAULT_NAMESPACE = "minecraft";
918
+
916
919
  /** Runs queued tasks in bounded batches. Idle executors do not keep a timer running. */
917
920
  declare class BatchedExecutor {
918
921
  readonly interval: number;
@@ -930,6 +933,34 @@ declare class BatchedExecutor {
930
933
  }
931
934
  type Task<T = unknown> = () => T | Promise<T>;
932
935
 
936
+ /** Severity of a log message, from most to least verbose. */
937
+ type LogLevel = "debug" | "info" | "warn" | "error";
938
+ /** The lowest level that is printed, or `"silent"` to print nothing. */
939
+ type LogThreshold = LogLevel | "silent";
940
+ /** Receives each message that passes the threshold. `args` are the logger call's arguments, without a tag. */
941
+ type LogHandler = (level: LogLevel, namespace: string, args: unknown[]) => void;
942
+ interface LoggingOptions {
943
+ /** Threshold for namespaces without an override. Starts at `"warn"`. */
944
+ level?: LogThreshold;
945
+ /** Thresholds by logger name, such as `{ UVMapper: "debug" }`. Replaces earlier overrides. */
946
+ namespaces?: Record<string, LogThreshold>;
947
+ }
948
+ interface Logger {
949
+ debug(...args: unknown[]): void;
950
+ info(...args: unknown[]): void;
951
+ warn(...args: unknown[]): void;
952
+ error(...args: unknown[]): void;
953
+ }
954
+ /** Global log settings for every MineRender logger. */
955
+ declare class Logging {
956
+ /** Updates the given settings and keeps the others. */
957
+ static configure(options: LoggingOptions): void;
958
+ /** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */
959
+ static setHandler(handler?: LogHandler): void;
960
+ }
961
+ /** Creates a logger whose messages are tagged and filtered as `namespace`. */
962
+ declare function logger(namespace: string): Logger;
963
+ /** @deprecated Use {@link logger}. */
933
964
  declare function prefix(prefix?: string): string;
934
965
 
935
966
  /** Rotates geometry in place around the element's origin. The supplied angle is in degrees. */
@@ -941,8 +972,11 @@ declare function addWireframeToObject(obj: Object3D, color?: number, w?: number)
941
972
  /** Adds edge and axis helpers to a mesh and returns a function that disposes their resources. */
942
973
  declare function addWireframeToMesh(geo: BufferGeometry, mesh: Mesh, color?: number, w?: number): () => void;
943
974
 
975
+ /** @deprecated Unused by MineRender. */
944
976
  declare function captureException(e: any, ...extra: any[]): void;
977
+ /** @deprecated Unused by MineRender. */
945
978
  declare function timingStart(marker: string): void;
979
+ /** @deprecated Unused by MineRender. */
946
980
  declare function timingEnd(marker: string): void;
947
981
 
948
982
  declare function sha1(str: string): string;
@@ -962,7 +996,8 @@ declare enum AssetParser {
962
996
  NBT = "nbt",
963
997
  IMAGE = "image",
964
998
  LIST = "list",
965
- JSON = "json"
999
+ JSON = "json",
1000
+ BINARY = "binary"
966
1001
  }
967
1002
 
968
1003
  /** An asset provider registered with {@link AssetLoader.addSource}. */
@@ -1056,8 +1091,6 @@ type MultipartCondition = Record<string, string> | {
1056
1091
  AND: MultipartCondition[];
1057
1092
  };
1058
1093
 
1059
- declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
1060
- declare const DEFAULT_NAMESPACE = "minecraft";
1061
1094
  /** Convenience accessors for model and blockstate loading. */
1062
1095
  declare class Assets {
1063
1096
  /**
@@ -1280,14 +1313,20 @@ interface BitmapGlyph {
1280
1313
  scale: number;
1281
1314
  ascent: number;
1282
1315
  advance: number;
1316
+ /** Extra advance and drawing offset for bold text, in GUI pixels. Defaults to 1. */
1317
+ boldOffset?: number;
1318
+ /** Shadow displacement in GUI pixels. Defaults to 1. */
1319
+ shadowOffset?: number;
1283
1320
  }
1284
1321
  /** Character-to-glyph lookup assembled from the active resource-pack fonts. */
1285
1322
  interface BitmapFont {
1286
1323
  glyphs: Map<string, BitmapGlyph>;
1324
+ /** Resolves characters through the font providers before measuring or drawing them. */
1325
+ resolve?(characters: string): Promise<void>;
1287
1326
  }
1288
- /** Loads Minecraft bitmap, space, and reference font providers for GUI text. */
1327
+ /** Loads Minecraft bitmap, Unihex, space, and reference font providers for GUI text. */
1289
1328
  declare class Fonts {
1290
- /** Combines font definitions in source-priority order. Unsupported Unihex and TrueType providers are skipped. */
1329
+ /** Combines font definitions in source-priority order. TrueType providers are skipped. */
1291
1330
  static get(key?: AssetKey | string): Promise<BitmapFont>;
1292
1331
  private static relatedKey;
1293
1332
  private static load;
@@ -1576,25 +1615,35 @@ interface EntityAnimationOptions {
1576
1615
  speed?: number;
1577
1616
  /** Start time in seconds; defaults to 0. */
1578
1617
  time?: number;
1618
+ /** Nonnegative finite weights in clip order; defaults to 1 per clip. Offsets add without normalizing weights. */
1619
+ weights?: readonly number[];
1579
1620
  }
1580
1621
  /**
1581
- * Poses part groups from a keyframe animation the way vanilla does: every update restores the
1582
- * default pose of each animated part, then adds the sampled offsets to its position, Euler angles and scale.
1622
+ * Poses part groups from keyframe animations: every update restores the default pose of each
1623
+ * animated part, then adds weighted sampled offsets to its position, Euler angles and scale.
1583
1624
  * It owns no timer; the owner advances it.
1584
1625
  */
1585
1626
  declare class EntityAnimationPlayer {
1586
1627
  private parts;
1587
- private _animation?;
1628
+ private _animations;
1629
+ private _weights;
1630
+ private loops;
1588
1631
  private _time;
1589
- private loop;
1590
1632
  private speed;
1591
1633
  get animation(): EntityAnimation | undefined;
1634
+ get animations(): readonly EntityAnimation[];
1635
+ get weights(): readonly number[];
1592
1636
  get time(): number;
1593
1637
  /**
1594
1638
  * Starts an animation on matching named parts. Supplied baked poses are the baseline for offsets;
1595
1639
  * without them, the current pose is used. Stopping restores the pose from before playback.
1596
1640
  */
1597
1641
  play(layers: Object3D[], animation: EntityAnimation, options?: EntityAnimationOptions, poses?: ReadonlyMap<Object3D, EntityModelPart["pose"]>): void;
1642
+ /**
1643
+ * Starts clips on matching parts with a shared clock. Weighted offsets add to the supplied baked poses
1644
+ * or, without poses, to each animated part's pose when playback starts.
1645
+ */
1646
+ playAnimations(layers: Object3D[], animations: readonly EntityAnimation[], options?: EntityAnimationOptions, poses?: ReadonlyMap<Object3D, EntityModelPart["pose"]>): void;
1598
1647
  /** Restores the poses from before playback. Returns whether an animation was active. */
1599
1648
  stop(): boolean;
1600
1649
  /** Forgets the animation without touching the parts, for parts that no longer exist. */
@@ -1603,8 +1652,12 @@ declare class EntityAnimationPlayer {
1603
1652
  setTime(seconds: number): boolean;
1604
1653
  /** Advances playback by elapsed seconds multiplied by the speed passed to {@link play}. */
1605
1654
  advance(deltaSeconds: number): boolean;
1655
+ /** Changes weights in clip order and reapplies the current time without restarting playback. */
1656
+ setWeights(weights: readonly number[]): boolean;
1606
1657
  private apply;
1607
1658
  }
1659
+ /** @internal */
1660
+ declare function validateAnimationWeights(weights: readonly number[], count: number): number[];
1608
1661
 
1609
1662
  /** Renders selected entity layers as named part groups. Create it through {@link MineRenderScene.addEntity}. */
1610
1663
  declare class EntityObject extends SceneObject {
@@ -1633,8 +1686,10 @@ declare class EntityObject extends SceneObject {
1633
1686
  private updateScroll;
1634
1687
  /** The first active clip, until playback is stopped or the object is disposed. */
1635
1688
  get animation(): Maybe<EntityAnimation>;
1636
- /** Clips playing together, each targeting a separate geometry layer. */
1689
+ /** Clips playing together, in the order passed to {@link playAnimations}. */
1637
1690
  get activeAnimations(): readonly EntityAnimation[];
1691
+ /** Weights of the active clips, in the same order as {@link activeAnimations}. */
1692
+ get animationWeights(): readonly number[];
1638
1693
  /** Seconds since the animation started, before looping. */
1639
1694
  get animationTime(): number;
1640
1695
  /**
@@ -1644,8 +1699,13 @@ declare class EntityObject extends SceneObject {
1644
1699
  * The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
1645
1700
  */
1646
1701
  playAnimation(animation: EntityAnimation, options?: EntityAnimationOptions): void;
1647
- /** Plays clips with a shared clock and no blending. Selected layers without their own clip follow `main`. */
1702
+ /**
1703
+ * Plays clips with a shared clock, adding their weighted offsets within each geometry layer.
1704
+ * Weights default to 1 and are not normalized. Selected layers without their own clip follow `main`.
1705
+ */
1648
1706
  playAnimations(animations: readonly EntityAnimation[], options?: EntityAnimationOptions): void;
1707
+ /** Changes weights in active clip order, notifying the scene without restarting the shared clock. Has no effect without an animation. */
1708
+ setAnimationWeights(weights: readonly number[]): void;
1649
1709
  /** Stops all clips and restores the poses from before playback. */
1650
1710
  stopAnimation(): void;
1651
1711
  /** Poses the object at an explicit time in seconds. Has no effect without an animation. */
@@ -2431,11 +2491,21 @@ interface Palette {
2431
2491
  };
2432
2492
  }
2433
2493
  interface PaletteEntry {
2434
- Name: {
2494
+ Name?: {
2495
+ type: "string";
2496
+ value: string;
2497
+ };
2498
+ id?: {
2435
2499
  type: "string";
2436
2500
  value: string;
2437
2501
  };
2438
- Properties: {
2502
+ Properties?: {
2503
+ type: "compound";
2504
+ value: {
2505
+ [property: string]: PalettePropertyValue;
2506
+ };
2507
+ };
2508
+ properties?: {
2439
2509
  type: "compound";
2440
2510
  value: {
2441
2511
  [property: string]: PalettePropertyValue;
@@ -2493,6 +2563,7 @@ declare class HostedAssetSource extends AssetSource {
2493
2563
  static readonly IMAGE: ResponseParser<TextureAsset>;
2494
2564
  static readonly LIST: ResponseParser<ListAsset>;
2495
2565
  static readonly JSON: ResponseParser<any>;
2566
+ static readonly BINARY: ResponseParser<BinaryAsset>;
2496
2567
  static readonly PARSER_MAP: Map<AssetParser, ResponseParser<any>>;
2497
2568
  /** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
2498
2569
  loadOrRetryWithDefaults<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>>;
@@ -2513,6 +2584,10 @@ declare class HostedAssetSource extends AssetSource {
2513
2584
  interface HostedAssetSourceOptions {
2514
2585
  retryDefaults: boolean;
2515
2586
  }
2587
+ /** Encoded asset bytes loaded without JSON or image decoding. */
2588
+ interface BinaryAsset extends MinecraftAsset {
2589
+ data: Uint8Array;
2590
+ }
2516
2591
 
2517
2592
  /** A resource-pack ZIP entry, with its archive-relative path and lazily extracted bytes. */
2518
2593
  interface ArchiveEntry {
@@ -2650,6 +2725,12 @@ interface BedrockGeometryFile {
2650
2725
  [key: string]: BedrockGeometry | any;
2651
2726
  }
2652
2727
 
2728
+ interface UnihexFile {
2729
+ indices: Int32Array;
2730
+ rows: Uint32Array;
2731
+ metrics: Uint8Array;
2732
+ }
2733
+
2653
2734
  /** Shared in-memory caches for loaded assets and render resources. Persistent stores are managed separately. */
2654
2735
  declare class Caching {
2655
2736
  private static _generation;
@@ -2675,6 +2756,7 @@ declare class Caching {
2675
2756
  static readonly entityTextureCache: AsyncLoadingCache<CacheKey, AssetKey>;
2676
2757
  static readonly entityAnimationCache: AsyncLoadingCache<CacheKey, EntityAnimationFile>;
2677
2758
  static readonly blockEntityIndexCache: AsyncLoadingCache<CacheKey, BlockEntityIndex>;
2759
+ static readonly unihexCache: AsyncLoadingCache<CacheKey, UnihexFile>;
2678
2760
  static readonly fontCache: AsyncLoadingCache<CacheKey, BitmapFont>;
2679
2761
  static readonly bannerPatternCache: AsyncLoadingCache<CacheKey, BannerPattern>;
2680
2762
  static readonly mineRenderDataCache: AsyncLoadingCache<CacheKey, unknown>;
@@ -3790,6 +3872,7 @@ interface SectionTemplateData {
3790
3872
  uvs: Float32Array;
3791
3873
  uvBounds: Float32Array;
3792
3874
  colors: Float32Array;
3875
+ shade?: Float32Array;
3793
3876
  indices: Uint16Array;
3794
3877
  cullFaces: Uint8Array;
3795
3878
  biomeTint?: Uint8Array;
@@ -3853,6 +3936,7 @@ interface SectionGeometryPage {
3853
3936
  uvs: Float32Array;
3854
3937
  uvBounds: Float32Array;
3855
3938
  colors: Float32Array;
3939
+ shade: Float32Array;
3856
3940
  indices: Uint32Array;
3857
3941
  /** Owning section cell for each quad; each quad contributes two consecutive triangles. */
3858
3942
  blockIndices: Uint16Array;
@@ -3992,7 +4076,7 @@ declare class Chunk<SectionMeshing extends boolean = false> {
3992
4076
  private ambientOcclusionCells?;
3993
4077
  private readonly blockChanges;
3994
4078
  private biomeChange?;
3995
- constructor(scene: MineRenderScene, x: number, y: number, z: number, onBlocksChanged?: ((positions: Vector3[]) => Promise<void>) | undefined, sectionModels?: SectionModels | undefined, neighborCell?: ((x: number, y: number, z: number) => number) | undefined, biomeAt?: ((x: number, y: number, z: number) => Maybe<string>) | undefined, onBiomesChanged?: ((biomes?: readonly string[]) => Promise<void>) | undefined, lightAt?: ((x: number, y: number, z: number) => number) | undefined, onLightCleared?: (() => Promise<void>) | undefined, ambientLight?: number, biomeBlend?: (() => BiomeBlend | undefined) | undefined);
4079
+ constructor(scene: MineRenderScene, x: number, y: number, z: number, onBlocksChanged?: ((positions: Vector3[], deferCulling?: boolean) => Promise<void>) | undefined, sectionModels?: SectionModels | undefined, neighborCell?: ((x: number, y: number, z: number) => number) | undefined, biomeAt?: ((x: number, y: number, z: number) => Maybe<string>) | undefined, onBiomesChanged?: ((biomes?: readonly string[]) => Promise<void>) | undefined, lightAt?: ((x: number, y: number, z: number) => number) | undefined, onLightCleared?: (() => Promise<void>) | undefined, ambientLight?: number, biomeBlend?: (() => BiomeBlend | undefined) | undefined);
3996
4080
  /** Finds the nearest owned block hit across sections, testing each shared mesh once. */
3997
4081
  static raycast<SectionMeshing extends boolean>(chunks: Iterable<Chunk<SectionMeshing>>, raycaster: Raycaster): WorldBlockIntersection | undefined;
3998
4082
  getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo<SectionMeshing>>;
@@ -4004,11 +4088,14 @@ declare class Chunk<SectionMeshing extends boolean = false> {
4004
4088
  getBiomeAt(pos: TripleArray): Maybe<string>;
4005
4089
  /** Copies 64 biome IDs in x + z * 4 + y * 16 order and refreshes placed blocks. Omit the array to clear biome data. */
4006
4090
  setBiomes(biomes?: readonly string[]): Promise<void>;
4007
- /** Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects. */
4091
+ /**
4092
+ * Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects.
4093
+ * The owning world can defer neighbor culling until all affected chunks are refreshed.
4094
+ */
4008
4095
  refreshBiomes(columns?: readonly {
4009
4096
  x: number;
4010
4097
  z: number;
4011
- }[]): Promise<void>;
4098
+ }[], deferCulling?: boolean): Promise<void>;
4012
4099
  private refreshBiomeBlocks;
4013
4100
  /**
4014
4101
  * Places a block at integer world block coordinates. Pass `undefined` to remove it.
@@ -4019,7 +4106,7 @@ declare class Chunk<SectionMeshing extends boolean = false> {
4019
4106
  /**
4020
4107
  * Places a block at integer chunk-local coordinates from 0 to 15.
4021
4108
  */
4022
- setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3, onBlocksChanged?: ((positions: Vector3[]) => Promise<void>) | undefined): Promise<Maybe<BlockInfo<SectionMeshing>>>;
4109
+ setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3, onBlocksChanged?: ((positions: Vector3[], deferCulling?: boolean) => Promise<void>) | undefined): Promise<Maybe<BlockInfo<SectionMeshing>>>;
4023
4110
  /** Places cells in input order and returns changed world positions without refreshing neighbors. */
4024
4111
  placeBlocks(blocks: readonly {
4025
4112
  index: number;
@@ -4184,6 +4271,14 @@ declare class MineRenderWorld<SectionMeshing extends boolean = false> {
4184
4271
  * Coordinates match AnvilChunk.x/z, not block positions. Missing columns are ignored.
4185
4272
  */
4186
4273
  unloadChunkColumn(x: number, z: number): Promise<void>;
4274
+ /**
4275
+ * Removes chunk columns together and refreshes surviving neighbors once.
4276
+ * Coordinates are absolute chunk columns. Duplicate and missing columns are ignored.
4277
+ */
4278
+ unloadChunkColumns(positions: readonly {
4279
+ x: number;
4280
+ z: number;
4281
+ }[]): Promise<void>;
4187
4282
  private clearChunkColumn;
4188
4283
  private markSectionChanged;
4189
4284
  /** Removes all chunks and releases their blocks, section meshes, and owned entities. */
@@ -4261,7 +4356,7 @@ declare class WorldStreamer {
4261
4356
  private running?;
4262
4357
  private disposal?;
4263
4358
  private disposed;
4264
- constructor(world: Pick<MineRenderWorld<boolean>, "placeChunk" | "unloadChunkColumn">, source: WorldChunkSource, options?: WorldStreamerOptions);
4359
+ constructor(world: Pick<MineRenderWorld<boolean>, "placeChunk" | "unloadChunkColumns">, source: WorldChunkSource, options?: WorldStreamerOptions);
4265
4360
  /** Returns absolute coordinates of successfully placed columns, including retained columns. */
4266
4361
  get loadedChunks(): readonly {
4267
4362
  x: number;
@@ -4295,7 +4390,7 @@ declare class WorldStreamer {
4295
4390
  dispose(): Promise<void>;
4296
4391
  private drain;
4297
4392
  private needsLoad;
4298
- private unload;
4393
+ private unloadMany;
4299
4394
  private validateChunk;
4300
4395
  private within;
4301
4396
  private key;
@@ -4344,4 +4439,4 @@ declare class BrowserCache extends PersistentCache<LocalForage> {
4344
4439
  */
4345
4440
  declare function probeImageSize(data: Uint8Array): ImageSizeInfo;
4346
4441
 
4347
- export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, type AnvilEntityChunk, type AnvilExternalChunkReader, type AnvilParseOptions, AnvilParser, type AnvilRegion, type AnvilRegionReader, AnvilWorldSource, type AnvilWorldSourceOptions, ArchiveAssetSource, type ArchiveAssetSourceOptions, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, type BannerPattern, type BannerPatternDraw, BannerPatterns, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type Biome, type BiomeColorKind, Biomes, type BitmapFont, type BitmapGlyph, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, Colormaps, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsMode, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, DYE_COLORS, type DebugOptions, type DecoratedPotSide, DecoratedPots, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, type DyeColor, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidQuads, type FluidRules, type FluidSample, type FluidSampler, type FlyAction, FlyControls, type FlyControlsEventMap, Fonts, type FrameCallback, type FromTo, GUI_CONTAINER_LAYOUTS, Geometries, type GuiBookButtonState, type GuiBookOptions, type GuiBossBarColor, type GuiBossBarOptions, type GuiContainerType, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiSpriteScaling, type GuiText, type GuiTextLayer, type GuiTextLayout, type GuiTextOptions, type GuiTextRun, type GuiTextStyle, type GuiTextureLayer, type GuiTooltipOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, ItemDefaults, ItemGlint, type ItemModel, type ItemModelContext, type ItemModelTextures, type ItemTintColor, type ItemTintSource, ItemTints, type ListAsset, LitematicaParser, type LitematicaRegion, type LitematicaStructure, type LoadedSceneDocument, type LoadedSceneObject, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderData, type MineRenderDataManifest, type MineRenderDatasets, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, type PackFormat, PackFormats, PackMetadata, PersistentCache, PlayerHeadTextures, type PositionedGuiGlyph, type QuadArray, type RawImageKey, type RenameKind, Renames, type RenderOptions, Renderer, type RendererControls, type RendererFrame, type RendererOptions, type RendererSurface, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResolvedMineRenderData, type ResponseParser, SCENE_DOCUMENT_MAX_BYTES, SKIN_PARTS, type SavedLightSample, type SceneBlockDefinition, type SceneDocument, SceneDocumentLoader, type SceneEntityDefinition, SceneExporter, type SceneGLTFExportOptions, type SceneGuiDefinition, type SceneGuiLayer, SceneInspector, type SceneItemContext, type SceneModelDefinition, SceneObject, type SceneObjectDefinition, type SceneObjectDefinitionBase, type SceneObjectOptions, type SceneSkinDefinition, type SceneSkinPosePart, SceneStats, SceneStatsDisplay, SchematicParser, type SchematicParserOptions, type SectionAtlasSize, type SectionFluidInput, type SectionFluidKind, type SectionFluids, type SectionGeometryInput, type SectionGeometryPage, type SectionLightData, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type SectionTemplateData, SectionWorker, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, SpongeSchematicParser, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, type VideoExportOptions, VideoExporter, type WorldBlockIntersection, type WorldChunkSource, type WorldEntityIntersection, WorldStreamer, type WorldStreamerOptions, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, buildFluidQuads, buildSectionGeometry, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, copySectionLight, createCanvas, createFluidGeometry, createGuiTextGeometry, createGuiTextureGeometry, createImage, decodeSceneDocument, encodeSceneDocument, entityAnimationTime, estimateBytesUsed, fluidKindOf, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isFlyControls, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isResourceLocation, isSceneObject, isTransformable, isTripleArray, isVector3, layoutGuiText, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, parseSceneDocument, prefix, probeImageSize, registerBrowserEnv, resolveBlockFluidState, resolveLegacyBlock, resolveLegacyBlockState, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, sampleSectionLight, sectionGeometryTransferables, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas, yieldToEventLoop };
4442
+ export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, type AnvilEntityChunk, type AnvilExternalChunkReader, type AnvilParseOptions, AnvilParser, type AnvilRegion, type AnvilRegionReader, AnvilWorldSource, type AnvilWorldSourceOptions, ArchiveAssetSource, type ArchiveAssetSourceOptions, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, type BannerPattern, type BannerPatternDraw, BannerPatterns, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type BinaryAsset, type Biome, type BiomeColorKind, Biomes, type BitmapFont, type BitmapGlyph, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, Colormaps, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsMode, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, DYE_COLORS, type DebugOptions, type DecoratedPotSide, DecoratedPots, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, type DyeColor, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidQuads, type FluidRules, type FluidSample, type FluidSampler, type FlyAction, FlyControls, type FlyControlsEventMap, Fonts, type FrameCallback, type FromTo, GUI_CONTAINER_LAYOUTS, Geometries, type GuiBookButtonState, type GuiBookOptions, type GuiBossBarColor, type GuiBossBarOptions, type GuiContainerType, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiSpriteScaling, type GuiText, type GuiTextLayer, type GuiTextLayout, type GuiTextOptions, type GuiTextRun, type GuiTextStyle, type GuiTextureLayer, type GuiTooltipOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, ItemDefaults, ItemGlint, type ItemModel, type ItemModelContext, type ItemModelTextures, type ItemTintColor, type ItemTintSource, ItemTints, type ListAsset, LitematicaParser, type LitematicaRegion, type LitematicaStructure, type LoadedSceneDocument, type LoadedSceneObject, type LogHandler, type LogLevel, type LogThreshold, type Logger, Logging, type LoggingOptions, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderData, type MineRenderDataManifest, type MineRenderDatasets, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, type PackFormat, PackFormats, PackMetadata, PersistentCache, PlayerHeadTextures, type PositionedGuiGlyph, type QuadArray, type RawImageKey, type RenameKind, Renames, type RenderOptions, Renderer, type RendererControls, type RendererFrame, type RendererOptions, type RendererSurface, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResolvedMineRenderData, type ResponseParser, SCENE_DOCUMENT_MAX_BYTES, SKIN_PARTS, type SavedLightSample, type SceneBlockDefinition, type SceneDocument, SceneDocumentLoader, type SceneEntityDefinition, SceneExporter, type SceneGLTFExportOptions, type SceneGuiDefinition, type SceneGuiLayer, SceneInspector, type SceneItemContext, type SceneModelDefinition, SceneObject, type SceneObjectDefinition, type SceneObjectDefinitionBase, type SceneObjectOptions, type SceneSkinDefinition, type SceneSkinPosePart, SceneStats, SceneStatsDisplay, SchematicParser, type SchematicParserOptions, type SectionAtlasSize, type SectionFluidInput, type SectionFluidKind, type SectionFluids, type SectionGeometryInput, type SectionGeometryPage, type SectionLightData, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type SectionTemplateData, SectionWorker, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, SpongeSchematicParser, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, type VideoExportOptions, VideoExporter, type WorldBlockIntersection, type WorldChunkSource, type WorldEntityIntersection, WorldStreamer, type WorldStreamerOptions, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, buildFluidQuads, buildSectionGeometry, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, copySectionLight, createCanvas, createFluidGeometry, createGuiTextGeometry, createGuiTextureGeometry, createImage, decodeSceneDocument, encodeSceneDocument, entityAnimationTime, estimateBytesUsed, fluidKindOf, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isFlyControls, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isResourceLocation, isSceneObject, isTransformable, isTripleArray, isVector3, layoutGuiText, logger, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, parseSceneDocument, prefix, probeImageSize, registerBrowserEnv, resolveBlockFluidState, resolveLegacyBlock, resolveLegacyBlockState, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, sampleSectionLight, sectionGeometryTransferables, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas, validateAnimationWeights, yieldToEventLoop };
@@ -3,9 +3,9 @@ import { Raycaster, Vector2 } from "three";
3
3
  import { isSceneObject } from "../renderer/SceneObject.mjs";
4
4
  import { toDegrees, toRadians } from "../util/util.mjs";
5
5
  import { isTransformable } from "../Transformable.mjs";
6
- import { prefix } from "../util/log.mjs";
6
+ import { logger } from "../util/log.mjs";
7
7
  import { isMesh } from "../util/three.mjs";
8
- var p = prefix("SceneInspector");
8
+ var log = logger("SceneInspector");
9
9
  var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
10
10
  var SceneInspector = class {
11
11
  constructor(renderer) {
@@ -99,7 +99,7 @@ var SceneInspector = class {
99
99
  }
100
100
  selectObject(targetObject, targetIntersection, instance = this.getIntersectionInstance(targetIntersection)) {
101
101
  this.selectedObject = targetObject;
102
- console.log(p, "selected", targetObject);
102
+ log.debug("selected", targetObject);
103
103
  this.redraw(targetObject, targetIntersection, instance);
104
104
  }
105
105
  redraw(targetObject, targetIntersection, instance) {