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>
相关推荐
东风破_15 小时前
LLM 为什么记不住你?无状态、messages 和上下文管理
javascript·人工智能
梨子同志15 小时前
qiankun
前端
梨子同志15 小时前
Nginx
前端
梨子同志15 小时前
NestJS
前端
梨子同志16 小时前
Next.js
前端
谭光志16 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
Hilaku16 小时前
前端架构师的克制:什么时候该坚决对新技术说不?
前端·javascript·程序员
陈随易16 小时前
前端项目部署只要30秒
前端·后端·程序员
本末倒置18316 小时前
从 Vue CLI 迁移到 Rsbuild 后,JSX 突然全挂了?一次排查记录
前端
古夕16 小时前
多应用同域部署下 Favicon 异常问题排查与治理
前端·javascript