Three.js selectionBoxを使ってみた
Three.js selectionBoxを使ってみた:
three.jsで複数のオブジェクトを一気に選択できるselectionBoxって機能があったのでその使用方法と使用感の紹介
OS:Mac
ブラウザ:Chrome
three.jsのcanvasをドラッグ&ドロップすると始点を左上、終点を右下とした正方形の薄い範囲が示されてその中のオブジェクトを抽出できる
以下にgithubのコードがあるので参考に。githubのthree.jsを落としてこのサンプルを開けば起動できる
https://github.com/mrdoob/three.js/blob/dev/examples/misc_boxselection.html
githubのサンプルに沿って使い方の説明。selectionBox以外の説明は省略
主な工程は以下の三つ
- 初期化
- 始点の登録
- 終点の登録
new SelectionBox( camera, scene )は選択範囲のオブジェクトを発見するメイン機能のオブジェクト。sceneを渡してるがこれだとsceneに含まれる全てのオブジェクトを対象とする。対象を減らしたいときは自分で作ったオブジェクトリストを渡す。
ちなみに隠れた第三引数があり検索する奥行きを指定できる(デフォルトは無限)
new SelectionHelper( selectionBox, renderer, "selectBox" )はドラッグ&ドロップした時の範囲を視覚化する薄い青色の四角をだす
以下のようなcssをどっかに登録しとく必要がある
mousedownを検出したところでクリックの位置を導出してselectionBox.startPoint.set()で登録している
このサンプルでは範囲内のオブジェクトを薄い青色の効果をつけているのでその初期化をここでやっている(
ドラッグ中の終点の登録。
selectionBox.endPoint.set()で始点と同様に終点の登録を行なっている。
終点の登録を行えばselectionBox.select()で今範囲内にあるオブジェクトの計算が行われオブジェクトの取得ができる。
ドロップ時の終点の登録。ドラッグ中とほぼ同じ処理。範囲内にあるオブジェクトに青い効果をつけて終了
抽出範囲はドラッグ&ドロップで作られた正方形をカメラの位置と奥行きまでを前後させた時にできる立方体のなかに入ってるオブジェクトを抽出するようになっている。立方体作成にはTHREE.Frustumを使ってる。
また、THREE.Meshを継承したオブジェクトしか抽出できないので他のオブジェクトを抽出するためにはSelectionBox.jsで
コード的には簡単に複数選択が実装できて便利そうだけどMeshしか選択できなかったりscene渡すと全部のオブジェクトが判定対象になったりでちょっと工夫がいる。ちゃんとしたドキュメントも見つからなかったので頑張って元コードを見るしかなさそう
概要
three.jsで複数のオブジェクトを一気に選択できるselectionBoxって機能があったのでその使用方法と使用感の紹介
使用環境
OS:Macブラウザ:Chrome
selectionBoxで何ができるのか?
three.jsのcanvasをドラッグ&ドロップすると始点を左上、終点を右下とした正方形の薄い範囲が示されてその中のオブジェクトを抽出できる以下にgithubのコードがあるので参考に。githubのthree.jsを落としてこのサンプルを開けば起動できる
https://github.com/mrdoob/three.js/blob/dev/examples/misc_boxselection.html
使い方
githubのサンプルに沿って使い方の説明。selectionBox以外の説明は省略主な工程は以下の三つ
- 初期化
- 始点の登録
- 終点の登録
初期化
misc_boxselection.js
var selectionBox = new SelectionBox( camera, scene ); var helper = new SelectionHelper( selectionBox, renderer, "selectBox" );
ちなみに隠れた第三引数があり検索する奥行きを指定できる(デフォルトは無限)
new SelectionHelper( selectionBox, renderer, "selectBox" )はドラッグ&ドロップした時の範囲を視覚化する薄い青色の四角をだす
以下のようなcssをどっかに登録しとく必要がある
misc_boxselection.css
.selectBox { border: 1px solid #55aaff; background-color: rgba(75, 160, 255, 0.3); position: fixed; }
始点の登録
misc_boxselection.js
document.addEventListener("mousedown", function ( event ) { for ( var item of selectionBox.collection ) { item.material.emissive = new THREE.Color( 0x000000 ); } selectionBox.startPoint.set( ( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5 ); });
このサンプルでは範囲内のオブジェクトを薄い青色の効果をつけているのでその初期化をここでやっている(
for( var item・・・
のところ)
終点の登録
misc_boxselection.js
document.addEventListener( "mousemove", function ( event ) { if ( helper.isDown ) { for ( var i = 0; i < selectionBox.collection.length; i++ ) { selectionBox.collection[i].material.emissive = new THREE.Color( 0x000000 ); } selectionBox.endPoint.set( ( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5 ); var allSelected = selectionBox.select(); for ( var i = 0; i < allSelected.length; i++ ) { allSelected[i].material.emissive = new THREE.Color( 0x0000ff ); } } });
selectionBox.endPoint.set()で始点と同様に終点の登録を行なっている。
終点の登録を行えばselectionBox.select()で今範囲内にあるオブジェクトの計算が行われオブジェクトの取得ができる。
misc_boxselection.js
document.addEventListener("mouseup", function ( event ) { selectionBox.endPoint.set( (event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5 ); var allSelected = selectionBox.select(); for ( var i = 0; i < allSelected.length; i++ ) { allSelected[i].material.emissive = new THREE.Color(0x0000ff); } });
余談
抽出範囲はドラッグ&ドロップで作られた正方形をカメラの位置と奥行きまでを前後させた時にできる立方体のなかに入ってるオブジェクトを抽出するようになっている。立方体作成にはTHREE.Frustumを使ってる。また、THREE.Meshを継承したオブジェクトしか抽出できないので他のオブジェクトを抽出するためにはSelectionBox.jsで
if ( object instanceof THREE.Mesh ) {
ってなってるところを変更する必要がありそう
コメント
コメントを投稿