Edited at

Three.jsのRaycasterを使って、画面内のオブジェクトを得る

More than 3 years have passed since last update.

Three.jsのRaycasterクラスを使って、画面内のオブジェクトを取得するサンプル。

ざっくり手順を書くと、


  1. マウス位置を取得

  2. マウス位置をWebGL内の座標系に変換

  3. マウス位置からまっすぐに伸びる光線ベクトルを生成

  4. その光線とぶつかったオブジェクトを得る

という手順。色々めんどくさいこともThree.jsがやってくれるので、以下のようにするだけで該当オブジェクトをさくっと得ることができる。

[2015.01.18 upate]

unprojectメソッドは、Vectorクラスに移動したようです。


raycast-sample.js

function onmousemove(e) {

var rect = e.target.getBoundingClientRect();

// スクリーン上のマウス位置を取得する
var mouseX = e.clientX - rect.left;
var mouseY = e.clientY - rect.top;

// 取得したスクリーン座標を-1〜1に正規化する(WebGLは-1〜1で座標が表現される)
mouseX = (mouseX/window.innerWidth) * 2 - 1;
mouseY = -(mouseY/window.innerHeight) * 2 + 1;

// マウスの位置ベクトル
var pos = new THREE.Vector3(mouseX, mouseY, 1);

// pos はスクリーン座標系なので、オブジェクトの座標系に変換
// オブジェクト座標系は今表示しているカメラからの視点なので、第二引数にカメラオブジェクトを渡す
// new THREE.Projector.unprojectVector(pos, camera); ↓最新版では以下の方法で得る
pos.unproject(camera);

// 始点、向きベクトルを渡してレイを作成
var ray = new THREE.Raycaster(camera.position, pos.sub(camera.position).normalize());

// 交差判定
// 引数は取得対象となるMeshの配列を渡す。以下はシーン内のすべてのオブジェクトを対象に。
var objs = ray.intersectObjects(scene.children);

//ヒエラルキーを持った子要素も対象とする場合は第二引数にtrueを指定する
//var objs = ray.intersectObjects(scene.children, true);

if (obj.length > 0) {
// 交差していたらobjsが1以上になるので、やりたいことをやる。
objs[0].object.position.x = 10;
}
}