美文网首页
three.js(26)-模型拾取

three.js(26)-模型拾取

作者: 姜治宇 | 来源:发表于2023-01-03 15:01 被阅读0次
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            .elementTag {
                width: 200px;
                height: 200px;
                padding: 10px;
                background: blue;
            }
        </style>
        <script src="http://www.yanhuangxueyuan.com/threejs/build/three.min.js"></script>
        <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/controls/OrbitControls.js"></script>
        <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/GLTFLoader.js"></script>
        <script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/DRACOLoader.js"></script>
    </head>
    
    <body>
        <div id="webgl"></div>
    
    </body>
    
    </html>
    <script>
        var scene, camera, renderer;
        init();
        function init() {
            //场景
            scene = new THREE.Scene();
            //相机设置为世界坐标原点
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(100, 100, 100);
            scene.add(camera);//添加相机
    
            //添加坐标轴
            var axes = new THREE.AxesHelper(500);//500表示xyz轴的长度,红:x,绿:y,蓝:z
            scene.add(axes);
    
            addGlb('./model/floor2.glb');
            render();
            animate();
        }
    
        async function addGlb(filepath) {
            const loader = new THREE.GLTFLoader();
            const dracoloader = getDracoLoader();
            loader.setDRACOLoader(dracoloader);//注入loader
            //加载模型
            const floor = await loadGlb(filepath, loader);
    
            scene.add(floor.scene);
    
        }
    
        function getDracoLoader() {
            //对模型解压
            const dracoloader = new THREE.DRACOLoader();
            dracoloader.setDecoderPath("./draco/");//把examples\jsm\libs\draco这个文件夹复制过来
            dracoloader.setDecoderConfig({ type: "js" })
            dracoloader.preload();
            return dracoloader;
        }
        function loadGlb(filepath, loader) {
            return new Promise((resolve, reject) => {
    
                loader.setCrossOrigin('Anonymous');//跨域问题
                loader.load(filepath, (gltf) => {
                    console.log('gltf>>>', gltf);
                    //处理材质丢失的情况
                    gltf.scene.traverse(child => {
                        if (child.isMesh) {
                            child.material.emissive = child.material.color;
                            child.material.emissiveMap = child.material.map;
                        }
                    });
                    resolve(gltf);
                }, undefined, (error) => {
    
                    console.error(error);
                    reject(error);
    
                });
            });
        }
    
        
        //元素拾取
        function getXYZ(renderer, camera, scene) {
            const raycaster = new THREE.Raycaster(); //光线投射,用于确定鼠标点击位置
            const mouse = new THREE.Vector2(); //创建二维平面
            window.addEventListener("mousedown", mousedown); //页面绑定鼠标点击事件
            //点击方法
            function mousedown(e) {
                //将html坐标系转化为webgl坐标系,并确定鼠标点击位置
                mouse.x = (e.clientX / renderer.domElement.clientWidth) * 2 - 1;
                mouse.y = -((e.clientY / renderer.domElement.clientHeight) * 2) + 1;
                //以camera为z坐标,确定所点击物体的3D空间位置
                raycaster.setFromCamera(mouse, camera);
                //确定所点击位置上的物体数量
                const intersects = raycaster.intersectObjects(scene.children);
                //选中后进行的操作
                if (intersects.length) {
                    var selected = intersects[0]; //取第一个物体
                    console.log(selected);
                    console.log("x坐标:" + selected.point.x);
                    console.log("y坐标:" + selected.point.y);
                    console.log("z坐标:" + selected.point.z);
                }
            }
        }
    
        function render() {
            renderer = new THREE.WebGLRenderer({
                antialias: true,
    
            });//画布
            renderer.setSize(window.innerWidth, window.innerHeight);//设置渲染区域尺寸
            renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    
            window.addEventListener('resize', () => {
                camera.aspect = window.innerWidth / window.innerHeight;
    
                camera.updateProjectionMatrix();
    
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.setPixelRatio(window.devicePixelRatio);
    
            });
    
            //将渲染好的canvas追加到dom
            var cont = document.getElementById('webgl');
            cont.appendChild(renderer.domElement);
            var controls = new THREE.OrbitControls(camera, renderer.domElement);
    
            getXYZ(renderer, camera, scene);
        }
    
        function animate() {
    
            renderer.render(scene, camera);//开始渲染
            requestAnimationFrame(animate);
    
        }
    
    
    
    </script>
    

    相关文章

      网友评论

          本文标题:three.js(26)-模型拾取

          本文链接:https://www.haomeiwen.com/subject/fyflcdtx.html