I have a simple cannon.js (cannon-es) scene three.js scene set up where 2 boxes are present, and 1 of the boxes moves forwards and backwards on command of the W and S keyboard keys.
But currently i have an issue such that when the 2 boxes collide, they sorta overlap each other before the physics takes effect onto box bodies, even at slow speed.
I've tried adjusting the mass, friction and restitution of the bodies. also tried different broadphases to no avail.
What could be the issue here? Strangely there's no overlap issue between the floor and the box bodies.
If included a gif capture of this issue here:
i cant quite reproduce a working pen of this source as its module based but anyway here's a snippet of the key parts
/*** Physics ***/
const world = new CANNON.World();
world.broadphase = new CANNON.SAPBroadphase(world);
world.allowSleep = true;
world.gravity.set(0, -9.82, 0);
// Default material
const defaultMaterial = new CANNON.Material('default');
const defaultContactMaterial = new CANNON.ContactMaterial(defaultMaterial, defaultMaterial, {
friction: 0.1,
restitution: 0.1,
});
world.defaultContactMaterial = defaultContactMaterial;
// Floor
const floorShape = new CANNON.Plane();
const floorBody = new CANNON.Body();
floorBody.mass = 0;
floorBody.addShape(floorShape);
floorBody.quaternion.setFromAxisAngle(new CANNON.Vec3(-1, 0, 0), Math.PI * 0.5);
world.addBody(floorBody);
/*** Utils ***/
const objectsToUpdate = [];
// Create box
const boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const boxMaterial = new THREE.MeshStandardMaterial({
metalness: 0.3,
roughness: 0.4,
// envMap: environmentMapTexture,
});
var boxes_mesh = [];
const createBox = (width, height, depth, position) => {
// Three.js mesh
const mesh = new THREE.Mesh(boxGeometry, boxMaterial);
mesh.scale.set(width, height, depth);
mesh.castShadow = true;
mesh.position.copy(position);
scene.add(mesh);
// Cannon.js body
const shape = new CANNON.Box(new CANNON.Vec3(width * 0.5, height * 0.5, depth * 0.5));
const body = new CANNON.Body({
mass: 0.1,
position: new CANNON.Vec3(0, 3, 0),
shape: shape,
material: defaultMaterial,
});
body.position.copy(position);
// body.addEventListener('collide', playHitSound);
world.addBody(body);
boxes_mesh.push(body);
// Save in objects
objectsToUpdate.push({ mesh, body });
};
/// create 2 boxes at the start
createBox(1, 1.5, 2, { x: 0, y: 3, z: 0 });
createBox(0.5, 0.5, 0.5, { x: -3, y: 3, z: 0 });
/*** Floor ***/
const floor = new THREE.Mesh(
new THREE.PlaneGeometry(10, 10),
new THREE.MeshStandardMaterial({
color: '#777777',
metalness: 0.3,
roughness: 0.4,
})
);
floor.receiveShadow = true;
floor.rotation.x = -Math.PI * 0.5;
scene.add(floor);
render loop
const tick = () => {
const elapsedTime = clock.getElapsedTime();
const deltaTime = elapsedTime - oldElapsedTime;
oldElapsedTime = elapsedTime;
// Update physics
world.step(1 / 60, deltaTime, 3);
// onkeydown "W" or "S"
if (moveForward == true) {
boxes_mesh[1].position.x += 0.05;
}
if (moveBackward == true) {
boxes_mesh[1].position.x -= 0.05;
}
for (const object of objectsToUpdate) {
object.mesh.position.copy(object.body.position);
object.mesh.quaternion.copy(object.body.quaternion);
}
// Update controls
controls.update();
// Render
renderer.render(scene, camera);
// Call tick again on the next frame
window.requestAnimationFrame(tick);
};
