finally
If you're looking for a quick solution, consider using negative rotation for the groundbody: groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0), and set the position for your boxbody as boxBody.position.y = 100.
However, whether this is the correct approach or why it works over other methods is still uncertain.
Below are some alternative solutions.
Although I'm not well-versed in cannonJS, it appears that there are two working options. For instance, in https://github.com/schteppe/cannon.js?files=1, where gravity is set to the Z coordinate, simply adjust the gravity to the Z coordinate and omit the rotation with the plane. Then, assign a position to boxBody.position.z = 100 and observe the results.
Alternatively, you can resize your plane geometry by using the new CANNON.Plane() shape, or a new CANNON.Box(new CANNON.Vec3(15, 15, 1)) shape where the Z coordinate is only 1 (this becomes the Y size after rotation). In this scenario, set the position in Y instead of Z (boxBody.position.y = 100). The issue in the provided example, in my opinion, is that both physics are combined in each, leading to a failure.
Below are some code snippets that should function correctly:
const groundBody = new CANNON.Body({
shape: new CANNON.Box(new CANNON.Vec3(15, 15, 1)),
type: CANNON.Body.STATIC,
});
world.addBody(boxBody);
boxBody.position.y = 100;
Additional note: Since your plane is static, there's no need to constantly update its position in the animation loop. I have tested this with an example from and it works smoothly.
const planeGeometry = new THREE.PlaneGeometry(25, 25);
const planeMesh = new THREE.Mesh(
planeGeometry,
new THREE.MeshPhysicalMaterial({ color: "white" })
);
planeMesh.rotateX(-Math.PI / 2);
planeMesh.receiveShadow = true;
scene.add(planeMesh);
const planeShape = new CANNON.Plane();
const planeBody = new CANNON.Body({ mass: 0 });
planeBody.addShape(planeShape);
planeBody.quaternion.setFromAxisAngle(
new CANNON.Vec3(1, 0, 0),
-Math.PI / 2
);
world.addBody(planeBody);
It's important to set the initial position of your boxBody to avoid it being in the ground plane at the start, as this could result in excessive velocity for the boxBody.
Alternatively, based on your code template:
- Set boxBody.position.y = 100
- Avoid rotating your groundBody
- Rotate your groundMesh as desired: groundMesh.rotateX(-Math.PI / 2);
- Apply the rotation to your groundBody: groundBody.quaternion.copy(groundMesh.quaternion).
The issue might not be straightforward; it could be challenging to rotate the cannon body. Instead, consider adding the mesh's quaternion after rotation. Remember not to perform a world step update until the objects have the correct initial positions. Therefore, groundBody.quaternion.copy(groundMesh.quaternion) should precede the world.step().