Can't dispose of cloned and impostorized meshes

So… it turns out it’s a little bigger than I thought.
I looked into the world property as you suggested and found this
:

It seems the prototype doesn’t have an remove() method indeed (but removeBody() instead). So I figured it must be an issue about cannon. And doing my research, I realized :

  • I am actually using cannon-es instead of cannon. That is why my issue wasn’t reproduced on the playground.
  • Cannon-es has had several threads regarding this kind of problems, some of them discussing an awkwardly similar issue, that has been brought up here on babylon’s forum.

A Babylon PR has since fixed this issue (in 5.0.0-alpha.16), following this issue here.

But while the deprecated add() method was replaced with addBody(), the remove() method is still used and I assume that it is what’s throwing the error (the parallel seems obvious).

Since I can’t reproduce the problem on the playground due to cannon-es being used instead of cannon, here is a stand alone html file that demonstrates the issue :

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <title>cannon.js + babylon.js - basic integration example</title>
  <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
  <style>
    body {
      margin: 0;
      padding: 0;
    }

    canvas {
      width: 100vw;
      height: 100vh;
    }

    #scene-explorer-host,
    #inspector-host {
      position: absolute !important;
    }
  </style>
</head>

<body>
  <canvas id="renderCanvas"></canvas>
<!-- replace below CDN with 5.0.0-alpha.15 version and you'll see the fixed issue about deprecated world.add()-->
  <script src="https://unpkg.com/babylonjs@5.0.0-alpha.16/babylon.js"></script>
  <script type="module">
    import * as CANNON from 'https://unpkg.com/cannon-es@0.17.0/dist/cannon-es.js'

    // Canvas
    const canvas = document.querySelector('#renderCanvas')

    // Engine
    const engine = new BABYLON.Engine(canvas, true)
    window.addEventListener('resize', () => engine.resize())

    // Scene
    const scene = new BABYLON.Scene(engine)

    // Camera
    const camera = new BABYLON.ArcRotateCamera(
      'camera',
      -Math.PI / 2,
      Math.PI / 2.5,
      15,
      new BABYLON.Vector3(0, 0, 0),
      scene
    )
    camera.attachControl(canvas, true)

    // Light
    const light = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene)

    // Box
    const box = BABYLON.MeshBuilder.CreateBox('box', {}, scene)

    // Physics
    window.CANNON = CANNON // force the usage of cannon-es
    const physEngine = new BABYLON.CannonJSPlugin(false)
    scene.enablePhysics(undefined, physEngine)

    // Ground
    const ground = BABYLON.Mesh.CreateGround('ground1', 10, 10, 2, scene)
    ground.physicsImpostor = new BABYLON.PhysicsImpostor(
      ground,
      BABYLON.PhysicsImpostor.BoxImpostor,
      { mass: 0, friction: 0.5, restitution: 0.7 },
      scene
    )
    ground.position.y -= 2

    // Box body
    box.physicsImpostor = new BABYLON.PhysicsImpostor(box, BABYLON.PhysicsImpostor.BoxImpostor, { mass: 5 }, scene)
    box.physicsImpostor.setAngularVelocity(new BABYLON.Quaternion(0, 10, 0, 0))
    box.physicsImpostor._physicsBody.angularDamping = 0.5

    scene.debugLayer.show()
    engine.runRenderLoop(() => {
      scene.render()
    })
    setTimeout(() => {
      /** ---------------------------------------------
        * BELOW IS THE BREAKING LINE
        */
      box.dispose()
    }, 3000)
  </script>
</body>

</html>

I’d like to submit a PR about this based on the merge that fixed the add() part, but not before confirming my conclusion was right. Sorry to bother, hope I made it clear enough to evaluate. :smiley:

1 Like