import * as React from 'react' import { GLTFLoader, DRACOLoader, MeshoptDecoder, GLTF } from 'three-stdlib' import { ObjectMap, useLoader } from '@react-three/fiber' import { Clone } from './Clone' let dracoLoader: DRACOLoader | null = null let decoderPath: string = 'https://www.gstatic.com/draco/versioned/decoders/1.5.5/' type Path = string | string[] type UseDraco = boolean | string type UseMeshopt = boolean type ExtendLoader = (loader: GLTFLoader) => void function extensions(useDraco: UseDraco = true, useMeshopt: UseMeshopt = true, extendLoader?: ExtendLoader) { return (loader: GLTFLoader) => { if (extendLoader) { extendLoader(loader) } if (useDraco) { if (!dracoLoader) { dracoLoader = new DRACOLoader() } dracoLoader.setDecoderPath(typeof useDraco === 'string' ? useDraco : decoderPath) loader.setDRACOLoader(dracoLoader) } if (useMeshopt) { loader.setMeshoptDecoder(typeof MeshoptDecoder === 'function' ? MeshoptDecoder() : MeshoptDecoder) } } } export const useGLTF = ( path: T, useDraco?: UseDraco, useMeshopt?: UseMeshopt, extendLoader?: ExtendLoader ): T extends any[] ? (GLTF & ObjectMap)[] : GLTF & ObjectMap => useLoader(GLTFLoader, path, extensions(useDraco, useMeshopt, extendLoader)) useGLTF.preload = (path: Path, useDraco?: UseDraco, useMeshopt?: UseMeshopt, extendLoader?: ExtendLoader) => useLoader.preload(GLTFLoader, path, extensions(useDraco, useMeshopt, extendLoader)) useGLTF.clear = (path: Path) => useLoader.clear(GLTFLoader, path) useGLTF.setDecoderPath = (path: string) => { decoderPath = path } // type CloneProps = React.ComponentProps type GltfRef = React.ElementRef type GltfProps = Omit & { src: string // simple string, not a string[] as useGLTF supports (otherwise we should render multiple s?) useDraco?: UseDraco useMeshOpt?: UseMeshopt extendLoader?: ExtendLoader } export const Gltf = /* @__PURE__ */ React.forwardRef( ({ src, useDraco, useMeshOpt, extendLoader, ...props }, ref) => { const { scene } = useGLTF(src, useDraco, useMeshOpt, extendLoader) return } )