概要
three.jsでクリックした面の色が変わるような物を作ります。
バージョンはr93
デモ:https://arihide.github.io/demos/face_pick/
ソースコードはこちら
https://github.com/Arihide/demos/tree/master/face_pick
解説
普通にオブジェクト追加するのと異なる部分に絞って説明します。
material作成時のvertexColorsの指定
以下のように、Materialを作成する際にvertexColorsを指定するようにします。
こうすることで、面ごとに色を指定できるようになります。
var loader = new THREE.JSONLoader();
var mesh;
loader.load('./rough_plane.json', function (geo) {
var material = new THREE.MeshLambertMaterial({ color: 0xffffff, vertexColors: THREE.FaceColors });
mesh = new THREE.Mesh(geo, material);
scene.add(mesh);
renderer.render(scene, camera);
});
クリック時の処理
次に、クリックされた面の取得および、色変更について説明します。
以下がその処理部分です。
window.addEventListener('click', function (e) {
//クリックした面番号の取得
var square = getIntersectedIndex(e);
if (square !== undefined && mesh) {
mesh.geometry.colorsNeedUpdate = true;
mesh.geometry.faces[square].color.set(0x00ff00);
}
renderer.render(scene, camera);
}, false);
var raycaster = new THREE.Raycaster();
function getIntersectedIndex(e) {
var raymouse = new THREE.Vector2();
raymouse.x = (e.offsetX / width) * 2 - 1;
raymouse.y = -(e.offsetY / height) * 2 + 1;
raycaster.setFromCamera(raymouse, camera);
var intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
var square = intersects[0].faceIndex;
}
return square;
}
ここでは大きく
- getIntersectedIndexによる面番号の取得
- 面番号から実際に色を変更
の二つで構成されています。
1. getIntersectedIndexによる面番号の取得
そもそも、three.jsのメッシュには、faceIndexと呼ばれる面一つ一つに割り振られている番号があります。
THREE.RayCasterは交差判定処理をまとめたオブジェクトですが、「どの面番号の面と交差したか?」を調べることもできます。
getIntersectedIndexでは、これらを利用して、「クリックした面の面番号を返却する」処理になっています。
2. 面番号から実際に色を変更
色を変更したい面番号がわかったら
mesh.geometry.faces[faceIndex].color.set(color);
で、色を変更することができます。ただし、rendererに色が変更されたことを知らせるために
mesh.geometry.colorsNeedUpdate = true;
も指定する必要があります。