How to delete an object (THREE.Group) by Ctrl + mouse click

Hello,

I want to delete object by Ctrl + mouse click:

        renderer.domElement.onpointerdown = (event) =>
        {
            if (event.button === 0 && window.event.ctrlKey)
            {
                console.log("click");
            }
        }

I can get an object name using the Raycaster:

        const raycaster = new THREE.Raycaster();
        const pointer = new THREE.Vector2();

        renderer.domElement.onpointerdown = (event) =>
        {
            if (event.button === 0 && window.event.ctrlKey)
            {
                // calculate pointer position in normalized device coordinates
                // (-1 to +1) for both components
                pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
                pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;
                raycaster.setFromCamera(pointer, camera);

                const intersects = raycaster.intersectObjects(scene.children);
                if (intersects.length > 0)
                {
                    const objectName = intersects[0].object.name;
                    console.log(objectName);
                }
            }
        }

If I know the object name I can find the object itself and try to remove it from the scene:

                if (intersects.length > 0)
                {
                    const objectName = intersects[0].object.name;
                    const obj = scene.getObjectByName(objectName);
                    scene.remove(obj);
                }

While I was writing the question, I found my mistake. I must delete the parent object:

                if (intersects.length > 0)
                {
                    const objectName = intersects[0].object.name;
                    const obj = scene.getObjectByName(objectName);
                    scene.remove(obj.parent);
                }

Sandbox: Plunker - Deleting the Three object by Ctrl + mouse click

image

index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Deleting the Three.Group</title>

    <style>
        body {
            margin: 0;
        }
    </style>
</head>

<body>
    <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

    <script type="importmap">
        {
            "imports": {
            "three": "https://unpkg.com/three@0.140.2/build/three.module.js"
            }
        }
    </script>

    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from "https://unpkg.com/three@0.140.2/examples/jsm/controls/OrbitControls.js";
        import { ColladaLoader } from "https://unpkg.com/three@0.140.2/examples/jsm/loaders/ColladaLoader.js";

        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.y = 8;
        camera.position.z = 4;

        const renderer = new THREE.WebGLRenderer(); // { antialias: true }
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        const orbitControls = new OrbitControls(camera, renderer.domElement);
        orbitControls.target = new THREE.Vector3(0, 0, 0);

        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight();
        directionalLight.position.set(-0.5, 0.9, 1);
        scene.add(directionalLight);

        const loader = new ColladaLoader();

        loader.load("assets/models/flat.dae", function (collada)
        {
            const flat = collada.scene;
            flat.position.set(0, 0, 0);
            scene.add(flat);
        });
        loader.load("assets/models/table.dae", function (collada)
        {
            const table = collada.scene;
            table.position.set(-2, 0, -1);
            scene.add(table);
        });
        loader.load("assets/models/chair.dae", function (collada)
        {
            const chair = collada.scene;
            chair.position.set(-2.8, 0, -1);
            scene.add(chair);
        });
        loader.load("assets/models/ground.dae", function (collada)
        {
            scene.add(collada.scene);
        });

        window.addEventListener("resize", onWindowResize, false);
        function onWindowResize()
        {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        const raycaster = new THREE.Raycaster();
        const pointer = new THREE.Vector2();

        renderer.domElement.onpointerdown = (event) =>
        {
            if (event.button === 0 && window.event.ctrlKey)
            {
                // calculate pointer position in normalized device coordinates
                // (-1 to +1) for both components
                pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
                pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;
                raycaster.setFromCamera(pointer, camera);

                const intersects = raycaster.intersectObjects(scene.children);
                if (intersects.length > 0)
                {
                    const objectName = intersects[0].object.name;
                    const obj = scene.getObjectByName(objectName);
                    scene.remove(obj.parent);
                }
            }
        }

        function render()
        {
            requestAnimationFrame(render);
            orbitControls.update();
            renderer.render(scene, camera);
        };

        render();
    </script>
</body>

</html>

Some improvements to the code above. I have replaced this code:

with this code:

    <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

    <script type="importmap">
        {
            "imports": {
            "three": "https://unpkg.com/three@0.140.2/build/three.module.js",
            "collada-loader": "https://unpkg.com/three@0.140.2/examples/jsm/loaders/ColladaLoader.js",
            "orbit-controls": "https://unpkg.com/three@0.140.2/examples/jsm/controls/OrbitControls.js"
            }
        }
    </script>

I replaced the model loading code with this function loadAsync and moved the loading code to a separate module. I also moved the scene creation to a separate module: Plunker - Deleting the Three object by Ctrl + mouse click

assets.zip (33.9 KB)

public/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Deleting the Three.Group</title>

    <style>
        body {
            margin: 0;
        }
    </style>
</head>

<body>
    <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

    <script type="importmap">
        {
            "imports": {
            "three": "https://unpkg.com/three@0.140.2/build/three.module.js",
            "collada-loader": "https://unpkg.com/three@0.140.2/examples/jsm/loaders/ColladaLoader.js",
            "orbit-controls": "https://unpkg.com/three@0.140.2/examples/jsm/controls/OrbitControls.js"
            }
        }
    </script>

    <script type="module">
        import { loadModels } from "./js/loader.js";
        import { createScene } from "./js/scene.js"

        async function main()
        {
            const scene = createScene();
            loadModels(scene);
        }
        main();
    </script>
</body>

</html>

public/js/loader.js

import { ColladaLoader } from "collada-loader";

export async function loadModels(scene)
{
    const loader = new ColladaLoader();

    let result = await loader.loadAsync("assets/models/flat.dae");
    const flat = result.scene;
    scene.add(flat);

    result = await loader.loadAsync("assets/models/table.dae");
    const table = result.scene;
    table.position.set(-2, 0, -1);
    scene.add(table);

    result = await loader.loadAsync("assets/models/chair.dae");
    const chair = result.scene;
    chair.position.set(-2.8, 0, -1);
    scene.add(chair);

    result = await loader.loadAsync("assets/models/ground.dae");
    const ground = result.scene;
    scene.add(ground);
}

public/js/scene.js

import * as THREE from "three";
import { OrbitControls } from "orbit-controls";

export function createScene()
{
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.y = 8;
    camera.position.z = 4;

    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    const orbitControls = new OrbitControls(camera, renderer.domElement);
    orbitControls.target = new THREE.Vector3(0, 0, 0);

    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);

    const directionalLight = new THREE.DirectionalLight();
    directionalLight.position.set(-0.5, 0.9, 1);
    scene.add(directionalLight);

    window.addEventListener("resize", onWindowResize, false);
    function onWindowResize()
    {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }

    const raycaster = new THREE.Raycaster();
    const pointer = new THREE.Vector2();

    renderer.domElement.onpointerdown = (event) =>
    {
        if (event.button === 0 && window.event.ctrlKey)
        {
            // calculate pointer position in normalized device coordinates
            // (-1 to +1) for both components
            pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
            pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;
            raycaster.setFromCamera(pointer, camera);

            const intersects = raycaster.intersectObjects(scene.children);
            if (intersects.length > 0)
            {
                const objectName = intersects[0].object.name;
                const obj = scene.getObjectByName(objectName);
                scene.remove(obj.parent);
            }
        }
    }

    function render()
    {
        requestAnimationFrame(render);
        orbitControls.update();
        renderer.render(scene, camera);
    };

    render();

    return scene;
}