import { BlockDefinition, BlockModel, Identifier, Structure, StructureRenderer } from 'deepslate/render' import type { mat4 } from 'gl-matrix' import { useCallback, useRef } from 'preact/hooks' import { useVersion } from '../../contexts/index.js' import { useAsync } from '../../hooks/useAsync.js' import { AsyncCancel } from '../../hooks/useAsyncFn.js' import { getResources, ResourceWrapper } from '../../services/Resources.js' import { safeJsonParse } from '../../Utils.js' import type { PreviewProps } from './index.js' import { InteractiveCanvas3D } from './InteractiveCanvas3D.jsx' const PREVIEW_ID = Identifier.parse('misode:preview') const PREVIEW_DEFINITION = new BlockDefinition({ '': { model: PREVIEW_ID.toString() }}, undefined) export const ModelPreview = ({ docAndNode, shown }: PreviewProps) => { const { version } = useVersion() const text = docAndNode.doc.getText() const { value: resources } = useAsync(async () => { if (!shown) return AsyncCancel const resources = await getResources(version, new Map()) const blockModel = BlockModel.fromJson(safeJsonParse(text) ?? {}) blockModel.flatten(resources) const wrapper = new ResourceWrapper(resources, { getBlockDefinition(id) { if (id.equals(PREVIEW_ID)) return PREVIEW_DEFINITION return null }, getBlockModel(id) { if (id.equals(PREVIEW_ID)) return blockModel return null }, }) return wrapper }, [shown, version, text]) const renderer = useRef(undefined) const onSetup = useCallback((canvas: HTMLCanvasElement) => { if (!resources || !shown) return const gl = canvas.getContext('webgl') if (!gl) return renderer.current = new StructureRenderer(gl, new Structure([1, 1, 1]).addBlock([0, 0, 0], PREVIEW_ID), resources) }, [resources, shown]) const onResize = useCallback((width: number, height: number) => { renderer.current?.setViewport(0, 0, width, height) }, [resources]) const onDraw = useCallback((transform: mat4) => { renderer.current?.drawStructure(transform) }, []) return <>
}