|
||||||||||||||||||||||||||||||||||||||
■Twitter: @FumioNonaka / Facebook Page: Away3D
Away3D Workshop
|
[Vol. 1] Broadcast live streaming video on Ustream |
[Vol. 2] Broadcast live streaming video on Ustream |
[Vol. 3] Broadcast live streaming video on Ustream |
「Away3D TypeScript」サイトには、作例やソースファイルのリンクなどが掲げられている。最新のライブラリは、「Source Files」の欄に示されたGitHubのリンクからダウンロードできる(図001)。
図001■Away3D TypeScriptライブラリのソースファイル
Away3D TypeScriptを試すには、ソースファイルのふたつのリンクからダウンロードしたファイルの中から3つのライブラリ「awayjs-core.next.min.js」と「stagegl-context.next.min.js」および「stagegl-renderer.next.min.js」を使う(図002)。
図002■Away3Dで使う3つのライブラリのJSファイル
HTMLドキュメントには、まずscript要素にAway3Dの3つのJSファイルawayjs-core.next.min.jsとstagegl-context.next.min.jsおよびstagegl-renderer.next.min.jsを読込む。つぎに、JavaScriptコードには初めに呼出す関数(initialize())を設け、body要素のonload属性にその呼出しを加える。
<script src="lib/awayjs-core.next.min.js"></script>
<script src="lib/stagegl-context.next.min.js"></script>
<script src="lib/stagegl-renderer.next.min.js"></script>
<script>
function initialize() {
// 初期設定
}
</script>
<body onload="initialize();">
Away3Dで3次元表現するには、つぎの3つを用意しなければならない。
第1につくらなければならないのは、3次元空間の表示領域を定めるViewオブジェクトだ。3次元の座標空間や、それを表示領域に映すカメラもオブジェクトの中にもつ。View()コンストラクタの引数にはレンダラを渡す。
new away.containers.View(new away.render.DefaultRenderer())
Viewオブジェクトには、プロパティで設定が加えられる(表001)。多くのプロパティには、デフォルト値が定められている。
表001■Viewクラスに備わる基本的なプロパティ
Viewクラスの プロパティ |
プロパティの値 |
width height |
表示される領域の幅と高さ。 |
backgroundColor | 画面の背景色。デフォルト値は黒(0x000000)。 |
camera | 表示領域を描くために用いられるCamera3Dオブジェクト。 |
scene | 表示領域を描くもととなる3次元空間のScene3Dオブジェクト。 |
Viewオブジェクトをつくって返す関数(createView())を新たに定める(第16〜23行目)。引数に渡すのは、表示領域の幅と高さ、および背景色だ。そして、初期設定の関数(initialize())から呼出す(第10行目)。なお、抜書きの行番号は、後掲コード001にもとづく。
- var view;
- function initialize() {
- view = createView(240, 180, 0x0);
- }
- function createView(width, height, backgroundColor) {
- var defaultRenderer = new away.render.DefaultRenderer();
- var view = new away.containers.View(defaultRenderer);
- view.width = width;
- view.height = height;
- view.backgroundColor = backgroundColor;
- return view;
- }
第2に、光源を定める。3次元表現で使われる光源で基本となるのは「平行光源」(directional light)だ。太陽の光のように同じ向き(平行)に進み、距離によって強さが変わらない(図003右上)。
図003■3次元表現で使われる光源の種類
*Tcpp's fileより引用
平行光源は、DirectionalLight()コンストラクタで定める。この光で、後からつくる物体の表面を照らす。
new away.entities.DirectionalLight()
地球上では「環境光」(ambient light)があることで、陰も見える。そこで、DirectionalLightオブジェクトをつくって返す関数(createDirectionalLight())は、環境光の強さとその光の色を引数に与えてつぎのように定めた。DirectionalLightオブジェクトのambientプロパティに強さの数値を与えると、環境光が加わる(第35行目)。また、colorプロパティで光の色を定める(第36行目)。なお、directionプロパティには、Vector3Dオブジェクトの3次元ベクトルで光源の位置を与える(第34行目)。
- function initialize() {
- var directionalLight = createDirectionalLight(0.25, 0x00FFFF);
- }
- function createDirectionalLight(ambient, color) {
- var light = new away.entities.DirectionalLight();
- light.direction = new away.geom.Vector3D(0, -1, 1);
- light.ambient = ambient;
- light.color = color;
- return light;
- }
いよいよ第3の、役者となる物体のインスタンスを登場させる。そのためには、まず立方体のひながた(プレハブ)となるPrimitiveCubePrefabオブジェクトをつくる。コンストラクタに与える引数は立方体の幾何情報だ。つぎに、そのひながたの参照に対してgetNewObject()メソッドを呼出すと、物体のインスタンスが得られる。
new away.prefabs.PrimitiveCubePrefab(幅, 高さ, 奥行き).getNewObject()
表面素材は、デフォルトのテクスチャでつくることにする。静的メソッドDefaultMaterialManager.getDefaultTexture()で得られたオブジェクトを、TriangleMaterial()コンストラクタの引数に渡す。
new away.materials.TriangleMaterial(away.materials.DefaultMaterialManager.getDefaultTexture())
物体の表面を照らす光はStaticLightPickerオブジェクトで定め、素材のオブジェクトのlightPickerプロパティに加える。StaticLightPicker()コンストラクタには、光源のオブジェクトを配列に納めて渡す。
new away.materials.StaticLightPicker(光源の配列)
立方体のインスタンスをつくって返す関数(createCube())は、つぎのように初期設定の関数(initialize())から呼出して、できあがったインスタンスをScene3D.addChild()メソッドで3次元空間に加える(第11〜12行目)。引数には、立方体の幅と高さと奥行きに加えて、光源のオブジェクトを渡す。なお、3次元空間のScene3DオブジェクトはView.sceneプロパティで参照した(前掲表001)。関数は、PrimitiveCubePrefabオブジェクトから立方体のインスタンスをつくり、テクスチャと光源のオブジェクトを設定して返す(第24〜31行目)。
- var view;
- var mesh;
- function initialize() {
- var directionalLight = createDirectionalLight(0.25, 0x00FFFF);
- view = createView(240, 180, 0x0);
- mesh = createCube(400, 400, 400, directionalLight);
- view.scene.addChild(mesh);
- }
- function createCube(width, height, depth, light) {
- var defaultTexture = away.materials.DefaultMaterialManager.getDefaultTexture();
- var material = new away.materials.TriangleMaterial(defaultTexture);
- var mesh = new away.prefabs.PrimitiveCubePrefab(width, height, depth).getNewObject();
- mesh.material = material;
- material.lightPicker = new away.materials.StaticLightPicker([light]);
- return mesh;
- }
3次元空間を表示領域に描くには、必ずView.render()メソッドを呼出さなければならない。さらに、3次元空間の立方体を上下左右に回してみよう。アニメーションは、RequestAnimationFrameクラスで扱う。一定の時間間隔で行うアニメーションの処理を関数で定め、コンストラクタの引数として渡す。コールバックの呼出しは、RequestAnimationFrame.start()メソッドにより始まる。
new away.utils.RequestAnimationFrame(コールバック)
RequestAnimationFrameオブジェクト.start()
これらふたつのメソッドは、初期設定の関数(initialize())から呼出す(第13〜14行目)。RequestAnimationFrame()コンストラクタに渡したコールバック関数(rotate())は、立方体のプロパティrotationXとrotationYに角度をそれぞれ1度ずつ加えて回した(第40〜41行目)。コールバックの最後には、View.render()メソッドを呼出す。
- var timer;
- function initialize() {
- timer = new away.utils.RequestAnimationFrame(rotate);
- timer.start();
- }
- function rotate(timeStamp) {
- mesh.rotationX = (mesh.rotationX + 1) % 360;
- mesh.rotationY = (mesh.rotationY + 1) % 360;
- view.render();
- }
これで、3次元空間に置いた立方体をx軸とy軸で回すアニメーションが描ける(図004)。script要素全体を以下のコード001にまとめた。
図004■3次元空間に描かれた立方体が水平および垂直の向きに回る
|
サンプル001■Away3D 14/06/24 : Rotating a cube in the 3D space
仕上げとして、立方体の向きをマウスでインタラクティブに変えよう。ただし、前掲コード001と違って、立方体そのものは動かさず、カメラの位置や向きによって立方体の見せ方をコントロールする。カメラワークには、表現が多彩なHoverControllerクラスのコントローラを用いることにする。HoverController()コンストラクタの第1引数には、カメラのオブジェクトを与える。
new away.controllers.HoverController(カメラ)
HoverControllerオブジェクトは、カメラをパンやチルトできる(オリオン技研株式会社「パン・チルト・ロールとはなにですか」参照)。HoverControllerクラスのプロパティは、つぎの表002に掲げた。そして、プロパティHoverController.panAngleやHoverController.tiltAngleでパンあるいはチルトを定めると、カメラは直ちにその角度に切替わるのではなく、ステップ(デフォルトは8)に分けてトゥイーンされる。
表002■HoverControllerクラスに備わる基本的なプロパティ
HoverController クラスのプロパティ |
プロパティの値 |
distance | カメラと撮影対象との距離で、デフォルト値は1000。 |
maxTiltAngle minTiltAngle |
チルトできる角度の範囲の最大度数(デフォルト値90)と最小度数(デフォルト値-90)。 |
panAngle | カメラがy軸を中心に回る度数の角度で、デフォルト値は0。 |
tiltAngle | カメラの仰角を示す度数で、デフォルト値は90。 |
まず、HoverControllerクラスのオブジェクトでコントローラをつくるクラスは、つぎのような関数(setupCameraController())として定める。引数にはカメラオブジェクトのほか、前掲表002のHoverControllerクラスのプロパティに定める値を渡します。
setupCameraController(カメラ, 距離, チルト最小度数, チルト最大度数, パン度数, チルト度数)
でき上がったJavaScript全体は、後にコード002としてまとめた。HoverControllerオブジェクトのコントローラをつくる関数(setupCameraController())はつぎのとおりだ(第42〜50行目)。新たにつくったHoverControllerオブジェクトのプロパティに、引数の値を定めて返す。なお、前述のとおり、パンとチルトはトゥイーンするので、アニメーションの関数は名前を変えて(render())、View.render()メソッドの呼出しのみ行う(第16行目および第51〜53行目)。
- var cameraController;
- function initialize() {
- cameraController = setupCameraController(view.camera, 1000, 0, 90, 45, 20);
// timer = new away.utils.RequestAnimationFrame(rotate);
- timer = new away.utils.RequestAnimationFrame(render);
- timer.start();
- }
- function setupCameraController(camera, distance, minTiltAngle, maxTiltAngle, panAngle, tiltAngle) {
- var cameraController = new away.controllers.HoverController(camera);
- cameraController.distance = distance;
- cameraController.minTiltAngle = minTiltAngle;
- cameraController.maxTiltAngle = maxTiltAngle;
- cameraController.panAngle = panAngle;
- cameraController.tiltAngle = tiltAngle;
- return cameraController;
- }
// function rotate(timeStamp) {- function render(timeStamp) {
// mesh.rotationX = (mesh.rotationX + 1) % 360;
// mesh.rotationY = (mesh.rotationY + 1) % 360;- view.render();
- }
この書替えだけでも、HoverController.panAngleとHoverController.tiltAngleプロパティに定めたパンとチルトの位置にカメラはトゥイーンして、立方体の映る角度が変わる(図005)。この後さらに、マウスドラッグでパンとチルトをインタラクティブに動かそう。
図005■立方体を映すカメラのパンとチルトがトゥイーンする→ |
ドラッグは、3つのマウスイベントで扱うのがお約束だ。
[1] マウスボタンを押す(onmousedownイベント)
ドラッグが始まる(第15行目)。コールバック関数(startDrag())は、マウスポインタの座標やカメラのパンとチルト角など、必要な値を変数にとる(第55〜58行目)。そして、マウスポインタを動かしたとき(onmousemoveイベント)のドラッグと、ボタンを放したとき(onmouseupイベント)の終了のイベントハンドラ(drag()とstopDrag())をそれぞれ定めた(第59〜60行目)。
[2] ドラッグする(onmousemoveイベント)
コールバック関数(drag())は、マウスポインタの水平な動きからパン(HoverController.panAngleプロパティ)を、垂直な動きでチルト(HoverController.tiltAngleプロパティ)を増減させる(第63〜64行目)。このとき、ドラッグ開始時(startDrag())にとっておいたマウス座標とパンおよびチルト角の変数値から差を求めている。
[3] マウスボタンを放す(onmouseupイベント)
ドラッグを終える。イベントハンドラ(stopDrag())は、onmousemoveとonmouseupイベントにnullを代入してコールバック関数の定めは消す(第67〜68行目)。
- var lastMouseX;
- var lastMouseY;
- var lastPanAngle;
- var lastTiltAngle;
- function initialize() {
- document.onmousedown = startDrag;
- }
- function startDrag(eventObject) {
- lastMouseX = eventObject.clientX;
- lastMouseY = eventObject.clientY;
- lastPanAngle = cameraController.panAngle;
- lastTiltAngle = cameraController.tiltAngle;
- document.onmousemove = drag;
- document.onmouseup = stopDrag;
- }
- function drag(eventObject) {
- cameraController.panAngle = 0.5 * (eventObject.clientX - lastMouseX) + lastPanAngle;
- cameraController.tiltAngle = 0.3 * (eventObject.clientY - lastMouseY) + lastTiltAngle;
- }
- function stopDrag(eventObject) {
- document.onmousemove = null;
- document.onmouseup = null;
- }
これで、マウスドラッグによりカメラが立方体の周りをパンあるいはチルトする。JavaScript全体はつぎのコード002にまとめた。また、jsdo.itにサンプルコードを掲げた(サンプル001)。
コード002■3次元空間でカメラをインタラクティブにパンおよびチルトさせる
|
サンプル001■Away3D 14/06/24: Panning and tilting the camera in the 3D space
サンプル002■Away3D 14/06/24: Animating particle fires on a floor with texture finished
作成者: 野中文雄
更新日: 2014年7月26日 USTREAMビデオを掲載。
作成日: 2014年7月25日