TiagoCavalcante / r3f-native-orbitcontrols

OrbitControls for React Three Fiber in React Native
MIT License
72 stars 10 forks source link

Using OrbitControls makes object clicking not work on Android (at least) #27

Closed creativedrewy closed 12 months ago

creativedrewy commented 1 year ago

I tried the native orbitcontrols sample app, and when the OrbitControls are activated clicking on the individual cubes does not work. Removing the OrbitControls from the scene entirely as well as from the useControls() assignment makes clicking work again.

Saw this functionality on physical Android device.

a-jb02 commented 1 year ago

Im not sure that is correct way but in my case these changes solved the problem

      events: {
        ....  
        onStartShouldSetResponder(event: GestureResponderEvent) {
          // On some devices this fires only for 2+ touches.
          if (!scope.enabled) return false

          return functions.onTouchStart(event)
        },

        onMoveShouldSetResponder(event: GestureResponderEvent) {
          // And on the same devices this fires only for 1 touch.
          if (!scope.enabled) return false

          return functions.onTouchStart(event)
        },
        ...
     }

and here are onTouchStart changes (you have to add moveStart: Vector3 to internals)

      onTouchStart(event: GestureResponderEvent) {
        let state = event.nativeEvent.touches.length
        if (state === STATE.ROTATE)
        {
            const x = event.nativeEvent.touches[0].locationX
            const y = event.nativeEvent.touches[0].locationY
            const t = event.nativeEvent.touches[0].timestamp

            const dx = (x - internals.moveStart.x);
            const dy = (y - internals.moveStart.y);
            const dt = (t - internals.moveStart.z);

            // prevent state changing 
            if ((Math.abs(dx/dt) <= 0.4 && Math.abs(dy/dt) <= 0.4) 
                || (!internals.moveStart.length()))
            {
                state = STATE.NONE
                internals.moveStart.set(x, y, t)                
            }
            else
            {
                internals.moveStart.set(0, 0, 0)
            }
        }

        switch (state) {
          case STATE.ROTATE:
            if (!scope.enableRotate) return false
            this.handleTouchStartRotate(event)
            internals.state = STATE.ROTATE
            return true

          case STATE.DOLLY:
            if (!scope.enableZoom && !scope.enablePan) return false
            this.handleTouchStartDollyPan(event)
            internals.state = STATE.DOLLY
            return true

          default:
            internals.state = STATE.NONE
            return false
        }
      }
TiagoCavalcante commented 12 months ago

@creativedrewy Thanks for reporting the issue, I hadn't noted it in the devices I tested. Sorry for the delay in checking it, but it should be fixed now with 1.0.9.

@a-jb02 thanks for the code!

creativedrewy commented 12 months ago

Thanks for fixing this!