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