minerender 2.1.0-beta.5 → 2.1.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/esm/Materials.mjs +6 -3
- package/dist/browser/esm/Materials.mjs.map +1 -1
- package/dist/browser/esm/Ticker.mjs +3 -1
- package/dist/browser/esm/Ticker.mjs.map +1 -1
- package/dist/browser/esm/UVMapper.mjs +9 -9
- package/dist/browser/esm/UVMapper.mjs.map +1 -1
- package/dist/browser/esm/assets/AssetDefaults.mjs +8 -0
- package/dist/browser/esm/assets/AssetDefaults.mjs.map +1 -0
- package/dist/browser/esm/assets/AssetKey.mjs +1 -1
- package/dist/browser/esm/assets/AssetKey.mjs.map +1 -1
- package/dist/browser/esm/assets/AssetLoader.mjs +5 -5
- package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
- package/dist/browser/esm/assets/Assets.mjs +1 -5
- package/dist/browser/esm/assets/Assets.mjs.map +1 -1
- package/dist/browser/esm/assets/BlockEntities.mjs +3 -1
- package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
- package/dist/browser/esm/assets/BlockStates.mjs +1 -1
- package/dist/browser/esm/assets/BlockStates.mjs.map +1 -1
- package/dist/browser/esm/assets/Entities.mjs +1 -1
- package/dist/browser/esm/assets/Entities.mjs.map +1 -1
- package/dist/browser/esm/assets/Fonts.mjs +31 -4
- package/dist/browser/esm/assets/Fonts.mjs.map +1 -1
- package/dist/browser/esm/assets/Models.mjs +1 -1
- package/dist/browser/esm/assets/Models.mjs.map +1 -1
- package/dist/browser/esm/assets/_fonts/Unihex.mjs +168 -0
- package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -0
- package/dist/browser/esm/assets/index.mjs +1 -0
- package/dist/browser/esm/assets/index.mjs.map +1 -1
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs +19 -9
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
- package/dist/browser/esm/assets/source/parser/AssetParsers.mjs +1 -0
- package/dist/browser/esm/assets/source/parser/AssetParsers.mjs.map +1 -1
- package/dist/browser/esm/cache/Caching.mjs +2 -0
- package/dist/browser/esm/cache/Caching.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs +62 -11
- package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityObject.mjs +53 -20
- package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
- package/dist/browser/esm/env/browser/BrowserCache.mjs +3 -3
- package/dist/browser/esm/env/browser/BrowserCache.mjs.map +1 -1
- package/dist/browser/esm/env/browser/section.worker.mjs +5 -3
- package/dist/browser/esm/env/browser/section.worker.mjs.map +1 -1
- package/dist/browser/esm/gui/GuiText.mjs +4 -3
- package/dist/browser/esm/gui/GuiText.mjs.map +1 -1
- package/dist/browser/esm/image/ImageLoader.mjs +3 -3
- package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +115 -20
- package/dist/browser/esm/inspector/SceneInspector.mjs +3 -3
- package/dist/browser/esm/inspector/SceneInspector.mjs.map +1 -1
- package/dist/browser/esm/instance/InstanceManager.mjs +4 -4
- package/dist/browser/esm/instance/InstanceManager.mjs.map +1 -1
- package/dist/browser/esm/model/block/scene/BlockObject.mjs +3 -1
- package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
- package/dist/browser/esm/model/multiblock/StructureParser.mjs +7 -4
- package/dist/browser/esm/model/multiblock/StructureParser.mjs.map +1 -1
- package/dist/browser/esm/model/scene/ModelObject.mjs +8 -4
- package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
- package/dist/browser/esm/nbt/NBTHelper.mjs +5 -2
- package/dist/browser/esm/nbt/NBTHelper.mjs.map +1 -1
- package/dist/browser/esm/renderer/Renderer.mjs +4 -2
- package/dist/browser/esm/renderer/Renderer.mjs.map +1 -1
- package/dist/browser/esm/renderer/SceneObject.mjs +0 -6
- package/dist/browser/esm/renderer/SceneObject.mjs.map +1 -1
- package/dist/browser/esm/request/Requests.mjs +3 -3
- package/dist/browser/esm/request/Requests.mjs.map +1 -1
- package/dist/browser/esm/skin/Skins.mjs +6 -4
- package/dist/browser/esm/skin/Skins.mjs.map +1 -1
- package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
- package/dist/browser/esm/texture/TextureLoader.mjs.map +1 -1
- package/dist/browser/esm/util/log.mjs +75 -0
- package/dist/browser/esm/util/log.mjs.map +1 -1
- package/dist/browser/esm/util/model.mjs +7 -7
- package/dist/browser/esm/util/model.mjs.map +1 -1
- package/dist/browser/esm/util/performance.mjs.map +1 -1
- package/dist/browser/esm/world/Chunk.mjs +8 -5
- package/dist/browser/esm/world/Chunk.mjs.map +1 -1
- package/dist/browser/esm/world/MineRenderWorld.mjs +96 -54
- package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
- package/dist/browser/esm/world/SectionGeometry.mjs +5 -3
- package/dist/browser/esm/world/SectionGeometry.mjs.map +1 -1
- package/dist/browser/esm/world/SectionMesh.mjs +4 -0
- package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
- package/dist/browser/esm/world/SectionModels.mjs +2 -2
- package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
- package/dist/browser/esm/world/WorldStreamer.mjs +21 -20
- package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
- package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
- package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
- package/dist/browser/esm/world/_entities/WorldEntities.mjs +3 -1
- package/dist/browser/esm/world/_entities/WorldEntities.mjs.map +1 -1
- package/dist/browser/index.d.ts +115 -20
- package/dist/browser/index.js +3449 -3025
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +13217 -12745
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +115 -20
- package/dist/node/index.d.ts +115 -20
- package/dist/node/index.js +3477 -3046
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +3456 -3027
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -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 {
|
|
3
|
-
var
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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":[]}
|
|
@@ -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);
|
|
@@ -119,7 +121,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
119
121
|
created.push(await this.scene.addEntity(entity, { wireframe: this.options.wireframe }));
|
|
120
122
|
}
|
|
121
123
|
} catch (error) {
|
|
122
|
-
|
|
124
|
+
log.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
|
|
123
125
|
this.removeEntities(created);
|
|
124
126
|
return false;
|
|
125
127
|
}
|
|
@@ -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 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 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 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":[]}
|
|
@@ -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
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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:
|
|
33
|
+
type: name,
|
|
31
34
|
properties: props,
|
|
32
35
|
position: block.pos.value.value,
|
|
33
36
|
nbt: block.nbt
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/model/multiblock/StructureParser.ts"],"sourcesContent":["import { MultiBlockBlock, MultiBlockStructure } from \"./MultiBlockStructure\";\nimport { TripleArray } from \"../Model\";\nimport type { NBT } from \"prismarine-nbt\";\nimport { MineRenderError } from \"../../error/MineRenderError\";\nimport { BlockStateProperties } from \"../block/BlockStateProperties\";\n\n/** Converts Java structure NBT into blocks and preserved entity data for world placement. */\nexport class StructureParser {\n\n /**\n * Parses decoded NBT, omitting air blocks.\n * @param _nbt - Structure data decoded by {@link NBTHelper.fromBuffer}.\n * @param paletteIndex - Palette to select when the structure has several. Defaults to 0.\n */\n public static async parse(_nbt: NBT, paletteIndex?: number): Promise<MultiBlockStructure> {\n const nbt = _nbt.value as unknown as StructureNBT;\n\n let palette: Palette;\n if (\"palette\" in nbt) {\n palette = nbt.palette!;\n } else if (\"palettes\" in nbt) {\n const selected = nbt.palettes!.value.value[paletteIndex ?? 0];\n if (!selected) throw new MineRenderError(`Structure palette ${paletteIndex ?? 0} does not exist`);\n palette = { type: \"list\", value: selected };\n } else {\n throw new MineRenderError(\"Structure does not have palette(s)\");\n }\n\n const blocks: MultiBlockBlock[] =\n nbt.blocks.value.value.map(block => {\n const state = palette.value.value[block.state.value];\n if (!state) throw new MineRenderError(`Structure palette index ${block.state.value} does not exist`);\n if ([\"minecraft:air\", \"minecraft:cave_air\", \"minecraft:void_air\"].includes(
|
|
1
|
+
{"version":3,"sources":["../../../../../src/model/multiblock/StructureParser.ts"],"sourcesContent":["import { MultiBlockBlock, MultiBlockStructure } from \"./MultiBlockStructure\";\nimport { TripleArray } from \"../Model\";\nimport type { NBT } from \"prismarine-nbt\";\nimport { MineRenderError } from \"../../error/MineRenderError\";\nimport { BlockStateProperties } from \"../block/BlockStateProperties\";\n\n/** Converts Java structure NBT into blocks and preserved entity data for world placement. */\nexport class StructureParser {\n\n /**\n * Parses decoded NBT, omitting air blocks.\n * @param _nbt - Structure data decoded by {@link NBTHelper.fromBuffer}.\n * @param paletteIndex - Palette to select when the structure has several. Defaults to 0.\n */\n public static async parse(_nbt: NBT, paletteIndex?: number): Promise<MultiBlockStructure> {\n const nbt = _nbt.value as unknown as StructureNBT;\n\n let palette: Palette;\n if (\"palette\" in nbt) {\n palette = nbt.palette!;\n } else if (\"palettes\" in nbt) {\n const selected = nbt.palettes!.value.value[paletteIndex ?? 0];\n if (!selected) throw new MineRenderError(`Structure palette ${paletteIndex ?? 0} does not exist`);\n palette = { type: \"list\", value: selected };\n } else {\n throw new MineRenderError(\"Structure does not have palette(s)\");\n }\n\n const blocks: MultiBlockBlock[] =\n nbt.blocks.value.value.map(block => {\n const state = palette.value.value[block.state.value];\n if (!state) throw new MineRenderError(`Structure palette index ${block.state.value} does not exist`);\n const name = (state.Name ?? state.id)?.value;\n if (!name) throw new MineRenderError(`Structure palette entry ${block.state.value} has no block name`);\n if ([\"minecraft:air\", \"minecraft:cave_air\", \"minecraft:void_air\"].includes(name)) return undefined;\n\n const props: BlockStateProperties = {};\n const properties = (state.Properties ?? state.properties)?.value;\n for (let k in properties) {\n props[k] = properties[k].value;\n }\n return <MultiBlockBlock>{\n type: name,\n properties: props,\n position: block.pos.value.value,\n nbt: block.nbt\n }\n }).filter(m => typeof m !== \"undefined\") as MultiBlockBlock[] ;\n return {\n blocks: blocks,\n size: nbt.size.value.value,\n dataVersion: nbt.DataVersion?.value,\n entities: (nbt.entities?.value.value ?? []).map(entity => ({\n position: entity.pos.value.value,\n blockPosition: entity.blockPos.value.value,\n nbt: entity.nbt\n }))\n }\n }\n\n}\n\n/** Tagged NBT fields used by Java structure files. */\nexport interface StructureNBT {\n DataVersion?: {\n type: \"int\";\n value: number;\n }\n size: {\n type: \"list\";\n value: {\n type: \"int\";\n value: TripleArray;\n }\n }\n palette?: Palette;\n palettes?: {\n type: \"list\";\n value: { type: \"list\"; value: Palette[\"value\"][] };\n };\n blocks: {\n type: \"list\";\n value: {\n type: \"compound\";\n value: BlockEntry[];\n }\n }\n entities?: {\n type: \"list\";\n value: {\n type: \"compound\";\n value: {\n pos: { type: \"list\"; value: { type: \"double\"; value: TripleArray } };\n blockPos: { type: \"list\"; value: { type: \"int\"; value: TripleArray } };\n nbt: { type: \"compound\"; value: any };\n }[];\n };\n };\n}\n\ninterface Palette {\n type: \"list\";\n value: {\n type: \"compound\";\n value: PaletteEntry[]\n }\n}\n\n// Since DataVersion 5006 (26.3 snapshot 7), Minecraft saves these as `id` and `properties`; older versions use `Name` and `Properties`.\ninterface PaletteEntry {\n Name?: {\n type: \"string\";\n value: string;\n }\n id?: {\n type: \"string\";\n value: string;\n }\n Properties?: {\n type: \"compound\";\n value: { [property: string]: PalettePropertyValue; };\n }\n properties?: {\n type: \"compound\";\n value: { [property: string]: PalettePropertyValue; };\n }\n}\n\ninterface PalettePropertyValue {\n type: string;\n value: string;\n}\n\ninterface BlockEntry {\n pos: {\n type: \"list\";\n value: {\n type: \"int\";\n value: TripleArray;\n }\n }\n state: {\n type: \"int\";\n value: number;\n }\n nbt: {\n type: \"compound\";\n value: any;\n }\n}\n"],"mappings":";AAGA,SAAS,uBAAuB;AAIzB,IAAM,kBAAN,MAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzB,aAAoB,MAAM,MAAW,cAAqD;AACtF,UAAM,MAAM,KAAK;AAEjB,QAAI;AACJ,QAAI,aAAa,KAAK;AAClB,gBAAU,IAAI;AAAA,IAClB,WAAW,cAAc,KAAK;AAC1B,YAAM,WAAW,IAAI,SAAU,MAAM,MAAM,gBAAgB,CAAC;AAC5D,UAAI,CAAC,SAAU,OAAM,IAAI,gBAAgB,qBAAqB,gBAAgB,CAAC,iBAAiB;AAChG,gBAAU,EAAE,MAAM,QAAQ,OAAO,SAAS;AAAA,IAC9C,OAAO;AACH,YAAM,IAAI,gBAAgB,oCAAoC;AAAA,IAClE;AAEA,UAAM,SACF,IAAI,OAAO,MAAM,MAAM,IAAI,WAAS;AAChC,YAAM,QAAQ,QAAQ,MAAM,MAAM,MAAM,MAAM,KAAK;AACnD,UAAI,CAAC,MAAO,OAAM,IAAI,gBAAgB,2BAA2B,MAAM,MAAM,KAAK,iBAAiB;AACnG,YAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK;AACvC,UAAI,CAAC,KAAM,OAAM,IAAI,gBAAgB,2BAA2B,MAAM,MAAM,KAAK,oBAAoB;AACrG,UAAI,CAAC,iBAAiB,sBAAsB,oBAAoB,EAAE,SAAS,IAAI,EAAG,QAAO;AAEzF,YAAM,QAA8B,CAAC;AACrC,YAAM,cAAc,MAAM,cAAc,MAAM,aAAa;AAC3D,eAAS,KAAK,YAAY;AACtB,cAAM,CAAC,IAAI,WAAW,CAAC,EAAE;AAAA,MAC7B;AACA,aAAwB;AAAA,QACpB,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,UAAU,MAAM,IAAI,MAAM;AAAA,QAC1B,KAAK,MAAM;AAAA,MACf;AAAA,IACJ,CAAC,EAAE,OAAO,OAAK,OAAO,MAAM,WAAW;AAC3C,WAAO;AAAA,MACH;AAAA,MACA,MAAM,IAAI,KAAK,MAAM;AAAA,MACrB,aAAa,IAAI,aAAa;AAAA,MAC9B,WAAW,IAAI,UAAU,MAAM,SAAS,CAAC,GAAG,IAAI,aAAW;AAAA,QACvD,UAAU,OAAO,IAAI,MAAM;AAAA,QAC3B,eAAe,OAAO,SAAS,MAAM;AAAA,QACrC,KAAK,OAAO;AAAA,MAChB,EAAE;AAAA,IACN;AAAA,EACJ;AAEJ;","names":[]}
|
|
@@ -6,7 +6,7 @@ import { BoxGeometry, BufferAttribute, Color, DoubleSide, Euler, FrontSide, Matr
|
|
|
6
6
|
import { mergeBufferGeometries } from "../../three/BufferGeometryUtils.mjs";
|
|
7
7
|
import { addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation } from "../../util/model.mjs";
|
|
8
8
|
import { merge } from "../../util/_internal/merge.mjs";
|
|
9
|
-
import {
|
|
9
|
+
import { logger } from "../../util/log.mjs";
|
|
10
10
|
import { CUBE_FACES } from "../../CubeFace.mjs";
|
|
11
11
|
import { DisplayPosition } from "../DisplayPosition.mjs";
|
|
12
12
|
import { DisplayTransforms } from "../DisplayTransforms.mjs";
|
|
@@ -16,7 +16,7 @@ import { EntityObject } from "../../entity/scene/EntityObject.mjs";
|
|
|
16
16
|
import { GuiLight } from "../GuiLight.mjs";
|
|
17
17
|
import { ItemTints } from "../ItemTints.mjs";
|
|
18
18
|
import { ItemGlint } from "../ItemGlint.mjs";
|
|
19
|
-
var
|
|
19
|
+
var log = logger("ModelObject");
|
|
20
20
|
var _ModelObject = class _ModelObject extends SceneObject {
|
|
21
21
|
constructor(originalModel, options) {
|
|
22
22
|
super(options);
|
|
@@ -149,6 +149,10 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
149
149
|
this.atlas.model.elements?.forEach((el) => {
|
|
150
150
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
151
151
|
this.geometries.add(elGeo);
|
|
152
|
+
elGeo.setAttribute("shade", new BufferAttribute(
|
|
153
|
+
new Float32Array(elGeo.getAttribute("position").count).fill(!this.originalModel.itemId && el.shade === false ? 0 : 1),
|
|
154
|
+
1
|
|
155
|
+
));
|
|
152
156
|
if (this.options.cullMask) {
|
|
153
157
|
const indices = Array.from(elGeo.getIndex().array);
|
|
154
158
|
elGeo.setIndex(indices.filter((_, index) => {
|
|
@@ -194,10 +198,10 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
194
198
|
}
|
|
195
199
|
});
|
|
196
200
|
} else {
|
|
197
|
-
|
|
201
|
+
log.debug(this.atlas.model, "has no elements");
|
|
198
202
|
}
|
|
199
203
|
} else {
|
|
200
|
-
|
|
204
|
+
log.debug("Missing atlas for", this);
|
|
201
205
|
}
|
|
202
206
|
if (this.options.mergeMeshes) {
|
|
203
207
|
let combinedGeo;
|