How to add mouse events to each mesh part loaded from Rhino3dm file in React-Three-Fiber?

it’s a little bit confused. object.children could be deeply nested.

you can do something like this

const hovered = new THREE.MeshStandardMaterial({ color: "hotpink" })
const unhovered = new THREE.MeshStandardMaterial({ color: "orange" })

const Model = (props) => {
  const object = useLoader(Rhino3dmLoader, "./rhino_logo.3dm", (loader) => {
    loader.setLibraryPath("https://cdn.jsdelivr.net/npm/rhino3dm@0.15.0-beta/")
  })
  useLayoutEffect(() => {
    object.traverse(o => o.material = unhovered)
  }, [])
  return (
    <primitive
      onPointerOver={(e) => {
        e.stopPropagation()
        e.object.material = hovered
      }}
      onPointerOut={(e) => {
        e.stopPropagation()
        e.object.material = unhovered
      }}
      object={object}
      {...props}
    />
  )
}

<Canvas>
  <Model scale={0.15} rotation={[-Math.PI / 2, 0, 0]} />

but keep in mind that if that model were declarative everything would be so easy. this is the difference between imperative and declarative in a nutshell, in vanilla threejs you get served a blob, a black box, and it’s hard to control that with traverse and it gets way too complex. all this evaporates with the declarative approach: save it as gltf and type npx gltfjsx yourmodel.gltf --transform

now the full graph would be under your control.

1 Like