File size: 1,780 Bytes
2485dd8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import {useRef} from 'react';
import {useFrame} from '@react-three/fiber';
import {useController, useXR} from '@react-three/xr';
import * as THREE from 'three';

const USE_HORIZONTAL = true;
const USE_VERTICAL = true;
const USE_ROTATION = true;
const HORIZONTAL_AXIS = 2;
const VERTICAL_AXIS = 3;
const ROTATION_AXIS = 2;
const SENSITIVITY = 0.05;
const DEADZONE = 0.05;

/**
 * Component to add into the ThreeJS canvas that reads controller (Quest) inputs to change camera position
 */
export default function MovementController() {
  const xr = useXR();
  const controller = useController('right');
  const forward = useRef(new THREE.Vector3());
  const horizontal = useRef(new THREE.Vector3());

  useFrame(() => {
    const player = xr.player;
    const camera = xr.player.children[0];
    const cameraMatrix = camera.matrixWorld.elements;
    forward.current
      .set(-cameraMatrix[8], -cameraMatrix[9], -cameraMatrix[10])
      .normalize();

    const axes = controller?.inputSource?.gamepad?.axes ?? [0, 0, 0, 0];

    if (USE_HORIZONTAL) {
      horizontal.current.copy(forward.current);
      horizontal.current.cross(camera.up).normalize();

      player.position.add(
        horizontal.current.multiplyScalar(
          (Math.abs(axes[HORIZONTAL_AXIS]) > DEADZONE
            ? axes[HORIZONTAL_AXIS]
            : 0) * SENSITIVITY,
        ),
      );
    }

    if (USE_VERTICAL) {
      player.position.add(
        forward.current.multiplyScalar(
          (Math.abs(axes[VERTICAL_AXIS]) > DEADZONE ? axes[VERTICAL_AXIS] : 0) *
            SENSITIVITY,
        ),
      );
    }

    if (USE_ROTATION) {
      player.rotation.y -=
        (Math.abs(axes[ROTATION_AXIS]) > DEADZONE ? axes[ROTATION_AXIS] : 0) *
        SENSITIVITY;
    }
  });

  return <></>;
}