Muljayan
Muljayan

Reputation: 3886

Using lookAt in @react-three/fiber

I am trying learn how to use three js with react.For this purpose I am using @react-three/fiber and @react-three/drei.

This project by chriscourses was what I used to learn three js and I hope to use it to learn using threejs with react.

The below code should show boxes sprouting out of the cordinates given however currently they are all skewed towards one direction. Using lookat should solve the problem, however I do not know how to use lookat in @react-three/fiber / @react-three/drei.

import React, { FC, useRef } from 'react';
import { Box as NativeBox } from '@react-three/drei'
import { Vector3 } from 'three';
import { useFrame } from '@react-three/fiber';


type Props = {
  country: any,
}
const lookAtCubePosition = new Vector3(0, 0, 0)
const Box: FC<Props> = (props) => {
  const mesh = useRef()
  
  const { country } = props;
  const scale = country.population / 1000000000
  const lat = country.latlng[0]
  const lng = country.latlng[1]
  const zScale = 0.8 * scale

  const latitude = (lat / 180) * Math.PI
  const longitude = (lng / 180) * Math.PI
  const radius = 5

  const x = radius * Math.cos(latitude) * Math.sin(longitude)
  const y = radius * Math.sin(latitude)
  const z = radius * Math.cos(latitude) * Math.cos(longitude)

  console.log('box');

  const lookAtFunc = (lookAt: Vector3) => {
    lookAt.x = 0;
    lookAt.y = 0;
    lookAt.z = 0;
  }

  useFrame((state) => {
    state.camera.lookAt(lookAtCubePosition)
  })


  return <NativeBox
    args={[
      Math.max(0.1, 0.2 * scale),
      Math.max(0.1, 0.2 * scale),
      Math.max(zScale, 0.4 * Math.random())
    ]}
    position={[
      x, y, z
    ]}
    lookAt={lookAtFunc}
    ref={mesh}
  >
    <meshBasicMaterial
      attach="material"
      color="#3BF7FF"
      opacity={0.6}
      transparent={true}
    />
  </NativeBox>;
};

export default Box;

Upvotes: 7

Views: 4010

Answers (2)

robfuscator
robfuscator

Reputation: 741

I think (the documentation is not too specific on that) that we are not meant to set lookAt as a prop but instead use it as a function. We can gain access to the active camera using the useThree hook.

In a component which is mounted as a child of Canvas do:

import { useThree } from "@react-three/fiber";

// Takes a lookAt position and adjusts the camera accordingly
const SetupComponent = (
  { lookAtPosition }: { lookAtPosition: { x: number, y: number, z: number } }
) => {
  // "Hook into" camera and set the lookAt position
  const { camera } = useThree();
  camera.lookAt(lookAtPosition.x, lookAtPosition.y, lookAtPosition.z);
  
  // Return an empty fragment
  return <></>;
}

Upvotes: 0

Epiczzor
Epiczzor

Reputation: 427

If you are using OrbitControls, you must set the 'target' for OrbitControls rather than lookAt of the Camera since the lookAt of the camera is being overridden by OrbitControls

Upvotes: 4

Related Questions