Three.jsでのオブジェクト = メッシュの移動
これには便利なクラスが用意されてました
その名もTransformControlsというもの
使ってみたら本当に便利だったので、
このTransformControlsの使い方を紹介します。
このページの目次
1.Three.js本体とTransformControls.jsを読み込み
まずはここからスタート。
必要なライブラリを読み込みします。
▼ ヘッダーなどでjsを読み込みしておく
1 2 3 4 5 6 7 8 |
<!-- Three.js本体 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <!-- OrbitControls --> <script src="https://unpkg.com/three@0.137.4/examples/js/controls/OrbitControls.js"></script> <!-- TransformControls --> <script src="https://unpkg.com/three@0.137.4/examples/js/controls/TransformControls.js"></script> |
それぞれ次の役割があります。
- three.min.js
どんなバージョンでもいいけどThree.js本体を読み込み。ここではバージョンr128を使用。もちろんCDN経由ではなくてローカルから直接読み込みしてもOK
- OrbitControls.js
マウス・タッチ操作などでSceneをグリグリと回転させたりズームイン・ズームアウトができるThree.js用のライブラリ。
- TransformControls.js
今回の主役。特定のメッシュ(Object3D)に対してマウス・タッチでの移動用UIを表示させることができるライブラリ。見た目などは後述
こういう感じです。
2.全体(Scene/Renderer)などの初期化
次に以下に対しての初期化を行います。
- Scene / WebGLRenderer
- Camera / Light
- Mesh(ここではBoxGeometry)
- その他OrbitControlsの初期化など
※ ただしTransformControlsの処理は後述
以下のようなコードで初期化してみました。
▼ Scene / Rendererの初期化コード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
window.addEventListener('load', function(){ 'use strict'; var world = null; var scene = null; var camera = null; var controls = null; var renderer = null; var timeStep = 1 / 60; function initThree(){ var w = window.innerWidth; var h = window.innerHeight; scene = new THREE.Scene(); /// レンダラー初期化 renderer = new THREE.WebGLRenderer({ canvas: document.querySelector('#appCanvas') }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(w, h); renderer.setClearColor(0x000000, 1); /// カメラ camera = new THREE.PerspectiveCamera(45, w/h, 1, 10000); camera.position.set(0, 0, +10); camera.lookAt(new THREE.Vector3(0, 0, 0)); /// ライト(光源) var directLight = new THREE.DirectionalLight(0xffffff, 1.2); directLight.position.set(1, 0, 1).normalize(); /// OrbitControls初期化 controls = new THREE.OrbitControls(camera, renderer.domElement); controls.autoRotate = false; /// 移動させたい対象メッシュ const geometry = new THREE.BoxGeometry(1,1,1) const material = new THREE.MeshLambertMaterial( { color: 0x308050 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); /// TransformControlsの初期化 /// この部分は後述するのでスキップ scene.add(camera); camera.add(directLight); renderer.render(scene, camera); } function stepFrame(){ requestAnimationFrame(stepFrame); renderer.render(scene, camera); } initThree(); stepFrame(); window.addEventListener('resize', function(){ // サイズを取得 const width = window.innerWidth; const height = window.innerHeight; // レンダラーのサイズを調整する renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(width, height); // カメラのアスペクト比を正す camera.aspect = width / height; camera.updateProjectionMatrix(); }); }) |
黒背景に1つのボックスが表示されたはず
ここまでで下準備ができました。
3.TransformControlsに移動メッシュを結びつけ
ここからが肝心のメッシュ移動の実装です。
先ほどのコードに以下を追加します。
▼ TransformControlsの初期化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
const transformControls = new THREE.TransformControls( camera, renderer.domElement ) transformControls.addEventListener( 'mouseDown', function(e){ /// OrbitControls無効化 controls.enablePan = false; controls.enableRotate = false; }.bind(this) ) transformControls.addEventListener( 'mouseUp', function(e){ /// OrbitControls有効化 controls.enablePan = true; controls.enableRotate = true; }.bind(this) ) /// 移動対象のメッシュを指定 transformControls.attach( cube ); /// TransformControlsを追加 scene.add(transformControls) |
何をしてるかはコメントを参照
初めに new THREE.TransformControls(camera, renderer.domElement) のようにカメラ・レンダラーのDOMを渡してTransformControlsをインスタンス化
そして transformControls.attach( cube ) のように移動対象のメッシュ(Mesh / Object3D)を渡すことで、そのオブジェクトを移動できるようになります。
あとOrbitControlsとの併用も行えるように改造
TransformControlsでは移動が開始すると mouseDown 、移動終了すると mouseUp が発火するので、それぞれでOrbitControlsを無効化/有効化してます。
4.実際のTransformControlsの見た目・動作
こんな感じになりました。
▼ TransformControlsの見た目
▼ 実際にメッシュを動かしている様子
移動用UIの表示もとても分かりやすいです。
XYZ軸方向に動かせることが一目で理解できるので
あと次のCodePenでも動作の確認は可能です。
See the Pen
Three.js - Move mesh by TransformControls by ぴー助 (@pisuke-code)
on CodePen.
以上、three.js+TransformControlsでした。ではまた