- 2009年05月26日 (火)
- Tweet
フレームアクションで覚える PV3D Vol.05 : Cameraを理解する
Papervision3Dのチュートリアル5回目。前回はPapervision3Dの仕組みについて簡単に説明しました。今回は3Dを自在に撮影できるカメラについて説明します。冒頭の画像は今回の目標とします。ソースファイルはこちらにアップしていますので、ダウンロードした上で読み進めてください(DLした中の画像はPlanet Earth Texture Mapsのものを使用しています)。今回のカメラの動かし方は使い回しのできるものですので、ストックにしておくとよいかもしれません。
まずはカメラを動かすことを体験
上記ブログのページ中頃で紹介されているデモがカメラのシミュレーションとして大変分かりやすいものですので、ぜひ試してみてください。
デモはカメラの移動軌跡をトゥイーンライブラリのTweenerを使って、ベジェ曲線として動かすものです。断面図でベジェ曲線をカスタマイズできるのでカメラの動かし方を自由に設定してみるとよいでしょう。
[追記]
また、カメラのプロパティ(xyzや、rotationXYZなど)のイメージをつかむには次の記事が参考になります。
Papervision3Dはこのように3D空間内でカメラ(視点)を自由に移動できます。これを習得することで3Dの表現力が格段に高まります。本記事ではカメラの動かし方を3分類に分け、それらを順を追って説明していきます。
課題0 : まずは前回までのおさらい
カメラを学習する前に前回までのおさらいも兼ねて準備しておきましょう。
今回は地球の周りを飛ぶ衛星を作ります。ファーストステップとして以下の設定を行っておきます。これはダウンロードしたソースファイルの「sample00.fla」が該当しますので、一通り目を通しておいてください。
- Papervision3Dの初期化
- プリミティブオブジェクト(球面)の作成
- マテリアルの作成
結果としては次のものがゴールです。
今回はよりリアリティーを出すために地球の周りを浮遊する隕石も作ってみました。これはPapervision3Dのパーティクル機能を作って再現しています。次のスクリプトは2000の幅を持った立方体の中に幅4のパーティクルを500個生成するというものです。
import org.papervision3d.objects.special.ParticleField; import org.papervision3d.materials.special.ParticleMaterial; // ついでにパーティクルを生成します(彗星) var particleMat:ParticleMaterial = new ParticleMaterial(0xFFFFFF, 1) var particles:ParticleField = new ParticleField(particleMat, 500, 4, 2000, 2000, 2000) world.scene.addChild( particles );
課題1 : 地球の周りをカメラを回転させる
そもそもPapervision3Dのカメラには大きく2種類の制御方法があります。
- 常に一点を向き続けるターゲットカメラ
- カメラの視点を自由に設定できるフリーカメラ
今回は前者のターゲットカメラで試していきます。なおBasicViewの初期設定はターゲットカメラですので特に設定することはありませんが、カメラに二種類の制御方法があることは覚えておいてください。
結果としては次のものがゴールです。
課題0で準備したフレームアクションに対して、エンターフレームのハンドラーの部分に次のスクリプトを記載します。(一部抜粋)
// アニメーション var rot:Number = 0 // 角度 addEventListener(Event.ENTER_FRAME, function(e){ rot += 0.5 // 毎フレーム角度を0.5度ずつ足していく // 角度に応じてカメラの位置を設定 world.camera.x = 1000 * Math.sin(rot * Math.PI / 180) world.camera.z = 1000 * Math.cos(rot * Math.PI / 180) // 地球は常に回転させておく sphere.rotationY -= 0.25 })
解説すると、カメラの座標の設定方法はcameraのx,y,zプロパティーに値を入れるだけです。カメラはターゲットカメラですので、常に1点を向き続けています。BasicViewでは特に設定しない限り原点(0,0,0)を向いてます。
動きの演出については、フレーム毎に衛星の配置角度を0.5度ずつ加算し、それをカメラの座標に変換しています。カメラの座標は三角関数(sinとcos)を使って、角度から求めています。1000という値は円の半径です。
課題2 : マウスの座標に応じて回転させる
Flashですのでインタラクティブ性を持たせてみたいと思います。マウスの位置に応じて衛星の位置を変えてみたいと思います。デモとスクリプトは以下の通りとなります。(一部抜粋)
// アニメーション var rot:Number = 0 // 角度 addEventListener(Event.ENTER_FRAME, function(e){ // マウスの位置に応じて角度を設定 // マウスのX座標がステージの幅の何%の位置にあるか調べてそれを360度で乗算する var targetRot:Number = ( mouseX / stage.stageWidth ) * 360 // イージングの公式を用いて滑らかにする // 値 += (目標値 - 現在の値) * 減速値 rot += (targetRot - rot) * 0.02 // 角度に応じてカメラの位置を設定 world.camera.x = 1000 * Math.sin(rot * Math.PI / 180) world.camera.z = 1000 * Math.cos(rot * Math.PI / 180) // 地球は常に回転させておく sphere.rotationY -= 0.25 })
ポイントとしては、角度の算出方法をステージの幅の何%の位置にマウスがあるかを計算で求め、それを角度に反映しているところです。その点が課題2と違うところで、さほど難しくはありません。
なお途中にイージングの公式というのがでてきていますが、Flashでは一般的によく使われる公式なので、知らない方はぜひ覚えておきましょう。
課題3 : マウスのドラッグに応じてカメラを制御する
マウスのドラッグ&ドロップでカメラの位置を制御できるようにしてみます。デモとフレームアクションは次の通りです。(一部抜粋)
// マウスを押した状態かどうかを判別するフラグ var isMouseDown:Boolean = false // 一時的なマウスの値を格納する変数 var oldX:Number = 0 var targetRot:Number = 0 // イベントの設定 stage.addEventListener(MouseEvent.MOUSE_DOWN, downHandler) stage.addEventListener(MouseEvent.MOUSE_UP, upHandler) stage.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler) // マウスを押されたとき function downHandler(e){ isMouseDown = true oldX = mouseX } // マウスを放したとき function upHandler(e){ isMouseDown = false } // マウスが動いたとき function moveHandler(e){ if(isMouseDown){ var dy:Number = e.stageX - oldX targetRot += dy * 0.25 oldX = e.stageX } } // アニメーション var rot:Number = 0 // 角度 addEventListener(Event.ENTER_FRAME, function(e){ // イージングの公式を用いて滑らかにする // 値 += (目標値 - 現在の値) * 減速値 rot += (targetRot - rot) * 0.05 // 角度に応じてカメラの位置を設定 world.camera.x = 1000 * Math.sin(rot * Math.PI / 180) world.camera.z = 1000 * Math.cos(rot * Math.PI / 180) // 地球は常に回転させておく sphere.rotationY -= 0.25 })
スクリプトが長くなりましたが、これはよく使うので基本を押さえておきましょう。ドラッグ&ドロップはマウスを押したとき・移動したとき・離したときの3パターンのイベントに分解できます。コアのロジックは、押したときのマウス座標から移動したときのそれとの差分を求めることです。
求めた差分を角度に変換し(適当な0.25という値を乗算しています)、それをイージングの公式を用いて滑らかにし、それをカメラの座標に三角関数で設定しています。後半は今までの課題と変わりませんので、角度を求めるところが、ドラッグ&ドロップになったと違いだけとなります。
課題4 : ドラッグ&ドロップを上下左右対応に
ここは自主課題とします。課題4のロジックに縦方向の制御を加えるだけですので、それほど難しくはありません。
まとめ
今回はカメラの動かし方について、基本的なパターンを演習しました。これで簡単ですが一通りPapervision3Dに触れましたので、次回はPapervision3Dのサンプルを作って最終回とします。次回をお楽しみに。
書籍になりました
なお、Papervision3Dの解説はさらに詳しく書籍にもまとめています。このブログを読んでさらにスキルを高めたいという方がいましたら当ブログ管理者が執筆した次の書籍をオススメします。書籍はこちらのページで紹介してますので、興味がありましたらぜひご確認ください。
「Flash3Dコンテンツ制作のためのPapervision3D入門」
2009年05月29日(金) 14:03
[…] フレームアクションで覚える PV3D Vol.05 : Cameraを理解する […]
2009年05月29日(金) 16:03
[…] フレームアクションで覚える PV3D Vol.05 : Cameraを理解する あと、実際にカメラのrotationとかxとかどうゆう風になってんだ。イメージがわかないよ(;_;)って思ったら 合わせてy_tti さんのこ […]
2009年05月30日(土) 12:15
いつも楽しみにしてます。
特に前々から触ってみたいと思ってた、Papervision3Dのチュートリアルということで更新をwktkと待ってました。
課題4も無事クリアできたのですが、課題3で出てきた変数nowXが結局使わず終いだったのですが、どこで使う予定だったのでしょうか?
2009年06月07日(日) 14:36
>sw_lucchinさん
すみません、コメントに気づくのが遅くなってしまいました。
課題3にでてきたnowXはご指摘の通り必要なかったですね。
データからも消しておきますね。
2009年09月27日(日) 13:13
[…] フレームアクションで覚える PV3D Vol.05 : Cameraを理解する […]