plunkerでthree.js その7

# 概要
plunkerでthree.jsやってみた。
THREE.Raycaster、やってみた。

# 参考にしたページ

https://codepen.io/wwwang176/pen/gdWbBd


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0f099db4-19d6-c696-573d-2ad7840d2f81.png)


# サンプルコード

```

function LaserBeam(iconfig) {
    var config = {
        length: 100,
        reflectMax: 1
    };
    config = $.extend(config, iconfig);
    this.object3d = new THREE.Object3D();
    this.reflectObject = null;
    this.pointLight = new THREE.PointLight(0xffffff, 1, 4);
    var raycaster = new THREE.Raycaster();
    var canvas = generateLaserBodyCanvas();
    var texture = new THREE.Texture(canvas);
    texture.needsUpdate = true;
    var material = new THREE.MeshBasicMaterial({
        map: texture,
        blending: THREE.AdditiveBlending,
        color: 0x4444aa,
        side: THREE.DoubleSide,
        depthWrite: false,
        transparent: true
    });
    var geometry = new THREE.PlaneGeometry(1, 0.1 * 5);
    geometry.rotateY(0.5 * Math.PI);
    var i, 
        nPlanes = 15;
    for (i = 0; i < nPlanes; i++) 
    {
        var mesh = new THREE.Mesh(geometry, material);
        mesh.position.z = 1 / 2;
        mesh.rotation.z = i / nPlanes * Math.PI;
        this.object3d.add(mesh);
    }
    if (config.reflectMax > 0)
        this.reflectObject = new LaserBeam($.extend(config, {
            reflectMax: config.reflectMax - 1
        }));
    this.intersect = function(direction, objectArray = []) {
        raycaster.set(this.object3d.position.clone(), direction.clone().normalize());
        var intersectArray = [];
        intersectArray = raycaster.intersectObjects(objectArray, true);
        if (intersectArray.length > 0) 
        {
            this.object3d.scale.z = intersectArray[0].distance;
            this.object3d.lookAt(intersectArray[0].point.clone());
            this.pointLight.visible = true;
            var normalMatrix = new THREE.Matrix3().getNormalMatrix(intersectArray[0].object.matrixWorld);
            var normalVector = intersectArray[0].face.normal.clone().applyMatrix3(normalMatrix).normalize();
            this.pointLight.position.x = intersectArray[0].point.x + normalVector.x * 0.5;
            this.pointLight.position.y = intersectArray[0].point.y + normalVector.y * 0.5;
            this.pointLight.position.z = intersectArray[0].point.z + normalVector.z * 0.5;
            var reflectVector = new THREE.Vector3(intersectArray[0].point.x - this.object3d.position.x, intersectArray[0].point.y - this.object3d.position.y, intersectArray[0].point.z - this.object3d.position.z).normalize().reflect(normalVector);
            if (this.reflectObject != null) 
            {
                this.reflectObject.object3d.visible = true;
                this.reflectObject.object3d.position.set(intersectArray[0].point.x, intersectArray[0].point.y, intersectArray[0].point.z);
                this.reflectObject.intersect(reflectVector.clone(), objectArray);
            }
        }
        else 
        {
            this.object3d.scale.z = config.length;
            this.pointLight.visible = false;
            this.object3d.lookAt(this.object3d.position.x + direction.x, this.object3d.position.y + direction.y, this.object3d.position.z + direction.z);
            this.hiddenReflectObject();
        }
    }
    this.hiddenReflectObject = function() {
        if (this.reflectObject != null) 
        {
            this.reflectObject.object3d.visible = false;
            this.reflectObject.pointLight.visible = false;
            this.reflectObject.hiddenReflectObject();
        }
    }
    return;
    function generateLaserBodyCanvas() {
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        canvas.width = 1;
        canvas.height = 64;
        var gradient = context.createLinearGradient(0, 0, canvas.width, canvas.height);
        gradient.addColorStop(0, 'rgba(0, 0, 0, 0.1)');
        gradient.addColorStop(0.1, 'rgba(160, 160, 160, 0.3)');
        gradient.addColorStop(0.5, 'rgba(255, 255, 255, 0.5)');
        gradient.addColorStop(0.9, 'rgba(160, 160, 160, 0.3)');
        gradient.addColorStop(1.0, 'rgba(0, 0, 0, 0.1)');
        context.fillStyle = gradient;
        context.fillRect(0, 0, canvas.width, canvas.height);
        return canvas;
    }
}

function add2Scene(obj) {
    scene.add(obj.object3d);
    scene.add(obj.pointLight);
    if (obj.reflectObject != null) 
    {
        add2Scene(obj.reflectObject);
    }
}

function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
}

var scene, 
    camera, 
    renderer, 
    container;
var Ambient, 
    sunLight;
var LaserBeam1;
var Geometry, 
    Material;
var objectArray = [];
renderer = new THREE.WebGLRenderer({ 
	antialias: true 
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 200000);
camera.position.set(0, 10, 10);
camera.lookAt(0, 0, 0);
scene.add(camera);
var mouse = {
    x: 0,
    y: 0
}
document.addEventListener('mousemove', function(event) {
    mouse.x = (event.clientX / window.innerWidth) - 0.5
    mouse.y = (event.clientY / window.innerHeight) - 0.5
}, false);
renderer.setClearColor(0x222222);
window.addEventListener('resize', onWindowResize, false);
Ambient = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(Ambient);
sunLight = new THREE.DirectionalLight(0xffffff, 0.5);
sunLight.position.set(5, 2, -10);
scene.add(sunLight);
for (var i = 0; i < 5; i++) 
{
    Geometry = new THREE.BoxGeometry(1, 2, 4);
    Material = new THREE.MeshPhongMaterial({
        color: 0x00ff00
    });
    var Mash = new THREE.Mesh(Geometry, Material);
    Mash.position.set((i % 2) * 5 - 2.5, 0, i * -5);
    objectArray.push(Mash);
    scene.add(Mash);
}
var LaserBeam1 = new LaserBeam({
    reflectMax: 5
});
add2Scene(LaserBeam1);
function animate() {
    requestAnimationFrame(animate);
    LaserBeam1.object3d.position.set(4.5, 0, 7);
    LaserBeam1.intersect(new THREE.Vector3(-4.5, 0, -4.5 + Math.cos(Date.now() * 0.05 * Math.PI / 180) * 2), objectArray);
    camera.position.x += (mouse.x * 30 - camera.position.x) * 0.05
    camera.position.y += (mouse.y * -10 - camera.position.y + 5) * 0.05
    camera.lookAt(scene.position);
    renderer.render(scene, camera);
}
animate();




```

# 成果物

https://embed.plnkr.co/plunk/NCX6k8EMkHTccNDp


以上。