Skip to content

Commit

Permalink
fix(useGLTF): useGLTF dry-types (#2116)
Browse files Browse the repository at this point in the history
* drying types

* UseMeshopt

---------

Co-authored-by: Cody Bennett <hi@codyb.co>
  • Loading branch information
abernier and CodyJasonBennett authored Oct 7, 2024
1 parent 838764f commit f51395f
Showing 1 changed file with 24 additions and 31 deletions.
55 changes: 24 additions & 31 deletions src/core/Gltf.tsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,60 @@
import * as React from 'react'

import { GLTFLoader, DRACOLoader, MeshoptDecoder, GLTF } from 'three-stdlib'
import { ObjectMap, useLoader } from '@react-three/fiber'
import { Clone } from './Clone'
import { type Loader } from 'three'
import { type GLTF, GLTFLoader, DRACOLoader, MeshoptDecoder } from 'three-stdlib'
import { type ObjectMap, useLoader } from '@react-three/fiber'

let dracoLoader: DRACOLoader | null = null

let decoderPath: string = 'https://www.gstatic.com/draco/versioned/decoders/1.5.5/'

function extensions(useDraco: boolean | string, useMeshopt: boolean, extendLoader?: (loader: GLTFLoader) => void) {
return (loader: Loader) => {
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 as GLTFLoader)
extendLoader(loader)
}
if (useDraco) {
if (!dracoLoader) {
dracoLoader = new DRACOLoader()
}
dracoLoader.setDecoderPath(typeof useDraco === 'string' ? useDraco : decoderPath)
;(loader as GLTFLoader).setDRACOLoader(dracoLoader)
loader.setDRACOLoader(dracoLoader)
}
if (useMeshopt) {
;(loader as GLTFLoader).setMeshoptDecoder(
typeof MeshoptDecoder === 'function' ? MeshoptDecoder() : MeshoptDecoder
)
loader.setMeshoptDecoder(typeof MeshoptDecoder === 'function' ? MeshoptDecoder() : MeshoptDecoder)
}
}
}

export function useGLTF<T extends string | string[]>(
export const useGLTF = <T extends Path>(
path: T,
useDraco: boolean | string = true,
useMeshOpt: boolean = true,
extendLoader?: (loader: GLTFLoader) => void
): T extends any[] ? (GLTF & ObjectMap)[] : GLTF & ObjectMap {
return useLoader(GLTFLoader, path, extensions(useDraco, useMeshOpt, extendLoader))
}
useDraco?: UseDraco,
useMeshopt?: UseMeshopt,
extendLoader?: ExtendLoader
): T extends any[] ? (GLTF & ObjectMap)[] : GLTF & ObjectMap =>
useLoader(GLTFLoader, path, extensions(useDraco, useMeshopt, extendLoader))

useGLTF.preload = (
path: string | string[],
useDraco: boolean | string = true,
useMeshOpt: boolean = true,
extendLoader?: (loader: GLTFLoader) => void
) => useLoader.preload(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 = (input: string | string[]) => useLoader.clear(GLTFLoader, input)
useGLTF.clear = (path: Path) => useLoader.clear(GLTFLoader, path)
useGLTF.setDecoderPath = (path: string) => {
decoderPath = path
}

//

type UseGLTF = Parameters<typeof useGLTF>
type CloneProps = React.ComponentProps<typeof Clone>

type GltfRef = React.ElementRef<typeof Clone>

type GltfProps = Omit<CloneProps, 'object'> & {
src: string // simple string, not a string[] as useGLTF supports (otherwise we should render multiple <Clone>s?)
useDraco?: UseGLTF[1]
useMeshOpt?: UseGLTF[2]
extendLoader?: UseGLTF[3]
useDraco?: UseDraco
useMeshOpt?: UseMeshopt
extendLoader?: ExtendLoader
}
export const Gltf = /* @__PURE__ */ React.forwardRef<GltfRef, GltfProps>(
({ src, useDraco, useMeshOpt, extendLoader, ...props }, ref) => {
Expand Down

0 comments on commit f51395f

Please sign in to comment.