three#Euler TypeScript Examples

The following examples show how to use three#Euler. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From use-ammojs with MIT License 6 votes vote down vote up
export function isEuler(v): v is Euler {
  return v && v.isEuler;
}
Example #2
Source File: DisplayObject.ts    From FairyGUI-threejs with MIT License 5 votes vote down vote up
protected _rot: Euler;
Example #3
Source File: DragControls.tsx    From spacesvr with MIT License 5 votes vote down vote up
/**
 * DragControls allows for a click-and-drag control
 * of the camera
 *
 * @param props
 * @constructor
 */
export function DragControls() {
  const originEuler = useRef<Euler>(new Euler(0, 0, 0, "YXZ"));
  const setEuler = useRef<Euler>(new Euler(0, 0, 0, "YXZ"));
  const mouseDownPos = useRef<Vector2>(new Vector2(0, 0));
  const dragging = useRef(false);
  const camera = useThree((state) => state.camera);
  const { containerRef } = useEnvironment();
  const [xyz, setXYZ] = useState([0, 0, 0]);

  const { x, y, z } = useSpring({
    x: xyz[0],
    y: xyz[1],
    z: xyz[2],
    config: { ...config.default, precision: 0.0001 },
  });

  useFrame(() => {
    if (setEuler.current) {
      setEuler.current.set(x.get(), y.get(), z.get());
      camera.quaternion.setFromEuler(setEuler.current);
    }
  });

  const getNewEuler = (
    dragX: number,
    dragY: number,
    isHover?: boolean
  ): Euler => {
    const newEuler = originEuler.current.clone();
    const moveX = dragX - mouseDownPos.current.x;
    const moveY = dragY - mouseDownPos.current.y;

    const SENSITIVITY = isHover ? HOVER_SENSITIVITY : DRAG_SENSITIVITY;

    newEuler.setFromQuaternion(camera.quaternion);
    newEuler.y = originEuler.current.y - (moveX * SENSITIVITY.x) / 100;
    newEuler.x = originEuler.current.x - (moveY * SENSITIVITY.y) / 100;
    // newEuler.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, newEuler.x));

    return newEuler;
  };

  // touch move scripts
  const onMouseDown = (ev: MouseEvent) => {
    dragging.current = true;
    mouseDownPos.current.set(ev.clientX, ev.clientY);
    containerRef?.current?.classList.add("grabbing");
  };
  const onMouseMove = (ev: MouseEvent) => {
    const newEuler = getNewEuler(ev.clientX, ev.clientY, !dragging.current);
    setXYZ(newEuler.toArray());
  };
  const onMouseUp = (ev: MouseEvent) => {
    dragging.current = false;
    originEuler.current = getNewEuler(ev.clientX, ev.clientY);
    mouseDownPos.current.set(ev.clientX, ev.clientY);
    containerRef?.current?.classList.remove("grabbing");
  };

  useEffect(() => {
    document.addEventListener("mousedown", onMouseDown);
    document.addEventListener("mousemove", onMouseMove);
    document.addEventListener("mouseup", onMouseUp);

    return () => {
      document.removeEventListener("mousedown", onMouseDown);
      document.removeEventListener("mousemove", onMouseMove);
      document.removeEventListener("mouseup", onMouseUp);
    };
  }, [containerRef]);

  return null;
}
Example #4
Source File: PointerLockControls.tsx    From spacesvr with MIT License 4 votes vote down vote up
/**
 * PointerLockCamera is a react port of PointerLockControls.js from THREE,
 * with some changes. Some parameters are listed above
 *
 * https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/PointerLockControls.js
 *
 * @param props = { onUnlock: function to run when the pointer lock controls are unlocked }
 * @constructor
 */
