はじめに
「マンガで分かる Java入門講座」を作る際に、「箱人形マンガ(Box Comic)」というWebアプリを開発しました。このアプリは「HTML5」+「JavaScript」+「WebGL」で作られています。このアプリで利用しているライブラリ「three.js」を、サンプルコードとともに解説していく短期連載です。今回は最終回。
前回は、3Dオブジェクトをマウスで操作する方法を紹介しました。最終回の今回は応用編として、集中線やフキダシや箱人形の作成、そしてそれらをまとめて、オブジェクトや部品をマウスで操作するサンプルを作成して解説します。
対象読者
以下の読者を対象にしています。
- JavaScriptでプログラミングを書ける人。
- jQueryを使ったプログラムを書いたことがある人。
- HTML5のCanvasを使ったプログラムを書いたことがある人。
必要な環境
「Google Chrome」や「Mozilla Firefox」といった、WebGLに対応したブラウザが必要です。「Internet Explorer」は、WebGLが利用できませんので、実行環境として適していません。
記事の構成
本連載では、以下の内容を、コードを示しながら解説していき、最後にマンガのコマとして、すべてのプログラムを統合したサンプルを作成します。
また、サンプルはテクスチャを読み込む関係上、ローカルでは動作しません。そこで、サーバー上にもサンプルをアップロードしておきました。どういった内容か、以下からご確認ください。
内容 | ページ |
シーンとカメラとレンダラーの準備 | 3ページ |
立方体の表示 | 4ページ |
色付き板ポリゴンの表示 | 5ページ |
画像をテクスチャとして読み込み1 | 5ページ |
画像をテクスチャとして読み込み2 | 6ページ |
Canvasをテクスチャとして読み込み | 6ページ |
内容 | ページ |
マウスによる移動、回転、拡縮操作 | 2ページ |
レイキャスターを利用した選択と移動1 | 3ページ |
レイキャスターを利用した選択と移動2 | 4ページ |
クォータニオンによる回転 | 5ページ |
内容 | ページ |
集中線の表示 | 1ページ |
フキダシの表示 | 2ページ |
箱人形の表示 | 3ページ |
WebGLからPNGを出力 | 4ページ |
まとめ | 4~5ページ |
それでは、コードを示して解説していきます。
集中線の表示
![集中線の表示](http://cz-cdn.shoeisha.jp/static/images/article/7210/ss_sample_view_flash_s.jpg)
集中線は球を利用して作成します。どう利用するかというと、球を細長くしたものを1本の線と見立てて、その線を放射状に配置して集中線とします。ここで球を使うのは、ペンの入りと抜きを再現するためです。
「three.js」には、球を作るジオメトリ「SphereGeometry」が存在します。このジオメトリで作った球の「scale.x」「scale.z」を小さくして、「scale.y」を大きくすることで、線状に変形させます。描画位置は「Math.cos」「Math.sin」を使って求めます。後は、放射状になるように回転させれば完成です。
ポイントは、集中線はオブジェクトが多いので、グループに登録してまとめて扱えるようにすることです。すると、後で集中線の位置を移動したり、角度を変えたりする際に、グループの属性を変更するだけでよくなります。中の線を1本ずつ変更するのは大変です。グループ化をうまく使い、階層構造を持ったオブジェクトを作るのがコツです。
以下、集中線を作成して表示する「crocro.bc.viewFlash.js」を掲載します。
//= サンプル:集中線の表示 //== 集中線の表示 crocro.bc.viewFlash = function() { // 変数の初期化 var d3 = crocro.bc.d3; // 3D格納用 var flsh; // 要素の作成と格納 flsh = crocro.bc.mkFlash(0x000000); d3.scene.add(flsh); crocro.bc.render(); }; //== 集中線の作成 crocro.bc.mkFlash = function(col) { // マテリアルの作成 var material = new THREE.MeshBasicMaterial({color: col}); // グループの作成 var group = new THREE.Object3D(); // 集中線設定の初期化 var rMax = Math.PI * 2; var rStp = Math.PI / 32; var mvY = 300; // 集中線の作成 for (var r = 0; r < rMax; r += rStp) { // メッシュの作成 var mesh = new THREE.Mesh( new THREE.SphereGeometry(1, 32, 32), material ); // サイズを縦長に mesh.scale.x = 2; mesh.scale.y = 200; mesh.scale.z = 2; // 描画位置の移動 mesh.position.x = mvY * Math.cos(r); mesh.position.y = - mvY * Math.sin(r); // 回転 mesh.rotation.z = Math.PI / 2 - r; // グループにメッシュを追加 group.add(mesh); } // グループを戻して終了 return group; };