I am currently working on creating a d20, which is a dice with 20 sides or an icosahedron. Here is how I have been approaching it:
const IcosahedronDice = (props) => {
const [ref] = useBox(() => ({ mass: 1, position: [0, 10, 0] }));
return (
<mesh ref={ref} position={[0, 2, 0]} castShadow receiveShadow>
<icosahedronBufferGeometry attach="geometry" args={[1, 0]}/>
<meshStandardMaterial attach="material" color="#802d2d" />
</mesh>
)
}
The problem I'm facing is that while using "useBox", the dice collides like a box and rotates accordingly, even though its appearance is still that of an icosahedron. When attempting to use "useConvexPolyhedron" instead (which should be more suitable for an icosahedron), the object passes through my plane without any collision.
Plane:
const Plane = () => {
const [ref] = usePlane(() => ({ rotation: [-Math.PI / 2, 0, 0] }));
return (
<mesh ref={ref} position={[0, 0, 0]} rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
<planeBufferGeometry attach="geometry" args={[100, 100]} />
<meshStandardMaterial attach="material" color="#49687a" />
</mesh>
)
}
I have tried searching for a solution in the documentation, but so far, I have not found anything helpful. It's unclear whether I'm missing something or if the documentation itself is too complex.
Edit: The complete code:
import './App.css';
import { Canvas } from '@react-three/fiber';
import { OrbitControls, Stars, Icosahedron } from '@react-three/drei';
import * as THREE from 'three'
import { Physics, useBox, usePlane, useConvexPolyhedron } from '@react-three/cannon';
const IcosahedronDice = (props) => {
const icosahedron = new THREE.IcosahedronGeometry(4)
const [ref] = useBox(() => ({ mass: 1, position: [0, 10, 0] })); // THIS should be useConvexPolyhedron
return (
<mesh ref={ref} position={[0, 2, 0]} castShadow receiveShadow>
<icosahedronBufferGeometry attach="geometry" args={[1, 0]}/>
<meshStandardMaterial attach="material" color="#802d2d" />
</mesh>
)
}
const Plane = () => {
const [ref] = usePlane(() => ({ rotation: [-Math.PI / 2, 0, 0] }));
return (
<mesh ref={ref} position={[0, 0, 0]} rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
<planeBufferGeometry attach="geometry" args={[100, 100]} />
<meshStandardMaterial attach="material" color="#49687a" />
</mesh>
)
}
const DiceCanvas = () => {
return (
<Canvas>
<Stars />
<OrbitControls />
<ambientLight intensity={0.5} />
<spotLight
position={[10, 10, 10]}
intensity={0.5}
penumbra={1}
castShadow
/>
<Physics>
<IcosahedronDice position={[0, 0, 4]} rotation={[0, 1, 0]}/>
<Plane />
</Physics>
</Canvas>
);
}
export default DiceCanvas;