3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

three.js マウスクリックで一部の面の色を変える

Last updated at Posted at 2020-06-28

概要

three.jsでクリックした面の色が変わるような物を作ります。
バージョンはr93

デモ:https://arihide.github.io/demos/face_pick/
スクリーンショット 2020-06-28 14.42.12.png

ソースコードはこちら
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;
}

ここでは大きく

  1. getIntersectedIndexによる面番号の取得
  2. 面番号から実際に色を変更
    の二つで構成されています。
1. getIntersectedIndexによる面番号の取得

そもそも、three.jsのメッシュには、faceIndexと呼ばれる面一つ一つに割り振られている番号があります。
THREE.RayCasterは交差判定処理をまとめたオブジェクトですが、「どの面番号の面と交差したか?」を調べることもできます。
getIntersectedIndexでは、これらを利用して、「クリックした面の面番号を返却する」処理になっています。

2. 面番号から実際に色を変更

色を変更したい面番号がわかったら
mesh.geometry.faces[faceIndex].color.set(color);
で、色を変更することができます。ただし、rendererに色が変更されたことを知らせるために
mesh.geometry.colorsNeedUpdate = true;
も指定する必要があります。

3
4
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
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?