Giter Site home page Giter Site logo

gltfjsx's Introduction

GLTFSJSX

Version Discord Shield

Turns GLTF assets into dynamic, re-usable react-three-fiber JSX components. See it in action here: https://twitter.com/0xca0a/status/1224335000755146753

The usual GLTF workflow is cumbersome: objects can only be found by traversal, changes are made by mutation, making contents conditional is hard.

With gltfjsx the full graph is declarative and immutable. It creates look-up tables of all the objects and materials inside your asset, it will not touch or modify your files in any way.

Usage

Usage
  npx @react-three/gltfjsx [Model.js] [options]

Options
  --types, -t      Add Typescript definitions
  --verbose, -v    Verbose output w/ names and empty groups
  --precision, -p  Number of fractional digits (default: 2)
  --draco, -d      Draco binary path
  --root, -r       Sets directory from which .gltf file is served

Examples
  npx @react-three/gltfjsx model.glb -t

Requirements

A typical result will look like this

/*
auto-generated by: https://github.com/react-spring/gltfjsx
author: abcdef (https://sketchfab.com/abcdef)
license: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
source: https://sketchfab.com/models/...
title: Model
*/

import React from 'react'
import { useLoader } from 'react-three-fiber'
import { useGLTF } from '@react-three/drei/useGLTF'

export default function Model(props) {
  const { nodes, materials } = useGLTF('/model.gltf')
  return (
    <group {...props} dispose={null}>
      <group name="Camera" position={[10, 0, 50]} rotation={[Math.PI / 2, 0, 0]}>
        <primitive object={nodes.Camera_Orientation} />
      </group>
      <group name="Sun" position={[100, 50, 100]} rotation={[-Math.PI / 2, 0, 0]}>
        <primitive object={nodes.Sun_Orientation} />
      </group>
      <group name="Cube">
        <mesh material={materials.base} geometry={nodes.Cube_003_0.geometry} />
        <mesh material={materials.inner} geometry={nodes.Cube_003_1.geometry} />
      </group>
    </group>
  )
}

useGLTF.preload('/model.gltf')

This component is async and must be wrapped into <Suspense> for fallbacks:

import React, { Suspense } from 'react'

function App() {
  return (
    <Suspense fallback={null}>
      <Model />
    </Suspense>

Draco compression

You don't need to do anything if your models are draco compressed, since useGLTF defaults to a draco CDN (https://www.gstatic.com/draco/v1/decoders/). By adding the --draco flag you can refer to local binaries which must reside in your /public folder.

Animation

If your GLTF contains animations it will add a THREE.AnimationMixer to your component and extract the clips:

const actions = useRef()
const [mixer] = useState(() => new THREE.AnimationMixer())
useFrame((state, delta) => mixer.update(delta))
useEffect(() => {
  actions.current = { storkFly_B_: mixer.clipAction(gltf.animations[0]) }
  return () => gltf.animations.forEach((clip) => mixer.uncacheClip(clip))
}, [])

If you want to play an animation you can do so at any time:

<mesh onClick={(e) => actions.current.storkFly_B_.play()} />

Preload

The asset will be preloaded by default, this makes it quicker to load and reduces time-to-paint. Remove the preloader if you don't need it.

export default function Model(props) {
  const { nodes, materials } = useGLTF('/model.gltf')
  ...
}

useGLTF.preload('/model.gltf')

Types

Add the --types flag and your GLTF will be typesafe.

type GLTFResult = GLTF & {
  nodes: {
    cube1: THREE.Mesh
    cube2: THREE.Mesh
  }
  materials: {
    base: THREE.MeshStandardMaterial
    inner: THREE.MeshStandardMaterial
  }
}

export default function Model(props: JSX.IntrinsicElements['group']) {
  const { nodes, materials } = useGLTF<GLTFResult>('/model.gltf')

gltfjsx's People

Contributors

andrewprifer avatar badrpas avatar dependabot[bot] avatar drcmda avatar gsimone avatar hugomcphee avatar jeremytenjo avatar luanbitar avatar mattgperry avatar meesrutten avatar psullivan6 avatar stephencorwin avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.