不到断气不罢休 发表于 7 小时前

ThreeJs功能演示——多少体操纵导入导出

1、内部创建多少体导出编辑能力
1)支持内部创建的面、正方体、球体

内部创建物体时,如果是三维物体,要创建聚集形状geometry,和对应的材质material。再一起创建一个三维物体。
        // 存储创建的几何体列表
        const geometries = [];
        createPlane()
        createCube()
        createSphere()
        addGUIForGeometry(geometries)
        // 几何体创建函数
        function createPlane() {
                const geometry = new THREE.PlaneGeometry(1,1);
                const material = new THREE.MeshBasicMaterial({color:0xffff00, side:THREE.DoubleSide})
                const plane = new THREE.Mesh(geometry, material)
                plane.name = "Plane";
                plane.position.set(-1, -1, -1)
                scene.add(plane)
                geometries.push(plane)
                return plane;
        }
        // 创建正方体
        function createCube() {
                const geometry = new THREE.BoxGeometry(1, 1, 1 );
                const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
                const cube = new THREE.Mesh( geometry, material );
                cube.name = 'Cube';
                scene.add( cube );
                geometries.push(cube);
                return cube;
        }
        // 创建球体
        function createSphere() {
                const geometry = new THREE.SphereGeometry( 1, 32, 32 );
                const material = new THREE.MeshBasicMaterial( {color: 0x0000ff} );
                const sphere = new THREE.Mesh( geometry, material );
                sphere.name = 'Sphere';
                sphere.position.set(2,2,2)
                scene.add( sphere );
                geometries.push(sphere);
                return sphere;
        } 2)支持多少体的位置、角度、比例调解

通过GUI控制器调解创建物体的位置、角度、放大比例信息。
        // GUI控制器
        function addGUIForGeometry(geometryArr) {
                const gui = new GUI();
                gui.add({x:0}, 'x', -10, 10).name('Position X').onChange((value)=>{
                        for (let element of geometryArr) {
                                console.log(element.position)
                                element.position.set(value, element.position.y, element.position.z)
                        }
                        animate()
                });
                gui.add({scale:1}, 'scale', 0.1, 10).name('Scale').onChange((value)=>{
                        for (let element of geometryArr) {
                                element.scale.set(value, value, value)
                        }
                        animate()
                });
                gui.add({rotateX:0}, "rotateX",-Math.PI, Math.PI).name("Rotate X").onChange((value)=>{
                        for (let element of geometryArr) {
                                element.rotation.set(value, element.rotation.y, element.rotation.z)
                        }
                        animate()
                })
                gui.open();
        } 3)支持多少体批量导出、重新导入

将3D物体的位置、形状、角度、放大序列化到json文件,支持导出。
导入时,根据物体的类型分别创建3D模型
        // 导入几何体
        function importGeometries() {
                const input = document.createElement('input');
                input.type = 'file';
                input.accept = '.json';
                input.addEventListener('change', (event) => {
                        const file = event.target.files;
                        if (file) {
                                const reader = new FileReader();
                                reader.onload = (e) => {
                                        const geometriesData = JSON.parse(e.target.result);
                                        geometriesData.forEach(data => {
                                                let geometry;
                                                let material;
                                                switch (data.type) {
                                                        case 'Mesh':
                                                                switch (data.name) {
                                                                        case 'Plane':
                                                                                geometry = new THREE.PlaneGeometry(data.geometryData.vertices, data.geometryData.indices);
                                                                                material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
                                                                                break;
                                                                        case 'Cube':
                                                                                geometry = new THREE.BoxGeometry(data.geometryData.vertices, data.geometryData.indices);
                                                                                material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
                                                                                break;
                                                                        case 'Sphere':
                                                                                geometry = new THREE.SphereGeometry(data.geometryData.vertices, data.geometryData.indices);
                                                                                material = new THREE.MeshBasicMaterial({ color: 0x0000ff });
                                                                                break;
                                                                }
                                                                const mesh = new THREE.Mesh(geometry, material);
                                                                mesh.name = data.name;
                                                                mesh.position.fromArray(data.position);
                                                                mesh.rotation.fromArray(data.rotation);
                                                                mesh.scale.fromArray(data.scale);
                                                                scene.add(mesh);
                                                                geometries.push(mesh);
                                                                break;
                                                }
                                        });
                                };
                                reader.readAsText(file);
                        }
                });
                input.click();
        } 2、整体代码

