3Dの中にある物体をドラッグで自由に動かす

Three.jsの例、webgl_interactive_draggablecubes.htmlを見る。

物体の選択はRayクラスのオブジェクトを使ってる。
これはcanvasのときと同じ。
SELECTED = intersects[0].object;
で一番手前の物体を得る。
ドラッグを止めたときはSELECTEDがnullになる。

マウスをドラッグしたとき、SELECTEDがあれば
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObject( plane );
SELECTED.position.copy( intersects[0].point.subSelf( offset ) );
の順で実行される。

はて? なんですか、このplaneは? …とプログラムをたどると
plane = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.25, transparent: true, wireframe: true } ) );
plane.geometry.applyMatrix( new THREE.Matrix4().makeRotationX( Math.PI / 2 ) );
plane.visible = false;
scene.add( plane );
という部分を発見。
実は、見えない平面のオブジェクトを配置していた。
この平面のオブジェクト上でポイントされた位置をRayクラスを作って取得している。
plane.visible = false; をコメントアウトして、planeを表示した状態で動作を確認するのもおもしろい。

ブラウザ上のマウスの位置からもポイントされた位置を算出できるけど、こっちの方がスマートw

ということで、
  • SELECTEDの位置をplane上でポイントされた位置にする
  • = 選択された物体がマウスに動きに合わせて動く
という訳。
2012/07/28 16:05
タグ