minerender 2.1.0-beta.6 → 2.1.0-beta.8

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 (128) hide show
  1. package/README.md +10 -1
  2. package/dist/browser/esm/Materials.mjs +3 -1
  3. package/dist/browser/esm/Materials.mjs.map +1 -1
  4. package/dist/browser/esm/Ticker.mjs +3 -1
  5. package/dist/browser/esm/Ticker.mjs.map +1 -1
  6. package/dist/browser/esm/UVMapper.mjs +9 -9
  7. package/dist/browser/esm/UVMapper.mjs.map +1 -1
  8. package/dist/browser/esm/armor/Armor.mjs +84 -0
  9. package/dist/browser/esm/armor/Armor.mjs.map +1 -0
  10. package/dist/browser/esm/armor/index.mjs +3 -0
  11. package/dist/browser/esm/armor/index.mjs.map +1 -0
  12. package/dist/browser/esm/assets/AssetDefaults.mjs +8 -0
  13. package/dist/browser/esm/assets/AssetDefaults.mjs.map +1 -0
  14. package/dist/browser/esm/assets/AssetKey.mjs +1 -1
  15. package/dist/browser/esm/assets/AssetKey.mjs.map +1 -1
  16. package/dist/browser/esm/assets/AssetLoader.mjs +5 -5
  17. package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
  18. package/dist/browser/esm/assets/Assets.mjs +1 -5
  19. package/dist/browser/esm/assets/Assets.mjs.map +1 -1
  20. package/dist/browser/esm/assets/BlockEntities.mjs +5 -1
  21. package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
  22. package/dist/browser/esm/assets/BlockStates.mjs +1 -1
  23. package/dist/browser/esm/assets/BlockStates.mjs.map +1 -1
  24. package/dist/browser/esm/assets/Entities.mjs +40 -12
  25. package/dist/browser/esm/assets/Entities.mjs.map +1 -1
  26. package/dist/browser/esm/assets/MineRenderData.mjs +8 -17
  27. package/dist/browser/esm/assets/MineRenderData.mjs.map +1 -1
  28. package/dist/browser/esm/assets/ModelTextures.mjs +13 -7
  29. package/dist/browser/esm/assets/ModelTextures.mjs.map +1 -1
  30. package/dist/browser/esm/assets/Models.mjs +1 -1
  31. package/dist/browser/esm/assets/Models.mjs.map +1 -1
  32. package/dist/browser/esm/assets/_fonts/Unihex.mjs +5 -3
  33. package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -1
  34. package/dist/browser/esm/assets/_versions/DatasetVersions.mjs +22 -0
  35. package/dist/browser/esm/assets/_versions/DatasetVersions.mjs.map +1 -0
  36. package/dist/browser/esm/assets/index.mjs +1 -0
  37. package/dist/browser/esm/assets/index.mjs.map +1 -1
  38. package/dist/browser/esm/assets/source/HostedAssetSource.mjs +7 -8
  39. package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
  40. package/dist/browser/esm/cache/Caching.mjs +8 -0
  41. package/dist/browser/esm/cache/Caching.mjs.map +1 -1
  42. package/dist/browser/esm/entity/scene/EntityObject.mjs +31 -5
  43. package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
  44. package/dist/browser/esm/env/browser/BrowserCache.mjs +3 -3
  45. package/dist/browser/esm/env/browser/BrowserCache.mjs.map +1 -1
  46. package/dist/browser/esm/env/browser/BrowserEnv.mjs +11 -4
  47. package/dist/browser/esm/env/browser/BrowserEnv.mjs.map +1 -1
  48. package/dist/browser/esm/image/ImageLoader.mjs +3 -3
  49. package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
  50. package/dist/browser/esm/index.browser.d.mts +191 -22
  51. package/dist/browser/esm/index.browser.mjs.map +1 -1
  52. package/dist/browser/esm/index.mjs +1 -0
  53. package/dist/browser/esm/index.mjs.map +1 -1
  54. package/dist/browser/esm/inspector/SceneInspector.mjs +3 -3
  55. package/dist/browser/esm/inspector/SceneInspector.mjs.map +1 -1
  56. package/dist/browser/esm/instance/InstanceManager.mjs +4 -4
  57. package/dist/browser/esm/instance/InstanceManager.mjs.map +1 -1
  58. package/dist/browser/esm/model/ItemGlint.mjs +7 -6
  59. package/dist/browser/esm/model/ItemGlint.mjs.map +1 -1
  60. package/dist/browser/esm/model/block/scene/BlockObject.mjs +19 -6
  61. package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
  62. package/dist/browser/esm/model/multiblock/StructureParser.mjs +7 -4
  63. package/dist/browser/esm/model/multiblock/StructureParser.mjs.map +1 -1
  64. package/dist/browser/esm/model/scene/ModelObject.mjs +4 -4
  65. package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
  66. package/dist/browser/esm/nbt/NBTHelper.mjs +5 -2
  67. package/dist/browser/esm/nbt/NBTHelper.mjs.map +1 -1
  68. package/dist/browser/esm/renderer/Renderer.mjs +4 -2
  69. package/dist/browser/esm/renderer/Renderer.mjs.map +1 -1
  70. package/dist/browser/esm/renderer/SceneObject.mjs +0 -6
  71. package/dist/browser/esm/renderer/SceneObject.mjs.map +1 -1
  72. package/dist/browser/esm/request/Requests.mjs +3 -3
  73. package/dist/browser/esm/request/Requests.mjs.map +1 -1
  74. package/dist/browser/esm/scene/SceneDocument.mjs +35 -5
  75. package/dist/browser/esm/scene/SceneDocument.mjs.map +1 -1
  76. package/dist/browser/esm/scene/SceneDocumentLoader.mjs +14 -3
  77. package/dist/browser/esm/scene/SceneDocumentLoader.mjs.map +1 -1
  78. package/dist/browser/esm/skin/SkinGeometries.mjs +4 -1
  79. package/dist/browser/esm/skin/SkinGeometries.mjs.map +1 -1
  80. package/dist/browser/esm/skin/SkinPart.mjs +2 -0
  81. package/dist/browser/esm/skin/SkinPart.mjs.map +1 -1
  82. package/dist/browser/esm/skin/SkinTextureCoordinates.mjs +11 -1
  83. package/dist/browser/esm/skin/SkinTextureCoordinates.mjs.map +1 -1
  84. package/dist/browser/esm/skin/SkinTextures.mjs +1 -1
  85. package/dist/browser/esm/skin/SkinTextures.mjs.map +1 -1
  86. package/dist/browser/esm/skin/Skins.mjs +6 -4
  87. package/dist/browser/esm/skin/Skins.mjs.map +1 -1
  88. package/dist/browser/esm/skin/scene/SkinObject.mjs +119 -7
  89. package/dist/browser/esm/skin/scene/SkinObject.mjs.map +1 -1
  90. package/dist/browser/esm/texture/PalettedTextures.mjs +46 -0
  91. package/dist/browser/esm/texture/PalettedTextures.mjs.map +1 -0
  92. package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
  93. package/dist/browser/esm/texture/TextureLoader.mjs.map +1 -1
  94. package/dist/browser/esm/texture/index.mjs +1 -0
  95. package/dist/browser/esm/texture/index.mjs.map +1 -1
  96. package/dist/browser/esm/util/log.mjs +75 -0
  97. package/dist/browser/esm/util/log.mjs.map +1 -1
  98. package/dist/browser/esm/util/performance.mjs.map +1 -1
  99. package/dist/browser/esm/util/util.mjs +0 -2
  100. package/dist/browser/esm/util/util.mjs.map +1 -1
  101. package/dist/browser/esm/world/Chunk.mjs +70 -38
  102. package/dist/browser/esm/world/Chunk.mjs.map +1 -1
  103. package/dist/browser/esm/world/MineRenderWorld.mjs +187 -60
  104. package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
  105. package/dist/browser/esm/world/SectionMesh.mjs +65 -9
  106. package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
  107. package/dist/browser/esm/world/SectionModels.mjs +21 -15
  108. package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
  109. package/dist/browser/esm/world/SectionWorker.mjs +8 -2
  110. package/dist/browser/esm/world/SectionWorker.mjs.map +1 -1
  111. package/dist/browser/esm/world/WorldStreamer.mjs +129 -34
  112. package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
  113. package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
  114. package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
  115. package/dist/browser/esm/world/_entities/WorldEntities.mjs +3 -1
  116. package/dist/browser/esm/world/_entities/WorldEntities.mjs.map +1 -1
  117. package/dist/browser/index.d.ts +191 -22
  118. package/dist/browser/index.js +4461 -3648
  119. package/dist/browser/index.js.map +1 -1
  120. package/dist/bundle.js +13482 -12651
  121. package/dist/bundle.js.map +1 -1
  122. package/dist/node/index.d.mts +179 -21
  123. package/dist/node/index.d.ts +179 -21
  124. package/dist/node/index.js +4495 -3666
  125. package/dist/node/index.js.map +1 -1
  126. package/dist/node/index.mjs +4412 -3586
  127. package/dist/node/index.mjs.map +1 -1
  128. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/inspector/SceneInspector.ts"],"sourcesContent":["import { Renderer } from \"../renderer/Renderer\";\nimport { Intersection, Mesh, Object3D, Raycaster, Vector2 } from \"three\";\nimport { isSceneObject, SceneObject } from \"../renderer/SceneObject\";\nimport { Maybe, toDegrees, toRadians } from \"../util/util\";\nimport { isTransformable, Transformable } from \"../Transformable\";\nimport { prefix } from \"../util/log\";\nimport { isMesh } from \"../util/three\";\nimport { TextureAtlas } from \"../texture\";\nimport { InstanceReference } from \"../instance/InstanceReference\";\n\nconst p = prefix(\"SceneInspector\");\n\nconst help = \"<span>Ctrl/Cmd+Click to Select<br/></span><br/>\";\n\n/**\n * Browser controls for inspecting and editing scene objects with Ctrl/Cmd-click selection.\n * Construct it with a renderer, attach its panels with {@link appendTo}, and call {@link dispose} when finished.\n */\nexport class SceneInspector {\n\n readonly objectInfoContainer: HTMLDivElement;\n readonly objectControlsContainer: HTMLDivElement;\n\n protected readonly raycaster: Raycaster;\n private readonly mouse: Vector2 = new Vector2();\n\n private selectedObject?: Object3D;\n private pointer?: PointerEvent;\n private readonly listeners = new AbortController();\n\n constructor(readonly renderer: Renderer) {\n this.objectInfoContainer = document.createElement(\"div\");\n this.objectControlsContainer = document.createElement(\"div\");\n\n this.raycaster = new Raycaster();\n\n this.init();\n }\n\n protected init() {\n this.objectInfoContainer.classList.add(\"minerender-inspector\", \"minerender-object-info\");\n this.objectControlsContainer.classList.add(\"minerender-inspector\", \"minerender-object-controls\");\n\n this.objectInfoContainer.innerHTML = help;\n\n const canvas = this.renderer.renderer.domElement;\n const options = { signal: this.listeners.signal };\n canvas.addEventListener(\"pointerdown\", event => {\n this.pointer = event.button === 0 && (event.ctrlKey || event.metaKey) ? event : undefined;\n }, options);\n canvas.addEventListener(\"pointermove\", event => {\n if (this.pointer?.pointerId === event.pointerId\n && Math.hypot(event.clientX - this.pointer.clientX, event.clientY - this.pointer.clientY) > 5) {\n this.pointer = undefined;\n }\n }, options);\n canvas.addEventListener(\"pointerup\", event => {\n const start = this.pointer;\n this.pointer = undefined;\n if (start?.pointerId === event.pointerId\n && Math.hypot(event.clientX - start.clientX, event.clientY - start.clientY) <= 5) {\n this.onClick(event);\n }\n }, options);\n canvas.addEventListener(\"pointercancel\", () => { this.pointer = undefined; }, options);\n canvas.addEventListener(\"pointerleave\", () => { this.pointer = undefined; }, options);\n canvas.addEventListener(\"contextmenu\", event => {\n // macOS Ctrl+click opens a context menu instead of firing click.\n if (this.pointer?.ctrlKey) event.preventDefault();\n }, options);\n }\n\n public dispose(): void {\n this.listeners.abort();\n this.pointer = undefined;\n this.selectedObject = undefined;\n this.objectInfoContainer.remove();\n this.objectControlsContainer.remove();\n }\n\n findMeshChildren(from: Object3D, out: Mesh[] = []) {\n if (!from.visible) return out;\n for (let c of from.children) {\n if (c.visible && isMesh(c)) {\n out.push(c);\n }\n this.findMeshChildren(c, out);\n }\n return out;\n }\n\n onClick(event: MouseEvent) {\n const canvas = this.renderer.renderer.domElement;\n if (event.target !== canvas || event.button !== 0 || !(event.ctrlKey || event.metaKey)) return;\n const rect = canvas.getBoundingClientRect();\n const x = event.clientX - rect.left, y = event.clientY - rect.top;\n if (rect.width <= 0 || rect.height <= 0 || x < 0 || y < 0 || x >= rect.width || y >= rect.height) return;\n this.mouse.set(x / rect.width * 2 - 1, 1 - y / rect.height * 2);\n this.renderer.camera.updateWorldMatrix(true, false);\n this.renderer.scene.updateMatrixWorld(true);\n this.raycaster.setFromCamera(this.mouse, this.renderer.camera);\n this.handleRaycasterObjects(this.raycaster.intersectObjects(this.findMeshChildren(this.renderer.scene), false));\n }\n\n appendTo(el: HTMLElement) {\n el.append(this.objectInfoContainer);\n el.append(this.objectControlsContainer);\n }\n\n protected handleRaycasterObjects(intersections: Intersection[]) {\n const hit = intersections[0];\n if (!hit) return;\n const instance = this.getIntersectionInstance(hit);\n this.selectObject(instance?.instanceable ?? hit.object, hit, instance);\n }\n\n private getIntersectionInstance(hit?: Intersection): Maybe<InstanceReference<SceneObject>> {\n if (hit?.instanceId === undefined) return undefined;\n for (let parent = hit.object.parent; parent; parent = parent.parent) {\n if (isSceneObject(parent)) {\n const instance = parent.getInstanceReference(hit.object, hit.instanceId);\n if (instance) return instance;\n }\n }\n return undefined;\n }\n\n public selectObject(targetObject: Object3D, targetIntersection?: Intersection,\n instance = this.getIntersectionInstance(targetIntersection)) {\n this.selectedObject = targetObject;\n console.log(p, \"selected\", targetObject);\n this.redraw(targetObject, targetIntersection, instance);\n }\n\n protected redraw(targetObject: Object3D, targetIntersection?: Intersection, instance?: InstanceReference<SceneObject>) {\n this.objectInfoContainer.innerHTML = help;\n if (targetIntersection) {\n this.addInfoLine(\"Distance\", \"D\", targetIntersection.distance);\n this.addInfoLine(\"Instance #\", \"I\", targetIntersection.instanceId);\n }\n this.addInfoLine(\"Type\", \"T\", targetObject.constructor.name + \"/\" + targetObject.type);\n this.addInfoLine(\"Name\", \"N\", targetObject.name);\n if (targetObject.parent) {\n this.addInfoLine(\"Parent\", \"P\", targetObject.parent.constructor.name);\n if (isSceneObject(targetObject.parent)) {\n //...\n }\n }\n\n const atlas = 'atlas' in targetObject ? targetObject['atlas'] as Maybe<TextureAtlas> : undefined;\n if (atlas?.image.canvas) {\n // const img = document.createElement(\"img\");\n const img = atlas.image.canvas as HTMLCanvasElement;\n // img.src = atlas.image.dataUrl;\n img.style.width = \"100px\";\n img.style.height = \"100px\";\n img.style.float = \"right\";\n img.style.imageRendering = \"pixelated\";\n this.objectInfoContainer.prepend(img);\n }\n\n this.objectControlsContainer.innerHTML = '';\n this.addControls(targetObject, targetIntersection, instance);\n }\n\n protected addControls(object: Object3D, intersection?: Intersection, instance?: InstanceReference<SceneObject>) {\n const container = document.createElement(\"div\");\n\n container.append(this.separator(\"Select Parent/Child\"));\n\n if (object.parent) {\n container.append(this.buttonControl(\"Select Parent \" + object.parent.constructor.name + \" \" + object.parent.name, \"P\", () => {\n this.selectObject(object.parent!, intersection, instance);\n }));\n }\n if (object.children.length > 0) {\n let i = 1;\n for (let child of object.children) {\n container.append(this.buttonControl(\"Select Child \" + child.constructor.name + \" \" + child.name, \"C\" + (i++), () => {\n this.selectObject(child, intersection, instance);\n }));\n }\n }\n container.append(this.separator());\n\n const selectedInstance = instance && (object === instance.instanceable || object === intersection?.object) ? instance : undefined;\n if (!selectedInstance) {\n container.append(this.toggleControl(\"Visibility\", \"V\", object.visible, v => object.visible = v));\n }\n\n container.append(this.separator(\"Mesh\"))\n this.addObjectControls(object, intersection, container, selectedInstance);\n container.append(this.separator());\n\n\n this.objectControlsContainer.append(container);\n }\n\n\n protected addInfoLine(name: string, id: string, value: any): HTMLElement {\n const el = document.createElement(\"span\");\n el.innerText = `${ id }: ${ value }`;\n el.setAttribute(\"title\", name);\n\n this.objectInfoContainer.append(el);\n this.objectInfoContainer.append(document.createElement(\"br\"));\n\n return el;\n }\n\n\n protected addObjectControls(target: Object3D, intersection: Maybe<Intersection>, container: HTMLElement, instance?: InstanceReference<SceneObject>) {\n\n const posRange = 16 * 16;\n const rotRange = 360;\n const scaleRange = 4;\n\n const transform = instance ?? (isTransformable(target) ? target : undefined);\n if (transform) {\n const parent: Transformable = transform;\n\n container.append(this.separator(\"Position\"))\n\n let pos = parent.getPosition();\n container.append(this.rangeControl(\"X Position\", \"X\", pos.x - posRange, pos.x + posRange, pos.x, 1, v => {\n pos = parent.getPosition();\n pos.x = v;\n parent.setPosition(pos)\n }));\n container.append(this.rangeControl(\"Y Position\", \"Y\", pos.y - posRange, pos.y + posRange, pos.y, 1, v => {\n pos = parent.getPosition();\n pos.y = v;\n parent.setPosition(pos)\n }));\n container.append(this.rangeControl(\"Z Position\", \"Z\", pos.z - posRange, pos.z + posRange, pos.z, 1, v => {\n pos = parent.getPosition();\n pos.z = v;\n parent.setPosition(pos)\n }));\n\n container.append(this.separator(\"Rotation\"))\n\n let rot = parent.getRotation();\n container.append(this.rangeControl(\"X Rotation\", \"X\", 0, rotRange, Math.round(toDegrees(rot.x)), 1, v => {\n rot = parent.getRotation();\n rot.x = toRadians(v);\n parent.setRotation(rot);\n }));\n container.append(this.rangeControl(\"Y Rotation\", \"Y\", 0, rotRange, Math.round(toDegrees(rot.y)), 1, v => {\n rot = parent.getRotation();\n rot.y = toRadians(v);\n parent.setRotation(rot);\n }));\n container.append(this.rangeControl(\"Z Rotation\", \"Z\", 0, rotRange, Math.round(toDegrees(rot.z)), 1, v => {\n rot = parent.getRotation();\n rot.z = toRadians(v);\n parent.setRotation(rot);\n }));\n\n container.append(this.separator(\"Scale\"))\n\n let scl = parent.getScale();\n container.append(this.rangeControl(\"X Scale\", \"X\", 0, scaleRange, scl.x, 0.1, v => {\n scl = parent.getScale();\n scl.x = v;\n parent.setScale(scl);\n }));\n container.append(this.rangeControl(\"Y Scale\", \"Y\", 0, scaleRange, scl.y, 0.1, v => {\n scl = parent.getScale();\n scl.y = v;\n parent.setScale(scl);\n }));\n container.append(this.rangeControl(\"Z Scale\", \"Z\", 0, scaleRange, scl.z, 0.1, v => {\n scl = parent.getScale();\n scl.z = v;\n parent.setScale(scl);\n }));\n } else {\n container.append(this.separator(\"Position\"))\n\n container.append(this.rangeControl(\"X Position\", \"X\", -posRange, posRange, target.position.x, 1, v => target!.position.setX(v)));\n container.append(this.rangeControl(\"Y Position\", \"Y\", -posRange, posRange, target.position.y, 1, v => target!.position.setY(v)));\n container.append(this.rangeControl(\"Z Position\", \"Z\", -posRange, posRange, target.position.z, 1, v => target!.position.setZ(v)));\n\n container.append(this.separator(\"Rotation\"))\n\n container.append(this.rangeControl(\"X Rotation\", \"X\", 0, rotRange, toDegrees(target.rotation.x), 1, v => target!.rotation.x = toRadians(v)));\n container.append(this.rangeControl(\"Y Rotation\", \"Y\", 0, rotRange, toDegrees(target.rotation.y), 1, v => target!.rotation.y = toRadians(v)));\n container.append(this.rangeControl(\"Z Rotation\", \"Z\", 0, rotRange, toDegrees(target.rotation.z), 1, v => target!.rotation.z = toRadians(v)));\n\n container.append(this.separator(\"Scale\"))\n\n container.append(this.rangeControl(\"X Scale\", \"X\", 0, scaleRange, target.scale.x, 0.1, v => target!.scale.x = v));\n container.append(this.rangeControl(\"Y Scale\", \"Y\", 0, scaleRange, target.scale.y, 0.1, v => target!.scale.y = v));\n container.append(this.rangeControl(\"Z Scale\", \"Z\", 0, scaleRange, target.scale.z, 0.1, v => target!.scale.z = v));\n }\n }\n\n protected buttonControl(name: string, id: string, click: () => void): HTMLElement {\n const button = document.createElement(\"button\");\n button.innerText = id;\n button.setAttribute(\"title\", name);\n button.addEventListener(\"click\", click);\n return button;\n }\n\n protected selectControl(name: string, id: string, options: string[], change: (v: string) => void): HTMLElement {\n const label = document.createElement(\"label\");\n label.innerText = id;\n label.setAttribute(\"title\", name);\n\n const select = document.createElement(\"select\");\n options.forEach(o => {\n const opt = document.createElement(\"option\");\n opt.value = o;\n opt.innerText = o;\n select.append(opt);\n });\n select.addEventListener(\"change\", e => {\n change(options[select.selectedIndex]);\n });\n select.selectedIndex = 0;\n label.append(select);\n label.append(document.createElement(\"br\"));\n return label;\n }\n\n protected toggleControl(name: string, id: string, val: boolean, change: (v: boolean) => void): HTMLElement {\n const label = document.createElement(\"label\");\n label.innerText = id;\n label.setAttribute(\"title\", name);\n\n const toggle = document.createElement(\"input\");\n toggle.setAttribute(\"type\", \"checkbox\");\n toggle.checked = val; //TODO: instance\n toggle.addEventListener(\"change\", e => {\n change(toggle.checked);\n this.renderer.scene.dirty = true;\n });\n label.append(toggle);\n label.append(document.createElement(\"br\"));\n return label;\n }\n\n protected rangeControl(name: string, id: string, min: number, max: number, val: number, step: number, change: (v: number) => void): HTMLElement {\n const label = document.createElement(\"label\");\n const labelText = document.createElement(\"span\");\n label.append(labelText);\n label.setAttribute(\"title\", name);\n labelText.style.width = \"18%\";\n labelText.style.display = \"inline-block\";\n\n const range = document.createElement(\"input\");\n range.setAttribute(\"type\", \"range\");\n range.style.width = \"80%\";\n range.max = `${ max }`;\n range.min = `${ min }`;\n range.step = `${ step }`;\n range.value = `${ val }`;\n labelText.innerText = `${ id } (${ range.value })`;\n const onChange = () => {\n change(parseFloat(range.value));\n this.renderer.scene.dirty = true;\n labelText.innerText = `${ id } (${ range.value })`\n };\n // range.addEventListener(\"change\", onChange);\n range.addEventListener(\"input\", onChange);\n range.addEventListener(\"wheel\", e => {\n e.preventDefault();\n if (e.deltaY < 0) {\n range.value = `${ parseFloat(range.value) + step }`;\n onChange();\n } else if (e.deltaY > 0) {\n range.value = `${ parseFloat(range.value) - step }`;\n onChange();\n }\n })\n label.append(range);\n label.append(document.createElement(\"br\"));\n return label;\n }\n\n protected separator(name?: string): HTMLElement {\n const span = document.createElement(\"span\");\n if (name) {\n span.innerText = name;\n }\n span.prepend(document.createElement(\"br\"));\n span.append(document.createElement(\"br\"));\n return span;\n }\n\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/inspector/SceneInspector.ts"],"sourcesContent":["import { Renderer } from \"../renderer/Renderer\";\nimport { Intersection, Mesh, Object3D, Raycaster, Vector2 } from \"three\";\nimport { isSceneObject, SceneObject } from \"../renderer/SceneObject\";\nimport { Maybe, toDegrees, toRadians } from \"../util/util\";\nimport { isTransformable, Transformable } from \"../Transformable\";\nimport { logger } from \"../util/log\";\nimport { isMesh } from \"../util/three\";\nimport { TextureAtlas } from \"../texture\";\nimport { InstanceReference } from \"../instance/InstanceReference\";\n\nconst log = logger(\"SceneInspector\");\n\nconst help = \"<span>Ctrl/Cmd+Click to Select<br/></span><br/>\";\n\n/**\n * Browser controls for inspecting and editing scene objects with Ctrl/Cmd-click selection.\n * Construct it with a renderer, attach its panels with {@link appendTo}, and call {@link dispose} when finished.\n */\nexport class SceneInspector {\n\n readonly objectInfoContainer: HTMLDivElement;\n readonly objectControlsContainer: HTMLDivElement;\n\n protected readonly raycaster: Raycaster;\n private readonly mouse: Vector2 = new Vector2();\n\n private selectedObject?: Object3D;\n private pointer?: PointerEvent;\n private readonly listeners = new AbortController();\n\n constructor(readonly renderer: Renderer) {\n this.objectInfoContainer = document.createElement(\"div\");\n this.objectControlsContainer = document.createElement(\"div\");\n\n this.raycaster = new Raycaster();\n\n this.init();\n }\n\n protected init() {\n this.objectInfoContainer.classList.add(\"minerender-inspector\", \"minerender-object-info\");\n this.objectControlsContainer.classList.add(\"minerender-inspector\", \"minerender-object-controls\");\n\n this.objectInfoContainer.innerHTML = help;\n\n const canvas = this.renderer.renderer.domElement;\n const options = { signal: this.listeners.signal };\n canvas.addEventListener(\"pointerdown\", event => {\n this.pointer = event.button === 0 && (event.ctrlKey || event.metaKey) ? event : undefined;\n }, options);\n canvas.addEventListener(\"pointermove\", event => {\n if (this.pointer?.pointerId === event.pointerId\n && Math.hypot(event.clientX - this.pointer.clientX, event.clientY - this.pointer.clientY) > 5) {\n this.pointer = undefined;\n }\n }, options);\n canvas.addEventListener(\"pointerup\", event => {\n const start = this.pointer;\n this.pointer = undefined;\n if (start?.pointerId === event.pointerId\n && Math.hypot(event.clientX - start.clientX, event.clientY - start.clientY) <= 5) {\n this.onClick(event);\n }\n }, options);\n canvas.addEventListener(\"pointercancel\", () => { this.pointer = undefined; }, options);\n canvas.addEventListener(\"pointerleave\", () => { this.pointer = undefined; }, options);\n canvas.addEventListener(\"contextmenu\", event => {\n // macOS Ctrl+click opens a context menu instead of firing click.\n if (this.pointer?.ctrlKey) event.preventDefault();\n }, options);\n }\n\n public dispose(): void {\n this.listeners.abort();\n this.pointer = undefined;\n this.selectedObject = undefined;\n this.objectInfoContainer.remove();\n this.objectControlsContainer.remove();\n }\n\n findMeshChildren(from: Object3D, out: Mesh[] = []) {\n if (!from.visible) return out;\n for (let c of from.children) {\n if (c.visible && isMesh(c)) {\n out.push(c);\n }\n this.findMeshChildren(c, out);\n }\n return out;\n }\n\n onClick(event: MouseEvent) {\n const canvas = this.renderer.renderer.domElement;\n if (event.target !== canvas || event.button !== 0 || !(event.ctrlKey || event.metaKey)) return;\n const rect = canvas.getBoundingClientRect();\n const x = event.clientX - rect.left, y = event.clientY - rect.top;\n if (rect.width <= 0 || rect.height <= 0 || x < 0 || y < 0 || x >= rect.width || y >= rect.height) return;\n this.mouse.set(x / rect.width * 2 - 1, 1 - y / rect.height * 2);\n this.renderer.camera.updateWorldMatrix(true, false);\n this.renderer.scene.updateMatrixWorld(true);\n this.raycaster.setFromCamera(this.mouse, this.renderer.camera);\n this.handleRaycasterObjects(this.raycaster.intersectObjects(this.findMeshChildren(this.renderer.scene), false));\n }\n\n appendTo(el: HTMLElement) {\n el.append(this.objectInfoContainer);\n el.append(this.objectControlsContainer);\n }\n\n protected handleRaycasterObjects(intersections: Intersection[]) {\n const hit = intersections[0];\n if (!hit) return;\n const instance = this.getIntersectionInstance(hit);\n this.selectObject(instance?.instanceable ?? hit.object, hit, instance);\n }\n\n private getIntersectionInstance(hit?: Intersection): Maybe<InstanceReference<SceneObject>> {\n if (hit?.instanceId === undefined) return undefined;\n for (let parent = hit.object.parent; parent; parent = parent.parent) {\n if (isSceneObject(parent)) {\n const instance = parent.getInstanceReference(hit.object, hit.instanceId);\n if (instance) return instance;\n }\n }\n return undefined;\n }\n\n public selectObject(targetObject: Object3D, targetIntersection?: Intersection,\n instance = this.getIntersectionInstance(targetIntersection)) {\n this.selectedObject = targetObject;\n log.debug(\"selected\", targetObject);\n this.redraw(targetObject, targetIntersection, instance);\n }\n\n protected redraw(targetObject: Object3D, targetIntersection?: Intersection, instance?: InstanceReference<SceneObject>) {\n this.objectInfoContainer.innerHTML = help;\n if (targetIntersection) {\n this.addInfoLine(\"Distance\", \"D\", targetIntersection.distance);\n this.addInfoLine(\"Instance #\", \"I\", targetIntersection.instanceId);\n }\n this.addInfoLine(\"Type\", \"T\", targetObject.constructor.name + \"/\" + targetObject.type);\n this.addInfoLine(\"Name\", \"N\", targetObject.name);\n if (targetObject.parent) {\n this.addInfoLine(\"Parent\", \"P\", targetObject.parent.constructor.name);\n if (isSceneObject(targetObject.parent)) {\n //...\n }\n }\n\n const atlas = 'atlas' in targetObject ? targetObject['atlas'] as Maybe<TextureAtlas> : undefined;\n if (atlas?.image.canvas) {\n // const img = document.createElement(\"img\");\n const img = atlas.image.canvas as HTMLCanvasElement;\n // img.src = atlas.image.dataUrl;\n img.style.width = \"100px\";\n img.style.height = \"100px\";\n img.style.float = \"right\";\n img.style.imageRendering = \"pixelated\";\n this.objectInfoContainer.prepend(img);\n }\n\n this.objectControlsContainer.innerHTML = '';\n this.addControls(targetObject, targetIntersection, instance);\n }\n\n protected addControls(object: Object3D, intersection?: Intersection, instance?: InstanceReference<SceneObject>) {\n const container = document.createElement(\"div\");\n\n container.append(this.separator(\"Select Parent/Child\"));\n\n if (object.parent) {\n container.append(this.buttonControl(\"Select Parent \" + object.parent.constructor.name + \" \" + object.parent.name, \"P\", () => {\n this.selectObject(object.parent!, intersection, instance);\n }));\n }\n if (object.children.length > 0) {\n let i = 1;\n for (let child of object.children) {\n container.append(this.buttonControl(\"Select Child \" + child.constructor.name + \" \" + child.name, \"C\" + (i++), () => {\n this.selectObject(child, intersection, instance);\n }));\n }\n }\n container.append(this.separator());\n\n const selectedInstance = instance && (object === instance.instanceable || object === intersection?.object) ? instance : undefined;\n if (!selectedInstance) {\n container.append(this.toggleControl(\"Visibility\", \"V\", object.visible, v => object.visible = v));\n }\n\n container.append(this.separator(\"Mesh\"))\n this.addObjectControls(object, intersection, container, selectedInstance);\n container.append(this.separator());\n\n\n this.objectControlsContainer.append(container);\n }\n\n\n protected addInfoLine(name: string, id: string, value: any): HTMLElement {\n const el = document.createElement(\"span\");\n el.innerText = `${ id }: ${ value }`;\n el.setAttribute(\"title\", name);\n\n this.objectInfoContainer.append(el);\n this.objectInfoContainer.append(document.createElement(\"br\"));\n\n return el;\n }\n\n\n protected addObjectControls(target: Object3D, intersection: Maybe<Intersection>, container: HTMLElement, instance?: InstanceReference<SceneObject>) {\n\n const posRange = 16 * 16;\n const rotRange = 360;\n const scaleRange = 4;\n\n const transform = instance ?? (isTransformable(target) ? target : undefined);\n if (transform) {\n const parent: Transformable = transform;\n\n container.append(this.separator(\"Position\"))\n\n let pos = parent.getPosition();\n container.append(this.rangeControl(\"X Position\", \"X\", pos.x - posRange, pos.x + posRange, pos.x, 1, v => {\n pos = parent.getPosition();\n pos.x = v;\n parent.setPosition(pos)\n }));\n container.append(this.rangeControl(\"Y Position\", \"Y\", pos.y - posRange, pos.y + posRange, pos.y, 1, v => {\n pos = parent.getPosition();\n pos.y = v;\n parent.setPosition(pos)\n }));\n container.append(this.rangeControl(\"Z Position\", \"Z\", pos.z - posRange, pos.z + posRange, pos.z, 1, v => {\n pos = parent.getPosition();\n pos.z = v;\n parent.setPosition(pos)\n }));\n\n container.append(this.separator(\"Rotation\"))\n\n let rot = parent.getRotation();\n container.append(this.rangeControl(\"X Rotation\", \"X\", 0, rotRange, Math.round(toDegrees(rot.x)), 1, v => {\n rot = parent.getRotation();\n rot.x = toRadians(v);\n parent.setRotation(rot);\n }));\n container.append(this.rangeControl(\"Y Rotation\", \"Y\", 0, rotRange, Math.round(toDegrees(rot.y)), 1, v => {\n rot = parent.getRotation();\n rot.y = toRadians(v);\n parent.setRotation(rot);\n }));\n container.append(this.rangeControl(\"Z Rotation\", \"Z\", 0, rotRange, Math.round(toDegrees(rot.z)), 1, v => {\n rot = parent.getRotation();\n rot.z = toRadians(v);\n parent.setRotation(rot);\n }));\n\n container.append(this.separator(\"Scale\"))\n\n let scl = parent.getScale();\n container.append(this.rangeControl(\"X Scale\", \"X\", 0, scaleRange, scl.x, 0.1, v => {\n scl = parent.getScale();\n scl.x = v;\n parent.setScale(scl);\n }));\n container.append(this.rangeControl(\"Y Scale\", \"Y\", 0, scaleRange, scl.y, 0.1, v => {\n scl = parent.getScale();\n scl.y = v;\n parent.setScale(scl);\n }));\n container.append(this.rangeControl(\"Z Scale\", \"Z\", 0, scaleRange, scl.z, 0.1, v => {\n scl = parent.getScale();\n scl.z = v;\n parent.setScale(scl);\n }));\n } else {\n container.append(this.separator(\"Position\"))\n\n container.append(this.rangeControl(\"X Position\", \"X\", -posRange, posRange, target.position.x, 1, v => target!.position.setX(v)));\n container.append(this.rangeControl(\"Y Position\", \"Y\", -posRange, posRange, target.position.y, 1, v => target!.position.setY(v)));\n container.append(this.rangeControl(\"Z Position\", \"Z\", -posRange, posRange, target.position.z, 1, v => target!.position.setZ(v)));\n\n container.append(this.separator(\"Rotation\"))\n\n container.append(this.rangeControl(\"X Rotation\", \"X\", 0, rotRange, toDegrees(target.rotation.x), 1, v => target!.rotation.x = toRadians(v)));\n container.append(this.rangeControl(\"Y Rotation\", \"Y\", 0, rotRange, toDegrees(target.rotation.y), 1, v => target!.rotation.y = toRadians(v)));\n container.append(this.rangeControl(\"Z Rotation\", \"Z\", 0, rotRange, toDegrees(target.rotation.z), 1, v => target!.rotation.z = toRadians(v)));\n\n container.append(this.separator(\"Scale\"))\n\n container.append(this.rangeControl(\"X Scale\", \"X\", 0, scaleRange, target.scale.x, 0.1, v => target!.scale.x = v));\n container.append(this.rangeControl(\"Y Scale\", \"Y\", 0, scaleRange, target.scale.y, 0.1, v => target!.scale.y = v));\n container.append(this.rangeControl(\"Z Scale\", \"Z\", 0, scaleRange, target.scale.z, 0.1, v => target!.scale.z = v));\n }\n }\n\n protected buttonControl(name: string, id: string, click: () => void): HTMLElement {\n const button = document.createElement(\"button\");\n button.innerText = id;\n button.setAttribute(\"title\", name);\n button.addEventListener(\"click\", click);\n return button;\n }\n\n protected selectControl(name: string, id: string, options: string[], change: (v: string) => void): HTMLElement {\n const label = document.createElement(\"label\");\n label.innerText = id;\n label.setAttribute(\"title\", name);\n\n const select = document.createElement(\"select\");\n options.forEach(o => {\n const opt = document.createElement(\"option\");\n opt.value = o;\n opt.innerText = o;\n select.append(opt);\n });\n select.addEventListener(\"change\", e => {\n change(options[select.selectedIndex]);\n });\n select.selectedIndex = 0;\n label.append(select);\n label.append(document.createElement(\"br\"));\n return label;\n }\n\n protected toggleControl(name: string, id: string, val: boolean, change: (v: boolean) => void): HTMLElement {\n const label = document.createElement(\"label\");\n label.innerText = id;\n label.setAttribute(\"title\", name);\n\n const toggle = document.createElement(\"input\");\n toggle.setAttribute(\"type\", \"checkbox\");\n toggle.checked = val; //TODO: instance\n toggle.addEventListener(\"change\", e => {\n change(toggle.checked);\n this.renderer.scene.dirty = true;\n });\n label.append(toggle);\n label.append(document.createElement(\"br\"));\n return label;\n }\n\n protected rangeControl(name: string, id: string, min: number, max: number, val: number, step: number, change: (v: number) => void): HTMLElement {\n const label = document.createElement(\"label\");\n const labelText = document.createElement(\"span\");\n label.append(labelText);\n label.setAttribute(\"title\", name);\n labelText.style.width = \"18%\";\n labelText.style.display = \"inline-block\";\n\n const range = document.createElement(\"input\");\n range.setAttribute(\"type\", \"range\");\n range.style.width = \"80%\";\n range.max = `${ max }`;\n range.min = `${ min }`;\n range.step = `${ step }`;\n range.value = `${ val }`;\n labelText.innerText = `${ id } (${ range.value })`;\n const onChange = () => {\n change(parseFloat(range.value));\n this.renderer.scene.dirty = true;\n labelText.innerText = `${ id } (${ range.value })`\n };\n // range.addEventListener(\"change\", onChange);\n range.addEventListener(\"input\", onChange);\n range.addEventListener(\"wheel\", e => {\n e.preventDefault();\n if (e.deltaY < 0) {\n range.value = `${ parseFloat(range.value) + step }`;\n onChange();\n } else if (e.deltaY > 0) {\n range.value = `${ parseFloat(range.value) - step }`;\n onChange();\n }\n })\n label.append(range);\n label.append(document.createElement(\"br\"));\n return label;\n }\n\n protected separator(name?: string): HTMLElement {\n const span = document.createElement(\"span\");\n if (name) {\n span.innerText = name;\n }\n span.prepend(document.createElement(\"br\"));\n span.append(document.createElement(\"br\"));\n return span;\n }\n\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  // src/instance/InstanceManager.ts
2
- import { prefix } from "../util/log.mjs";
3
- var p = prefix("InstanceManager");
2
+ import { logger } from "../util/log.mjs";
3
+ var log = logger("InstanceManager");
4
4
  var InstanceManager = class {
5
5
  constructor() {
6
6
  this.isInstanceManager = true;
@@ -9,7 +9,7 @@ var InstanceManager = class {
9
9
  /** Allocates a new placement of a cached model, or returns `undefined` if the key is unknown. */
10
10
  async get(key) {
11
11
  if (key in this.instanceCache) {
12
- console.debug(p, "key in cache", key);
12
+ log.debug("key in cache", key);
13
13
  return (await this.instanceCache[key]).nextInstance();
14
14
  }
15
15
  return void 0;
@@ -19,7 +19,7 @@ var InstanceManager = class {
19
19
  if (key in this.instanceCache) {
20
20
  return await this.get(key);
21
21
  }
22
- console.debug(p, "key not in cache", key);
22
+ log.debug("key not in cache", key);
23
23
  const pending = Promise.resolve().then(supplier).then((obj) => obj.nextInstance());
24
24
  this.instanceCache[key] = pending;
25
25
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/instance/InstanceManager.ts"],"sourcesContent":["import { InstanceReference } from \"./InstanceReference\";\nimport { SceneObject } from \"../renderer/SceneObject\";\nimport { Maybe } from \"../util/util\";\nimport { prefix } from \"../util/log\";\n\nconst p = prefix(\"InstanceManager\");\n\n/** Shares initialized model objects by cache key and allocates references to their placements. */\nexport class InstanceManager {\n\n public readonly isInstanceManager: true = true;\n\n protected readonly instanceCache: { [key: string]: Promise<InstanceReference<SceneObject>>; } = {};\n\n constructor() {\n }\n\n /** Allocates a new placement of a cached model, or returns `undefined` if the key is unknown. */\n public async get<T extends SceneObject>(key: string): Promise<Maybe<InstanceReference<T>>> {\n if (key in this.instanceCache) {\n console.debug(p, \"key in cache\", key)\n // create next instance of existing object\n return (await this.instanceCache[key]).nextInstance() as InstanceReference<T>;\n }\n return undefined;\n }\n\n /** Allocates a placement, calling the supplier once when the shared model is first needed. */\n public async getOrCreate<T extends SceneObject>(key: string, supplier: () => T | Promise<T>): Promise<InstanceReference<T>> {\n if (key in this.instanceCache) {\n return await (this.get<T>(key)) as InstanceReference<T>;\n }\n console.debug(p, \"key not in cache\", key)\n const pending = Promise.resolve().then(supplier).then(obj => obj.nextInstance());\n this.instanceCache[key] = pending;\n try {\n return await pending as InstanceReference<T>;\n } catch (error) {\n if (this.instanceCache[key] === pending) {\n delete this.instanceCache[key];\n }\n throw error;\n }\n }\n\n /** Forgets cached models without disposing them or releasing their existing placements. */\n public reset() {\n for (let instanceCacheKey in this.instanceCache) {\n delete this.instanceCache[instanceCacheKey];\n }\n }\n\n\n}\n\nexport function isInstanceManager(obj: any): obj is InstanceManager {\n return (<InstanceManager>obj).isInstanceManager;\n}\n"],"mappings":";AAGA,SAAS,cAAc;AAEvB,IAAM,IAAI,OAAO,iBAAiB;AAG3B,IAAM,kBAAN,MAAsB;AAAA,EAMzB,cAAc;AAJd,SAAgB,oBAA0B;AAE1C,SAAmB,gBAA6E,CAAC;AAAA,EAGjG;AAAA;AAAA,EAGA,MAAa,IAA2B,KAAmD;AACvF,QAAI,OAAO,KAAK,eAAe;AAC3B,cAAQ,MAAM,GAAG,gBAAgB,GAAG;AAEpC,cAAQ,MAAM,KAAK,cAAc,GAAG,GAAG,aAAa;AAAA,IACxD;AACA,WAAO;AAAA,EACX;AAAA;AAAA,EAGA,MAAa,YAAmC,KAAa,UAA+D;AACxH,QAAI,OAAO,KAAK,eAAe;AAC3B,aAAO,MAAO,KAAK,IAAO,GAAG;AAAA,IACjC;AACA,YAAQ,MAAM,GAAG,oBAAoB,GAAG;AACxC,UAAM,UAAU,QAAQ,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAO,IAAI,aAAa,CAAC;AAC/E,SAAK,cAAc,GAAG,IAAI;AAC1B,QAAI;AACA,aAAO,MAAM;AAAA,IACjB,SAAS,OAAO;AACZ,UAAI,KAAK,cAAc,GAAG,MAAM,SAAS;AACrC,eAAO,KAAK,cAAc,GAAG;AAAA,MACjC;AACA,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA,EAGO,QAAQ;AACX,aAAS,oBAAoB,KAAK,eAAe;AAC7C,aAAO,KAAK,cAAc,gBAAgB;AAAA,IAC9C;AAAA,EACJ;AAGJ;AAEO,SAAS,kBAAkB,KAAkC;AAChE,SAAyB,IAAK;AAClC;","names":[]}
1
+ {"version":3,"sources":["../../../../src/instance/InstanceManager.ts"],"sourcesContent":["import { InstanceReference } from \"./InstanceReference\";\nimport { SceneObject } from \"../renderer/SceneObject\";\nimport { Maybe } from \"../util/util\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"InstanceManager\");\n\n/** Shares initialized model objects by cache key and allocates references to their placements. */\nexport class InstanceManager {\n\n public readonly isInstanceManager: true = true;\n\n protected readonly instanceCache: { [key: string]: Promise<InstanceReference<SceneObject>>; } = {};\n\n constructor() {\n }\n\n /** Allocates a new placement of a cached model, or returns `undefined` if the key is unknown. */\n public async get<T extends SceneObject>(key: string): Promise<Maybe<InstanceReference<T>>> {\n if (key in this.instanceCache) {\n log.debug(\"key in cache\", key)\n // create next instance of existing object\n return (await this.instanceCache[key]).nextInstance() as InstanceReference<T>;\n }\n return undefined;\n }\n\n /** Allocates a placement, calling the supplier once when the shared model is first needed. */\n public async getOrCreate<T extends SceneObject>(key: string, supplier: () => T | Promise<T>): Promise<InstanceReference<T>> {\n if (key in this.instanceCache) {\n return await (this.get<T>(key)) as InstanceReference<T>;\n }\n log.debug(\"key not in cache\", key)\n const pending = Promise.resolve().then(supplier).then(obj => obj.nextInstance());\n this.instanceCache[key] = pending;\n try {\n return await pending as InstanceReference<T>;\n } catch (error) {\n if (this.instanceCache[key] === pending) {\n delete this.instanceCache[key];\n }\n throw error;\n }\n }\n\n /** Forgets cached models without disposing them or releasing their existing placements. */\n public reset() {\n for (let instanceCacheKey in this.instanceCache) {\n delete this.instanceCache[instanceCacheKey];\n }\n }\n\n\n}\n\nexport function isInstanceManager(obj: any): obj is InstanceManager {\n return (<InstanceManager>obj).isInstanceManager;\n}\n"],"mappings":";AAGA,SAAS,cAAc;AAEvB,IAAM,MAAM,OAAO,iBAAiB;AAG7B,IAAM,kBAAN,MAAsB;AAAA,EAMzB,cAAc;AAJd,SAAgB,oBAA0B;AAE1C,SAAmB,gBAA6E,CAAC;AAAA,EAGjG;AAAA;AAAA,EAGA,MAAa,IAA2B,KAAmD;AACvF,QAAI,OAAO,KAAK,eAAe;AAC3B,UAAI,MAAM,gBAAgB,GAAG;AAE7B,cAAQ,MAAM,KAAK,cAAc,GAAG,GAAG,aAAa;AAAA,IACxD;AACA,WAAO;AAAA,EACX;AAAA;AAAA,EAGA,MAAa,YAAmC,KAAa,UAA+D;AACxH,QAAI,OAAO,KAAK,eAAe;AAC3B,aAAO,MAAO,KAAK,IAAO,GAAG;AAAA,IACjC;AACA,QAAI,MAAM,oBAAoB,GAAG;AACjC,UAAM,UAAU,QAAQ,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAO,IAAI,aAAa,CAAC;AAC/E,SAAK,cAAc,GAAG,IAAI;AAC1B,QAAI;AACA,aAAO,MAAM;AAAA,IACjB,SAAS,OAAO;AACZ,UAAI,KAAK,cAAc,GAAG,MAAM,SAAS;AACrC,eAAO,KAAK,cAAc,GAAG;AAAA,MACjC;AACA,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA,EAGO,QAAQ;AACX,aAAS,oBAAoB,KAAK,eAAe;AAC7C,aAAO,KAAK,cAAc,gBAAgB;AAAA,IAC9C;AAAA,EACJ;AAGJ;AAEO,SAAS,kBAAkB,KAAkC;AAChE,SAAyB,IAAK;AAClC;","names":[]}
@@ -31,16 +31,16 @@ var ItemGlint = class _ItemGlint {
31
31
  return Object.keys(enchantments).length > 0;
32
32
  }
33
33
  /** @internal */
34
- static async create(owner, baseMap, root, entityMeshes) {
35
- const key = new AssetKey("minecraft", "enchanted_glint_item", "textures", "misc", "assets", ".png", root);
34
+ static async create(owner, baseMap, root, entityMeshes, kind = "item") {
35
+ const key = new AssetKey("minecraft", `enchanted_glint_${kind}`, "textures", "misc", "assets", ".png", root);
36
36
  const assetKey = key.serialize(), textureKey = `item-glint:${assetKey}`;
37
37
  let texture = Caching.textureCache.getIfPresent(textureKey);
38
38
  if (!texture) {
39
39
  const pending = ModelTextures.get(key);
40
40
  const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKey);
41
41
  const [image, metadata] = await Promise.all([pending, ModelTextures.getMeta(key)]);
42
- if (!image) throw new Error(`Missing item glint texture ${key.toNamespacedString()}`);
43
- if (cachedAsset && Caching.textureAssetCache.getIfPresent(assetKey) !== cachedAsset) return this.create(owner, baseMap, root, entityMeshes);
42
+ if (!image) throw new Error(`Missing ${kind} glint texture ${key.toNamespacedString()}`);
43
+ if (cachedAsset && Caching.textureAssetCache.getIfPresent(assetKey) !== cachedAsset) return this.create(owner, baseMap, root, entityMeshes, kind);
44
44
  texture = Caching.textureCache.get(textureKey, () => {
45
45
  const texture2 = Textures.createCanvasTexture(image.data.canvas);
46
46
  texture2.wrapS = texture2.wrapT = metadata?.texture?.clamp ? ClampToEdgeWrapping : RepeatWrapping;
@@ -61,7 +61,8 @@ var ItemGlint = class _ItemGlint {
61
61
  blendSrcAlpha: ZeroFactor,
62
62
  blendDstAlpha: OneFactor,
63
63
  toneMapped: false,
64
- defines: entityMeshes ? { ENTITY_GLINT: true } : {},
64
+ // TextureTransform.ARMOR_ENTITY_GLINT_TEXTURING uses a smaller UV scale than item glint.
65
+ defines: entityMeshes ? { ENTITY_GLINT: true, ENTITY_GLINT_SCALE: kind === "armor" ? "0.16" : "0.5" } : {},
65
66
  uniforms: {
66
67
  ...!entityMeshes && { baseMap: { value: baseMap } },
67
68
  glintMap: { value: texture },
@@ -79,7 +80,7 @@ var ItemGlint = class _ItemGlint {
79
80
  varying vec2 vGlintUv;
80
81
  void main() {
81
82
  #ifdef ENTITY_GLINT
82
- vec2 p = vec2(uv.x, 1.0 - uv.y) * 0.5;
83
+ vec2 p = vec2(uv.x, 1.0 - uv.y) * ENTITY_GLINT_SCALE;
83
84
  #else
84
85
  vUv = uv;
85
86
  vUvBounds = uvBounds;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/model/ItemGlint.ts"],"sourcesContent":["import { ClampToEdgeWrapping, CustomBlending, DoubleSide, EqualDepth, Float32BufferAttribute, LinearFilter, Mesh, OneFactor, RepeatWrapping, ShaderMaterial, SrcColorFactor, Vector2, ZeroFactor } from \"three\";\nimport type { BufferGeometry, Texture } from \"three\";\nimport { AssetKey } from \"../assets/AssetKey\";\nimport { Models } from \"../assets/Models\";\nimport { ModelTextures } from \"../assets/ModelTextures\";\nimport { Caching } from \"../cache/Caching\";\nimport type { SceneObject } from \"../renderer/SceneObject\";\nimport { Textures } from \"../texture/Textures\";\nimport { Ticker } from \"../Ticker\";\nimport { CUBE_FACES } from \"../CubeFace\";\nimport type { ModelFaces } from \"./ModelElement\";\nimport type { TextureAtlas } from \"../texture/TextureAtlas\";\nimport { DisplayPosition } from \"./DisplayPosition\";\n\n/** An owned glint material over item geometry; textures and geometry retain their owners. */\nexport class ItemGlint {\n private ticker?: number;\n\n private constructor(private readonly owner: SceneObject, readonly material: ShaderMaterial) {\n this.updateTime();\n }\n\n /** Enables glint for enchantments or a lodestone compass unless a boolean component overrides them. */\n public static enabled(components: Record<string, unknown> = {}, itemId?: string): boolean {\n const override = Models.componentValue(components, \"enchantment_glint_override\");\n if (override !== undefined) {\n if (typeof override !== \"boolean\") throw new Error(\"Item enchantment_glint_override must be a boolean\");\n return override;\n }\n if (itemId === \"minecraft:compass\") {\n Models.componentValue(components, \"lodestone_tracker\");\n if (Object.prototype.hasOwnProperty.call(components, \"lodestone_tracker\")\n || Object.prototype.hasOwnProperty.call(components, \"minecraft:lodestone_tracker\")) return true;\n }\n const enchantments = Models.componentValue(components, \"enchantments\");\n if (enchantments === undefined) return false;\n if (!enchantments || typeof enchantments !== \"object\" || Array.isArray(enchantments)) throw new Error(\"Item enchantments must be an object\");\n return Object.keys(enchantments).length > 0;\n }\n\n /** @internal */\n public static async create(owner: SceneObject, baseMap?: Texture, root?: string,\n entityMeshes?: readonly { mesh: Mesh; parent?: Mesh }[]): Promise<ItemGlint> {\n const key = new AssetKey(\"minecraft\", \"enchanted_glint_item\", \"textures\", \"misc\", \"assets\", \".png\", root);\n const assetKey = key.serialize(), textureKey = `item-glint:${assetKey}`;\n let texture = Caching.textureCache.getIfPresent(textureKey);\n if (!texture) {\n const pending = ModelTextures.get(key);\n const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKey);\n const [image, metadata] = await Promise.all([pending, ModelTextures.getMeta(key)]);\n if (!image) throw new Error(`Missing item glint texture ${key.toNamespacedString()}`);\n // A cache clear during decoding must not restore an older source's texture.\n if (cachedAsset && Caching.textureAssetCache.getIfPresent(assetKey) !== cachedAsset) return this.create(owner, baseMap, root, entityMeshes);\n texture = Caching.textureCache.get(textureKey, () => {\n const texture = Textures.createCanvasTexture((image.data as CanvasRenderingContext2D).canvas);\n texture.wrapS = texture.wrapT = metadata?.texture?.clamp ? ClampToEdgeWrapping : RepeatWrapping;\n if (metadata?.texture?.blur) texture.magFilter = texture.minFilter = LinearFilter;\n return texture;\n });\n }\n const material = new ShaderMaterial({\n name: \"item-glint\", transparent: true, depthWrite: false, depthFunc: EqualDepth, side: DoubleSide, forceSinglePass: true,\n blending: CustomBlending, blendSrc: SrcColorFactor, blendDst: OneFactor, blendSrcAlpha: ZeroFactor, blendDstAlpha: OneFactor,\n toneMapped: false,\n defines: entityMeshes ? { ENTITY_GLINT: true } : {},\n uniforms: { ...(!entityMeshes && { baseMap: { value: baseMap } }),\n glintMap: { value: texture }, glintOffset: { value: new Vector2() }, glintAlpha: { value: 0.75 } },\n vertexShader: `\n uniform vec2 glintOffset;\n #ifndef ENTITY_GLINT\n attribute vec4 uvBounds;\n attribute vec2 glintUv;\n flat out vec4 vUvBounds;\n centroid out vec2 vUv;\n #endif\n varying vec2 vGlintUv;\n void main() {\n #ifdef ENTITY_GLINT\n vec2 p = vec2(uv.x, 1.0 - uv.y) * 0.5;\n #else\n vUv = uv;\n vUvBounds = uvBounds;\n vec2 p = glintUv * 8.0;\n #endif\n float angle = radians(10.0);\n vGlintUv = vec2(cos(angle) * p.x - sin(angle) * p.y, sin(angle) * p.x + cos(angle) * p.y) + glintOffset;\n vec4 mvPosition = vec4(position, 1.0);\n mvPosition = modelViewMatrix * mvPosition;\n gl_Position = projectionMatrix * mvPosition;\n }\n `,\n fragmentShader: `\n #ifndef ENTITY_GLINT\n uniform sampler2D baseMap;\n flat in vec4 vUvBounds;\n centroid in vec2 vUv;\n #endif\n uniform sampler2D glintMap;\n uniform float glintAlpha;\n varying vec2 vGlintUv;\n void main() {\n #ifndef ENTITY_GLINT\n vec2 mapUv = clamp(vUv, vUvBounds.xy, vUvBounds.zw);\n if (texture2D(baseMap, mapUv).a < 0.01) discard;\n #endif\n vec4 color = texture2D(glintMap, vec2(vGlintUv.x, 1.0 - vGlintUv.y));\n if (color.a < 0.1) discard;\n gl_FragColor = color;\n #include <colorspace_fragment>\n gl_FragColor.rgb *= glintAlpha;\n }\n `\n });\n if (!entityMeshes) Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });\n const targets: { mesh: Mesh; parent?: Mesh }[] = entityMeshes ? [...entityMeshes] : [];\n if (!entityMeshes) owner.iterateAllMeshes(mesh => targets.push({ mesh }));\n for (const { mesh: base, parent = base } of targets) {\n const pass = new Mesh(base.geometry, material);\n pass.name = `${base.name}:glint`;\n pass.userData.minerenderItemGlint = true;\n pass.raycast = () => {};\n pass.renderOrder = parent.renderOrder + 0.5;\n parent.add(pass);\n }\n return new ItemGlint(owner, material);\n }\n\n /**\n * Maps glint before model centering and display transforms. Ordinary sprites approximate Minecraft's shared atlas density.\n * @internal\n */\n public static mapUvs(geometry: BufferGeometry, faces: ModelFaces, atlas: TextureAtlas, itemId?: string, display?: DisplayPosition): void {\n const uv = geometry.getAttribute(\"uv\");\n const mapped = new Float32Array(uv.count * 2);\n if (itemId === \"minecraft:compass\" || itemId === \"minecraft:recovery_compass\" || itemId === \"minecraft:clock\") {\n const positions = geometry.getAttribute(\"position\"), normals = geometry.getAttribute(\"normal\");\n const scale = display === DisplayPosition.GUI ? 0.5\n : display === DisplayPosition.FIRSTPERSON_LEFTHAND || display === DisplayPosition.FIRSTPERSON_RIGHTHAND ? 0.75 : 1;\n // The decal's inverse pose cancels the display transform; its face projection uses block units at 1/128 scale.\n const factor = 1 / (16 * 128 * scale);\n for (let index = 0; index < positions.count; index++) {\n const x = positions.getX(index), y = positions.getY(index), z = positions.getZ(index);\n const nx = normals.getX(index), ny = normals.getY(index), nz = normals.getZ(index);\n const ax = Math.abs(nx), ay = Math.abs(ny), az = Math.abs(nz);\n let u: number, v: number;\n if (ay >= az && ay >= ax) { u = x; v = ny < 0 ? -z : z; }\n else if (az >= ax) { u = nz < 0 ? -x : x; v = -y; }\n else { u = nx < 0 ? -z : z; v = -y; }\n mapped[index * 2] = u * factor;\n mapped[index * 2 + 1] = v * factor;\n }\n geometry.setAttribute(\"glintUv\", new Float32BufferAttribute(mapped, 2));\n return;\n }\n for (const [faceIndex, face] of CUBE_FACES.entries()) {\n const texture = faces[face]?.texture?.substring(1);\n const position = texture && atlas.positions[texture] || [0, 0];\n const size = texture && atlas.sizes[texture] || [atlas.image.width, atlas.image.height];\n for (let corner = 0; corner < 4; corner++) {\n const index = faceIndex * 4 + corner;\n mapped[index * 2] = (uv.getX(index) * atlas.image.width - position[0]) / size[0] / 32;\n mapped[index * 2 + 1] = ((1 - uv.getY(index)) * atlas.image.height - position[1]) / size[1] / 32;\n }\n }\n geometry.setAttribute(\"glintUv\", new Float32BufferAttribute(mapped, 2));\n }\n\n private updateTime(): void {\n const time = Math.trunc(Date.now() * 4);\n (this.material.uniforms.glintOffset.value as Vector2).set(-(time % 110000) / 110000, (time % 30000) / 30000);\n }\n\n /** @internal */\n public updateSubscription(active: boolean): void {\n if (active && this.ticker === undefined) {\n this.updateTime();\n this.ticker = Ticker.add(() => { this.updateTime(); this.owner.notifyDirty(); });\n } else if (!active) {\n Ticker.remove(this.ticker);\n this.ticker = undefined;\n }\n }\n\n public dispose(): void {\n Ticker.remove(this.ticker);\n this.ticker = undefined;\n this.material.dispose();\n }\n}\n"],"mappings":"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","names":["texture"]}
1
+ {"version":3,"sources":["../../../../src/model/ItemGlint.ts"],"sourcesContent":["import { ClampToEdgeWrapping, CustomBlending, DoubleSide, EqualDepth, Float32BufferAttribute, LinearFilter, Mesh, OneFactor, RepeatWrapping, ShaderMaterial, SrcColorFactor, Vector2, ZeroFactor } from \"three\";\nimport type { BufferGeometry, Texture } from \"three\";\nimport { AssetKey } from \"../assets/AssetKey\";\nimport { Models } from \"../assets/Models\";\nimport { ModelTextures } from \"../assets/ModelTextures\";\nimport { Caching } from \"../cache/Caching\";\nimport type { SceneObject } from \"../renderer/SceneObject\";\nimport { Textures } from \"../texture/Textures\";\nimport { Ticker } from \"../Ticker\";\nimport { CUBE_FACES } from \"../CubeFace\";\nimport type { ModelFaces } from \"./ModelElement\";\nimport type { TextureAtlas } from \"../texture/TextureAtlas\";\nimport { DisplayPosition } from \"./DisplayPosition\";\n\n/** An owned glint material over item geometry; textures and geometry retain their owners. */\nexport class ItemGlint {\n private ticker?: number;\n\n private constructor(private readonly owner: SceneObject, readonly material: ShaderMaterial) {\n this.updateTime();\n }\n\n /** Enables glint for enchantments or a lodestone compass unless a boolean component overrides them. */\n public static enabled(components: Record<string, unknown> = {}, itemId?: string): boolean {\n const override = Models.componentValue(components, \"enchantment_glint_override\");\n if (override !== undefined) {\n if (typeof override !== \"boolean\") throw new Error(\"Item enchantment_glint_override must be a boolean\");\n return override;\n }\n if (itemId === \"minecraft:compass\") {\n Models.componentValue(components, \"lodestone_tracker\");\n if (Object.prototype.hasOwnProperty.call(components, \"lodestone_tracker\")\n || Object.prototype.hasOwnProperty.call(components, \"minecraft:lodestone_tracker\")) return true;\n }\n const enchantments = Models.componentValue(components, \"enchantments\");\n if (enchantments === undefined) return false;\n if (!enchantments || typeof enchantments !== \"object\" || Array.isArray(enchantments)) throw new Error(\"Item enchantments must be an object\");\n return Object.keys(enchantments).length > 0;\n }\n\n /** @internal */\n public static async create(owner: SceneObject, baseMap?: Texture, root?: string,\n entityMeshes?: readonly { mesh: Mesh; parent?: Mesh }[], kind: \"item\" | \"armor\" = \"item\"): Promise<ItemGlint> {\n const key = new AssetKey(\"minecraft\", `enchanted_glint_${kind}`, \"textures\", \"misc\", \"assets\", \".png\", root);\n const assetKey = key.serialize(), textureKey = `item-glint:${assetKey}`;\n let texture = Caching.textureCache.getIfPresent(textureKey);\n if (!texture) {\n const pending = ModelTextures.get(key);\n const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKey);\n const [image, metadata] = await Promise.all([pending, ModelTextures.getMeta(key)]);\n if (!image) throw new Error(`Missing ${kind} glint texture ${key.toNamespacedString()}`);\n // A cache clear during decoding must not restore an older source's texture.\n if (cachedAsset && Caching.textureAssetCache.getIfPresent(assetKey) !== cachedAsset) return this.create(owner, baseMap, root, entityMeshes, kind);\n texture = Caching.textureCache.get(textureKey, () => {\n const texture = Textures.createCanvasTexture((image.data as CanvasRenderingContext2D).canvas);\n texture.wrapS = texture.wrapT = metadata?.texture?.clamp ? ClampToEdgeWrapping : RepeatWrapping;\n if (metadata?.texture?.blur) texture.magFilter = texture.minFilter = LinearFilter;\n return texture;\n });\n }\n const material = new ShaderMaterial({\n name: \"item-glint\", transparent: true, depthWrite: false, depthFunc: EqualDepth, side: DoubleSide, forceSinglePass: true,\n blending: CustomBlending, blendSrc: SrcColorFactor, blendDst: OneFactor, blendSrcAlpha: ZeroFactor, blendDstAlpha: OneFactor,\n toneMapped: false,\n // TextureTransform.ARMOR_ENTITY_GLINT_TEXTURING uses a smaller UV scale than item glint.\n defines: entityMeshes ? { ENTITY_GLINT: true, ENTITY_GLINT_SCALE: kind === \"armor\" ? \"0.16\" : \"0.5\" } : {},\n uniforms: { ...(!entityMeshes && { baseMap: { value: baseMap } }),\n glintMap: { value: texture }, glintOffset: { value: new Vector2() }, glintAlpha: { value: 0.75 } },\n vertexShader: `\n uniform vec2 glintOffset;\n #ifndef ENTITY_GLINT\n attribute vec4 uvBounds;\n attribute vec2 glintUv;\n flat out vec4 vUvBounds;\n centroid out vec2 vUv;\n #endif\n varying vec2 vGlintUv;\n void main() {\n #ifdef ENTITY_GLINT\n vec2 p = vec2(uv.x, 1.0 - uv.y) * ENTITY_GLINT_SCALE;\n #else\n vUv = uv;\n vUvBounds = uvBounds;\n vec2 p = glintUv * 8.0;\n #endif\n float angle = radians(10.0);\n vGlintUv = vec2(cos(angle) * p.x - sin(angle) * p.y, sin(angle) * p.x + cos(angle) * p.y) + glintOffset;\n vec4 mvPosition = vec4(position, 1.0);\n mvPosition = modelViewMatrix * mvPosition;\n gl_Position = projectionMatrix * mvPosition;\n }\n `,\n fragmentShader: `\n #ifndef ENTITY_GLINT\n uniform sampler2D baseMap;\n flat in vec4 vUvBounds;\n centroid in vec2 vUv;\n #endif\n uniform sampler2D glintMap;\n uniform float glintAlpha;\n varying vec2 vGlintUv;\n void main() {\n #ifndef ENTITY_GLINT\n vec2 mapUv = clamp(vUv, vUvBounds.xy, vUvBounds.zw);\n if (texture2D(baseMap, mapUv).a < 0.01) discard;\n #endif\n vec4 color = texture2D(glintMap, vec2(vGlintUv.x, 1.0 - vGlintUv.y));\n if (color.a < 0.1) discard;\n gl_FragColor = color;\n #include <colorspace_fragment>\n gl_FragColor.rgb *= glintAlpha;\n }\n `\n });\n if (!entityMeshes) Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });\n const targets: { mesh: Mesh; parent?: Mesh }[] = entityMeshes ? [...entityMeshes] : [];\n if (!entityMeshes) owner.iterateAllMeshes(mesh => targets.push({ mesh }));\n for (const { mesh: base, parent = base } of targets) {\n const pass = new Mesh(base.geometry, material);\n pass.name = `${base.name}:glint`;\n pass.userData.minerenderItemGlint = true;\n pass.raycast = () => {};\n pass.renderOrder = parent.renderOrder + 0.5;\n parent.add(pass);\n }\n return new ItemGlint(owner, material);\n }\n\n /**\n * Maps glint before model centering and display transforms. Ordinary sprites approximate Minecraft's shared atlas density.\n * @internal\n */\n public static mapUvs(geometry: BufferGeometry, faces: ModelFaces, atlas: TextureAtlas, itemId?: string, display?: DisplayPosition): void {\n const uv = geometry.getAttribute(\"uv\");\n const mapped = new Float32Array(uv.count * 2);\n if (itemId === \"minecraft:compass\" || itemId === \"minecraft:recovery_compass\" || itemId === \"minecraft:clock\") {\n const positions = geometry.getAttribute(\"position\"), normals = geometry.getAttribute(\"normal\");\n const scale = display === DisplayPosition.GUI ? 0.5\n : display === DisplayPosition.FIRSTPERSON_LEFTHAND || display === DisplayPosition.FIRSTPERSON_RIGHTHAND ? 0.75 : 1;\n // The decal's inverse pose cancels the display transform; its face projection uses block units at 1/128 scale.\n const factor = 1 / (16 * 128 * scale);\n for (let index = 0; index < positions.count; index++) {\n const x = positions.getX(index), y = positions.getY(index), z = positions.getZ(index);\n const nx = normals.getX(index), ny = normals.getY(index), nz = normals.getZ(index);\n const ax = Math.abs(nx), ay = Math.abs(ny), az = Math.abs(nz);\n let u: number, v: number;\n if (ay >= az && ay >= ax) { u = x; v = ny < 0 ? -z : z; }\n else if (az >= ax) { u = nz < 0 ? -x : x; v = -y; }\n else { u = nx < 0 ? -z : z; v = -y; }\n mapped[index * 2] = u * factor;\n mapped[index * 2 + 1] = v * factor;\n }\n geometry.setAttribute(\"glintUv\", new Float32BufferAttribute(mapped, 2));\n return;\n }\n for (const [faceIndex, face] of CUBE_FACES.entries()) {\n const texture = faces[face]?.texture?.substring(1);\n const position = texture && atlas.positions[texture] || [0, 0];\n const size = texture && atlas.sizes[texture] || [atlas.image.width, atlas.image.height];\n for (let corner = 0; corner < 4; corner++) {\n const index = faceIndex * 4 + corner;\n mapped[index * 2] = (uv.getX(index) * atlas.image.width - position[0]) / size[0] / 32;\n mapped[index * 2 + 1] = ((1 - uv.getY(index)) * atlas.image.height - position[1]) / size[1] / 32;\n }\n }\n geometry.setAttribute(\"glintUv\", new Float32BufferAttribute(mapped, 2));\n }\n\n private updateTime(): void {\n const time = Math.trunc(Date.now() * 4);\n (this.material.uniforms.glintOffset.value as Vector2).set(-(time % 110000) / 110000, (time % 30000) / 30000);\n }\n\n /** @internal */\n public updateSubscription(active: boolean): void {\n if (active && this.ticker === undefined) {\n this.updateTime();\n this.ticker = Ticker.add(() => { this.updateTime(); this.owner.notifyDirty(); });\n } else if (!active) {\n Ticker.remove(this.ticker);\n this.ticker = undefined;\n }\n }\n\n public dispose(): void {\n Ticker.remove(this.ticker);\n this.ticker = undefined;\n this.material.dispose();\n }\n}\n"],"mappings":"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","names":["texture"]}
@@ -15,6 +15,8 @@ import { MineRenderData } from "../../../assets/MineRenderData.mjs";
15
15
  import { BlockEntities } from "../../../assets/BlockEntities.mjs";
16
16
  import { Entities } from "../../../assets/Entities.mjs";
17
17
  import { Biomes } from "../../../assets/Biomes.mjs";
18
+ import { logger } from "../../../util/log.mjs";
19
+ var log = logger("BlockObject");
18
20
  var _BlockObject = class _BlockObject extends SceneObject {
19
21
  constructor(blockState, options) {
20
22
  super(options);
@@ -106,20 +108,28 @@ var _BlockObject = class _BlockObject extends SceneObject {
106
108
  if (!key || this.options.displayPosition) return false;
107
109
  const generation = this._entityGeneration;
108
110
  const created = [];
111
+ const placement = new Matrix4();
109
112
  let resolved;
110
113
  try {
111
114
  resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);
112
115
  if (!resolved) return false;
116
+ BlockEntities.matrix(resolved, placement);
113
117
  for (const part of resolved.parts) {
114
118
  const [namespace, path] = part.model.includes(":") ? part.model.split(":") : [key.namespace, part.model];
115
- const texture = part.textureLocation === void 0 ? void 0 : AssetKey.parse("textures", part.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
119
+ let texture = part.textureLocation === void 0 ? void 0 : AssetKey.parse("textures", part.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
120
+ if (part.textureLocation === void 0 && namespace === "minecraft" && path === "player_head") {
121
+ const { PlayerHeadTextures } = await import("../../../skin/PlayerHeadTextures.mjs");
122
+ texture = (await PlayerHeadTextures.get(void 0, key.root)).texture;
123
+ }
116
124
  if (texture) texture.root = key.root;
117
125
  const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });
118
126
  if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);
119
- created.push(await this.scene.addEntity(entity, { wireframe: this.options.wireframe }));
127
+ const object = await this.scene.addEntity(entity, { wireframe: this.options.wireframe });
128
+ this.placeEntity(object, placement);
129
+ created.push(object);
120
130
  }
121
131
  } catch (error) {
122
- console.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
132
+ log.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
123
133
  this.removeEntities(created);
124
134
  return false;
125
135
  }
@@ -127,18 +137,21 @@ var _BlockObject = class _BlockObject extends SceneObject {
127
137
  this.removeEntities(created);
128
138
  return true;
129
139
  }
130
- BlockEntities.matrix(resolved, this._entityPlacement);
140
+ this._entityPlacement.copy(placement);
131
141
  this._entities = created;
132
142
  this.placeEntities();
133
143
  this.setVisible(this.visible);
134
144
  return true;
135
145
  }
136
146
  placeEntities() {
137
- const matrix = new Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
138
147
  for (const entity of this._entities) {
139
- matrix.decompose(entity.position, entity.quaternion, entity.scale);
148
+ this.placeEntity(entity, this._entityPlacement);
140
149
  }
141
150
  }
151
+ placeEntity(entity, placement) {
152
+ const matrix = new Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(placement);
153
+ matrix.decompose(entity.position, entity.quaternion, entity.scale);
154
+ }
142
155
  get isOccluding() {
143
156
  if (!this.visible) {
144
157
  return false;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/model/block/scene/BlockObject.ts"],"sourcesContent":["import { SceneObject } from \"../../../renderer/SceneObject\";\nimport { BlockState, BlockStateVariant } from \"../BlockState\";\nimport { SceneObjectOptions } from \"../../../renderer/SceneObjectOptions\";\nimport { isModelObject, ModelObject, ModelObjectOptions } from \"../../scene/ModelObject\";\nimport { Caching } from \"../../../cache/Caching\";\nimport { Models } from \"../../../assets/Models\";\nimport { merge } from \"../../../util/_internal/merge\";\nimport { Euler, Matrix4, Quaternion, Vector3 } from \"three\";\nimport { Maybe } from \"../../../util/util\";\nimport { MineRenderError } from \"../../../error/MineRenderError\";\nimport { BlockStateProperties, BlockStatePropertyDefaults } from \"../BlockStateProperties\";\nimport { InstanceReference, isInstanceReference } from \"../../../instance/InstanceReference\";\nimport { AssetKey, BasicAssetKey } from \"../../../assets/AssetKey\";\nimport { BlockTints } from \"../BlockTints\";\nimport { ModelCulling } from \"../../ModelCulling\";\nimport { BlockStateResolver } from \"../BlockStateResolver\";\nimport { FluidKind, FluidRules, FluidSampler, resolveBlockFluidState } from \"../../fluid/FluidGeometry\";\nimport { MineRenderData } from \"../../../assets/MineRenderData\";\nimport { BlockEntities, ResolvedBlockEntity } from \"../../../assets/BlockEntities\";\nimport { Entities } from \"../../../assets/Entities\";\nimport type { EntityObject } from \"../../../entity/scene/EntityObject\";\nimport { Biomes } from \"../../../assets/Biomes\";\nimport type { TripleArray } from \"../../Model\";\n\n/** Controls the model parts selected by a blockstate. Create it through {@link MineRenderScene.addBlock}. */\nexport class BlockObject extends SceneObject {\n\n public readonly isBlockObject: true = true;\n\n public static readonly DEFAULT_OPTIONS: BlockObjectOptions = merge({}, ModelObject.DEFAULT_OPTIONS, <BlockObjectOptions>{\n applyDefaultState: true\n });\n public readonly options: BlockObjectOptions;\n private readonly variantPosition?: TripleArray;\n\n private _previousState: BlockStateProperties = {};\n private _state: BlockStateProperties = {};\n private _variant: Maybe<BlockStateVariant> = undefined;\n\n private _instanceState: BlockStateProperties[] = [];\n private _instanceVariant: BlockStateVariant[][] = [];\n private _instanceModel: (ModelObject | InstanceReference<ModelObject>)[] = [];\n\n private _variants: BlockStateVariant[] = [];\n private _models: (ModelObject | InstanceReference<ModelObject>)[] = [];\n private _cullMask = 0;\n private _fluidKey?: string;\n private _fluidRules: FluidRules = {};\n private _fluidSampler?: FluidSampler;\n private readonly biomePosition?: TripleArray;\n private waterTint?: number;\n private _fluidModel?: ModelObject | InstanceReference<ModelObject>;\n private _entities: EntityObject[] = [];\n private _entityPlacement = new Matrix4();\n private _entityGeneration = 0;\n\n constructor(readonly blockState: BlockState, options?: Partial<BlockObjectOptions>) {\n super(options);\n this.options = merge({}, BlockObject.DEFAULT_OPTIONS, options ?? {});\n this.variantPosition = options?.variantPosition ? [...options.variantPosition] : undefined;\n this.biomePosition = options?.biomePosition ? [...options.biomePosition] : undefined;\n //TODO\n }\n\n async init(): Promise<void> {\n this._fluidRules = await MineRenderData.get(\"fluids\", this.blockState.key?.root);\n if (this.options.applyDefaultState) {\n this._setState(await BlockStateResolver.defaults(this.blockState));\n }\n if (this.options.initialState !== undefined) this._setState(this.options.initialState);\n await this.recreateModels();\n //TODO\n }\n\n dispose() {\n this.clearModels();\n super.dispose();\n }\n\n removeFromScene() {\n this.clearModels();\n super.removeFromScene();\n }\n\n private clearModels() {\n this.removeModels(this._models.splice(0));\n this._entityGeneration++;\n this.removeEntities(this._entities.splice(0));\n this._fluidKey = undefined;\n this._fluidModel = undefined;\n this._isInstanced = false;\n this._instanceCounter = 0;\n }\n\n private removeModels(models: (ModelObject | InstanceReference<ModelObject>)[]) {\n for (const model of models) {\n model.removeFromScene();\n if (!isInstanceReference(model)) model.dispose();\n }\n }\n\n private removeEntities(entities: EntityObject[]) {\n for (const entity of entities) {\n entity.removeFromScene();\n entity.dispose();\n }\n }\n\n /** Entity models drawn for this block instead of its block model; they are scene children, unlike the block. */\n public get blockEntities(): readonly EntityObject[] {\n return this._entities;\n }\n\n /** Model placements drawn for this block, including its fluid surface. */\n public get models(): readonly (ModelObject | InstanceReference<ModelObject>)[] {\n return this._models;\n }\n\n /** Sets visibility for this block's model instances and block entities. */\n public setVisible(visible: boolean): void {\n this.visible = visible;\n for (const model of this._models) {\n if (isInstanceReference(model)) {\n model.setVisible(visible);\n } else {\n model.visible = visible;\n }\n }\n for (const entity of this._entities) {\n entity.visible = visible;\n }\n this.notifyDirty();\n }\n\n /**\n * Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,\n * when the block is not listed or one of its models cannot be loaded.\n */\n private async createBlockEntities(): Promise<boolean> {\n const key = this.blockState.key;\n if (!key || this.options.displayPosition) return false;\n const generation = this._entityGeneration;\n const created: EntityObject[] = [];\n let resolved: Maybe<ResolvedBlockEntity>;\n try {\n resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);\n if (!resolved) return false;\n for (const part of resolved.parts) {\n const [namespace, path] = part.model.includes(\":\") ? part.model.split(\":\") : [key.namespace, part.model];\n const texture = part.textureLocation === undefined ? undefined\n : AssetKey.parse(\"textures\", part.textureLocation.replace(/^([^:]+:)?textures\\//, \"$1\"));\n if (texture) texture.root = key.root;\n const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });\n if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);\n created.push(await this.scene.addEntity(entity, { wireframe: this.options.wireframe }) as EntityObject);\n }\n } catch (error) {\n console.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);\n this.removeEntities(created);\n return false;\n }\n // The block was cleared while the models loaded.\n if (generation !== this._entityGeneration) {\n this.removeEntities(created);\n return true;\n }\n BlockEntities.matrix(resolved, this._entityPlacement);\n this._entities = created;\n this.placeEntities();\n this.setVisible(this.visible);\n return true;\n }\n\n private placeEntities() {\n // Block models are centred on the block position; entity transforms use the block's 0..16 space.\n const matrix = new Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);\n for (const entity of this._entities) {\n matrix.decompose(entity.position, entity.quaternion, entity.scale);\n }\n }\n\n public get isOccluding(): boolean {\n if (!this.visible) {\n return false;\n }\n return this._models.some(model => {\n const object = isInstanceReference(model) ? model.instanceable : model;\n return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;\n });\n }\n\n private getModelMatrix(model: ModelObject | InstanceReference<ModelObject>): Matrix4 {\n if (isInstanceReference(model)) return model.getMatrix();\n if (model.matrixAutoUpdate) model.updateMatrix();\n return model.matrix.clone();\n }\n\n private getModelCullMask(model: ModelObject | InstanceReference<ModelObject>, worldMask: number): number {\n const object = isInstanceReference(model) ? model.instanceable : model;\n if (object.options.displayPosition) return 0;\n const position = new Vector3();\n const rotation = new Quaternion();\n const scale = new Vector3();\n this.getModelMatrix(model).decompose(position, rotation, scale);\n if (position.distanceToSquared(this.position) > 1e-10\n || scale.distanceToSquared(new Vector3(1, 1, 1)) > 1e-10) return 0;\n return ModelCulling.toLocalMask(worldMask, new Euler().setFromQuaternion(rotation));\n }\n\n /** World-space face mask currently applied to this block. */\n public get cullMask(): number {\n return this._cullMask;\n }\n\n public async setCullMask(worldMask: number): Promise<void> {\n worldMask &= 63;\n const replacements: (ModelObject | InstanceReference<ModelObject>)[] = [];\n try {\n for (const model of this._models) {\n if (model === this._fluidModel) {\n replacements.push(model);\n continue;\n }\n const object = isInstanceReference(model) ? model.instanceable : model;\n const cullMask = this.getModelCullMask(model, worldMask);\n if (cullMask === (object.options.cullMask ?? 0)) {\n replacements.push(model);\n continue;\n }\n const matrix = this.getModelMatrix(model);\n const replacement = await this.scene.addModel(object.originalModel, { ...object.options, cullMask });\n replacements.push(replacement);\n if (isInstanceReference(replacement)) {\n replacement.setMatrix(matrix);\n } else {\n replacement.matrix.copy(matrix);\n replacement.matrixWorldNeedsUpdate = true;\n matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);\n replacement.matrixAutoUpdate = object.matrixAutoUpdate;\n replacement.visible = object.visible;\n }\n }\n } catch (error) {\n this.removeModels(replacements.filter(model => !this._models.includes(model)));\n throw error;\n }\n const previous = this._models;\n this._models = replacements;\n this._cullMask = worldMask;\n this.removeModels(previous.filter(model => !replacements.includes(model)));\n if (!this.visible) {\n this.setVisible(false);\n }\n this.notifyDirty();\n }\n\n /** Selected property values. Use {@link setState} to change properties and rebuild the rendered models. */\n public get state(): { [key: string]: string; } {\n return this._state;\n }\n\n public get fluidKind(): FluidKind | undefined {\n return resolveBlockFluidState(this.blockState.key, this.state, this._fluidRules)?.kind;\n }\n\n public get fluidLevel(): number {\n return resolveBlockFluidState(this.blockState.key, this.state, this._fluidRules)?.level ?? 0;\n }\n\n /** Refreshes fluid surfaces from relative neighbors; standalone previews use air around the block. */\n public async updateFluid(sample?: FluidSampler): Promise<void> {\n const kind = this.fluidKind;\n if (!kind) return;\n const { FluidModelObject, sampleFluid } = await import(\"../../fluid/FluidModelObject\");\n this._fluidSampler = sample;\n const surface = sampleFluid(kind, (x, y, z) => x === 0 && y === 0 && z === 0\n ? { fluid: kind, level: this.fluidLevel } : sample?.(x, y, z) ?? {});\n const tint = this.options.tints?.[0] ?? this.waterTint;\n const fluidKey = `${surface.key}|${tint ?? \"default\"}`;\n if (this._fluidKey === fluidKey) return;\n const key = new AssetKey(\"minecraft\", `${kind}/${surface.key}`, \"models\", \"fluid\", \"assets\", \".json\", this.blockState.key?.root);\n const replacement = await this.scene.addSceneObject({ key },\n () => new FluidModelObject(kind, surface.sample, this.blockState.key, {\n ...this.options, tints: tint === undefined ? this.options.tints : { ...this.options.tints, 0: tint }\n }));\n const previous = this._fluidModel;\n const matrix = previous ? this.getModelMatrix(previous) : new Matrix4().makeTranslation(...this.position.toArray());\n if (isInstanceReference(replacement)) replacement.setMatrix(matrix);\n else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);\n this._models = this._models.filter(model => model !== previous);\n this._models.push(replacement);\n this._fluidModel = replacement;\n this._fluidKey = fluidKey;\n this._isInstanced ||= isInstanceReference(replacement);\n this._instanceCounter = this._isInstanced ? 1 : 0;\n if (previous) this.removeModels([previous]);\n if (!this.visible) {\n this.setVisible(false);\n }\n this.notifyDirty();\n }\n\n nextInstance(): InstanceReference<SceneObject> {\n\n const ref = super.nextInstance();\n for (let child of this.children) {\n if (isModelObject(child)) {\n child._instanceCounter = this.instanceCounter;\n }\n }\n return ref;\n }\n\n protected async mapStateToVariant(state: BlockStateProperties): Promise<BlockStateVariant[]> {\n return BlockStateResolver.select(this.blockState, state, variants => this.getSingleVariant(variants));\n }\n\n public async recreateModels(): Promise<void> {\n //TODO: change this to create models once, and then modify rotations when updating the state\n\n // Remove all children\n // this.disposeAndRemoveAllChildren(); //TODO: just removes all children of all instances atm...\n\n // TODO: try to reuse models instead of just removing them and creating new ones\n this.clearModels();\n\n this.waterTint = this.fluidKind === \"water\" && this.options.biome && this.options.tints?.[0] === undefined\n ? await Biomes.getColor(this.options.biome, \"water\", this.blockState.key) : undefined;\n\n if (resolveBlockFluidState(this.blockState.key, this.state, this._fluidRules)?.renderModel === false) {\n await this.updateFluid(this._fluidSampler);\n return;\n }\n\n\n //TODO: might want to preload all possible states & cache their data\n //TODO: make sure to only instance stuff with different rotations together; i.e. not those with different multipart settings, or different models\n\n /*\n if (this.isInstanced) {\n //TODO: only map once per state\n for (let i = 0; i < this.instanceCounter; i++) {\n this._instanceVariant[i] = await this.mapStateToVariant(this._instanceState[i]);\n for (let variant of this._instanceVariant[i]) {\n this._instanceModel[i] = await this.createVariant(variant);\n }\n }\n //TODO: actually create\n //TODO: group by model\n this._isInstanced = true;\n } else {\n */\n const hasEntities = await this.createBlockEntities();\n const variantsToCreate = await this.mapStateToVariant(this.state);\n this._variants = variantsToCreate;\n for (let blockStateVariant of variantsToCreate) {\n // A block entity replaces only block models without geometry (a chest); a bell keeps its frame.\n if (hasEntities && !await this.hasGeometry(blockStateVariant)) continue;\n this._models.push(await this.createVariant(blockStateVariant));\n }\n await this.updateFluid(this._fluidSampler);\n this.setVisible(this.visible);\n /*\n }\n\n */\n\n }\n\n private async hasGeometry(variant: BlockStateVariant): Promise<boolean> {\n const modelKey = AssetKey.parse(\"models\", variant.model!);\n modelKey.root = this.blockState.key?.root;\n return !!(await Models.getMerged(modelKey))?.elements?.length;\n }\n\n protected getSingleVariant(variants: BlockStateVariant | BlockStateVariant[]): BlockStateVariant {\n return BlockStateResolver.choose(variants, this.variantPosition);\n }\n\n // @deprecated\n protected async createAVariant(variants: BlockStateVariant | BlockStateVariant[], instanceInfo: Matrix4[]) {\n const variant = this.getSingleVariant(variants);\n await this.createVariant(variant);\n }\n\n protected async createVariant(variant: BlockStateVariant): Promise<ModelObject | InstanceReference<ModelObject>> {\n const rotation = BlockStateResolver.rotation(variant);\n\n // The model and its textures must come from the same asset root as the blockstate.\n const modelKey = AssetKey.parse(\"models\", variant.model!);\n modelKey.root = this.blockState.key?.root;\n const model = await Models.getMerged(modelKey);\n const options: Partial<ModelObjectOptions> = {\n ...this.options,\n tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints,\n () => BlockTints.getBiomeColor(this.blockState.key, this.options.biome, this.biomePosition)) : this.options.tints,\n uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0)\n ? [rotation.x, rotation.y, rotation.z] : undefined,\n cullMask: this.options.displayPosition ? 0 : ModelCulling.toLocalMask(this._cullMask, rotation)\n };\n const obj = await this.scene.addModel(model!, options);\n if (isInstanceReference(obj) || (<ModelObject>obj).isInstanced) {\n this._isInstanced = true;\n this._instanceCounter = 1;//TODO: BlockObject itself isn't technically instanced, but needs the id for the get/setMatrix calls to work properly\n }\n obj.setRotation(rotation);\n obj.setPosition(this.position);\n return obj;\n }\n\n /** Clears selected properties and rebuilds models without reapplying property defaults. */\n public async resetState() {\n this._previousState = this._state;\n this._state = {};\n await this.recreateModels();\n }\n\n // TODO: support state per instance\n /**\n * Updates properties and rebuilds the selected models.\n * Accepts `\"facing=north,open=true\"`, a property object, or a key and value.\n * Properties omitted from the call keep their current values.\n */\n public async setState(string: string);\n public async setState(state: BlockStateProperties);\n public async setState(key: string, value: string);\n public async setState(stringOrKeyOrState: string | BlockStateProperties, value?: string) {\n this._setState(stringOrKeyOrState, value);\n await this.recreateModels();\n }\n\n protected _setState(stringOrKeyOrState: string | BlockStateProperties, value?: string): void {\n this._previousState = this._state;\n if (typeof value === \"undefined\") { // a=b,c=d,... or state object\n if (typeof stringOrKeyOrState === \"string\") {\n if (stringOrKeyOrState === \"\") return;\n const split = stringOrKeyOrState.split(\",\");\n for (let s of split) {\n let [k, v] = s.split(\"=\");\n this._setState(k, v);\n }\n } else if (typeof stringOrKeyOrState === \"object\") {\n for (let k in stringOrKeyOrState) {\n this._state[k] = stringOrKeyOrState[k];\n }\n }\n } else {\n this._state[stringOrKeyOrState as string] = value;\n }\n }\n\n /*\n public async setStateAt(index: number, string: string);\n public async setStateAt(index: number, state: BlockStateProperties);\n public async setStateAt(index: number, key: string, value: string);\n public async setStateAt(index: number, stringOrKeyOrState: string | BlockStateProperties, value?: string);\n public async setStateAt(index: number, stringOrKeyOrState: string | BlockStateProperties, value?: string) {\n this._setStateAt(index, stringOrKeyOrState, value);\n await this.recreateModels();\n }\n\n protected _setStateAt(index: number, stringOrKeyOrState: string | BlockStateProperties, value?: string): void {\n if (!this._instanceState[index]) this._instanceState[index] = {};\n if (typeof value === \"undefined\") { // a=b,c=d,... or state object\n if (typeof stringOrKeyOrState === \"string\") {\n if (stringOrKeyOrState === \"\") return;\n const split = stringOrKeyOrState.split(\",\");\n for (let s of split) {\n let [k, v] = s.split(\"=\");\n this._setStateAt(index, k, v);\n }\n } else if (typeof stringOrKeyOrState === \"object\") {\n for (let k in stringOrKeyOrState) {\n this._instanceState[index][k] = stringOrKeyOrState[k];\n }\n }\n } else {\n this._instanceState[index][stringOrKeyOrState as string] = value;\n }\n }\n\n _getStateAt(index: number): BlockStateProperties {\n return this._instanceState[index];\n }\n\n */\n\n setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3) {\n super.setPositionRotationScaleAt(index, position, rotation, scale);\n }\n\n getMatrixAt(index: number, matrix: Matrix4 = new Matrix4()): Matrix4 {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n const child = this._models[0];\n if (child && isModelObject(child)) {\n child.getMatrixAt(index, matrix);\n } else if (child && isInstanceReference(child)) {\n child.getMatrix(matrix);\n }\n /*\n const child = this.children[0];\n if (child && isModelObject(child)) {\n if (!child.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n child.getMatrixAt(index, matrix);\n }\n return matrix;\n */\n // return super.getMatrixAt(0, matrix);\n return matrix;\n }\n\n setMatrixAt(index: number, matrix: Matrix4) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n // const child = this._models[0];\n for(let child of this._models) {\n if (child && isModelObject(child)) {\n child.setMatrixAt(index, matrix);\n } else if (child && isInstanceReference(child)) {\n child.setMatrix(matrix);\n }\n }\n /*\n for (let child of this.children) {\n if (isModelObject(child)) {\n if (!child.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n child.setMatrixAt(index, matrix);\n }\n }\n */\n }\n\n setPosition(position: Vector3) {\n this.position.copy(position);\n // Each part keeps its own variant rotation when the block moves.\n for (let model of this._models) {\n model.setPosition(position);\n }\n this.placeEntities();\n this.notifyDirty();\n }\n\n //TODO: should override rotation + scale methods\n\n //TODO\n\n}\n\n/** Block settings passed to `scene.addBlock(blockState, options)` or the BlockObject constructor. */\nexport interface BlockObjectOptions extends ModelObjectOptions {\n /** Loads vanilla property defaults before applying `initialState`. Defaults to `true`. */\n applyDefaultState: boolean;\n /** Properties applied before model creation, overriding defaults when applyDefaultState is enabled. */\n initialState?: BlockStateProperties;\n /** Absolute block coordinates for repeatable variants, copied at construction. Omit for random previews. */\n variantPosition?: TripleArray;\n /** Saved biome ID used for automatic grass, foliage, and water colors. */\n biome?: string;\n /** World block coordinates used by biome grass modifiers. Copied at construction; defaults to the origin. */\n biomePosition?: TripleArray;\n}\n\nexport function isBlockObject(obj: any): obj is BlockObject {\n return (<BlockObject>obj).isBlockObject;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../../src/model/block/scene/BlockObject.ts"],"sourcesContent":["import { SceneObject } from \"../../../renderer/SceneObject\";\nimport { BlockState, BlockStateVariant } from \"../BlockState\";\nimport { SceneObjectOptions } from \"../../../renderer/SceneObjectOptions\";\nimport { isModelObject, ModelObject, ModelObjectOptions } from \"../../scene/ModelObject\";\nimport { Caching } from \"../../../cache/Caching\";\nimport { Models } from \"../../../assets/Models\";\nimport { merge } from \"../../../util/_internal/merge\";\nimport { Euler, Matrix4, Quaternion, Vector3 } from \"three\";\nimport { Maybe } from \"../../../util/util\";\nimport { MineRenderError } from \"../../../error/MineRenderError\";\nimport { BlockStateProperties, BlockStatePropertyDefaults } from \"../BlockStateProperties\";\nimport { InstanceReference, isInstanceReference } from \"../../../instance/InstanceReference\";\nimport { AssetKey, BasicAssetKey } from \"../../../assets/AssetKey\";\nimport { BlockTints } from \"../BlockTints\";\nimport { ModelCulling } from \"../../ModelCulling\";\nimport { BlockStateResolver } from \"../BlockStateResolver\";\nimport { FluidKind, FluidRules, FluidSampler, resolveBlockFluidState } from \"../../fluid/FluidGeometry\";\nimport { MineRenderData } from \"../../../assets/MineRenderData\";\nimport { BlockEntities, ResolvedBlockEntity } from \"../../../assets/BlockEntities\";\nimport { Entities } from \"../../../assets/Entities\";\nimport type { EntityObject } from \"../../../entity/scene/EntityObject\";\nimport { Biomes } from \"../../../assets/Biomes\";\nimport type { TripleArray } from \"../../Model\";\nimport { logger } from \"../../../util/log\";\n\nconst log = logger(\"BlockObject\");\n\n/** Controls the model parts selected by a blockstate. Create it through {@link MineRenderScene.addBlock}. */\nexport class BlockObject extends SceneObject {\n\n public readonly isBlockObject: true = true;\n\n public static readonly DEFAULT_OPTIONS: BlockObjectOptions = merge({}, ModelObject.DEFAULT_OPTIONS, <BlockObjectOptions>{\n applyDefaultState: true\n });\n public readonly options: BlockObjectOptions;\n private readonly variantPosition?: TripleArray;\n\n private _previousState: BlockStateProperties = {};\n private _state: BlockStateProperties = {};\n private _variant: Maybe<BlockStateVariant> = undefined;\n\n private _instanceState: BlockStateProperties[] = [];\n private _instanceVariant: BlockStateVariant[][] = [];\n private _instanceModel: (ModelObject | InstanceReference<ModelObject>)[] = [];\n\n private _variants: BlockStateVariant[] = [];\n private _models: (ModelObject | InstanceReference<ModelObject>)[] = [];\n private _cullMask = 0;\n private _fluidKey?: string;\n private _fluidRules: FluidRules = {};\n private _fluidSampler?: FluidSampler;\n private readonly biomePosition?: TripleArray;\n private waterTint?: number;\n private _fluidModel?: ModelObject | InstanceReference<ModelObject>;\n private _entities: EntityObject[] = [];\n private _entityPlacement = new Matrix4();\n private _entityGeneration = 0;\n\n constructor(readonly blockState: BlockState, options?: Partial<BlockObjectOptions>) {\n super(options);\n this.options = merge({}, BlockObject.DEFAULT_OPTIONS, options ?? {});\n this.variantPosition = options?.variantPosition ? [...options.variantPosition] : undefined;\n this.biomePosition = options?.biomePosition ? [...options.biomePosition] : undefined;\n //TODO\n }\n\n async init(): Promise<void> {\n this._fluidRules = await MineRenderData.get(\"fluids\", this.blockState.key?.root);\n if (this.options.applyDefaultState) {\n this._setState(await BlockStateResolver.defaults(this.blockState));\n }\n if (this.options.initialState !== undefined) this._setState(this.options.initialState);\n await this.recreateModels();\n //TODO\n }\n\n dispose() {\n this.clearModels();\n super.dispose();\n }\n\n removeFromScene() {\n this.clearModels();\n super.removeFromScene();\n }\n\n private clearModels() {\n this.removeModels(this._models.splice(0));\n this._entityGeneration++;\n this.removeEntities(this._entities.splice(0));\n this._fluidKey = undefined;\n this._fluidModel = undefined;\n this._isInstanced = false;\n this._instanceCounter = 0;\n }\n\n private removeModels(models: (ModelObject | InstanceReference<ModelObject>)[]) {\n for (const model of models) {\n model.removeFromScene();\n if (!isInstanceReference(model)) model.dispose();\n }\n }\n\n private removeEntities(entities: EntityObject[]) {\n for (const entity of entities) {\n entity.removeFromScene();\n entity.dispose();\n }\n }\n\n /** Entity models drawn for this block instead of its block model; they are scene children, unlike the block. */\n public get blockEntities(): readonly EntityObject[] {\n return this._entities;\n }\n\n /** Model placements drawn for this block, including its fluid surface. */\n public get models(): readonly (ModelObject | InstanceReference<ModelObject>)[] {\n return this._models;\n }\n\n /** Sets visibility for this block's model instances and block entities. */\n public setVisible(visible: boolean): void {\n this.visible = visible;\n for (const model of this._models) {\n if (isInstanceReference(model)) {\n model.setVisible(visible);\n } else {\n model.visible = visible;\n }\n }\n for (const entity of this._entities) {\n entity.visible = visible;\n }\n this.notifyDirty();\n }\n\n /**\n * Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,\n * when the block is not listed or one of its models cannot be loaded.\n */\n private async createBlockEntities(): Promise<boolean> {\n const key = this.blockState.key;\n if (!key || this.options.displayPosition) return false;\n const generation = this._entityGeneration;\n const created: EntityObject[] = [];\n const placement = new Matrix4();\n let resolved: Maybe<ResolvedBlockEntity>;\n try {\n resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);\n if (!resolved) return false;\n BlockEntities.matrix(resolved, placement);\n for (const part of resolved.parts) {\n const [namespace, path] = part.model.includes(\":\") ? part.model.split(\":\") : [key.namespace, part.model];\n let texture = part.textureLocation === undefined ? undefined\n : AssetKey.parse(\"textures\", part.textureLocation.replace(/^([^:]+:)?textures\\//, \"$1\"));\n if (part.textureLocation === undefined && namespace === \"minecraft\" && path === \"player_head\") {\n const { PlayerHeadTextures } = await import(\"../../../skin/PlayerHeadTextures\");\n texture = (await PlayerHeadTextures.get(undefined, key.root)).texture;\n }\n if (texture) texture.root = key.root;\n const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });\n if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);\n const object = await this.scene.addEntity(entity, { wireframe: this.options.wireframe }) as EntityObject;\n this.placeEntity(object, placement);\n created.push(object);\n }\n } catch (error) {\n log.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);\n this.removeEntities(created);\n return false;\n }\n // The block was cleared while the models loaded.\n if (generation !== this._entityGeneration) {\n this.removeEntities(created);\n return true;\n }\n this._entityPlacement.copy(placement);\n this._entities = created;\n this.placeEntities();\n this.setVisible(this.visible);\n return true;\n }\n\n private placeEntities() {\n for (const entity of this._entities) {\n this.placeEntity(entity, this._entityPlacement);\n }\n }\n\n private placeEntity(entity: EntityObject, placement: Matrix4) {\n // Block models are centred on the block position; entity transforms use the block's 0..16 space.\n const matrix = new Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(placement);\n matrix.decompose(entity.position, entity.quaternion, entity.scale);\n }\n\n public get isOccluding(): boolean {\n if (!this.visible) {\n return false;\n }\n return this._models.some(model => {\n const object = isInstanceReference(model) ? model.instanceable : model;\n return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;\n });\n }\n\n private getModelMatrix(model: ModelObject | InstanceReference<ModelObject>): Matrix4 {\n if (isInstanceReference(model)) return model.getMatrix();\n if (model.matrixAutoUpdate) model.updateMatrix();\n return model.matrix.clone();\n }\n\n private getModelCullMask(model: ModelObject | InstanceReference<ModelObject>, worldMask: number): number {\n const object = isInstanceReference(model) ? model.instanceable : model;\n if (object.options.displayPosition) return 0;\n const position = new Vector3();\n const rotation = new Quaternion();\n const scale = new Vector3();\n this.getModelMatrix(model).decompose(position, rotation, scale);\n if (position.distanceToSquared(this.position) > 1e-10\n || scale.distanceToSquared(new Vector3(1, 1, 1)) > 1e-10) return 0;\n return ModelCulling.toLocalMask(worldMask, new Euler().setFromQuaternion(rotation));\n }\n\n /** World-space face mask currently applied to this block. */\n public get cullMask(): number {\n return this._cullMask;\n }\n\n public async setCullMask(worldMask: number): Promise<void> {\n worldMask &= 63;\n const replacements: (ModelObject | InstanceReference<ModelObject>)[] = [];\n try {\n for (const model of this._models) {\n if (model === this._fluidModel) {\n replacements.push(model);\n continue;\n }\n const object = isInstanceReference(model) ? model.instanceable : model;\n const cullMask = this.getModelCullMask(model, worldMask);\n if (cullMask === (object.options.cullMask ?? 0)) {\n replacements.push(model);\n continue;\n }\n const matrix = this.getModelMatrix(model);\n const replacement = await this.scene.addModel(object.originalModel, { ...object.options, cullMask });\n replacements.push(replacement);\n if (isInstanceReference(replacement)) {\n replacement.setMatrix(matrix);\n } else {\n replacement.matrix.copy(matrix);\n replacement.matrixWorldNeedsUpdate = true;\n matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);\n replacement.matrixAutoUpdate = object.matrixAutoUpdate;\n replacement.visible = object.visible;\n }\n }\n } catch (error) {\n this.removeModels(replacements.filter(model => !this._models.includes(model)));\n throw error;\n }\n const previous = this._models;\n this._models = replacements;\n this._cullMask = worldMask;\n this.removeModels(previous.filter(model => !replacements.includes(model)));\n if (!this.visible) {\n this.setVisible(false);\n }\n this.notifyDirty();\n }\n\n /** Selected property values. Use {@link setState} to change properties and rebuild the rendered models. */\n public get state(): { [key: string]: string; } {\n return this._state;\n }\n\n public get fluidKind(): FluidKind | undefined {\n return resolveBlockFluidState(this.blockState.key, this.state, this._fluidRules)?.kind;\n }\n\n public get fluidLevel(): number {\n return resolveBlockFluidState(this.blockState.key, this.state, this._fluidRules)?.level ?? 0;\n }\n\n /** Refreshes fluid surfaces from relative neighbors; standalone previews use air around the block. */\n public async updateFluid(sample?: FluidSampler): Promise<void> {\n const kind = this.fluidKind;\n if (!kind) return;\n const { FluidModelObject, sampleFluid } = await import(\"../../fluid/FluidModelObject\");\n this._fluidSampler = sample;\n const surface = sampleFluid(kind, (x, y, z) => x === 0 && y === 0 && z === 0\n ? { fluid: kind, level: this.fluidLevel } : sample?.(x, y, z) ?? {});\n const tint = this.options.tints?.[0] ?? this.waterTint;\n const fluidKey = `${surface.key}|${tint ?? \"default\"}`;\n if (this._fluidKey === fluidKey) return;\n const key = new AssetKey(\"minecraft\", `${kind}/${surface.key}`, \"models\", \"fluid\", \"assets\", \".json\", this.blockState.key?.root);\n const replacement = await this.scene.addSceneObject({ key },\n () => new FluidModelObject(kind, surface.sample, this.blockState.key, {\n ...this.options, tints: tint === undefined ? this.options.tints : { ...this.options.tints, 0: tint }\n }));\n const previous = this._fluidModel;\n const matrix = previous ? this.getModelMatrix(previous) : new Matrix4().makeTranslation(...this.position.toArray());\n if (isInstanceReference(replacement)) replacement.setMatrix(matrix);\n else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);\n this._models = this._models.filter(model => model !== previous);\n this._models.push(replacement);\n this._fluidModel = replacement;\n this._fluidKey = fluidKey;\n this._isInstanced ||= isInstanceReference(replacement);\n this._instanceCounter = this._isInstanced ? 1 : 0;\n if (previous) this.removeModels([previous]);\n if (!this.visible) {\n this.setVisible(false);\n }\n this.notifyDirty();\n }\n\n nextInstance(): InstanceReference<SceneObject> {\n\n const ref = super.nextInstance();\n for (let child of this.children) {\n if (isModelObject(child)) {\n child._instanceCounter = this.instanceCounter;\n }\n }\n return ref;\n }\n\n protected async mapStateToVariant(state: BlockStateProperties): Promise<BlockStateVariant[]> {\n return BlockStateResolver.select(this.blockState, state, variants => this.getSingleVariant(variants));\n }\n\n public async recreateModels(): Promise<void> {\n //TODO: change this to create models once, and then modify rotations when updating the state\n\n // Remove all children\n // this.disposeAndRemoveAllChildren(); //TODO: just removes all children of all instances atm...\n\n // TODO: try to reuse models instead of just removing them and creating new ones\n this.clearModels();\n\n this.waterTint = this.fluidKind === \"water\" && this.options.biome && this.options.tints?.[0] === undefined\n ? await Biomes.getColor(this.options.biome, \"water\", this.blockState.key) : undefined;\n\n if (resolveBlockFluidState(this.blockState.key, this.state, this._fluidRules)?.renderModel === false) {\n await this.updateFluid(this._fluidSampler);\n return;\n }\n\n\n //TODO: might want to preload all possible states & cache their data\n //TODO: make sure to only instance stuff with different rotations together; i.e. not those with different multipart settings, or different models\n\n /*\n if (this.isInstanced) {\n //TODO: only map once per state\n for (let i = 0; i < this.instanceCounter; i++) {\n this._instanceVariant[i] = await this.mapStateToVariant(this._instanceState[i]);\n for (let variant of this._instanceVariant[i]) {\n this._instanceModel[i] = await this.createVariant(variant);\n }\n }\n //TODO: actually create\n //TODO: group by model\n this._isInstanced = true;\n } else {\n */\n const hasEntities = await this.createBlockEntities();\n const variantsToCreate = await this.mapStateToVariant(this.state);\n this._variants = variantsToCreate;\n for (let blockStateVariant of variantsToCreate) {\n // A block entity replaces only block models without geometry (a chest); a bell keeps its frame.\n if (hasEntities && !await this.hasGeometry(blockStateVariant)) continue;\n this._models.push(await this.createVariant(blockStateVariant));\n }\n await this.updateFluid(this._fluidSampler);\n this.setVisible(this.visible);\n /*\n }\n\n */\n\n }\n\n private async hasGeometry(variant: BlockStateVariant): Promise<boolean> {\n const modelKey = AssetKey.parse(\"models\", variant.model!);\n modelKey.root = this.blockState.key?.root;\n return !!(await Models.getMerged(modelKey))?.elements?.length;\n }\n\n protected getSingleVariant(variants: BlockStateVariant | BlockStateVariant[]): BlockStateVariant {\n return BlockStateResolver.choose(variants, this.variantPosition);\n }\n\n // @deprecated\n protected async createAVariant(variants: BlockStateVariant | BlockStateVariant[], instanceInfo: Matrix4[]) {\n const variant = this.getSingleVariant(variants);\n await this.createVariant(variant);\n }\n\n protected async createVariant(variant: BlockStateVariant): Promise<ModelObject | InstanceReference<ModelObject>> {\n const rotation = BlockStateResolver.rotation(variant);\n\n // The model and its textures must come from the same asset root as the blockstate.\n const modelKey = AssetKey.parse(\"models\", variant.model!);\n modelKey.root = this.blockState.key?.root;\n const model = await Models.getMerged(modelKey);\n const options: Partial<ModelObjectOptions> = {\n ...this.options,\n tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints,\n () => BlockTints.getBiomeColor(this.blockState.key, this.options.biome, this.biomePosition)) : this.options.tints,\n uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0)\n ? [rotation.x, rotation.y, rotation.z] : undefined,\n cullMask: this.options.displayPosition ? 0 : ModelCulling.toLocalMask(this._cullMask, rotation)\n };\n const obj = await this.scene.addModel(model!, options);\n if (isInstanceReference(obj) || (<ModelObject>obj).isInstanced) {\n this._isInstanced = true;\n this._instanceCounter = 1;//TODO: BlockObject itself isn't technically instanced, but needs the id for the get/setMatrix calls to work properly\n }\n obj.setRotation(rotation);\n obj.setPosition(this.position);\n return obj;\n }\n\n /** Clears selected properties and rebuilds models without reapplying property defaults. */\n public async resetState() {\n this._previousState = this._state;\n this._state = {};\n await this.recreateModels();\n }\n\n // TODO: support state per instance\n /**\n * Updates properties and rebuilds the selected models.\n * Accepts `\"facing=north,open=true\"`, a property object, or a key and value.\n * Properties omitted from the call keep their current values.\n */\n public async setState(string: string);\n public async setState(state: BlockStateProperties);\n public async setState(key: string, value: string);\n public async setState(stringOrKeyOrState: string | BlockStateProperties, value?: string) {\n this._setState(stringOrKeyOrState, value);\n await this.recreateModels();\n }\n\n protected _setState(stringOrKeyOrState: string | BlockStateProperties, value?: string): void {\n this._previousState = this._state;\n if (typeof value === \"undefined\") { // a=b,c=d,... or state object\n if (typeof stringOrKeyOrState === \"string\") {\n if (stringOrKeyOrState === \"\") return;\n const split = stringOrKeyOrState.split(\",\");\n for (let s of split) {\n let [k, v] = s.split(\"=\");\n this._setState(k, v);\n }\n } else if (typeof stringOrKeyOrState === \"object\") {\n for (let k in stringOrKeyOrState) {\n this._state[k] = stringOrKeyOrState[k];\n }\n }\n } else {\n this._state[stringOrKeyOrState as string] = value;\n }\n }\n\n /*\n public async setStateAt(index: number, string: string);\n public async setStateAt(index: number, state: BlockStateProperties);\n public async setStateAt(index: number, key: string, value: string);\n public async setStateAt(index: number, stringOrKeyOrState: string | BlockStateProperties, value?: string);\n public async setStateAt(index: number, stringOrKeyOrState: string | BlockStateProperties, value?: string) {\n this._setStateAt(index, stringOrKeyOrState, value);\n await this.recreateModels();\n }\n\n protected _setStateAt(index: number, stringOrKeyOrState: string | BlockStateProperties, value?: string): void {\n if (!this._instanceState[index]) this._instanceState[index] = {};\n if (typeof value === \"undefined\") { // a=b,c=d,... or state object\n if (typeof stringOrKeyOrState === \"string\") {\n if (stringOrKeyOrState === \"\") return;\n const split = stringOrKeyOrState.split(\",\");\n for (let s of split) {\n let [k, v] = s.split(\"=\");\n this._setStateAt(index, k, v);\n }\n } else if (typeof stringOrKeyOrState === \"object\") {\n for (let k in stringOrKeyOrState) {\n this._instanceState[index][k] = stringOrKeyOrState[k];\n }\n }\n } else {\n this._instanceState[index][stringOrKeyOrState as string] = value;\n }\n }\n\n _getStateAt(index: number): BlockStateProperties {\n return this._instanceState[index];\n }\n\n */\n\n setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3) {\n super.setPositionRotationScaleAt(index, position, rotation, scale);\n }\n\n getMatrixAt(index: number, matrix: Matrix4 = new Matrix4()): Matrix4 {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n const child = this._models[0];\n if (child && isModelObject(child)) {\n child.getMatrixAt(index, matrix);\n } else if (child && isInstanceReference(child)) {\n child.getMatrix(matrix);\n }\n /*\n const child = this.children[0];\n if (child && isModelObject(child)) {\n if (!child.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n child.getMatrixAt(index, matrix);\n }\n return matrix;\n */\n // return super.getMatrixAt(0, matrix);\n return matrix;\n }\n\n setMatrixAt(index: number, matrix: Matrix4) {\n if (!this.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n // const child = this._models[0];\n for(let child of this._models) {\n if (child && isModelObject(child)) {\n child.setMatrixAt(index, matrix);\n } else if (child && isInstanceReference(child)) {\n child.setMatrix(matrix);\n }\n }\n /*\n for (let child of this.children) {\n if (isModelObject(child)) {\n if (!child.isInstanced) throw new MineRenderError(\"Object is not instanced\");\n child.setMatrixAt(index, matrix);\n }\n }\n */\n }\n\n setPosition(position: Vector3) {\n this.position.copy(position);\n // Each part keeps its own variant rotation when the block moves.\n for (let model of this._models) {\n model.setPosition(position);\n }\n this.placeEntities();\n this.notifyDirty();\n }\n\n //TODO: should override rotation + scale methods\n\n //TODO\n\n}\n\n/** Block settings passed to `scene.addBlock(blockState, options)` or the BlockObject constructor. */\nexport interface BlockObjectOptions extends ModelObjectOptions {\n /** Loads vanilla property defaults before applying `initialState`. Defaults to `true`. */\n applyDefaultState: boolean;\n /** Properties applied before model creation, overriding defaults when applyDefaultState is enabled. */\n initialState?: BlockStateProperties;\n /** Absolute block coordinates for repeatable variants, copied at construction. Omit for random previews. */\n variantPosition?: TripleArray;\n /** Saved biome ID used for automatic grass, foliage, and water colors. */\n biome?: string;\n /** World block coordinates used by biome grass modifiers. Copied at construction; defaults to the origin. */\n biomePosition?: TripleArray;\n}\n\nexport function isBlockObject(obj: any): obj is BlockObject {\n return (<BlockObject>obj).isBlockObject;\n}\n"],"mappings":"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","names":[]}
@@ -21,13 +21,16 @@ var StructureParser = class {
21
21
  const blocks = nbt.blocks.value.value.map((block) => {
22
22
  const state = palette.value.value[block.state.value];
23
23
  if (!state) throw new MineRenderError(`Structure palette index ${block.state.value} does not exist`);
24
- if (["minecraft:air", "minecraft:cave_air", "minecraft:void_air"].includes(state.Name.value)) return void 0;
24
+ const name = (state.Name ?? state.id)?.value;
25
+ if (!name) throw new MineRenderError(`Structure palette entry ${block.state.value} has no block name`);
26
+ if (["minecraft:air", "minecraft:cave_air", "minecraft:void_air"].includes(name)) return void 0;
25
27
  const props = {};
26
- for (let k in state.Properties?.value) {
27
- props[k] = state.Properties.value[k].value;
28
+ const properties = (state.Properties ?? state.properties)?.value;
29
+ for (let k in properties) {
30
+ props[k] = properties[k].value;
28
31
  }
29
32
  return {
30
- type: state.Name.value,
33
+ type: name,
31
34
  properties: props,
32
35
  position: block.pos.value.value,
33
36
  nbt: block.nbt