动态修改几何体的顶点位置

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Custom Geometry</title>
    <script src="../../three-part/threejs/three.js"></script>
    <script src="../../three-part/utils/stats.min.js"></script>
    <script src="../../three-part/utils/dat.gui.min.js"></script>
    <script src="../controls/TrackballControls.js"></script>
    <script src="../util/util.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
    init();
    function init() {
        // show FPS
        let stats = initStats();
        // resize
        window.addEventListener('resize', onResize, false);

        let scene = new THREE.Scene();
        let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.x = -20;
        camera.position.y = 25;
        camera.position.z = 20;
        camera.lookAt(new THREE.Vector3(5, 0, 0));

        let renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(new THREE.Color(0x000000));
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.shadowMap.enabled = true;
        document.getElementById("container").appendChild(renderer.domElement);

        // init trackball control
        let trackballControls = initTrackballControls(camera, renderer);
        let clock = new THREE.Clock();

        // add a plane
        let planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
        let planeMaterial = new THREE.MeshLambertMaterial({
            color: 0xffffff
        });
        let plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.receiveShadow = true;
        plane.rotation.x = -0.5 * Math.PI;
        scene.add(plane);

        // add ambient lighting
        let ambientLight = new THREE.AmbientLight(0x555555);
        scene.add(ambientLight);

        let vertices = [
            new THREE.Vector3(1, 3, 1),
            new THREE.Vector3(1, 3, -1),
            new THREE.Vector3(1, -1, 1),
            new THREE.Vector3(1, -1, -1),
            new THREE.Vector3(-1, 3, -1),
            new THREE.Vector3(-1, 3, 1),
            new THREE.Vector3(-1, -1, -1),
            new THREE.Vector3(-1, -1, 1)
        ];

        let faces = [
            new THREE.Face3(0, 2, 1),
            new THREE.Face3(2, 3, 1),
            new THREE.Face3(4, 6, 5),
            new THREE.Face3(6, 7, 5),
            new THREE.Face3(4, 5, 1),
            new THREE.Face3(5, 0, 1),
            new THREE.Face3(7, 6, 2),
            new THREE.Face3(6, 3, 2),
            new THREE.Face3(5, 7, 0),
            new THREE.Face3(7, 2, 0),
            new THREE.Face3(1, 3, 4),
            new THREE.Face3(3, 6, 4),
        ];

        let geometry = new THREE.Geometry();
        geometry.vertices = vertices;
        geometry.faces = faces;
        geometry.computeFaceNormals();

        let material = new THREE.MeshLambertMaterial({opacity: 0.6, color: 0x44ff44, transparent: true});
        let mesh = new THREE.Mesh(geometry, material);
        mesh.castShadow = true;
        console.log(mesh);
        scene.add(mesh);

        // add spotlight
        let spotLight = new THREE.SpotLight(0xffffff, 1, 180, Math.PI / 4);
        spotLight.shadow.mapSize.height = 2048;
        spotLight.shadow.mapSize.width = 2048;
        spotLight.position.set(-40, 30, 30);
        spotLight.castShadow = true;
        spotLight.lookAt(mesh);
        scene.add(spotLight);

        // attributes which can be modified in GUI
        const controls = {
            "vertex_0" : getPosition(3, 5, 3),
            "vertex_1" : getPosition(3, 5, 0),
            "vertex_2" : getPosition(3, 0, 3),
            "vertex_3" : getPosition(3, 0, 0),
            "vertex_4" : getPosition(0, 5, 0),
            "vertex_5" : getPosition(0, 5, 3),
            "vertex_6" : getPosition(0, 0, 0),
            "vertex_7" : getPosition(0, 0, 3)
        };
        // init GUI
        initGUI();

        renderScene();

        function getPosition(x, y, z){
            return {
                "x" : x,
                "y" : y,
                "z" : z
            }
        }

        function initGUI(){
            let gui = new dat.GUI();
            for(let i=0; i<8; ++i){
                let folder = gui.addFolder("Vertex[" + (i+1) + "]");
                folder.add(controls["vertex_"+i], "x", -10, 10);
                folder.add(controls["vertex_"+i], "y", -10, 10);
                folder.add(controls["vertex_"+i], "z", -10, 10);
            }
        }

        function onResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function renderScene(){
            trackballControls.update(clock.getDelta());
            stats.update();
            let vertexes = [];
            for(let i=0; i<8; ++i){
                vertexes.push(new THREE.Vector3(controls["vertex_"+i].x, controls["vertex_"+i].y, controls["vertex_"+i].z));
            }
            mesh.geometry.vertices = vertexes;
            mesh.geometry.verticesNeedUpdate = true;
            mesh.geometry.computeFaceNormals();
            // 必须删掉这个属性,否则修改后不生效
            delete mesh.geometry.__directGeometry;
            requestAnimationFrame(renderScene);
            renderer.render(scene, camera);
        }
    }
</script>
</body>
</html>

运行结果:


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容