three.jsにはMeshをマウスドラッグで移動できる DragControls があります。
簡単にドラッグ処理を実装できますが、使う時に少しハマったのでTipsを共有します。
動作確認バージョン
- three.js version: r159
1. Groupはドラッグ対象にできない
DragControlsのドラッグ対象にGroupは設定できません。Meshのような3D Objectsだけです。
three.jsを使っているとよくGroupでMeshなどをグルーピングしますが、DragControlsを使う場合は親Meshの下に子Meshを入れる形が良いでしょう。
2. 移動する親Meshの子Meshもドラッグ対象になる
以下のようなコードで親Meshだけ指定しても子Meshもドラッグ対象になります。
new DragControls([親Mesh], camera, renderer.domElement );
以下では四隅の白いCube型のMeshは親Meshにaddすると、同じくドラッグ対象になります(親Meshの拡大縮小は自前で実装してます)
3. 後からSceneにMeshを追加する場合はdisposeした方が良い
ユーザー操作で後からMeshを追加する場合、DragControls.dispose()
して new DragControls()
し直しましょう。
でないと以下のようにドラッグ対象にする事ができません。
4. ドラッグ対象にしたくない子Meshはlayersを指定すると良い
ドラッグしたくない子Meshがある場合、layersを設定しましょう。
以下の画像では親Mesh配下にLineがあり、line.layers.set(1)
にしてドラッグ対象外にしてます。
また、カメラは camera.layers.enableAll()
にして全ての レイヤーが見える状態にしましょう。
DragControlsコード内のRaycasterはデフォルトのlayers:0になってるので、それ以外のlayers番号を指定すればドラッグ対象から外せます。
5. ドラッグ対象をハイライトさせたい
DragControlsにhoveron/hoveroffイベントがあるため、ハイライトも簡単にできます。
import { ColorRepresentation, Mesh } from 'three';
const BASE_COLOR: ColorRepresentation = 0x0066ff;
const HIGH_LIGHT_COLOR: ColorRepresentation = 0x00ccff;
dragControls.addEventListener('hoveron', (e: any) => {
if (e.object instanceof Mesh) {
e.object.material.color.set(HIGH_LIGHT_COLOR);
}
});
dragControls.addEventListener('hoveroff', (e: any) => {
if (e.object instanceof Mesh) {
e.object.material.color.set(BASE_COLOR);
}
});
以上、少しクセはありますが、DragControlsで簡単に移動操作ができるのでぜひ使ってみて下さい。