美文网首页Three.js
28three.js选择物体

28three.js选择物体

作者: 狂暴机甲 | 来源:发表于2018-05-31 19:18 被阅读2次
图片.png
点击所有的小球 演示地址:http://www.websql.xyz/projects/raycaster/index.html

var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());

    var scene,camera,renderer;
    var width = window.innerWidth;
    var height = window.innerHeight;
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(45,width/height,0.1,1000);
    camera.position.set(0,0,50);
    camera.lookAt(scene.position);
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(width,height);
    renderer.setClearColor(0x666666);
    renderer.shadowMap.enabled = true;
    var amblgiht = new THREE.AmbientLight(0x666666);
    scene.add(amblgiht);
    var spotlight = new THREE.SpotLight(0xffffff);
    spotlight.position.set(0,50,0);
    spotlight.castShadow = true;
    scene.add(spotlight);
    var axesh = new THREE.AxesHelper(1);
    scene.add(axesh);
    document.body.appendChild(renderer.domElement);
    renderer.render(scene,camera);
    var cube1 = new THREE.Mesh(new THREE.BoxGeometry(60,1,60),new THREE.MeshLambertMaterial({color:'#00dff5'}));
    cube1.position.set(0,-30,0);
    cube1.receiveShadow = true;
    scene.add(cube1);
    var controls;
    controls = new THREE.OrbitControls(camera);
    controls.autoRotate = true;
    controls.autoRotateSpeed = 1;
    var cubes = [];
    for(var i=0;i<36;i++){
        //x=rsinθcosφ.    y=rsinθsinφ.       z=rcosθ. 球空间坐标
        var angr1 = Math.round(360*Math.random());
        var angr2 = Math.round(360*Math.random());
        var xyz1 = 25*Math.sin(angr1)*Math.cos(angr2);
        var xyz2 = 25*Math.sin(angr1)*Math.sin(angr2);
        var xyz3 = 25*Math.cos(angr1);
        cubes[i] = new cubeDr();
        cubes[i].position.set(xyz1,xyz2,xyz3);
        scene.add(cubes[i]);
    }
    var ctimes = 0;//点击次数
    window.addEventListener( 'click', onDocumentMouseDown, false );
    function onDocumentMouseDown(event) {
        var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
        vector = vector.unproject(camera);
        var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());

        var intersects = raycaster.intersectObjects( cubes ); //只检测cubes里面的球体
        //如果选中物体且没有被点击过  修改其位置 并添加射线
        if(intersects[ 0 ].object.position.x != 0 && intersects[ 0 ].object.position.z != 0){
            if(intersects.length>0){
                //添加射线
                var points = [];
                points.push(new THREE.Vector3(0, intersects[ 0 ].object.position.y, 0));
                points.push(intersects[0].point);
                var mat = new THREE.MeshLambertMaterial({color: 0xff0000, transparent: true, opacity: 0.6});
                var tubeGeometry = new THREE.TubeGeometry(new THREE.CatmullRomCurve3(points), 64, 0.1);
                var tube = new THREE.Mesh(tubeGeometry, mat);
                scene.add(tube);

                ctimes ++;
                controls.autoRotateSpeed =  ctimes/4+1;
                intersects[ 0 ].object.material.color.set( 0xffffff );
                intersects[ 0 ].object.position.x = 0;
                intersects[ 0 ].object.position.z = 0;
            }
        }

        if(ctimes == 36){
            alert('您点中了全部小球,游戏结束');
            controls.autoRotate = false; //停止旋转
        }
        if(ctimes >= 36){
            window.removeEventListener( 'click', onDocumentMouseDown, false );
        }

        //如果穿过多个物体 全部选中
        /*for ( var i = 0; i < intersects.length; i++ ) {
            intersects[ i ].object.material.color.set( 0xffffff );
            intersects[ i ].object.position.x = 0;
            intersects[ i ].object.position.z = 0;
        }*/
    }
    rend();
    function rend() {
        renderer.render(scene,camera);
        controls.update();
        requestAnimationFrame(rend);
    }

    function cubeDr() {
        var cubeGem = new THREE.SphereGeometry(2,10,10,10);
        var cubeMat = new THREE.MeshLambertMaterial({color:0xffffff*Math.random()});
        var cube = new THREE.Mesh(cubeGem,cubeMat);
        cube.castShadow = true;
        return cube;
    }

流程:

  • 添加监听事件
  • 定义一个二维向量作为鼠标的坐标
  • 坐标转换
  • 交叉检测,可以设置参数true来递归组中的所有物体。
        window.addEventListener('click',onDocumentMouseDown,false);
        var mouse = new THREE.Vector2();
        var raycaster = new THREE.Raycaster();
        function getIntersects(event) {
            mouse.x = (event.clientX / window.innerWidth)*2 - 1;
            mouse.y = -(event.clientY / window.innerHeight)*2 + 1;
        }
        function onDocumentMouseDown(event) {
            getIntersects(event);
            clickParts();
        }
        function clickParts() {
            raycaster.setFromCamera(mouse,camera);
            var intersects = raycaster.intersectObjects(aiobject.children,true); //true递归后代
            if(intersects.length>0){
            //你的代码
            }
        }

相关文章

网友评论

    本文标题:28three.js选择物体

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