• Three.js中自定义控制几何体的点和面的属性


    场景

    Three.js中引入dat.gui库实现界面组件控制动画速度变量:

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/119391130

        Three.js库中的geometry和其他大多数三维库中的一样,基本上是三维空间中的点集,

    以及一些将这些点连接起来的面。举例来说,一个方块:

    1、一个方块有8个角。每个角都可以定义为X, y和z坐标的一个组合。所以每个方块

    都是三维空间中的8个点。在Three.js库中,这些点称为顶点(vertice) 。

    2、一个方块有6个侧面,每个角有一个顶点。在Three.js库里,每个侧面称为面(face)。

        当你使用Three. j s库提供的这些几何体时,你不必亲自定义所有的这些顶点和面。对于

    一个方块来讲,你只要定义长宽高即可。Three js库会利用这些信息,在正确的位置创建一

    个拥有8个顶点的几何体,并用正确的面连接起来。尽管你可以使用Three js库提供的几何

    体,或者自动生成,但是你仍然可以通过定义顶点和面,手工创建几何体。创建方法可以参

    考下面的代码片段:

            //定义顶点
            var 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)
            ];
    
            //定义面
            var 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),
            ];
    
            //定义方块
            var geom = new THREE.Geometry();
            geom.vertices = vertices;
            geom.faces = faces;
            geom.computeFaceNormals();
    
            //定义材质
            var materials = [
                new THREE.MeshLambertMaterial({opacity: 0.6, color: 0x44ff44, transparent: true}),
                new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true})
    
            ];
    
            //合并多个材质
            var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, materials);
            mesh.children.forEach(function (e) {
                e.castShadow = true
            });
    
            //方块添加进场景
            scene.add(mesh);

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    上面用到的不是一个单一的材质,而是有两个元素的材质数组。

    除了显示一个绿色透明的方块之外,还显示一个线框。

    完整示例代码

    <!DOCTYPE html>
    
    <html>
    
    <head>
        <title>dat.gui的使用</title>
        <script type="text/javascript" src="./js/three.js"></script>
        <script type="text/javascript" src="./js/dat.gui.js"></script>
        <style>
            body {
                /* 将边距设置为0,溢出设置为隐藏,以实现全屏显示 */
                margin: 0;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
    
    <!-- 显示的div -->
    <div id="WebGL-output">
    </div>
    
    <script type="text/javascript">
    
        // 初始化的方法
        function init() {
    
            // 创建一个场景,它将包含我们所有的元素,如物体,摄像机和灯光
            var scene = new THREE.Scene();
    
            // 创建一个相机,它定义了我们正在看的地方
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
            // 创建渲染器并设置大小
            var renderer = new THREE.WebGLRenderer();
            //将renderer的背景色设置为接近白色
            renderer.setClearColorHex();
            renderer.setClearColor(new THREE.Color(0xEEEEEE));
            //设置大小
            renderer.setSize(window.innerWidth, window.innerHeight);
    
    
            // 创建平面,并定义平面的尺寸
            var planeGeometry = new THREE.PlaneGeometry(60, 20);
            //创建一个基本材质,并设置颜色
            var planeMaterial = new THREE.MeshBasicMaterial({color: 0xcccccc});
            //把两个对象合并到Mesh网格对象
            var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    
            // 设置平面绕x轴旋转90度
            plane.rotation.x = -0.5 * Math.PI;
            // 设置平面的坐标位置
            plane.position.x = 15;
            plane.position.y = 0;
            plane.position.z = 0;
    
            // 将平面添加进场景
            scene.add(plane);
    
            // 定义相机的坐标,即悬挂在场景的上方
            camera.position.x = -30;
            camera.position.y = 40;
            camera.position.z = 30;
            //为了确保相机能够拍摄到这些物体,使用lookat函数指向场景的中心
            camera.lookAt(scene.position);
    
            // 添加环境光
            var spotLight = new THREE.SpotLight(0xffffff);
            spotLight.position.set(-40, 60, 10);
            spotLight.castShadow = true;
            scene.add(spotLight);
    
            // 将renderer的输出挂接到HTML终点div元素
            document.getElementById("WebGL-output").appendChild(renderer.domElement);
            // 渲染场景
            var step = 0;
    
            //定义顶点
            var 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)
            ];
    
            //定义面
            var 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),
            ];
    
            //定义方块
            var geom = new THREE.Geometry();
            geom.vertices = vertices;
            geom.faces = faces;
            geom.computeFaceNormals();
    
            //定义材质
            var materials = [
                new THREE.MeshLambertMaterial({opacity: 0.6, color: 0x44ff44, transparent: true}),
                new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true})
    
            ];
    
            //合并多个材质
            var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, materials);
            mesh.children.forEach(function (e) {
                e.castShadow = true
            });
    
            //方块添加进场景
            scene.add(mesh);
    
            //添加组件的方法
            function addControl(x, y, z) {
                var controls = new function () {
                    this.x = x;
                    this.y = y;
                    this.z = z;
                };
                return controls;
            }
    
            //组件坐标
            var controlPoints = [];
            controlPoints.push(addControl(3, 5, 3));
            controlPoints.push(addControl(3, 5, 0));
            controlPoints.push(addControl(3, 0, 3));
            controlPoints.push(addControl(3, 0, 0));
            controlPoints.push(addControl(0, 5, 0));
            controlPoints.push(addControl(0, 5, 3));
            controlPoints.push(addControl(0, 0, 0));
            controlPoints.push(addControl(0, 0, 3));
    
            //gui组件
            var gui = new dat.GUI();
    
            for (var i = 0; i < 8; i++) {
    
                f1 = gui.addFolder('Vertices ' + (i + 1));
                f1.add(controlPoints[i], 'x', -10, 10);
                f1.add(controlPoints[i], 'y', -10, 10);
                f1.add(controlPoints[i], 'z', -10, 10);
    
            }
    
            render();
    
            function render() {
    
                //几何体Geometry的顶点位置坐标在在三维空间笛卡尔坐标系中中坐标需要xyz三个分量,
                //所以顶点坐标使用Vector3对象表示;
                //Three.js模型对象的缩放属性可以在xyz三个方向上进行缩放,也就是说有三个分量需要表达
                var vertices = [];
                for (var i = 0; i < 8; i++) {
                    vertices.push(new THREE.Vector3(controlPoints[i].x, controlPoints[i].y, controlPoints[i].z));
                }
    
                mesh.children.forEach(function (e) {
                    //将vertices指向一个更新后的定点数组
                    e.geometry.vertices = vertices;
                    //告诉geometry对象,定点需要更新
                    e.geometry.verticesNeedUpdate = true;
                    //重新计算侧面
                    e.geometry.computeFaceNormals();
                });
    
                // 渲染
                requestAnimationFrame(render);
                renderer.render(scene, camera);
            }
    
        }
        window.onload = init;
    
    </script>
    </body>
    </html>

    实现效果

     



     

    博客园: https://www.cnblogs.com/badaoliumangqizhi/ 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。
  • 相关阅读:
    bat文件转换为exe文件
    桌面快捷方式增(删)
    客户推广微信小程序的几种方法如下
    小程序开发客户对接流程
    Java MySQL 连接
    前端开发构建工具
    [转]chrome 的devtools 中setting 开启workspace , 也有点用处。不是很大
    回归基础的东西,不能只是“感觉会了”
    angular 的ui.router 定义不同的state 对应相同的url
    学习javascript 非常好的博客
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/15111151.html
Copyright © 2020-2023  润新知