1

I haven't found any post that describes exactly this issue but I've noticed it's kinda hard to delete elements from the scene.

I'm making a house editor, it allows to draw a 2D house and then it generates a 3d version.

If I use the next line or scene.clear() to clear the scene, it won´t render anything else afterwards:

build(layers) {
        let height = 0;

       this.scene.remove.apply(this.scene, this.scene.children);

        layers.forEach(layer => {
            for (let y = 0; y < GRID_SIZE; y++) {
                for (let x = 0; x < GRID_SIZE; x++) {
                    if (layer.grid[y][x] != null) {
                        this.scene.add(layer.grid[y][x].get3DVersion(x, y, height));
                    }
                }
            }
            height += layer.getTotalHeight();
        });        
    }

However, if I empty the scene like this, it continues rendering the scene but it won't remove all the elements that were deleted in the grid properlty, I have to call build(layers) several times for all of them to be gone:

 this.scene.children.forEach((child) => {
             if (child.isMesh && child !== this.plane) {
                 this.scene.remove(child);
                 child.geometry.dispose(); 
                 child.material.dispose(); 
             }
         });

This is all my Three.js related code:

class HouseBuilder {
    constructor() {
        const section = document.getElementById("threeSection");

        this.scene = new THREE.Scene();
        this.camera = new THREE.PerspectiveCamera(30, 400 / 300, 0.1, 5000);
        this.camera.position.set(25, 25, 50);
        this.camera.lookAt(0, 0, 2.5);

        this.renderer = new THREE.WebGLRenderer();
        this.renderer.setSize(400, 300);
        section.appendChild(this.renderer.domElement);

        const ambientLight = new THREE.AmbientLight(0x404040);
        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        this.scene.add(ambientLight);
        directionalLight.position.set(5, 10, 5);
        this.scene.add(directionalLight);

        this.addFloor();
        this.animate();
    }

    addFloor() {
        const geometry = new THREE.PlaneGeometry(GRID_SIZE + 5, GRID_SIZE + 5);
        const material = new THREE.MeshStandardMaterial({ color: 0x228b22, side: THREE.DoubleSide });
        this.plane = new THREE.Mesh(geometry, material);
        this.plane.rotation.x = -Math.PI / 2;
        this.scene.add(this.plane);
    }

    animate() {
        requestAnimationFrame(() => this.animate());
        this.renderer.render(this.scene, this.camera);
    }

    build(layers) {
        let height = 0;

        // this.scene.children.forEach((child) => {
        //     if (child.isMesh && child !== this.plane) {
        //         this.scene.remove(child);
        //         child.geometry.dispose(); 
        //         child.material.dispose(); 
        //     }
        // });

       this.scene.remove.apply(this.scene, this.scene.children);

        layers.forEach(layer => {
            for (let y = 0; y < GRID_SIZE; y++) {
                for (let x = 0; x < GRID_SIZE; x++) {
                    if (layer.grid[y][x] != null) {
                        this.scene.add(layer.grid[y][x].get3DVersion(x, y, height));
                    }
                }
            }
            height += layer.getTotalHeight();
        });        
    }
}

1 Answer 1

1

As @Don McCurdy said, the problem was due to modifying an array while iterating over it. Here's the solution:

const objectsToRemove = this.scene.children.filter((child) => child !== this.plane);

    for (const child of objectsToRemove) {
        if (child.isMesh && child !== this.plane) {
            this.scene.remove(child);
            child.geometry.dispose();
            child.material.dispose();
        }
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.