import { useGLTF } from '@react-three/drei'; import { GroupProps } from '@react-three/fiber'; import debug from 'debug'; import { forwardRef, useEffect, useRef } from 'react'; import { BufferGeometry, Group, Material, Mesh, MeshStandardMaterial, Texture, Vector2, } from 'three'; import { image2, image3 } from './test-image'; const log = debug('three:macintosh'); export type UseGLTF = ReturnType & { nodes: Record; materials: Record; }; export interface MacintoshProps extends GroupProps {} export type RefType = Group; const base64ToSrc = (data: string) => `data:image/png;base64,${data}`; const Macintosh = forwardRef((props, ref) => { const { nodes, materials } = useGLTF( '/models/macintosh-classic--computer.glb', ) as UseGLTF; const screenImageRef = useRef(new Image()); const screenRef = useRef(null!); const screenTextureRef = useRef(new Texture(screenImageRef.current)); // TODO: come up with good looking materials for everything // eslint-disable-next-line @typescript-eslint/no-unused-vars const casePlastic: MeshStandardMaterial = Object.assign( materials['case-plastic'], { roughness: 100 }, ); const bodyRef = useRef>(null!); useEffect(() => { const texture = screenTextureRef.current; const image = screenImageRef.current; texture.center = new Vector2(1, 1); texture.flipY = false; texture.offset.y = 0.0155; texture.offset.x = 0.01; texture.repeat.set(1.02, 1.39); image.src = base64ToSrc(image2); image.onload = () => { texture.needsUpdate = true; }; }, []); return ( { log(`x: ${uv?.x ?? '?'}, y: ${uv?.y ?? '?'}`); screenImageRef.current.src = base64ToSrc(image3); }} position={[-1.05, 22.73, 12.08]} > ); }); useGLTF.preload('/models/macintosh-classic--computer.glb'); export { Macintosh };