Locking orbital controls while using transform controls on multiple meshes

776 Views Asked by At

I'm trying to have the orbital controls lock their position while I'm transforming either of the meshes in my example. My current implementation follows the logic found here: https://drei.pmnd.rs/?path=/story/controls-transformcontrols--transform-controls-lock-st it currently locks the orbital controls for one of the boxes being moved but not the other. Any help would be greatly appreciated.

https://codesandbox.io/s/mixing-controls-forked-uzmy8?file=/src/App.js

import { useRef, useEffect } from 'react'
import { Canvas } from '@react-three/fiber'
import { OrbitControls, TransformControls } from '@react-three/drei'

function Box() {
  return (
    <mesh>
      <boxGeometry />
      <meshNormalMaterial />
    </mesh>
  )
}

function TransformBox({ position, transform }) {
  return (
    <TransformControls position={position} ref={transform} mode="translate" showZ={false}>
      <Box />
    </TransformControls>
  )
}

function Main() {
  const orbit = useRef()
  const transform = useRef()

  useEffect(() => {
    const controls = transform.current
    const callback = (event) => (orbit.current.enabled = !event.value)
    controls.addEventListener('dragging-changed', callback)
    return () => controls.removeEventListener('dragging-changed', callback)
  }, [])

  return (
    <>
      <TransformBox transform={transform} position={[0, 2.5, 0]} />
      <TransformBox transform={transform} />
      <OrbitControls ref={orbit} />
    </>
  )
}

export default function App() {
  return (
    <Canvas dpr={[1, 2]}>
      <Main />
    </Canvas>
  )
}
1

There are 1 best solutions below

1
Adam Robinson On
import { Canvas } from '@react-three/fiber'
import { OrbitControls, TransformControls } from '@react-three/drei'

function Box({ active, setActive }) {
  return (
    <mesh
      onClick={() => {
        setActive(!active)
      }}>
      <boxGeometry />
      <meshNormalMaterial />
    </mesh>
  )
}

function TransformBox({ position, orbit }) {
  const transform = useRef()
  const [active, setActive] = useState(false)

  useEffect(() => {
    if (transform.current) {
      const { current: controls } = transform
      const callback = (event) => {
        orbit.current.enabled = !event.value
      }
      transform.current.addEventListener('dragging-changed', callback)
      return () => controls.removeEventListener('dragging-changed', callback)
    }
  })

  return (
    <TransformControls
      showX={active ? true : false}
      showY={active ? true : false}
      position={position}
      ref={transform}
      mode="translate"
      showZ={false}>
      <Box active={active} setActive={setActive} />
    </TransformControls>
  )
}

function Main() {
  const orbit = useRef()

  return (
    <>
      <TransformBox orbit={orbit} />
      <TransformBox orbit={orbit} position={[0, 2.5, 0]} />
      <OrbitControls ref={orbit} />
    </>
  )
}

export default function App() {
  return (
    <Canvas dpr={[1, 2]}>
      <Main />
    </Canvas>
  )
}