ThreeJS:通过 uuid 从场景中删除 object/mesh

ThreeJS: Remove object/mesh from scene by uuid

我正在通过 createFigure() 创建 figures\meshes。 理想情况下,我需要以某种方式将每个 uuid 存储在列表中,其中每个元素都有一个 button/cross 以通过其存储的 uuid 从场景中删除对象。

我是 three.js 的新生,很难找到合适的 documentation\samples。很乐意提供帮助。

    <body>
 <ul id="uuidList" class="live-list">
</ul>

    <div class="controls">
        <form>
            <input class="scalar-input" type="text" id="params" placeholder="2,2,2" />
            <div class="dropdown">
                <select class="dropbtn" id="geometry">
                    <option value="cube">Cube</option>
                    <option value="sphere">Sphere</option>
                    <option value="pyramid">Pyramid</option>
                </select>
                <Button id="createButton" class="createbtn"> CREATE </Button>
            </div>
        </form>
    </div>
    <script type="module">

        import * as THREE from "https://threejs.org/build/three.module.js";
        import { OrbitControls } from "https://threejs.org/examples/jsm/controls/OrbitControls.js";

        // Receiving scalars
        let scalars;
        var a,b,c;
        const params = document.querySelector('input');
        const log = document.getElementById('values');
        params.addEventListener('input', showParams);
        function showParams(e) {
        scalars = e.target.value;
        if(typeof scalars === "string"){
            scalars = scalars.split(",");
            a = scalars[0];
            b = scalars[1];
            c = scalars[2];
        }
        }

        // Receiving shape
        const btn = document.querySelector('#createButton');
        const shape = document.querySelector('#geometry')
        btn.onclick = (event) => {
        event.preventDefault();
        createFigure(shape.value, a,b,c);
        };

        var mesh, renderer, scene, camera, controls;

        init();
        animate();


        //Creating figure based on received data
        function createFigure(shape, a,b,c) {

            if(shape == "sphere"){
            var geometry = new THREE.SphereGeometry(a,b,c);
            }
            if(shape == "cube") {
            var geometry = new THREE.BoxGeometry(a,b,c);
            }
            if(shape == "pyramid")
            var geometry = new THREE.ConeGeometry(a,b,c);
            // material
            var material = new THREE.MeshPhongMaterial( {
                color: 0x00ffff, 
                flatShading: true,
                transparent: true,
                opacity: 1,
            } );

            // mesh
            mesh = new THREE.Mesh( geometry, material );
            mesh.position.x = Math.random() * 2 - 1;
            mesh.position.y = Math.random() + 0.15;
            mesh.position.z = Math.random() * 2 - 1;
            // ( Math.random() - 0.5) * 1000; // alternative gives us negative numbers 
            mesh.position.multiplyScalar( 30 );
            scene.add( mesh );
            console.log(mesh.uuid);
            console.log(scene);
            
            var node = document.createElement("LI");   
            var textnode = document.createTextNode(mesh.uuid);
            node.appendChild(textnode);
            document.getElementById("uuidList").appendChild(node);
            // can successfully logout each uuid and add them to a list. don't know what to do next

        }

图像示例,在列表项上添加 crosses/button 并通过 uuid

单击从场景中删除列表项和对象

要通过UUID删除Mesh,只需为您创建的每个节点添加一个点击事件监听器。然后use the method .getObjectById().

node.addEventListener("click", function() {
    const object = scene.getObjectById(mesh.uuid);
    scene.remove(object);
});

我这样做解决了

        <a class="live-list" id="myList"></a>  //in body

在 createFigure() 函数的末尾,我添加了以下内容,以便每次调用函数时 -> 创建网格并创建新的超链接

       <a id="uuidList" value="uuid"> "uuid" </a> // hyperlink construction
            var node = document.createElement("a"); //creating hyperlink tag
            var textnode = document.createTextNode(mesh.uuid); // with uuid as atext inside 
            node.appendChild(textnode);
            node.setAttribute("id", "uuidList"); // attribute "id" named "uuidlist"
            node.setAttribute("value", mesh.uuid); // attribute "value" with content of mesh.uuid that being created
            document.getElementById("myList").appendChild(node); //adding as a child to #myList

然后我的#idList 我绑定了一个按钮,-> onclick 我读取列表中项目的值 属性 并且它的 uuid 正在处理网格。

  const btnd = document.querySelector('#myList');
        btnd.onclick = (event) => {  // creating event onclick for #myList
        event.preventDefault();
        let i = 2;
        x = document.getElementsByTagName("a")[i].getAttribute("value"); // defining that variable x is attribute value in a tag 
        var element = document.getElementsByTagName("a");
        element[i].parentNode.removeChild(element[i]); // deleting selected tag
        i++;
        console.log(x);
        console.log(scene);
        const object = scene.getObjectByProperty( 'uuid', x); // getting object by property uuid and x is uuid of an object that we want to delete and clicked on before
        object.geometry.dispose();
        object.material.dispose();
        scene.remove( object ); // disposing and deleting mesh from scene
        };

代码并不完美,可以改进,但它确实有效。 检查实时代码:https://kramzin.github.io/threejs-task/