three.js(26)-模型拾取

2023-01-03  本文已影响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>
上一篇下一篇

猜你喜欢

热点阅读