ThreeJs能力演示——图层间物体迁移

1、支持图层间物体迁移

获取原图层下子节点,原图层删除此节点,新图层添加此节点。

javascript 复制代码
    // 添加迁移功能的 GUI
    const migrationFolder = gui.addFolder('Migration');
    const migrationOptions = {
        sourceLayer: 0,
        targetLayer: 1,
        objectType: 'cube',
        objectIndex: 0
    };
    const sourceLayerSelect = migrationFolder.add(migrationOptions, 'sourceLayer', [0, 1, 2]).name('源图层');
    const targetLayerSelect = migrationFolder.add(migrationOptions, 'targetLayer', [0, 1, 2]).name('目标图层');
    const objectIndexSelect = migrationFolder.add(migrationOptions, 'objectIndex', [0, 1, 2]).name('物体索引');
    migrationFolder.add({ migrate: () => migrateObject() }, 'migrate').name('迁移');
    // 迁移几何体
    function migrateObject() {
        const sourceLayer = layers[migrationOptions.sourceLayer];
        const targetLayer = layers[migrationOptions.targetLayer];
        let objectToMigrate = sourceLayer.children[migrationOptions.objectIndex];
        if (objectToMigrate) {
            sourceLayer.remove(objectToMigrate);
            targetLayer.add(objectToMigrate);
        }
    }

2、整体代码演示

html 复制代码
<!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 layer0 = new THREE.Object3D()
    const layer0_1 = new THREE.Object3D()
    layer0.add(layer0_1)
    const layer1 = new THREE.Object3D()
    const layer2 = new THREE.Object3D()
    const layers = [layer0, layer1, layer2]
    // 存储创建的几何体列表
    createCube(0, layer0)
    createCube(1, layer1)
    createCube(2, layer2)
    createCube(0.5, layer0_1)
    for (let layer of layers) {
        scene.add(layer)
    }
    // 创建正方体
    function createCube(place, layerObj) {
        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${layerIndex}';
        cube.position.set(place*2, place*2, place*2)
        layerObj.add(cube)
        return cube;
    }

    // GUI控制显示图层
    const gui = new GUI();
    const layerFolders = [];
    for (let i = 0; i < 3; i++) {
        const layerFolder = gui.addFolder(`Layer ${i}`);
        const layerEnabled = layerFolder.add({ enabled: true }, 'enabled').name('可见性');
        layerEnabled.onChange((value) => {
            console.log(`index ${i} enabled: ${value}`)
            layers[i].visible = value
        });
        layerFolders.push(layerFolder);
    }
    // 添加迁移功能的 GUI
    const migrationFolder = gui.addFolder('Migration');
    const migrationOptions = {
        sourceLayer: 0,
        targetLayer: 1,
        objectType: 'cube',
        objectIndex: 0
    };
    const sourceLayerSelect = migrationFolder.add(migrationOptions, 'sourceLayer', [0, 1, 2]).name('源图层');
    const targetLayerSelect = migrationFolder.add(migrationOptions, 'targetLayer', [0, 1, 2]).name('目标图层');
    const objectIndexSelect = migrationFolder.add(migrationOptions, 'objectIndex', [0, 1, 2]).name('物体索引');
    migrationFolder.add({ migrate: () => migrateObject() }, 'migrate').name('迁移');
    // 迁移几何体
    function migrateObject() {
        const sourceLayer = layers[migrationOptions.sourceLayer];
        const targetLayer = layers[migrationOptions.targetLayer];
        let objectToMigrate = sourceLayer.children[migrationOptions.objectIndex];
        if (objectToMigrate) {
            sourceLayer.remove(objectToMigrate);
            targetLayer.add(objectToMigrate);
        }
    }
</script>
</body>
</html>
相关推荐
明灯L27 分钟前
《深度剖析 Linux 权限管理:从基础到进阶,解锁系统安全密钥》
linux·运维·全网最全权限管理·小白0基础
luback41 分钟前
页面编辑器CodeMirror初始化不显示行号或文本内容
前端·codemirror
一勺-_-42 分钟前
Chrome浏览器和Microsoft Edge浏览器的导出收藏链接
前端·chrome·edge
无名之逆1 小时前
[特殊字符] 超轻高性能的 Rust HTTP 服务器 —— Hyperlane [特殊字符][特殊字符]
java·服务器·开发语言·前端·网络·http·rust
是覆盖对于变化1 小时前
ubuntu22.04 进入不了系统设置
linux·ubuntu
蘑菇头爱平底锅1 小时前
数字孪生-DTS-孪创城市-导览功能、虚拟现实
前端·数据可视化
应以大橘为重1 小时前
interrupt子系统中的数据结构
linux·数据结构·驱动开发
一口一个橘子1 小时前
[ctfshow web入门] web40
前端·web安全·网络安全
kfepiza1 小时前
硬盘分区格式方案之 MBR(Master Boot Record)主引导记录详解 笔记250407
linux·windows·笔记
mzak1 小时前
已经安装了pip,出现pip command not found【解决方法】
linux·pip·python3