export default function PointerLockCamera() {
  const camera = useThree((state) => state.camera);
  const gl = useThree((state) => state.gl);
  const { domElement } = gl;
  const { paused, setPaused, addEvent } = useEnvironment();

  const { current: euler } = useRef(new Euler(0, 0, 0, "YXZ"));
  const isLocked = useRef(false);
  const lock = () => domElement.requestPointerLock();
  const unlock = () => domElement.ownerDocument.exitPointerLock();

  useFrame(() => {
    if (isLocked.current) {
      const lookAt = new THREE.Vector3(0, 0, -1);
      lookAt.applyQuaternion(camera.quaternion);
      lookAt.multiply(new THREE.Vector3(1, 0, 1)).normalize();
    }
  });

  // update camera while controls are locked
  const onMouseMove = useCallback(
    (event: MouseEvent) => {
      if (!isLocked.current) return;

      const movementX =
        // @ts-ignore
        event.movementX || event.mozMovementX || event.webkitMovementX || 0;
      const movementY =
        // @ts-ignore
        event.movementY || event.mozMovementY || event.webkitMovementY || 0;

      euler.setFromQuaternion(camera.quaternion);

      euler.y -= movementX * SENSITIVITY * 0.002;
      euler.x -= movementY * SENSITIVITY * 0.002;

      euler.x = Math.max(
        PI_2 - MAX_POLAR_ANGLE,
        Math.min(PI_2 - MIN_POLAR_ANGLE, euler.x)
      );

      camera.quaternion.setFromEuler(euler);
    },
    [isLocked]
  );

  // handle pointer lock change
  function onPointerlockChange() {
    if (domElement.ownerDocument.pointerLockElement === domElement) {
      isLocked.current = true;
      if (paused) {
        setPaused(false);
      }
    } else {
      isLocked.current = false;
      if (!paused) {
        setPaused(true);
      }
    }
  }

  // automatically unlock on pointer lock error
  function onPointerlockError() {
    console.error("PointerLockControls: Unable to use Pointer Lock API");
    isLocked.current = false;
    setPaused(true);
  }

  // events setup
  useEffect(() => {
    setTimeout(() => {
      if (!isLocked.current && !paused) {
        setPaused(true);
      }
    }, 250);

    const { ownerDocument } = domElement;

    ownerDocument.addEventListener("mousemove", onMouseMove, false);
    ownerDocument.addEventListener(
      "pointerlockchange",
      onPointerlockChange,
      false
    );
    ownerDocument.addEventListener(
      "pointerlockerror",
      onPointerlockError,
      false
    );

    return () => {
      ownerDocument.removeEventListener("mousemove", onMouseMove, false);
      ownerDocument.removeEventListener(
        "pointerlockchange",
        onPointerlockChange,
        false
      );
      ownerDocument.removeEventListener(
        "pointerlockerror",
        onPointerlockError,
        false
      );
    };
  }, [paused, onMouseMove, isLocked, onPointerlockChange]);

  useEffect(() => {
    // initial camera rotation
    if (camera) {
      camera?.lookAt(0, 2, 0);
    }

    // lock and unlock controls based on set paused value
    addEvent("paused", (pausedVal: boolean, overlayVal: string | undefined) => {
      if (pausedVal) {
        unlock();
      } else {
        lock();
      }
    });
  }, []);

  return null;
}
Example #5
Source File: TouchFPSCamera.tsx    From spacesvr with MIT License 4 votes vote down vote up
/**
 * TouchFPSCamera controls the camera rotation by detecting
 * touch drag on the screen. Unlike MouseFPSCamera, this component
 * does not have a way to pause, that must be done externally.
 *
 * @param props
 * @constructor
 */
export default function TouchFPSCamera() {
  const touchStartPos = useRef<Touch>(DefaultTouch);
  const originEuler = useRef<Euler>(new Euler(0, 0, 0, "YXZ"));
  const camera = useThree((state) => state.camera);

  const getNewEuler = (dragX: number, dragY: number): Euler => {
    const newEuler = originEuler.current.clone();
    const moveX = dragX - touchStartPos.current.pos.x;
    const moveY = dragY - touchStartPos.current.pos.y;

    newEuler.setFromQuaternion(camera.quaternion);
    newEuler.y = originEuler.current.y - (moveX * DRAG_SENSITIVITY.x) / 100;
    newEuler.x = originEuler.current.x - (moveY * DRAG_SENSITIVITY.y) / 100;
    newEuler.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, newEuler.x));

    return newEuler;
  };

  // touch move scripts
  const onTouchStart = (ev: TouchEvent) => {
    if (touchStartPos.current.id !== -1) {
      return;
    }

    if (tappedNipple(ev)) {
      touchStartPos.current = DefaultTouch;
      return;
    }

    // get last in list (most recent touch) to not confuse with movement
    const touchIndex = ev.touches.length - 1;
    const { clientX, clientY, identifier: id } = ev.touches[touchIndex];

    touchStartPos.current = { pos: new Vector2(clientX, clientY), id };

    originEuler.current.setFromQuaternion(camera.quaternion);
  };

  const onTouchMove = (ev: TouchEvent) => {
    const touch = getCurrentTouch(touchStartPos.current.id, ev.touches);

    if (!touch) {
      return;
    }

    const { clientX, clientY } = touch;
    const newEuler = getNewEuler(clientX, clientY);
    camera.quaternion.setFromEuler(newEuler);
  };
  const onTouchEnd = (ev: TouchEvent) => {
    const touch = getCurrentTouch(touchStartPos.current.id, ev.changedTouches);

    if (!touch) {
      return;
    }

    const { clientX, clientY } = touch;
    originEuler.current = getNewEuler(clientX, clientY);
    touchStartPos.current.id = -1;
  };

  useEffect(() => {
    document.addEventListener("touchstart", onTouchStart);
    document.addEventListener("touchmove", onTouchMove);
    document.addEventListener("touchend", onTouchEnd);

    return () => {
      document.removeEventListener("touchstart", onTouchStart);
      document.removeEventListener("touchmove", onTouchMove);
      document.removeEventListener("touchend", onTouchEnd);
    };
  }, []);

  return null;
}