Create a wall that is 100% demolishable

Hi, I’d like to know how to do advanced destruction in panda3d.
I would like to make a wall which, when it receives an impact, is destroyed in the area where the impact occurred.

from panda3d.core import Point3, CollisionNode, CollisionBox, CollisionHandlerQueue, MouseButton, CollisionRay
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from panda3d.core import BitMask32
from panda3d.core import CollisionTraverser

class ShootingGallery(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.setFrameRateMeter(True)
        self.createWall()
        self.cTrav = CollisionTraverser()
        self.cHandler = CollisionHandlerQueue()
        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = self.camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(BitMask32.bit(1))
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.cTrav.addCollider(self.pickerNP, self.cHandler)
        self.taskMgr.add(self.update, "updateTask")
        self.accept('mouse1', self.handleMouseClick)

    def createWall(self):
        wall_size = 10
        for x in range(wall_size):
            for y in range(wall_size):
                cube = self.loader.loadModel("models/box")
                cube.setScale(1, 1, 0.2)
                cube.setPos(x - wall_size / 2, y - wall_size / 2, 0)
                cube.reparentTo(self.render)
                collider = cube.attachNewNode(CollisionNode(f"cube_{x}_{y}"))
                collider.node().addSolid(CollisionBox(Point3(0, 0, 0), 0.5, 0.5, 0.1))
                collider.setCollideMask(BitMask32.bit(1))

    def update(self, task):
        return Task.cont

    def handleMouseClick(self):
        if self.mouseWatcherNode.hasMouse():
            mpos = self.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(self.camNode, mpos.getX(), mpos.getY())
            self.cTrav.traverse(self.render)
            for i in range(self.cHandler.getNumEntries()):
                entry = self.cHandler.getEntry(i)
                cube_name = entry.getIntoNodePath().getName()
                if cube_name.startswith("cube"):
                    entry.getIntoNodePath().getParent().removeNode()

if __name__ == "__main__":
    app = ShootingGallery()
    app.run()

when I click with my mouse, I create a hole, with the physics engine it will be traversable

I’d like to know if there are simpler solutions? I haven’t found any information on this subject in the documentation.

the aim would be to be able to create impacts on simple objects (flat surfaces such as walls)

you first should better use copyTo to save your memery at out of for.

cube_source = self.loader.loadModel("models/box")
  for x in range(wall_size):
            for y in range(wall_size):
                cube = cube_source.copyTo(self.render)
                cube.setScale(1, 1, 0.2)
                cube.setPos(x - wall_size / 2, y - wall_size / 2, 0)
                collider = cube.attachNewNode(CollisionNode(f"cube_{x}_{y}"))
                collider.node().addSolid(CollisionBox(Point3(0, 0, 0), 0.5, 0.5, 0.1))
                collider.setCollideMask(BitMask32.bit(1))

that api in NodePath

def copyTo(self, *args, **kwargs): # real signature unknown
“”"
C++ Interface:
copy_to(NodePath self, const NodePath other, int sort, Thread current_thread)

    /**
     * Functions like instance_to(), except a deep copy is made of the referenced
     * node and all of its descendents, which is then parented to the indicated
     * node.  A NodePath to the newly created copy is returned.
     */
    """