three.js实现鼠标拾取例子

image

基本思路
1、获取与鼠标射线相交的第一个物体
2、保留物体原来的颜色
3、改变物体的颜色
4、鼠标已开物体,将物体的颜色换回原来的颜色

实现代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body{
            background-color: #f0f0f0;
            margin: 0px;
            overflow: hidden;
        }
    </style>
</head>
<body>
<script src="/js/three.js"></script>
<script src="/js/Stats.js"></script>
<script>
    var renderer,scene,camera;
    var light;
    var raycaster,mouse;
    var stats;
    init();
    animation();

    function init(){

        //性能
        stats = new Stats();
        stats.domElement.style.position = 'absolute';
        stats.domElement.style.top='0px';
        document.body.appendChild(stats.domElement);

        //创建一个渲染器
        renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth,window.innerHeight);
        renderer.setClearColor(0xf0f0f0);
        renderer.setPixelRatio(window.devicePixelRatio);//设置设备像素比。通常用于HiDPI设备防止模糊输出canvas。
        document.body.appendChild(renderer.domElement);
        //创建一个场景
        scene = new THREE.Scene();
        //创建一个相机
        camera = new  THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,5000);
        camera.position.x = 50;
        camera.position.y = 50;
        camera.position.z = 500;
        camera.up.x = 0;
        camera.up.y = 1;
        camera.up.z = 0;
        camera.lookAt({
            x:0,
            y:0,
            z:0
        });
        //创建一个方向光
        light = new THREE.DirectionalLight(0xffffff);
        light.position.z = 500;
        scene.add(light);
        //创建2000个立方体
        var geometry = new THREE.BoxGeometry(20,20,20);
        for(var i =0;i<2000;i++){
            var materail = new THREE.MeshLambertMaterial({color:Math.random()*0xffffff});
            var mesh = new THREE.Mesh(geometry,materail);

            mesh.position.x = Math.random()*800-400;
            mesh.position.y = Math.random()*800-400;
            mesh.position.z = Math.random()*800-400;

            mesh.rotation.x = Math.random()*Math.PI*2;//Math.PI*2为圆的周长
            mesh.rotation.y = Math.random()*Math.PI*2;
            mesh.rotation.z = Math.random()*Math.PI*2;

            mesh.scale.x = Math.random()+0.5
            mesh.scale.y = Math.random()+0.5
            mesh.scale.z = Math.random()+0.5

            scene.add(mesh);
        }
        //鼠标拾取
        //创建一个Raycaster光线投射
        raycaster = new THREE.Raycaster();
        //创建一个射线向量
        mouse = new THREE.Vector2();
        //鼠标移动事件,目的是将鼠标坐标归一化
        window.addEventListener('mousemove',onMouseMove,false);

    }
    function animation(){
        stats.begin();
        render();
        stats.end();
        requestAnimationFrame(animation);
        stats.update();
    }

    var radius=100,theta=0;
    var INTERSECTED;
    function render(){
        theta+=0.1;
        camera.position.x = radius*Math.sin(THREE.Math.degToRad(theta));
        camera.position.y = radius*Math.sin(THREE.Math.degToRad(theta));
        camera.position.z = radius*Math.cos(THREE.Math.degToRad(theta));
        camera.lookAt(scene.position);
        camera.updateMatrix();



        //更新鼠标与相机的射线
        raycaster.setFromCamera(mouse,camera);
        //获取与射线相交的所有物体
        var intersects = raycaster.intersectObjects(scene.children);
        //判断是否有相交的物体
        if(intersects.length>0){
            if(INTERSECTED) {//如果选中的不是相交的第一个对象,如果INTERSECTED不为空,说明之前有选中过对象,先把之前的物体恢复回原来的颜色,再将新的相交到的第一个物体赋给塔
                INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);//恢复物体原来的颜色
            }
            //不管之前有没有选中的物体,新的射线相交后有相交的物体都把第一个相交的赋给INTERSECTED
            INTERSECTED = intersects[0].object;//获取相交的第一个物体
            INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();//保存修改之前的颜色,以便后面恢复
            INTERSECTED.material.emissive.setHex(0xff0000);
        }else{
            if(INTERSECTED) INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
            INTERSECTED=null;
        }
        renderer.render(scene,camera);
    }

    function onMouseMove(event){
        event.preventDefault();
        mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
        mouse.y = -( event.clientY / window.innerHeight ) * 2 + 1;
    }
</script>
</body>
</html>

posted @ 2022-09-06 11:10  huangchun0121  阅读(336)  评论(0编辑  收藏  举报