Object can break through the plane by CANNON

Hello, I used CANNON.js and I have a problem when I try to drag the object to the plane, I can break through the plane to the other side :

  let world = new CANNON.World();
  world.gravity.set(0, -9.82, 0);
    const wallMaterial = new CANNON.Material('concrete');
    const objectMaterial = new CANNON.Material('concrete');
    const wallObjectContactMaterial = new CANNON.ContactMaterial(wallMaterial, objectMaterial, {
            friction: 0.1,
            restitution: 0.7,
            contactEquationStiffness: 1e8,
            contactEquationRelaxation: 3,
        });

    world.addContactMaterial(wallObjectContactMaterial);
    world.solver.iterations = 10;
    world.solver.tolerance = 0.01;


   await loaderGlb.load("https ..... .glb",
      async function (glb) {
        
        let object= glb.scene;
        scene.add(object);


        const halfExtents = new CANNON.Vec3(object.scale.x / 2, object.scale.y / 2, object.scale.z / 2);

        const shape = new  CANNON.Box(halfExtents);
        const body = new CANNON.Body({ mass: 1 ,material:objectMaterial});
        body.addShape(shape); 

        });

       // The plane 
       
         let Box = new BoxGeometry(
        wallLength + 0.08,
        measures.height + 0.198,
        0.198 // Depth
      );
      let plane = new Mesh(Box, wallMat);

      plane.material.shadowSide = DoubleSide;

      plane.castShadow = true;
      plane.receiveShadow = true;
      scene.add(plane);

      const wallQuaternion = plane.quaternion;
      const wallShape= new CANNON.Plane();

      const wallBody = new CANNON.Body({ mass: 0 ,material: wallMaterial});
      
      wallBody.addShape(wallShape);
      wallBody.position.set(plane.position.x, plane.position.y, plane.position.z);
      wallBody.quaternion.set(wallQuaternion.x, wallQuaternion.y, wallQuaternion.z, wallQuaternion.w);
      wallBody.collisionResponse = true;
      world.add(wallBody);

Can you help me, Thank you.

1 Like

What do you mean by “drag the object on the plane” ? Could you share video of what’s happening?

Cannon is a non-continuous physics engine - if you apply a force large enough for tunnelling to happen, then it may happen.

1 Like

I mean this:

The object can break through the plane(wall)

That’s not due to precision / scale of the force.

Are you dragging Three.Mesh or Cannon.Body (you should be dragging Cannon.Body, the only source of truth in terms of position / rotation for the bodies should be Cannon.World - you cannot modify bodies in Three directly, otherwise Cannon simulation will not be in-sync.)

Yes , I did that in the animate function :

    world.step(1/60 );


    for(const object of savedObjectsToPhysics)
    {   
      object.body.position.x = object.mesh.position.x - object.mesh.userData.W /2
      object.body.position.y = object.mesh.position.y + object.mesh.scale.y/2
      object.body.position.z = object.mesh.position.z + object.mesh.userData.L/2


    }

Does this happen all the time or only when dragging quickly?

It happen all the time.

Since you setting the position explicitly, you’re telling it move through walls.

See the cannon-es mouse pick example for how to move a shape around and still support collision

1 Like

here’s the same in rapier,

it’s react + three, but the principle is what matters:

the trick is to use two rigidbodies: an empty and one around the movable model. a fixed constraint binds the two. now the empty is driven by the mouse and that’s enough. if you want to move stuff around without much wobbling and spinning you can optionally disable rotations. this will work the same way in cannon.

3 Likes

If you drag the mouse fast enough, the cube can get through the wall. Perhaps this is just a stepping issue.

1 Like

Should be fixed.

<RigidBody ccd ...>

I don’t think it’s fixable in Cannon though, CCD (continuous collision detection) to my knowledge was never added. Objects will move through walls given enough force. There used to be a draft implementation CCD · Issue #366 · schteppe/cannon.js · GitHub but it was never finished.

1 Like

Thank you @drcmda @anidivr
Do you know if I can do it with another library?
I am using three.js in javascript not React three fiber.

See three.js/examples/physics_rapier_instancing.html at master · mrdoob/three.js (github.com)

It wouldn’t matter what you use, this is the important part, it directly applies to your usecase:

the trick is to use two rigidbodies: an empty and one around the movable model. a fixed constraint binds the two. now the empty is driven by the mouse and that’s enough. if you want to move stuff around without much wobbling and spinning you can optionally disable rotations. this will work the same way in cannon.

the demo is just a proof of concept so that you can see that indeed it works, but you have to apply it to your own app of course.

if you wanted to change a thing though i would suggest you do not use cannon but favour rapier, or anything else really. the ccd thing alone will always cause you trouble (as in, you can pull stuff through walls — there is nothing you can do to address this in cannon). well and it’s the slowest possible engine out there.

I agree. Skip over cannon

1 Like

I tried this but I don’t get any effect.

I think this is ok. Since you may be dragging objects between rooms, or though the house and outside into the garden.

You probably don’t want to drop the object inside the wall.

Here is an example that allows dragging, and through walls, but not drop inside, and doesn’t use any physics engines. It uses Threejs Box3 (AABB).

3 Likes