mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-24 07:37:10 +00:00
Add blockstate and model previews
This commit is contained in:
@@ -4,10 +4,9 @@ import { useState } from 'preact/hooks'
|
||||
import { useModel } from '../../hooks/index.js'
|
||||
import type { VersionId } from '../../services/index.js'
|
||||
import { checkVersion } from '../../services/index.js'
|
||||
import { BiomeSourcePreview, DecoratorPreview, DensityFunctionPreview, NoisePreview, NoiseSettingsPreview } from '../previews/index.js'
|
||||
import { LootTablePreview } from '../previews/LootTablePreview.jsx'
|
||||
import { BiomeSourcePreview, BlockStatePreview, DecoratorPreview, DensityFunctionPreview, LootTablePreview, ModelPreview, NoisePreview, NoiseSettingsPreview } from '../previews/index.js'
|
||||
|
||||
export const HasPreview = ['loot_table', 'dimension', 'worldgen/density_function', 'worldgen/noise', 'worldgen/noise_settings', 'worldgen/configured_feature', 'worldgen/placed_feature']
|
||||
export const HasPreview = ['loot_table', 'dimension', 'worldgen/density_function', 'worldgen/noise', 'worldgen/noise_settings', 'worldgen/configured_feature', 'worldgen/placed_feature', 'block_definition', 'model']
|
||||
|
||||
type PreviewPanelProps = {
|
||||
model: DataModel | undefined,
|
||||
@@ -51,5 +50,13 @@ export function PreviewPanel({ model, version, id, shown }: PreviewPanelProps) {
|
||||
return <DecoratorPreview {...{ model, version, shown, data }} />
|
||||
}
|
||||
|
||||
if (id === 'block_definition') {
|
||||
return <BlockStatePreview {...{ model, version, shown, data }} />
|
||||
}
|
||||
|
||||
if (id === 'model') {
|
||||
return <ModelPreview {...{ model, version, shown, data }} />
|
||||
}
|
||||
|
||||
return <></>
|
||||
}
|
||||
|
||||
51
src/app/components/previews/BlockStatePreview.tsx
Normal file
51
src/app/components/previews/BlockStatePreview.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { DataModel } from '@mcschema/core'
|
||||
import { BlockDefinition, 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 type { PreviewProps } from './index.js'
|
||||
import { InteractiveCanvas3D } from './InteractiveCanvas3D.jsx'
|
||||
|
||||
const PREVIEW_ID = Identifier.parse('misode:preview')
|
||||
|
||||
export const BlockStatePreview = ({ data, shown }: PreviewProps) => {
|
||||
const { version } = useVersion()
|
||||
const serializedData = JSON.stringify(data)
|
||||
|
||||
const { value: resources } = useAsync(async () => {
|
||||
if (!shown) return AsyncCancel
|
||||
const resources = await getResources(version)
|
||||
const definition = BlockDefinition.fromJson(PREVIEW_ID.toString(), DataModel.unwrapLists(data))
|
||||
const wrapper = new ResourceWrapper(resources, {
|
||||
getBlockDefinition(id) {
|
||||
if (id.equals(PREVIEW_ID)) return definition
|
||||
return null
|
||||
},
|
||||
})
|
||||
return wrapper
|
||||
}, [shown, version, serializedData])
|
||||
|
||||
const renderer = useRef<StructureRenderer | undefined>(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 <>
|
||||
<div class="full-preview">
|
||||
<InteractiveCanvas3D onSetup={onSetup} onDraw={onDraw} onResize={onResize} startDistance={3} startPosition={[0.5, 0, 0.5]} startYRotation={2.5} />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
@@ -100,7 +100,6 @@ export function InteractiveCanvas3D({ onSetup, onDraw, onResize, state, startPos
|
||||
redraw.current()
|
||||
}
|
||||
|
||||
console.warn('Uhhh...', canvas.current)
|
||||
onSetup(canvas.current)
|
||||
resizeHandler()
|
||||
|
||||
|
||||
57
src/app/components/previews/ModelPreview.tsx
Normal file
57
src/app/components/previews/ModelPreview.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import { DataModel } from '@mcschema/core'
|
||||
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 type { PreviewProps } from './index.js'
|
||||
import { InteractiveCanvas3D } from './InteractiveCanvas3D.jsx'
|
||||
|
||||
const PREVIEW_ID = Identifier.parse('misode:preview')
|
||||
const PREVIEW_DEFINITION = new BlockDefinition(PREVIEW_ID, { '': { model: PREVIEW_ID.toString() }}, undefined)
|
||||
|
||||
export const ModelPreview = ({ data, shown }: PreviewProps) => {
|
||||
const { version } = useVersion()
|
||||
const serializedData = JSON.stringify(data)
|
||||
|
||||
const { value: resources } = useAsync(async () => {
|
||||
if (!shown) return AsyncCancel
|
||||
const resources = await getResources(version)
|
||||
const model = BlockModel.fromJson(PREVIEW_ID.toString(), DataModel.unwrapLists(data))
|
||||
model.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 model
|
||||
return null
|
||||
},
|
||||
})
|
||||
return wrapper
|
||||
}, [shown, version, serializedData])
|
||||
|
||||
const renderer = useRef<StructureRenderer | undefined>(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 <>
|
||||
<div class="full-preview">
|
||||
<InteractiveCanvas3D onSetup={onSetup} onDraw={onDraw} onResize={onResize} startDistance={3} startPosition={[0.5, 0, 0.5]} startYRotation={2.6} />
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
@@ -2,8 +2,11 @@ import type { DataModel } from '@mcschema/core'
|
||||
import type { VersionId } from '../../services/index.js'
|
||||
|
||||
export * from './BiomeSourcePreview.js'
|
||||
export * from './BlockStatePreview.jsx'
|
||||
export * from './DecoratorPreview.js'
|
||||
export * from './DensityFunctionPreview.js'
|
||||
export * from './LootTablePreview.jsx'
|
||||
export * from './ModelPreview.jsx'
|
||||
export * from './NoisePreview.js'
|
||||
export * from './NoiseSettingsPreview.js'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user