I have a set of gltf file (links) in a list. This list might change, so I store them in a state (but to keep the example simple, we can assume that it is an array of string, which won’t change, and we can assume there will be at least 1 item in the array everytime).
I want a “showroom”, where I can display a gltf object, and when pressing a dedicated button, which displays the next object (and when iterated over, starts again with the first). My problem is, the object simply does not render after after click to the ‘next model’ button.
The way I tried:
import { Suspense, useRef, useState } from "react";
import { Canvas } from '@react-three/fiber'
import { useGLTF, Environment, CameraControls, } from '@react-three/drei'
import { Html, useProgress } from '@react-three/drei'
function Loader() {
const { progress } = useProgress()
return <Html center>{progress} % loaded</Html>
}
export default function PageShowroom() {
const cameraControlRef = useRef<CameraControls | null>(null);
/// we can assume that the list always contains at least 1 url, all urls are valid and stored in the public folder, and for the example, the list is hardcoded and won't change
const [modelUrls, setModelUrls] = useState<string[]>(['/arretratori.gltf', '/assembly1.gltf'])
const [activeModelIndex, setActiveModelIndex] = useState<number>(0)
return (
<div>
<div>
<button onClick={()=> {
setActiveModelIndex(
(activeModelIndex + 1) % modelUrls.length
)
cameraControlRef.current?.reset(false)
}}>
next model
</button>
</div>
<Canvas style={{height: 600}}>
<CameraControls ref={cameraControlRef}/>
<Suspense fallback={<Loader />}>
{
<Model path={modelUrls[activeModelIndex]}/>
}
</Suspense>
<Environment preset="city"/>
</Canvas>
</div>
)
}
function Model(props: {path: string}) {
const gltf = useGLTF(props.path)
return (<primitive object={gltf.scene} />)
}
Some notes:
- I experimented, the load does not fail with any error or gets stucked, since the
Loader
wrapper does not stays on the screen. - The models do render when I try to render them alone.
- The gltfs I’m using are relatively simple and in my opinion they can be replaced by any model for reproduction. Anyways, I can provide them if needed.