Three.js(r79)で、3Dオブジェクトをマウスで移動させてみる。具体的には、平面を作成して、その平面に対して立法体が平行に移動するようにする。
three.min.jsとTrackballControlsを読み込む。ともにjs_r79というディレクトリにあるとする。
Three.jsで立法体を2つ作成して表示できるようにする。
mousedown、mousemove、mouseupイベントのリスナーを登録する。平面を作成し、平面に対して平行に立法体を移動させる。平面の角度は、カメラの角度に合わせて変化させる(TrackballControlsで視点が変化するため)。
1~3を合わせると、以下のように立法体が2つ表示され、マウスでドラッグして移動させることができる。
1.jsファイルの読み込み
three.min.jsとTrackballControlsを読み込む。ともにjs_r79というディレクトリにあるとする。
2.オブジェクトの作成
Three.jsで立法体を2つ作成して表示できるようにする。
// オブジェクトを格納する配列
var objects = [];
// シーンの作成
var scene = new THREE.Scene();
// カメラの作成
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
// レンダラーの作成
var renderer = new THREE.WebGLRenderer();
// レンダラーが描画するキャンバスサイズの設定
renderer.setSize( window.innerWidth, window.innerHeight );
// キャンバスをDOMツリーに追加
document.body.appendChild( renderer.domElement );
// TrackballControlsインスタンス作成
var controls = new THREE.TrackballControls( camera );
// ジオメトリーの作成
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
// マテリアルの作成
var material = new THREE.MeshNormalMaterial( { color: 0x00ff00 } );
// オブジェクトの作成
var cube = new THREE.Mesh( geometry, material );
// オブジェクトの位置調整
cube.position.x = 2.0;
// オブジェクトをシーンに追加
scene.add( cube );
objects.push( cube );
// オブジェクトを複製
var cube2 = cube.clone();
// オブジェクトの位置調整
cube.position.x = -2.0;
// オブジェクトをシーンに追加
scene.add( cube2 );
objects.push( cube2 );
// カメラ位置設定
camera.position.z = 5;
camera.position.x = 0.5;
camera.position.y = 0.5;
animate();
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
3.マウスイベントの追加
mousedown、mousemove、mouseupイベントのリスナーを登録する。平面を作成し、平面に対して平行に立法体を移動させる。平面の角度は、カメラの角度に合わせて変化させる(TrackballControlsで視点が変化するため)。
// この平面に対してオブジェクトを平行に動かす
var plane = new THREE.Plane();
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var offset = new THREE.Vector3();
var intersection = new THREE.Vector3();
// マウスオーバーしているオブジェクト
var mouseoveredObj;
// ドラッグしているオブジェクト
var draggedObj;
renderer.domElement.addEventListener( 'mousedown', onDocumentMouseDown, false );
renderer.domElement.addEventListener( 'mousemove', onDocumentMouseMove, false );
renderer.domElement.addEventListener( 'mouseup', onDocumentMouseUp, false );
function onDocumentMouseDown( event ) {
event.preventDefault();
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( objects );
if ( intersects.length > 0 ) {
// マウスドラッグしている間はTrackballControlsを無効にする
controls.enabled = false;
draggedObj = intersects[ 0 ].object;
// rayとplaneの交点を求めてintersectionに設定
if ( raycaster.ray.intersectPlane( plane, intersection ) ) {
// ドラッグ中のオブジェクトとplaneの距離
offset.copy( intersection ).sub( draggedObj.position );
}
}
}
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
if ( draggedObj ) {
// オブジェクトをドラッグして移動させているとき
// rayとplaneの交点をintersectionに設定
if ( raycaster.ray.intersectPlane( plane, intersection ) ) {
// オブジェクトをplaneに対して平行に移動させる
draggedObj.position.copy( intersection.sub( offset ) );
}
} else {
// オブジェクトをドラッグしないでマウスを動かしている場合
var intersects = raycaster.intersectObjects( objects );
if ( intersects.length > 0 ) {
if ( mouseoveredObj != intersects[ 0 ].object ) {
// マウスオーバー中のオブジェクトを入れ替え
mouseoveredObj = intersects[ 0 ].object;
// plane.normalにカメラの方向ベクトルを設定
// 平面の角度をカメラの向きに対して垂直に維持する
camera.getWorldDirection( plane.normal );
}
} else {
mouseoveredObj = null;
}
}
}
function onDocumentMouseUp( event ) {
event.preventDefault();
controls.enabled = true;
if ( mouseoveredObj ) {
draggedObj = null;
}
}
4.実行結果
1~3を合わせると、以下のように立法体が2つ表示され、マウスでドラッグして移動させることができる。

0 件のコメント:
コメントを投稿