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>

实现效果

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

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

 

 



 

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

上一篇:netty系列之:Event、Handler和Pipeline


下一篇:线上环境vsftp文件上传后不能写入问题总结