<!DOCTYPE html><html lang="en"><head>        <meta charset="UTF-8">        <meta name="viewport" content="width=device-width, initial-scale=1.0">        <title>Three.js 多少体操纵示例</title>        <style>                body { margin: 0; overflow: hidden; }                #camera-info {                        position: absolute;                        top: 10px;                        left: 10px;                        background-color: rgba(0, 0, 0, 0.5);                        color: white;                        padding: 10px;                        font-family: Arial, sans-serif;                }        </style></head><body><div id="camera-info"></div><script type="importmap">        {                "imports": {                        "three": "./three.js-master/build/three.module.js",                        "three/addons/": "./three.js-master/examples/jsm/"                }        }</script><script type="module">        import * as THREE from "three"        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';        import { GUI } from 'three/addons/libs/lil-gui.module.min.js';        // 1) 创建画布        const scene = new THREE.Scene();        scene.background = new THREE.Color( 0xa0a0a0 );        const renderer = new THREE.WebGLRenderer();        renderer.setSize(window.innerWidth, window.innerHeight);        document.body.appendChild(renderer.domElement);        // 2) 设置 camera 位置,朝向角度        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);        camera.position.set(0, 0, 20); // 设置相机位置        camera.lookAt(scene.position); // 让相机朝向场景中心        // 设置控制轨道        const controls = new OrbitControls( camera, renderer.domElement );        controls.target.set( 0, 0.1, 0 );        controls.update();        controls.minDistance = 0.5;        controls.maxDistance = 1000;        controls.maxPolarAngle = 0.5 * Math.PI;        // 5) 支持动态显示摄像头位置、角度、缩放信息        const cameraInfo = document.getElementById('camera-info');        function updateCameraInfo() {                cameraInfo.innerHTML = `                摄像头信息:<br>                位置: (${camera.position.x.toFixed(2)}, ${camera.position.y.toFixed(2)}, ${camera.position.z.toFixed(2)})<br>                角度: (${camera.rotation.x.toFixed(2)}, ${camera.rotation.y.toFixed(2)}, ${camera.rotation.z.toFixed(2)})<br>                缩放: ${camera.zoom.toFixed(2)}            `;        }        updateCameraInfo();        // 渲染循环        function animate() {                requestAnimationFrame(animate);                updateCameraInfo();                renderer.render(scene, camera);        }        animate();        // 存储创建的几何体列表
        const geometries = [];
        createPlane()
        createCube()
        createSphere()
        addGUIForGeometry(geometries)
        // 几何体创建函数
        function createPlane() {
                const geometry = new THREE.PlaneGeometry(1,1);
                const material = new THREE.MeshBasicMaterial({color:0xffff00, side:THREE.DoubleSide})
                const plane = new THREE.Mesh(geometry, material)
                plane.name = "Plane";
                plane.position.set(-1, -1, -1)
                scene.add(plane)
                geometries.push(plane)
                return plane;
        }
        // 创建正方体
        function createCube() {
                const geometry = new THREE.BoxGeometry(1, 1, 1 );
                const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
                const cube = new THREE.Mesh( geometry, material );
                cube.name = 'Cube';
                scene.add( cube );
                geometries.push(cube);
                return cube;
        }
        // 创建球体
        function createSphere() {
                const geometry = new THREE.SphereGeometry( 1, 32, 32 );
                const material = new THREE.MeshBasicMaterial( {color: 0x0000ff} );
                const sphere = new THREE.Mesh( geometry, material );
                sphere.name = 'Sphere';
                sphere.position.set(2,2,2)
                scene.add( sphere );
                geometries.push(sphere);
                return sphere;
        }        // GUI控制器
        function addGUIForGeometry(geometryArr) {
                const gui = new GUI();
                gui.add({x:0}, 'x', -10, 10).name('Position X').onChange((value)=>{
                        for (let element of geometryArr) {
                                console.log(element.position)
                                element.position.set(value, element.position.y, element.position.z)
                        }
                        animate()
                });
                gui.add({scale:1}, 'scale', 0.1, 10).name('Scale').onChange((value)=>{
                        for (let element of geometryArr) {
                                element.scale.set(value, value, value)
                        }
                        animate()
                });
                gui.add({rotateX:0}, "rotateX",-Math.PI, Math.PI).name("Rotate X").onChange((value)=>{
                        for (let element of geometryArr) {
                                element.rotation.set(value, element.rotation.y, element.rotation.z)
                        }
                        animate()
                })
                gui.open();
        }        function handleKeyDown(event) {                switch (event.key) {                        case 'e':                                exportToJSON(geometries)                                break;                        case 'r':                                clearGeometries(geometries)                                break;                        case 'i':                                importGeometries(geometries)                                break;                }        }        document.addEventListener('keydown', handleKeyDown);        function exportToJSON(geometryList) {                const geometriesData = geometryList.map(geometry => {                        return {                                name: geometry.name,                                position: geometry.position.toArray(),                                rotation: geometry.rotation.toArray(),                                scale: geometry.scale.toArray(),                                // 根据多少体类型添加更多特定信息                                type: geometry.type,                                geometryData: geometry.geometry.toJSON()                        };                });                const blob = new Blob(, { type: 'application/json' });                const url = URL.createObjectURL(blob);                const a = document.createElement('a');                a.href = url;                a.download = 'geometries.json';                document.body.appendChild(a);                a.click();                document.body.removeChild(a);                URL.revokeObjectURL(url);        }        // 清除多少体        function clearGeometries(geoArr) {                geometries.forEach(geometry => scene.remove(geometry));                geometries.length = 0;        }        // 导入几何体
        function importGeometries() {
                const input = document.createElement('input');
                input.type = 'file';
                input.accept = '.json';
                input.addEventListener('change', (event) => {
                        const file = event.target.files;
                        if (file) {
                                const reader = new FileReader();
                                reader.onload = (e) => {
                                        const geometriesData = JSON.parse(e.target.result);
                                        geometriesData.forEach(data => {
                                                let geometry;
                                                let material;
                                                switch (data.type) {
                                                        case 'Mesh':
                                                                switch (data.name) {
                                                                        case 'Plane':
                                                                                geometry = new THREE.PlaneGeometry(data.geometryData.vertices, data.geometryData.indices);
                                                                                material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
                                                                                break;
                                                                        case 'Cube':
                                                                                geometry = new THREE.BoxGeometry(data.geometryData.vertices, data.geometryData.indices);
                                                                                material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
                                                                                break;
                                                                        case 'Sphere':
                                                                                geometry = new THREE.SphereGeometry(data.geometryData.vertices, data.geometryData.indices);
                                                                                material = new THREE.MeshBasicMaterial({ color: 0x0000ff });
                                                                                break;
                                                                }
                                                                const mesh = new THREE.Mesh(geometry, material);
                                                                mesh.name = data.name;
                                                                mesh.position.fromArray(data.position);
                                                                mesh.rotation.fromArray(data.rotation);
                                                                mesh.scale.fromArray(data.scale);
                                                                scene.add(mesh);
                                                                geometries.push(mesh);
                                                                break;
                                                }
                                        });
                                };
                                reader.readAsText(file);
                        }
                });
                input.click();
        }</script></body></html>

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: ThreeJs功能演示——多少体操纵导入导出