THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN

I’ve found this question asked before but the solutions offered did not solve my issue. I’ve tried creating this project in only react-three but I’ve added vanilla three and cannon to supplement react-three.

This error only occurs on rounded TextGeometry and I’ve been able to duplicate the error in a Codesandbox example.

I’ve tried:

  • Adding and removing computeBoundingBox() and computeBoundingSphere()
  • Removing the array from around my position const
  • I’ve added width segment and height segment parameters to PlaneBufferGeometry
  • Incorporating code I found in examples that had rounded TextGeometry
  • Parsing float values for coordinates

Here is the function for the TextGeometry:

// const position = [pos.x / 4, pos.y / 8, 2];

export function Font({ letter, position: initialPosition }) {
  const { size, viewport } = useThree();
  const [position, setPosition] = useState(initialPosition);
  const [quaternion, setQuaternion] = useState([0, 0, 0, 0]);
  const aspect = size.width / viewport.width;
  const font = new FontLoader().parse(Roboto);

  const textOptions = {
    font,
    size: 1,
    height: 0,
    curveSegments: 0,
    bevelEnabled: true,
    bevelThickness: 0.3,
    bevelSize: 0.1,
    bevelOffset: -0.01,
    bevelSegments: 12
  };

  const letterGeom = new TextGeometry(
    letter,
    textOptions
  );

  letterGeom.computeBoundingBox();
  letterGeom.computeBoundingSphere();

  const letterMat = new THREE.MeshLambertMaterial();
  const letterMesh = new THREE.Mesh(letterGeom, letterMat);
  letterMesh.size = letterMesh.geometry.boundingBox.getSize(new THREE.Vector3());

  const box = new CANNON.Box(new CANNON.Vec3().copy(letterMesh.size).scale(0.5));
  const { center } = letterMesh.geometry.boundingSphere;
  const { ref, body } = useCannon({ bodyProps: { mass: 10 } }, body => {
    body.addShape(box, new CANNON.Vec3(center.x, center.y, center.z));
    body.position.set(...position);
  }, []);

  const bind = useDrag(({ offset: [,], xy: [x, y], first, last }) => {
    if (first) {
      body.mass = 0;
      body.updateMassProperties();
    } else if (last) {
      body.mass = 10000;
      body.updateMassProperties();
    }
    body.position.set((x - size.width / 2) / aspect, -(y - size.height / 2) / aspect, -0.7);
  }, { pointerEvents: true });

  useFrame(() => {
    const deltaX = Math.abs(body.position.x - position[0]);
    const deltaY = Math.abs(body.position.y - position[1]);
    const deltaZ = Math.abs(body.position.z - position[2]);
    if (deltaX > 0.001 || deltaY > 0.001 || deltaZ > 0.001) {
      setPosition(body.position.clone().toArray());
    }
    const bodyQuaternion = body.quaternion.toArray();
    const quaternionDelta = bodyQuaternion.map((n, idx) => Math.abs(n - quaternion[idx]))
      .reduce((acc, curr) => acc + curr);
    if (quaternionDelta > 0.01) {
      setQuaternion(body.quaternion.toArray());
    }
  });

  // extend TextGeometry to THREE
  extend({ TextGeometry })

  return (
    <mesh ref={ref} castShadow position={position} quaternion={quaternion} {...bind()}
      onClick={e => {
        e.stopPropagation();
      }}
    >
      <textGeometry attach='geometry' args={[letter, textOptions]} />
      <meshLambertMaterial attach='material' color="lightcoral" />
    </mesh>
  );
}

I think that “height” and “curveSegments” will need to be greater than zero. Try something like 0.001 and 8, perhaps.

Thanks so much! Worked perfectly.