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>
);
}