loading asset handler

This commit is contained in:
wass08
2026-02-10 13:40:49 +09:00
parent 8ded112da3
commit 01de83f628
2 changed files with 26 additions and 2 deletions
@@ -3,9 +3,10 @@ import { Clone } from '@react-three/drei/core/Clone'
import { useGLTF } from '@react-three/drei/core/Gltf' import { useGLTF } from '@react-three/drei/core/Gltf'
import { Suspense, useEffect, useMemo, useRef } from 'react' import { Suspense, useEffect, useMemo, useRef } from 'react'
import type { Group, Material, Mesh } from 'three' import type { Group, Material, Mesh } from 'three'
import { positionLocal, smoothstep, time } from 'three/tsl'
import { DoubleSide, MeshStandardNodeMaterial } from 'three/webgpu' import { DoubleSide, MeshStandardNodeMaterial } from 'three/webgpu'
import { resolveCdnUrl } from '../../../lib/asset-url'
import { useNodeEvents } from '../../../hooks/use-node-events' import { useNodeEvents } from '../../../hooks/use-node-events'
import { resolveCdnUrl } from '../../../lib/asset-url'
// Shared materials to avoid creating new instances for every mesh // Shared materials to avoid creating new instances for every mesh
const defaultMaterial = new MeshStandardNodeMaterial({ const defaultMaterial = new MeshStandardNodeMaterial({
@@ -39,13 +40,35 @@ export const ItemRenderer = ({ node }: { node: ItemNode }) => {
return ( return (
<group position={node.position} rotation={node.rotation} ref={ref} visible={node.visible}> <group position={node.position} rotation={node.rotation} ref={ref} visible={node.visible}>
<Suspense> <Suspense fallback={<PreviewModel node={node} />}>
<ModelRenderer node={node} /> <ModelRenderer node={node} />
</Suspense> </Suspense>
</group> </group>
) )
} }
const previewMaterial = new MeshStandardNodeMaterial({
color: '#cccccc',
roughness: 1,
metalness: 0,
depthTest: false,
})
const previewOpacity = smoothstep(0.42, 0.55, positionLocal.y.add(time.mul(-0.2)).mul(10).fract())
previewMaterial.opacityNode = previewOpacity
previewMaterial.transparent = true
const PreviewModel = ({ node }: { node: ItemNode }) => {
return (
<mesh position-y={node.asset.dimensions[1] / 2} material={previewMaterial}>
<boxGeometry
args={[node.asset.dimensions[0], node.asset.dimensions[1], node.asset.dimensions[2]]}
/>
</mesh>
)
}
const ModelRenderer = ({ node }: { node: ItemNode }) => { const ModelRenderer = ({ node }: { node: ItemNode }) => {
const { scene, nodes } = useGLTF(resolveCdnUrl(node.asset.src) || '') const { scene, nodes } = useGLTF(resolveCdnUrl(node.asset.src) || '')
@@ -121,6 +121,7 @@ export const SiteRenderer = ({ node }: { node: SiteNode }) => {
position={[edge.midX, 0.5, edge.midZ]} position={[edge.midX, 0.5, edge.midZ]}
style={{ pointerEvents: 'none', userSelect: 'none' }} style={{ pointerEvents: 'none', userSelect: 'none' }}
zIndexRange={[10, 0]} zIndexRange={[10, 0]}
occlude
> >
<div className="whitespace-nowrap rounded bg-black/75 px-1.5 py-0.5 font-mono text-white text-xs backdrop-blur-sm"> <div className="whitespace-nowrap rounded bg-black/75 px-1.5 py-0.5 font-mono text-white text-xs backdrop-blur-sm">
{edge.dist.toFixed(2)}m {edge.dist.toFixed(2)}m