LoginSignup
0
0

More than 5 years have passed since last update.

オブジェクトの選択

Last updated at Posted at 2016-08-18

REVISION: '78'

デモ:http://codepen.io/mo4_9/pen/GqLjba

テストが終わり次第mousemoveイベントは削除

click処理の抜粋(ES6)

class MyRaycaster {
    constructor(opts = {}) {
        this.tube = null;
        this.controls = this.getControls();
        this.init();
    }

    init () {

        ------

        document.addEventListener('mousedown', e => {
            this.onDocumentMouseDown(e);
        }, false);
        // テストが終わったら削除
        document.addEventListener('mousemove', e => {
            this.onDocumentMouseMove(e);
        }, false);

        ------

        this.getControls();
        this.setDatGUI();
        this.render();
    }

    getControls () {
        const controls = new function () {
            this.showRay = true;
        };
        return controls;
    }

    setDatGUI () {
        const gui = new dat.GUI();
        console.log(this.controls.showRay);
        gui.add(this.controls, 'showRay').onChange( (e) => {
            if (this.tube) this.scene.remove(this.tube)
        });
    }

    render () {
        this.renderer.render(this.scene, this.camera);
        requestAnimationFrame( () => {
            this.render();
        });
    }

    // クリックしたオブジェクトを取得
    onDocumentMouseDown(e) {

        const intersects = this.getIntersectObjects(e);

        if (intersects.length > 0) {

            console.log('intersects[0] : ', intersects[0]); // 最も近いオブジェクト
            console.log('distance : ', intersects[0].distance);
            console.log('vector3 : ', intersects[0].point.x + ", " + intersects[0].point.y + ", " + intersects[0].point.z); // 光線との交差座標

            intersects[0].object.material.transparent = true;
            intersects[0].object.material.opacity = 0.1;
        }
    }

    // raycastの補助線
    onDocumentMouseMove(e) {
        if (!this.controls.showRay) return;

        const intersects = this.getIntersectObjects(e);

        if (intersects.length > 0) {

            let points = [];

            points.push(new THREE.Vector3(this.startPointX, this.startPointY - 0.2, this.startPointZ));
            points.push(intersects[0].point);

            const mat = new THREE.MeshBasicMaterial({color: 0xff0000, transparent: true, opacity: 0.6});
            const tubeGeometry = new THREE.TubeGeometry(new THREE.CatmullRomCurve3(points), 60, 0.001);

            if (this.tube) this.scene.remove(this.tube);

            if (this.controls.showRay) {
                this.tube = new THREE.Mesh(tubeGeometry, mat);
                this.scene.add(this.tube);
            }
            console.log(points[1].x, points[1].y, points[1].z);
        }
    }

    // 光線と交わるオブジェクトを収集
    getIntersectObjects(e) {
        // クリックされた位置を元にVector3を生成
        let vector = new THREE.Vector3(
          ( e.clientX / window.innerWidth ) * 2 - 1,
          -( e.clientY / window.innerHeight ) * 2 + 1, 0.5);
        // Three.js内の座標に変換
        // スクリーン座標系からワールド座標系に逆射影
        vector.unproject(this.camera);

        // カメラからクリックされた位置まで光線を飛ばす
        const raycaster = new THREE.Raycaster( this.camera.position, vector.sub(this.camera.position).normalize() );

        // 光線と交わるオブジェクトの登録
        const intersects = raycaster.intersectObjects([this.sphere, this.cylinder, this.cube]);

        return intersects;
    }

}

const myRaycaster = new MyRaycaster();

参考
初めてのThree.js 第2版――WebGLのためのJavaScript 3Dライブラリ
http://qiita.com/mo49/items/c8ca223fb90a8053f902

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0