pmndrs / gltfjsx

🎮 Turns GLTFs into JSX components
https://gltf.pmnd.rs
MIT License
4.41k stars 290 forks source link

Basic typing for instanced gltf #218

Closed jrabramson closed 10 months ago

jrabramson commented 10 months ago

from discussion here: https://discord.com/channels/740090768164651008/742331795843973171/1141370860075229186

Populates the types for the instanced mesh context

drcmda commented 10 months ago

could you show a before and after with the print out results?

jrabramson commented 10 months ago

before:

type GLTFResult = GLTF & {
  nodes: {
    fish_raw001: THREE.Mesh;
  };
  materials: {
    ["Material.005"]: THREE.MeshStandardMaterial;
  };
};

const context = createContext();
export function Instances({ children, ...props }) {
  const { nodes } = useGLTF("/fish.glb") as GLTFResult;
  const instances = useMemo(
    () => ({
      Fishraw: nodes.fish_raw001,
    }),
    [nodes]
  );
  return (
    <Merged meshes={instances} {...props}>
      {(instances) => (
        <context.Provider value={instances} children={children} />
      )}
    </Merged>
  );
}

export function Model(props: JSX.IntrinsicElements["group"]) {
  const instances = useContext(context);
  return (
    <group {...props} dispose={null}>
      <instances.Fishraw />
    </group>
  );
}

After:

type GLTFResult = GLTF & {
  nodes: {
    fish_raw001: THREE.Mesh
  }
  materials: {
    ['Material.005']: THREE.MeshStandardMaterial
  }
}

type ContextType = Record<string, React.ForwardRefExoticComponent<JSX.IntrinsicElements['mesh']>>

const context = createContext({} as ContextType)
export function Instances({ children, ...props }: JSX.IntrinsicElements['group']) {
  const { nodes } = useGLTF('/fish-transformed.glb') as GLTFResult
  const instances = useMemo(
    () => ({
      Fishraw: nodes.fish_raw001,
    }),
    [nodes]
  )
  return (
    <Merged meshes={instances} {...props}>
      {(instances: ContextType) => <context.Provider value={instances} children={children} />}
    </Merged>
  )
}

export function Model(props: JSX.IntrinsicElements['group']) {
  const instances = useContext(context)
  return (
    <group {...props} dispose={null}>
      <instances.Fishraw />
    </group>
  )
}