Flash3D/Papervision3DとJiglibからAway3Dに移行することにしてみた
昔作ったコンテンツがPapervision3Dで作られてまして
Flashで3Dが動くという話を聞いて、2,3年ほど前にPapervision3Dを使ってみたことがありました。それはまだ運用中のコンテンツなのですが、JiglibFlashで物理演算機能を追加したり、音声合成エンジンを追加したり、いろんなことを盛り込んだ結果当時の一般的なPCではFPSがでない、アニメーションがガタガタのものができあがりました。自分のPC環境ではなんとかみれるものの、他のユーザーからはいろいろ不満の声が聞かれました。
そんなコンテンツから収益が上がってくるわけもなく、プロジェクト的にはフェードアウトしていったのですが、年月を経てFlashはGPUを叩いて3D描画ができるようになりました。ひょっとしたらこのコンテンツは甦るんじゃないかと淡い気持ちを抱きました。
Away3Dを使ってみよう。
さて、Stage3Dについては別のプロジェクトで利用するために学習していたので基本的なことはわかっているつもりですが、Papervision3Dのようなある程度汎用性を担保しているライブラリを置き換える場合、同程度のライブラリが要求されることは想像に難くありません。自分用のライブラリも製作しているところではありますが、ちょっと特殊な仕様になっていたり、多くの機能を省いている都合で簡単にはPapervision3Dの代理は勤まらなそうです。Papervision3D自身がStage3D対応に動いてくれるのが一番よかったのかもしれませんが、期待できそうにはありません。
というわけで、いくつか世の中に出回っているStage3D対応ライブラリからAway3Dをチョイスしてみました。もともとPapervision3Dとも親戚にあたるようなライブラリらしいし、早いうちからアルファ版が出回っていて、多くの人に使われて、関連情報が得やすそうだし、AwayPhysicsなんていう物理演算ライブラリもあるそうだし、ということでライブラリファイルをダウンロードしてみました。
Papervision3Dとあわせて使っていたJiglibFlashという物理演算エンジンは多くの3Dエンジンとの親和性を実現してくれていたのですが、まだバージョンが若かったので機能的に不完全な部分が多くて、自分でソースを改変しながらプログラムを組んでいたのを覚えています。これをAwayPhysicsに置き換える作業がやはり一番面倒くさそうで途中で断念する可能性も捨て切れません。しかし、Awayシリーズでまとめたらそれ以上に3Dエンジンと物理演算エンジンに親和性が生まれて、きれいに実装ができるのではないかという期待もあります。
作業の方針
あまりプランを練らずに作業を開始してしまったのですが、とりあえずPapervision3DのクラスとJiglibFlashのクラスをソース上から追い出して、同等の機能を持つAwayシリーズのクラスで置き換えられれば目的が達成されるはずです。
とりあえず、Papervision3DでBasicViewという面倒なことを一手に引き受けてくれていたViewのクラスをAway3DのView3Dというクラスに置き換えてみます。そして、JiglibFlashのPapervision3DPhysicsクラスをAwayPhysicsのAWPDynamicsWorldクラスに置き換えます。この状態でコンパイルしようとするといろいろエラーが出てくるので、エラーがなくなるまで一つずつ直していけばいつか出来上がるんじゃないかという方針でスタートしました。Papervision3DとAway3Dは同名で同機能のクラスがあることが多いので、ライブラリの構成を把握しておくと作業が捗りそうです。
Date: 2012/2/12
修正ケース
修正前 | 修正後 |
RigidBody.material.frictionとRigidBody.material.restitution | AWPRigidBody.frictionとAWPRigidbody.restitutionへ |
物理演算の衝突を検知するときは衝突情報の配列を一つずつ調べてた | AWPEvent.COLLISION_ADDEDイベントのリスナーをAWPRigidBodyにつけておくと衝突時に呼び出される。AWPDynamicsWorld.collisionCallbackOnをtrueにする必要がある模様 |
JiglibFlashを勝手に拡張して衝突した物体を判別できるようにしていた | AWPCollisionObject.skin.extraに識別情報を付加しておくことに |
DisplayObject3Dのalphaプロパティを減衰するアニメーションがあった | Away3Dだと多分Materialを操作するのだろうけど、とりあえずScaleX、ScaleY、ScaleZを0に近づけるアニメーションでごまかした(後の課題とした) |
衝突すると物体の衝突する物体の角度の情報みたいなのを取得できたのができなくなった(dirToBody) | 衝突した二者の位置情報から計算した |
カメラのターゲットにDisplayObject3Dを指定するとカメラが勝手に追いかけてくれた | 毎フレーム、カメラ位置を更新してターゲットを追いかける |
addBody,removeBody | addRigidBody,removeRigidBody |
RigidBody.setVelocity | AWPRigidBody.applyCentralForce |
MovieMaterialとかGouraudMaterial | とりあえずBitmapMaterialとかColorMaterialに置換 |
Cylinder形状の側面だけMaterialを変更していた | |
JMatrix3Dは各行列要素をダイレクトに書き換えられた | Matrix3Dに置換してcopyRawDataTo |
Cube形状のマテリアルについてMaterialListで各面を制御 | CubeMapというクラスを発見したけどよくわからず |
Rigidbody.setActiveメソッド、setInactiveメソッド | AWPRigidBody.isActiveを操作はreadonlyなので困った。 |
DAEクラス | Loader3Dクラス |
DAEインスタンスはPVMeshにしてバウンディング情報を取得できた | |
MovieClipMaterialはtiled,maxU,maxVプロパティでタイリングを制御できた | BitmapMaterialのコンストラクタの三番目ぐらいの引数にrepeat設定があった |
MovieClipMaterialはMovieClip中の座標範囲を指定して描画できた | BitmapMaterialに渡すBitmapDataに適切にdrawすればよかった |
JPlane.yawで板ポリゴンを回転していた | AWPPlane.rotationXに回転角度を設定 |
Date: 2012/2/13-2012/2/29
調整
とりあえずコンパイル通りましたが、意図する絵がまだでてないです。
そして、ここでAway3D 4.0 Betaが2月17日に更新されていることに気づきました。いろいろ変更が入っているみたいで新たなエラーの原因が誕生しました。調整作業を断念し、再度、コンパイルを通すための修正作業に戻ります。
Data: 2012/3/28
修正ケース2
修正前 | 修正後 |
プリミティブのクラスがなくなった!? | PlaneはPlaneGeometryといったようにxxxGeometryクラスに移行 |
プリミティブのコンストラクタにマテリアルを指定できなくなった!? | プリミティブのような形状データ(geometry)とマテリアルを引数とするMeshクラスをシーンに追加するようにする模様 |
BitmapMaterialは使うなとの警告 | 4.0a版から非推奨でTextureMaterialを使えとのこと。BitmapTextureとあわせればこれまで通り。 |
直方体の各面に別個に画像を貼り付ける方法がよくわからなくなった | CubeGeometry.tile6プロパティをtrueにするとテクスチャを2x3のグリッドに分割して貼り付けてくれるとのこと |
DAE(Collada)のモデルデータを読み込めると思ってたのに読み込めない | Parsers.enableAllBundledを呼べと警告が出るも関係なし。Away3Dのフォーラムによると将来的にはcollada形式のモデルのパーサーも作るかもしれないけど、優先度は高くないから他のデータ形式にした方がいいとのこと。確かにColladaの仕様は複雑ですものね・・・ |
キャラクターのrotationYが-90丸いキャラクターですが天地があったのでrotationXとrotationZを毎フレーム、0に設定していたせいかも。rotationを軸別に動かないようにするには、AWPRigidbody.angularFactorを使えばいいらしい。 | |
剛体のrotationYがまだ-90剛体の位置を記述する方法に3つのオイラー角で表現する方法と四元数を使う方法とがあり、AwayPhysicsは前者を利用している。その場合、gimbal lockという現象が起こり、剛体の姿勢の自由度が失われることがあるらしい。それでもよく理由が理解できなかったのですが、こちらを読んでいろいろ納得しました。Matrix3Dを操作しているのがAwayPhysicsのパッケージの中なので、きれいに書けませんでした。 | |