Squished and demormed GLB model in the scene

Sometimes this strange thing happens when I try to load my GLB model into the scene.

import { useLoader} from "@react-three/fiber";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
const Model= () => {
    const {nodes, scene} = useLoader(GLTFLoader, "/myVeryNormalHuman.glb");
  return (
    <>
    <group ref={group}>
        <primitive object={nodes.mesh} position={[4, 0, 0]} scale={[6, 6, 6]} />
    </group>
</>
  )
}

The model looks good in other GLB viewers. TI noticed this squish, deformation on my models from time to time… was curious if someone else also faced this problem.

this is most likely a skinned mesh. skinning puts all mesh positions into the armature and bones. fishing out one single mesh or group, without the armature, and displaying it will look like that because positions will be at 0/0/0.

this will solve your problem:

 <primitive object={scene} ... />

and if you must access individual nodes declaratively you should use gltfjsx GitHub - pmndrs/gltfjsx: 🎮 Turns GLTFs into JSX components

ps, there’s no need for gltfloader, the drei abstraction takes care of everything, even draco and meshopt so you don’t need to worry about binaries in your public folder.

import { useGLTF } from "@react-three/drei"

function Model(props) {
  const { scene } = useGLTF("/myVeryNormalHuman.glb")
  return <primitive object={scene} {...props} />
}

<Model position={[4, 0, 0]} scale={6} />

Thanks, yes I also faced the draco decompressing error and noticed that useGLTF has that built in already.

Can I generate gltfjsx on the flow? Since I load different GLB files dynamically (user upload them)… OK maybe it works when the structure of all GLB files are the same (node names).

Yes it is indeed a skinnedmesh, I saw also the <skinnedmesh/> component, what exactly does that do? I couldn’t understand it, since I could get the model and bones also just with <primitive object={scene} /> and even modify (rotate…) the individual bones and the mesh deforms correctly I wanted… so why is needed?

gltfjsx is for models that you know compile time, you can only declare what you know. if you don’t know a dynamic object you can’t lay it out declaratively. like you said, it only makes sense if the node graph is exactly the same between models.

<skinnedMesh> exists but it it useless in your case because there is more to it, you need the armature and the bones and then connect them. skinnedmesh alone has no data. you need to delve into threejs docs to understand skinning, all in all react doesn’t change how it works, everything is according to threejs convention. in your case you need to use <primitive object={scene}>, that ensures that you have bones, armature, skinned mesh and all these things are connected.

the downside is that you can’t re-use that model because in threejs one mesh can’t be in two places. you also can’t clone skinned meshes ootb in threejs, scene.clone() will not work. but there’s a drei helper:

import { Clone } from '@react-three/drei'
...
const { scene } = useGLTF(url)
return <Clone object={scene} {...props} />

and now you can reuse it. it detects skinned meshes and runs three/examples/jsm/…/SkeletonUtils.clone on it.