wsgg
wsgg

Reputation: 984

Cannon.js + Three.js - Bodies overlapping on contact issue

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:

enter image description 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);
};

Upvotes: 1

Views: 1311

Answers (2)

Seckin
Seckin

Reputation: 1

I suspect it is caused by "broadphase", this is a little bit late answer but, You could try "NaiveBroadPhase":

world.broadphase = new CANNON.NaiveBroadphase(world)

Upvotes: 0

PartialFlavor_55KP
PartialFlavor_55KP

Reputation: 157

Floor and bodies intersection is not an issue because floor is mass 0 and bodies are moving parallel. That's not a binary true statement, but it's summarily true. If the cube were dropped so as to have a corner intersect, the corner would in fact intersect. Also, not a cornerstone theorem but a generality. Depending upon the method by which you reposition a physical body with incalculable precision, the weighted mass may offend the laws of nature. This may be due to clock cycle nonsense, RAM nonsense, unit precision nonsense, angle of trajectory nonsense, and config settings nonsense.

probably research "broadphase"

Upvotes: -2

Related Questions