Blender animation keyframes not included in JSX file

Hello!

I am working on learning react-three/fiber, and am trying to create a JSX component from a gltf Blender file.

First, I enter this command in the terminal to convert the file to gltf:

gltf-pipeline -i Monkey.glb -o Monkey.gltf

After that I enter this command to convert it to a JSX file:

npx gltfjsx public/models/Monkey.gltf

However, the animations still don’t appear as part of the JSX file as I’ve seen on some tutorials:

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx gltfjsx@6.2.12 public/models/Monkey.gltf 
*/

import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'

export function Model(props) {
  const { nodes, materials } = useGLTF('/Monkey.gltf')
  return (
    <group {...props} dispose={null}>
      <group position={[0, 2.829, 0]} scale={1.288}>
        <primitive object={nodes.spine0} />
        <primitive object={nodes.legIK} />
        <primitive object={nodes.legIKRight} />
        <primitive object={nodes.legIKLeft} />
        <skinnedMesh geometry={nodes.Cube_1.geometry} material={materials.Material} skeleton={nodes.Cube_1.skeleton} />
        <skinnedMesh geometry={nodes.Cube_2.geometry} material={materials['Material.003']} skeleton={nodes.Cube_2.skeleton} />
        <skinnedMesh geometry={nodes.Cube002_1.geometry} material={materials.Material} skeleton={nodes.Cube002_1.skeleton} />
        <skinnedMesh geometry={nodes.Cube002_2.geometry} material={materials['Material.003']} skeleton={nodes.Cube002_2.skeleton} />
        <skinnedMesh geometry={nodes.Cube005_1.geometry} material={materials.Material} skeleton={nodes.Cube005_1.skeleton} />
        <skinnedMesh geometry={nodes.Cube005_2.geometry} material={materials['Material.003']} skeleton={nodes.Cube005_2.skeleton} />
        <skinnedMesh geometry={nodes.Cube006.geometry} material={materials.Material} skeleton={nodes.Cube006.skeleton} />
        <skinnedMesh geometry={nodes.Cube006_1.geometry} material={materials['Material.003']} skeleton={nodes.Cube006_1.skeleton} />
      </group>
    </group>
  )
}

My options in Blender for exporting the file show this:

If you have any suggestions on what is preventing the animations from automatically showing up as a part of the JSX code upon execution of the gltfjsx command, please let me know!

Thank you!

imo you should never use gltf on the web, you dont need gltf-pipeline. just this

npx gltfjsx yourfile.gltf --transform

and it will create a compressed glb. as to why keyframes aren’t in it, that must have something to do with blender. animations never show up in jsx btw, all it will do is add a useAnimations hook.

1 Like

Hi, drcmda!

Out of curiosity, what are the downsides to using gltf files on the web?

In that case, I will look around to find out how to useAnimations hook.

Thank you for letting me know!

So I converted the glb file exported from Blender directly to a jsx file using the command you provided, and the useAnimation hook was mentioned right there in the file!

/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx gltfjsx@6.2.12 Monkey.glb --transform 
Files: Monkey.glb [225.68KB] > Monkey-transformed.glb [96.22KB] (57%)
*/

import React, { useRef } from 'react'
import { useGLTF, useAnimations } from '@react-three/drei'

export function Monkey(props) {
  const group = useRef()
  const { nodes, materials, animations } = useGLTF('/Monkey-transformed.glb')
  const { actions } = useAnimations(animations, group)
  return (
    <group ref={group} {...props} dispose={null}>
      <group name="Scene">
        <group name="Armature" position={[0, 2.829, 0]} scale={1.288}>
          <primitive object={nodes.spine0} />
          <primitive object={nodes.legIK} />
          <primitive object={nodes.legIKRight} />
          <primitive object={nodes.legIKLeft} />
        </group>
        <group name="Cube" position={[0, 2.829, 0]} scale={1.288}>
          <skinnedMesh name="Cube_1" geometry={nodes.Cube_1.geometry} material={materials.PaletteMaterial001} skeleton={nodes.Cube_1.skeleton} />
          <skinnedMesh name="Cube_2" geometry={nodes.Cube_2.geometry} material={materials.PaletteMaterial002} skeleton={nodes.Cube_2.skeleton} />
        </group>
        <group name="Cube002" position={[0, 2.829, 0]} scale={1.288}>
          <skinnedMesh name="Cube002_1" geometry={nodes.Cube002_1.geometry} material={materials.PaletteMaterial001} skeleton={nodes.Cube002_1.skeleton} />
          <skinnedMesh name="Cube002_2" geometry={nodes.Cube002_2.geometry} material={materials.PaletteMaterial002} skeleton={nodes.Cube002_2.skeleton} />
        </group>
        <group name="Cube004" position={[0, 2.829, 0]} scale={1.288}>
          <skinnedMesh name="Cube005_1" geometry={nodes.Cube005_1.geometry} material={materials.PaletteMaterial001} skeleton={nodes.Cube005_1.skeleton} />
          <skinnedMesh name="Cube005_2" geometry={nodes.Cube005_2.geometry} material={materials.PaletteMaterial002} skeleton={nodes.Cube005_2.skeleton} />
        </group>
        <group name="Cube005" position={[0, 2.829, 0]} scale={1.288}>
          <skinnedMesh name="Cube006" geometry={nodes.Cube006.geometry} material={materials.PaletteMaterial001} skeleton={nodes.Cube006.skeleton} />
          <skinnedMesh name="Cube006_1" geometry={nodes.Cube006_1.geometry} material={materials.PaletteMaterial002} skeleton={nodes.Cube006_1.skeleton} />
        </group>
      </group>
    </group>
  )
}

useGLTF.preload('/Monkey-transformed.glb')

Thank you!

gltf is big and refers to external files. glb is small and everything is contained in a single file.

1 Like

right, so all you have to do now is

export function Monkey(props) {
  const group = useRef()
  const { nodes, materials, animations } = useGLTF('/Monkey-transformed.glb')
  const { actions } = useAnimations(animations, group)
  useEffect(() => {
    actions.actionName.play()
  }, [])
  return (
    <group ref={group} {...props} dispose={null}>
      ..

gltfjsx should have also compressed the model, /Monkey-transformed.glb should be considerably smaller.

1 Like

Minor thing – there shouldn’t be a size difference unless you’re using the “glTF Embedded” mode (e.g. in Blender) that tries to pack all the data into a single .gltf file with Base64 strings… but I agree with @drcmda.glb is usually a better choice, unless you’re working with more advanced situations like sharing textures across multiple glTF files.

1 Like

So if it was a more advanced project, it would be better to choose the gltf Separate?

No, I guess I mean that there are certain less common cases where you might want glTF Separate. If you don’t already know you have one of those rare cases, best to stick with GLB as the default.

1 Like