three#MathUtils TypeScript Examples

The following examples show how to use three#MathUtils. 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: velocity.ts    From spacesvr with MIT License 6 votes vote down vote up
useSpringVelocity = (bodyApi: Api[1], speed: number) => {
  const direction = useRef(new Vector3());
  const { device } = useEnvironment();
  const dummy = useMemo(() => new Vector3(), []);

  const updateVelocity = (cam: Camera, velocity: Vector3) => {
    // get forward/back movement and left/right movement velocities
    dummy.x = direction.current.x * 0.75;
    dummy.z = direction.current.y; // forward/back
    dummy.multiplyScalar(speed);

    const moveQuaternion = cam.quaternion.clone();
    moveQuaternion.x = 0;
    moveQuaternion.z = 0;
    dummy.applyQuaternion(moveQuaternion);
    dummy.y = velocity.y;

    // keep y velocity intact and update velocity
    if (!device.desktop) {
      bodyApi.velocity.set(dummy.x, dummy.y, dummy.z);
    } else {
      const newX = MathUtils.lerp(velocity.x, dummy.x, 0.25);
      const newZ = MathUtils.lerp(velocity.z, dummy.z, 0.25);
      bodyApi.velocity.set(newX, dummy.y, newZ);
    }
  };

  return {
    direction,
    updateVelocity,
  };
}
Example #2
Source File: use-constraint.tsx    From use-ammojs with MIT License 5 votes vote down vote up
export function useConstraint(props: UseConstraintProps) {
  const {
    addConstraint,
    updateConstraint,
    removeConstraint,
  } = useAmmoPhysicsContext();

  const [constraintId] = useState(() => MathUtils.generateUUID());

  useEffect(() => {
    const uuidA: UUID | undefined =
      props.bodyARef.current?.userData?.useAmmo?.rigidBody?.uuid;
    const uuidB: UUID | undefined =
      props.bodyBRef?.current?.userData?.useAmmo?.rigidBody?.uuid;

    if (props.bodyBRef === undefined && uuidA) {
      const { bodyARef, bodyBRef, ...constraintConfig } = props;

      addConstraint(
        constraintId,
        uuidA,
        undefined,
        constraintConfig as SingleBodyConstraintConfig
      );

      return () => {
        removeConstraint(constraintId);
      };
    } else if (uuidA && uuidB) {
      const { bodyARef, bodyBRef, ...constraintConfig } = props;

      addConstraint(
        constraintId,
        uuidA,
        uuidB,
        constraintConfig as TwoBodyConstraintConfig
      );

      return () => {
        removeConstraint(constraintId);
      };
    }

    return () => {};
  }, [props.bodyARef.current, props.bodyBRef?.current]);
}
Example #3
Source File: use-softbody.tsx    From use-ammojs with MIT License 5 votes vote down vote up
export function useSoftBody(
  options: UseSoftBodyOptions | (() => UseSoftBodyOptions),
  mesh?: Mesh
): [MutableRefObject<Mesh | undefined>, SoftbodyApi] {
  const ref = useRef<Mesh>();

  const physicsContext = useAmmoPhysicsContext();
  const { addSoftBody, removeSoftBody } = physicsContext;

  const [bodyUUID] = useState(() => MathUtils.generateUUID());

  useEffect(() => {
    const meshToUse = mesh ? mesh : ref.current!;

    if (typeof options === "function") {
      options = options();
    }

    const { anchors, ...rest } = options;

    if (!meshToUse) {
      throw new Error("useSoftBody ref does not contain a mesh");
    }

    addSoftBody(bodyUUID, meshToUse, {
      anchors:
        anchors &&
        anchors.map((anchor) => {
          if (isSoftBodyRigidBodyAnchorRef(anchor)) {
            const { rigidBodyRef, ...anchorProps } = anchor;

            return {
              ...anchorProps,
              rigidBodyUUID:
                anchor.rigidBodyRef.current?.userData?.useAmmo?.rigidBody?.uuid,
            };
          }
          return anchor;
        }),
      ...rest,
    });

    return () => {
      removeSoftBody(bodyUUID);
    };
  }, []);

  return [ref, createSoftbodyApi(physicsContext, bodyUUID)];
}
Example #4
Source File: use-rigidbody.tsx    From use-ammojs with MIT License 4 votes vote down vote up
export function useRigidBody(
  options: UseRigidBodyOptions | (() => UseRigidBodyOptions),
  object3D?: Object3D
): [MutableRefObject<Object3D | undefined>, RigidbodyApi] {
  const ref = useRef<Object3D>();

  const physicsContext = useAmmoPhysicsContext();
  const { addRigidBody, removeRigidBody } = physicsContext;

  const [bodyUUID] = useState(() => MathUtils.generateUUID());

  useEffect(() => {
    const objectToUse = object3D ? object3D : ref.current!;

    if (typeof options === "function") {
      options = options();
    }
    const {
      bodyType,
      shapeType,
      shapeConfig,
      position,
      rotation,
      mesh,
      ...rest
    } = options;

    if (position) {
      if (isVector3(position)) {
        objectToUse.position.set(position.x, position.y, position.z);
      } else if (position.length === 3) {
        objectToUse.position.set(position[0], position[1], position[2]);
      } else {
        throw new Error("invalid position: expected Vector3 or VectorTuple");
      }

      objectToUse.updateMatrixWorld();
    }

    if (rotation) {
      if (isEuler(rotation)) {
        objectToUse.rotation.copy(rotation);
      } else if (isQuaternion(rotation)) {
        objectToUse.rotation.setFromQuaternion(rotation);
      } else if (rotation.length === 3 || rotation.length === 4) {
        objectToUse.rotation.set(
          rotation[0],
          rotation[1],
          rotation[2],
          rotation[3]
        );
      } else {
        throw new Error("invalid rotation: expected Euler or EulerTuple");
      }

      objectToUse.updateMatrixWorld();
    }

    if (!objectToUse) {
      throw new Error("useRigidBody ref does not contain a object");
    }

    const meshToUse = mesh ? mesh : objectToUse;

    addRigidBody(
      bodyUUID,
      objectToUse,
      {
        meshToUse,
        shapeConfig: {
          type: shapeType,
          ...shapeConfig,
        },
      },
      {
        type: bodyType,
        ...rest,
      }
    );

    return () => {
      removeRigidBody(bodyUUID);
    };
  }, []);

  return [ref, createRigidBodyApi(physicsContext, bodyUUID)];
}